summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--hwc2/common/base/HwcFenceControl.cpp22
-rw-r--r--hwc2/common/base/HwcLayer.cpp61
-rw-r--r--hwc2/common/base/HwcLayer.h7
-rw-r--r--hwc2/common/base/Hwcomposer.cpp3
-rw-r--r--hwc2/common/composers/Composers.cpp16
-rw-r--r--hwc2/common/composers/Composers.h15
-rw-r--r--hwc2/common/composers/GE2DComposer.cpp33
-rw-r--r--hwc2/common/composers/GE2DComposer.h22
-rw-r--r--hwc2/common/devices/PhysicalDevice.cpp598
-rw-r--r--hwc2/common/devices/PrimaryDevice.cpp13
-rw-r--r--hwc2/common/devices/VirtualDevice.cpp14
-rw-r--r--hwc2/common/hdmi/DisplayHdmi.cpp853
-rw-r--r--hwc2/common/hdmi/DisplayHdmi.h202
-rw-r--r--hwc2/common/observers/SoftVsyncObserver.cpp18
-rw-r--r--hwc2/common/observers/SoftVsyncObserver.h3
-rw-r--r--hwc2/common/observers/UeventObserver.cpp2
-rw-r--r--hwc2/common/utils/AmVideo.cpp109
-rw-r--r--hwc2/common/utils/AmVinfo.cpp928
-rw-r--r--hwc2/common/utils/Utils.cpp89
-rw-r--r--hwc2/common/utils/Utils.h30
-rw-r--r--hwc2/include/AmVideo.h45
-rw-r--r--hwc2/include/AmVinfo.h221
-rw-r--r--hwc2/include/HwcFenceControl.h15
-rw-r--r--hwc2/include/IComposer.h16
-rw-r--r--hwc2/include/IComposerFactory.h16
-rw-r--r--hwc2/include/IDisplayDevice.h16
-rw-r--r--hwc2/include/PhysicalDevice.h33
-rw-r--r--hwc2/include/VirtualDevice.h1
-rw-r--r--hwc2/platforms/Android.mk6
-rw-r--r--tvp/LICENSE23
-rw-r--r--tvp/OmxUtil.cpp48
-rw-r--r--tvp/OmxUtil.h13
32 files changed, 2617 insertions, 874 deletions
diff --git a/hwc2/common/base/HwcFenceControl.cpp b/hwc2/common/base/HwcFenceControl.cpp
index 15c24b5..b269be0 100644
--- a/hwc2/common/base/HwcFenceControl.cpp
+++ b/hwc2/common/base/HwcFenceControl.cpp
@@ -1,7 +1,21 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
+
#include <sync/sync.h>
#include <sw_sync.h>
@@ -34,7 +48,7 @@ int32_t HwcFenceControl::createFenceTimeline() {
syncTimelineFd = sw_sync_timeline_create();
if (syncTimelineFd < 0) {
- ETRACE("Stark, can't create sw_sync_timeline:");
+ ETRACE("Create sw_sync_timeline failed!");
return -1;
}
@@ -46,7 +60,7 @@ int32_t HwcFenceControl::createFence(int32_t syncTimelineFd,
int32_t fenceFd = sw_sync_fence_create(syncTimelineFd, str, val);
if (fenceFd < 0) {
- ETRACE("can't create sync pt %d: %s", val, strerror(errno));
+ ETRACE("Create fence %d failed, error(%s)", val, strerror(errno));
return -1;
}
@@ -58,7 +72,7 @@ status_t HwcFenceControl::syncTimelineInc(int32_t syncTimelineFd) {
err = sw_sync_timeline_inc(syncTimelineFd, 1);
if (err < 0) {
- ETRACE("can't increment sync obj:");
+ ETRACE("can't increment timeline(%d)", syncTimelineFd);
return -1;
}
return err;
diff --git a/hwc2/common/base/HwcLayer.cpp b/hwc2/common/base/HwcLayer.cpp
index 8163478..c0bf38e 100644
--- a/hwc2/common/base/HwcLayer.cpp
+++ b/hwc2/common/base/HwcLayer.cpp
@@ -23,6 +23,7 @@
#include <IDisplayDevice.h>
#include <cutils/properties.h>
#include <sync/sync.h>
+#include <AmVideo.h>
namespace android {
@@ -87,9 +88,9 @@ void HwcLayer::resetAcquireFence() {
bool HwcLayer::isCropped() {
bool rtn = true;
- private_handle_t const* buffer = reinterpret_cast<private_handle_t const*>(mBufferHnd);
+ private_handle_t const* buffer = private_handle_t::dynamicCast(mBufferHnd);
- if (buffer && buffer->width && buffer->height) {
+ if (buffer && buffer->width && buffer->height) {
float widthCmp = (mSourceCrop.right - mSourceCrop.left) / buffer->width;
float heightCmp = (mSourceCrop.bottom - mSourceCrop.top) / buffer->height;
@@ -153,19 +154,29 @@ bool HwcLayer::haveDataspace() {
return mDataSpace != HAL_DATASPACE_UNKNOWN;
}
+void HwcLayer::reverseScaledFrame(const float& scaleX, const float& scaleY) {
+ if (mScaleReversed)
+ return;
+
+ mDisplayFrame.left = mDisplayFrame.left * scaleX;
+ mDisplayFrame.top = mDisplayFrame.top * scaleY;
+ mDisplayFrame.right = mDisplayFrame.right * scaleX;
+ mDisplayFrame.bottom = mDisplayFrame.bottom * scaleY;
+ mScaleReversed = true;
+}
+
int32_t HwcLayer::setBuffer(buffer_handle_t buffer, int32_t acquireFence) {
Mutex::Autolock _l(mLock);
+ resetLayerBuffer();
// Bad parameter
- if (buffer && private_handle_t::validate(buffer) < 0)
- return HWC2_ERROR_BAD_PARAMETER;
-
- if (NULL == buffer) {
+ if (!private_handle_t::dynamicCast(buffer)) {
DTRACE("Layer buffer is null! no need to update this layer.");
+ return HWC2_ERROR_BAD_PARAMETER;
}
+
mBufferHnd = buffer;
mAcquireFence = acquireFence;
-
return HWC2_ERROR_NONE;
}
@@ -214,6 +225,7 @@ int32_t HwcLayer::setDisplayFrame(hwc_rect_t frame) {
// TODO: still have some work to do.
mDisplayFrame = frame;
+ mScaleReversed = false;
return HWC2_ERROR_NONE;
}
@@ -227,6 +239,7 @@ int32_t HwcLayer::setPlaneAlpha(float alpha) {
int32_t HwcLayer::setSidebandStream(const native_handle_t* stream) {
Mutex::Autolock _l(mLock);
+ resetLayerBuffer();
// Bad parameter.
if (NULL == stream) {
@@ -267,14 +280,24 @@ int32_t HwcLayer::setZ(uint32_t z) {
return HWC2_ERROR_NONE;
}
+void HwcLayer::resetLayerBuffer() {
+ mSidebandStream = NULL;
+ mBufferHnd = NULL;
+ HwcFenceControl::closeFd(mAcquireFence);
+ mAcquireFence = -1;
+}
+
#if WITH_LIBPLAYER_MODULE
-void HwcLayer::presentOverlay() {
+void HwcLayer::presentOverlay(bool bPresent) {
int32_t angle = 0;
bool vpp_changed = false;
bool axis_changed = false;
bool mode_changed = false;
bool free_scale_changed = false;
bool window_axis_changed =false;
+ hwc_rect_t* displayframe = &mDisplayFrame;
+
+ AmVideo::getInstance()->presentVideo(bPresent);
if (Utils::checkBoolProp("ro.vout.dualdisplay4")) {
vpp_changed = Utils::checkSysfsStatus(
@@ -287,10 +310,10 @@ void HwcLayer::presentOverlay() {
window_axis_changed = Utils::checkSysfsStatus(SYSFS_WINDOW_AXIS, mLastWindowaxis, 50);
if (mLastTransform == mTransform
- && mLastDisplayFrame.left == mDisplayFrame.left
- && mLastDisplayFrame.top == mDisplayFrame.top
- && mLastDisplayFrame.right == mDisplayFrame.right
- && mLastDisplayFrame.bottom== mDisplayFrame.bottom
+ && mLastDisplayFrame.left == displayframe->left
+ && mLastDisplayFrame.top == displayframe->top
+ && mLastDisplayFrame.right == displayframe->right
+ && mLastDisplayFrame.bottom== displayframe->bottom
&& !vpp_changed && !mode_changed && !axis_changed
&& !free_scale_changed && !window_axis_changed) {
return;
@@ -313,9 +336,9 @@ void HwcLayer::presentOverlay() {
return;
}
- amvideo_utils_set_virtual_position(mDisplayFrame.left, mDisplayFrame.top,
- mDisplayFrame.right - mDisplayFrame.left,
- mDisplayFrame.bottom - mDisplayFrame.top,
+ amvideo_utils_set_virtual_position(displayframe->left, displayframe->top,
+ displayframe->right -displayframe->left,
+ displayframe->bottom - displayframe->top,
angle);
/* the screen mode from Android framework should always be set to normal mode
@@ -324,10 +347,10 @@ void HwcLayer::presentOverlay() {
/*set screen_mode in amvideo_utils_set_virtual_position(),pls check in libplayer*/
//amvideo_utils_set_screen_mode(0);
mLastTransform = mTransform;
- mLastDisplayFrame.left = mDisplayFrame.left;
- mLastDisplayFrame.top = mDisplayFrame.top;
- mLastDisplayFrame.right = mDisplayFrame.right;
- mLastDisplayFrame.bottom = mDisplayFrame.bottom;
+ mLastDisplayFrame.left = displayframe->left;
+ mLastDisplayFrame.top = displayframe->top;
+ mLastDisplayFrame.right = displayframe->right;
+ mLastDisplayFrame.bottom = displayframe->bottom;
memset(mLastAxis, 0, sizeof(mLastAxis));
if (Utils::getSysfsStr(SYSFS_VIDEO_AXIS, mLastAxis, sizeof(mLastAxis)) == 0) {
diff --git a/hwc2/common/base/HwcLayer.h b/hwc2/common/base/HwcLayer.h
index 923248b..2c378ad 100644
--- a/hwc2/common/base/HwcLayer.h
+++ b/hwc2/common/base/HwcLayer.h
@@ -82,12 +82,16 @@ class HwcLayer {
bool haveColor();
bool havePlaneAlpha();
bool haveDataspace();
+ void reverseScaledFrame(const float& scaleX, const float& scaleY);
#if WITH_LIBPLAYER_MODULE
- void presentOverlay();
+ void presentOverlay(bool bPresent);
#endif
private:
+ void resetLayerBuffer();
+
+ private:
hwc2_display_t mDisplayId;
int32_t mBlendMode;
hwc_color_t mColor;
@@ -124,6 +128,7 @@ class HwcLayer {
// lock
Mutex mLock;
bool mInitialized;
+ bool mScaleReversed;
};
} // namespace amlogic
diff --git a/hwc2/common/base/Hwcomposer.cpp b/hwc2/common/base/Hwcomposer.cpp
index a271778..341ef53 100644
--- a/hwc2/common/base/Hwcomposer.cpp
+++ b/hwc2/common/base/Hwcomposer.cpp
@@ -124,8 +124,7 @@ int32_t Hwcomposer::registerCallback(
if (!device) {
ETRACE("no device found");
}
- device->updateDisplayConfigs();
- pfnHotplug(hotplug_cb_data, HWC_DISPLAY_PRIMARY, 1);
+ device->onHotplug(HWC_DISPLAY_PRIMARY, true);
}
break;
case HWC2_CALLBACK_REFRESH:
diff --git a/hwc2/common/composers/Composers.cpp b/hwc2/common/composers/Composers.cpp
index 093386c..a8ac50f 100644
--- a/hwc2/common/composers/Composers.cpp
+++ b/hwc2/common/composers/Composers.cpp
@@ -1,7 +1,21 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
+
#include <HwcTrace.h>
#include <Composers.h>
#include <IDisplayDevice.h>
diff --git a/hwc2/common/composers/Composers.h b/hwc2/common/composers/Composers.h
index 8f3dc69..26baa3f 100644
--- a/hwc2/common/composers/Composers.h
+++ b/hwc2/common/composers/Composers.h
@@ -1,5 +1,18 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
#ifndef COMPOSERS_H
diff --git a/hwc2/common/composers/GE2DComposer.cpp b/hwc2/common/composers/GE2DComposer.cpp
index 591b495..f18e7e8 100644
--- a/hwc2/common/composers/GE2DComposer.cpp
+++ b/hwc2/common/composers/GE2DComposer.cpp
@@ -1,6 +1,21 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
+
+
#include <HwcTrace.h>
#include <HwcFenceControl.h>
#include <GE2DComposer.h>
@@ -157,7 +172,7 @@ bool GE2DComposer::initialize(framebuffer_info_t* fbInfo)
if (ret < 0) {
DEINIT_AND_RETURN_FALSE("allocBuffer failed!");
}
- private_handle_t const *pHandle = reinterpret_cast<private_handle_t const*> (mGe2dBufHnd);
+ private_handle_t const *pHandle = private_handle_t::dynamicCast(mGe2dBufHnd);
if (pHandle) {
mSharedFd = pHandle->share_fd;
}
@@ -204,7 +219,7 @@ void GE2DComposer::deinitialize()
mSrcBufferInfo = NULL;
}
- private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(mGe2dBufHnd);
+ private_handle_t const* hnd = private_handle_t::dynamicCast(mGe2dBufHnd);
if (NULL != hnd) {
freeBuffer(hnd, mFbInfo->grallocModule);
mGe2dBufHnd = NULL;
@@ -448,7 +463,8 @@ void GE2DComposer::dumpLayers(
#if 1
int32_t base = 4 * (hnd->stride * (hnd->height / 2) + 10);
char* tmp = (char*)layerBuffer + base;
- DTRACE("[0x%x, 0x%x, 0x%x, 0x%x]\n"
+ ETRACE("GE2DComposer dump layer:\n"
+ "[0x%x, 0x%x, 0x%x, 0x%x]\n"
"[0x%x, 0x%x, 0x%x, 0x%x]\n"
"[0x%x, 0x%x, 0x%x, 0x%x]\n"
"[0x%x, 0x%x, 0x%x, 0x%x]\n",
@@ -463,7 +479,7 @@ void GE2DComposer::dumpLayers(
sprintf(path, "/data/local/tmp/layer_%" PRId64 ".bin", systemTime(SYSTEM_TIME_MONOTONIC));
fd = open(path, O_RDWR | O_CREAT);
if (-1 == fd) {
- ETRACE("Stark, open file failed!");
+ ETRACE("open file failed!");
return;
}
write(fd, layerBuffer, hnd->size);
@@ -471,7 +487,6 @@ void GE2DComposer::dumpLayers(
close(fd);
#endif
munmap(layerBuffer, hnd->size);
- DTRACE("dumpLayer ok");
} else {
ETRACE("layerBuffer mmap fail");
}
@@ -490,12 +505,12 @@ void GE2DComposer::runGE2DProcess(int32_t slot, Vector< LayerState* > &hwcLayers
layer[i] = hwcLayersState.itemAt(i);
sourceCrop[i] = layer[i]->mSourceCrop;
displayFrame[i] = layer[i]->mDisplayFrame;
- hnd[i] = reinterpret_cast<private_handle_t const*>(layer[i]->mBufferHnd);
+ hnd[i] = private_handle_t::dynamicCast(layer[i]->mBufferHnd);
DTRACE("layer[%d] zorder: %d, blend: %d, PlaneAlpha: %f, "
"mColor: [%d, %d, %d, %d], mDataSpace: %d, format hnd[%d]: %x",
i, layer[i]->mZ, layer[i]->mBlendMode, layer[i]->mPlaneAlpha,
layer[i]->mColor.r, layer[i]->mColor.g, layer[i]->mColor.b,
- layer[i]->mColor.a, layer[i]->mDataSpace, i, hnd[i]->format);
+ layer[i]->mColor.a, layer[i]->mDataSpace, i, hnd[i] ? hnd[i]->format : 0xff);
}
bool debugSameSize = Utils::checkBoolProp("sys.sf.debug.ss");
@@ -688,7 +703,7 @@ bool GE2DComposer::threadLoop()
// ge2d finished process, make sure fd close here.
for (int32_t i=0; i<layersState.size(); i++) {
LayerState* layer = layersState.itemAt(i);
- // ETRACE("close->layer:[%12" PRIxPTR ", %d]", layer->mBufferHnd, layer->mBufferFd);
+ // DTRACE("close->layer:[%12" PRIxPTR ", %d]", layer->mBufferHnd, layer->mBufferFd);
if (layer != NULL) {
Utils::closeFd(layer->mBufferFd);
layer->mBufferFd = -1;
diff --git a/hwc2/common/composers/GE2DComposer.h b/hwc2/common/composers/GE2DComposer.h
index c71c115..7dbff5c 100644
--- a/hwc2/common/composers/GE2DComposer.h
+++ b/hwc2/common/composers/GE2DComposer.h
@@ -1,5 +1,18 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
#ifndef GE2D_COMPOSER_H
@@ -43,8 +56,11 @@ public:
mDisplayFrame = hwcLayer->getDisplayFrame();
mBufferHnd = hwcLayer->getBufferHandle();
- private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(mBufferHnd);
- mBufferFd = Utils::checkAndDupFd(hnd->ion_hnd);
+ private_handle_t const* hnd = private_handle_t::dynamicCast(mBufferHnd);
+ if (hnd)
+ mBufferFd = Utils::checkAndDupFd(hnd->ion_hnd);
+ else
+ mBufferFd = -1;
}
int32_t mBlendMode;
diff --git a/hwc2/common/devices/PhysicalDevice.cpp b/hwc2/common/devices/PhysicalDevice.cpp
index 918c011..1d4f056 100644
--- a/hwc2/common/devices/PhysicalDevice.cpp
+++ b/hwc2/common/devices/PhysicalDevice.cpp
@@ -26,16 +26,8 @@
#include <Utils.h>
#include <HwcFenceControl.h>
#include <cutils/properties.h>
-#include <tvp/OmxUtil.h>
-#include <sys/utsname.h>
-#define FBIOPUT_OSD_CURSOR 0x451a
-
-static int Amvideo_Handle = 0;
-#include <vendor/amlogic/hardware/systemcontrol/1.0/ISystemControl.h>
-
-using ::vendor::amlogic::hardware::systemcontrol::V1_0::ISystemControl;
-using ::vendor::amlogic::hardware::systemcontrol::V1_0::Result;
+#define FBIOPUT_OSD_CURSOR 0x451a
namespace android {
namespace amlogic {
@@ -45,7 +37,7 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControl
mHwc(hwc),
mControlFactory(controlFactory),
mVsyncObserver(NULL),
- mIsConnected(false),
+ mConnectorPresent(false),
mSecure(false),
mFramebufferHnd(NULL),
mSystemControl(NULL),
@@ -55,6 +47,7 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControl
mClientTargetHnd(NULL),
mTargetAcquireFence(-1),
mRenderMode(GLES_COMPOSE_MODE),
+ mPreviousRenderMode(GLES_COMPOSE_MODE),
mIsValidated(false),
mIsContinuousBuf(true),
mDirectRenderLayerId(0),
@@ -62,8 +55,8 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControl
mGE2DClearVideoRegionCount(0),
mGE2DComposeFrameCount(0),
mDirectComposeFrameCount(0),
- mInitialized(false)
-{
+ mGetInitState(false),
+ mInitialized(false) {
CTRACE();
switch (id) {
@@ -78,41 +71,19 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControl
}
mHdrCapabilities.init = false;
- // init Display here.
- initDisplay();
-
- // set capacity of layers, layer's changed type, layer's changed request.
- // mHwcLayersChangeType.setCapacity(LAYER_MAX_NUM_CHANGE_TYPE);
- // mHwcLayersChangeRequest.setCapacity(LAYER_MAX_NUM_CHANGE_REQUEST);
- // mHwcGlesLayers.setCapacity(LAYER_MAX_NUM_CHANGE_TYPE);
- // mHwcLayers.setCapacity(LAYER_MAX_NUM_SUPPORT);
-#ifdef HWC_ENABLE_SECURE_LAYER
- // mHwcSecureLayers.setCapacity(LAYER_MAX_NUM_SECURE_PROTECTED);
- mHwcSecureLayers.clear();
-#endif
// clear layers vectors.
+ mHwcSecureLayers.clear();
mHwcLayersChangeType.clear();
mHwcLayersChangeRequest.clear();
mHwcGlesLayers.clear();
mHwcLayers.clear();
-
- // mGE2DRenderSortedLayerIds.setCapacity(HWC2_MAX_LAYERS);
mGE2DRenderSortedLayerIds.clear();
mHwcCurReleaseFences = mHwcPriorReleaseFences = NULL;
-
- int major = 0, minor = 0;
- struct utsname info;
- if (uname(&info) || sscanf(info.release, "%d.%d", &major, &minor) <= 0) {
- ETRACE("Could not get linux version: %s", strerror(errno));
- }
- // from kernel 4.9 use FBIOPUT_OSD_CURSOR instead of FBIO_CURSOR
- mUsingPutCurosr = major > 4 || (major == 4 && minor >= 9);
}
-PhysicalDevice::~PhysicalDevice()
-{
+PhysicalDevice::~PhysicalDevice() {
WARN_IF_NOT_DEINIT();
clearFenceList(mHwcCurReleaseFences);
clearFenceList(mHwcPriorReleaseFences);
@@ -126,14 +97,15 @@ bool PhysicalDevice::initialize() {
return false;
}
+ // init Display here.
+ initDisplay();
+
// create vsync event observer, we only have soft vsync now...
mVsyncObserver = new SoftVsyncObserver(*this);
if (!mVsyncObserver || !mVsyncObserver->initialize()) {
DEINIT_AND_RETURN_FALSE("failed to create vsync observer");
}
- mDisplayHdmi = new DisplayHdmi(mId);
- mDisplayHdmi->initialize();
UeventObserver *observer = Hwcomposer::getInstance().getUeventObserver();
if (observer) {
observer->registerListener(
@@ -144,20 +116,21 @@ bool PhysicalDevice::initialize() {
ETRACE("PhysicalDevice::Uevent observer is NULL");
}
+ mDisplayHdmi = new DisplayHdmi();
+ mDisplayHdmi->initialize(*(mFramebufferContext->getInfo()));
+
mInitialized = true;
return true;
}
-void PhysicalDevice::hdcpEventListener(void *data, bool status)
-{
+void PhysicalDevice::hdcpEventListener(void *data, bool status) {
PhysicalDevice *pThis = (PhysicalDevice*)data;
if (pThis) {
pThis->setSecureStatus(status);
}
}
-void PhysicalDevice::setSecureStatus(bool status)
-{
+void PhysicalDevice::setSecureStatus(bool status) {
DTRACE("hdcp event: %d", status);
mSecure = status;
}
@@ -203,7 +176,6 @@ int32_t PhysicalDevice::acceptDisplayChanges() {
hwc2_layer_t layerId = mHwcLayersChangeType.keyAt(i);
layer = mHwcLayersChangeType.valueAt(i);
if (layer) {
-#ifdef HWC_ENABLE_SECURE_LAYER
// deal non secure display.
if (!mSecure && !mHwcSecureLayers.isEmpty()) {
for (uint32_t j=0; j<mHwcSecureLayers.size(); j++) {
@@ -219,7 +191,6 @@ int32_t PhysicalDevice::acceptDisplayChanges() {
}
}
}
-#endif
if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE
|| layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
layer->setCompositionType(HWC2_COMPOSITION_CLIENT);
@@ -228,16 +199,6 @@ int32_t PhysicalDevice::acceptDisplayChanges() {
}
}
}
- // reset layer changed or requested size to zero.
- mHwcLayersChangeType.clear();
- mHwcLayersChangeRequest.clear();
-
-#ifdef HWC_ENABLE_SECURE_LAYER
- // deal non secure display device.
- if (!mHwcSecureLayers.isEmpty()) {
- mHwcSecureLayers.clear();
- }
-#endif
return HWC2_ERROR_NONE;
}
@@ -253,7 +214,7 @@ bool PhysicalDevice::createLayer(hwc2_layer_t* outLayer) {
hwc2_layer_t layerId = reinterpret_cast<hwc2_layer_t>(layer);
mHwcLayers.add(layerId, layer);
*outLayer = layerId;
- DTRACE("::createLayer layerId %lld, size: [%d].\n", layerId, mHwcLayers.size());
+ DTRACE("::createLayer layerId (%lld), size: [%d].\n", layerId, mHwcLayers.size());
return true;
}
@@ -272,7 +233,7 @@ bool PhysicalDevice::destroyLayer(hwc2_layer_t layerId) {
if (idx >= 0) {
HwcFenceControl::closeFd(mLayerReleaseFences[i].valueAt(idx));
mLayerReleaseFences[i].removeItemsAt(idx);
- DTRACE("destroyLayer remove layer %lld from cur release list %p\n", layerId, &(mLayerReleaseFences[i]));
+ DTRACE("destroyLayer layer(%lld) from cur release list (%p).\n", layerId, &(mLayerReleaseFences[i]));
}
}
@@ -302,7 +263,6 @@ int32_t PhysicalDevice::getChangedCompositionTypes(
hwc2_layer_t layerId = mHwcLayersChangeType.keyAt(i);
layer = mHwcLayersChangeType.valueAt(i);
if (layer) {
-#ifdef HWC_ENABLE_SECURE_LAYER
// deal non secure display.
if (!mSecure && !mHwcSecureLayers.isEmpty()) {
for (uint32_t j=0; j<mHwcSecureLayers.size(); j++) {
@@ -316,7 +276,6 @@ int32_t PhysicalDevice::getChangedCompositionTypes(
}
}
}
-#endif
if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE
|| layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
@@ -392,7 +351,7 @@ int32_t PhysicalDevice::getDisplayAttribute(
int32_t* outValue) {
Mutex::Autolock _l(mLock);
- if (!mIsConnected) {
+ if (!mConnectorPresent) {
ETRACE("display %d is not connected.", mId);
}
@@ -438,7 +397,7 @@ int32_t PhysicalDevice::getDisplayRequests(
}
/* if (layer->getBufferHandle()) {
private_handle_t const* hnd =
- reinterpret_cast<private_handle_t const*>(layer->getBufferHandle());
+ private_handle_t::dynamicCast(layer->getBufferHandle());
if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
outLayers[i] = layerId;
outLayerRequests[i] = HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET;
@@ -449,7 +408,6 @@ int32_t PhysicalDevice::getDisplayRequests(
// sideband stream.
if ((layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND && layer->getSidebandStream())
- //|| layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR
|| layer->getCompositionType() == HWC2_COMPOSITION_CURSOR) {
// TODO: we just transact SIDEBAND to OVERLAY for now;
DTRACE("get HWC_SIDEBAND layer, just change to overlay");
@@ -490,14 +448,13 @@ int32_t PhysicalDevice::getHdrCapabilities(
float* outMinLuminance) {
Mutex::Autolock _l(mLock);
- if (!mIsConnected) {
+ if (!mConnectorPresent) {
ETRACE("disp: %llu is not connected", mId);
return HWC2_ERROR_BAD_DISPLAY;
}
if (!mHdrCapabilities.init) {
- parseHdrCapabilities();
- mHdrCapabilities.init = true;
+ ETRACE("HDRCapability not updated.");
}
if (NULL == outTypes) {
@@ -540,7 +497,6 @@ void PhysicalDevice::swapReleaseFence() {
}
}
-
void PhysicalDevice::addReleaseFence(hwc2_layer_t layerId, int32_t fenceFd) {
ssize_t idx = mHwcCurReleaseFences->indexOfKey(layerId);
if (idx >= 0 && idx < mHwcCurReleaseFences->size()) {
@@ -550,7 +506,7 @@ void PhysicalDevice::addReleaseFence(hwc2_layer_t layerId, int32_t fenceFd) {
mHwcCurReleaseFences->replaceValueAt(idx, newFence);
HwcFenceControl::closeFd(oldFence);
HwcFenceControl::closeFd(fenceFd);
- ETRACE("addReleaseFence:(%d, %d) + %d -> (%d,%d)\n", idx, oldFence, fenceFd, idx, newFence);
+ DTRACE("addReleaseFence:(%d, %d) + %d -> (%d,%d)\n", idx, oldFence, fenceFd, idx, newFence);
dumpFenceList(mHwcCurReleaseFences);
} else {
mHwcCurReleaseFences->add(layerId, fenceFd);
@@ -682,15 +638,15 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOv
hwc2_layer_t layerId = mHwcLayers.keyAt(i);
layer = mHwcLayers.valueAt(i);
if (layer && layer->getCompositionType()== HWC2_COMPOSITION_CURSOR) {
- private_handle_t *hnd = (private_handle_t *)(layer->getBufferHandle());
- if (private_handle_t::validate(hnd) < 0) {
+ private_handle_t *hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
+ if (!hnd) {
ETRACE("invalid cursor layer handle.");
break;
}
haveCursorLayer = true;
DTRACE("This is a Sprite, hnd->stride is %d, hnd->height is %d", hnd->stride, hnd->height);
if (cbInfo->info.xres != (uint32_t)hnd->stride || cbInfo->info.yres != (uint32_t)hnd->height) {
- ETRACE("disp: %d cursor need to redrew", mId);
+ DTRACE("disp: %d cursor need to redrew", mId);
update_cursor_buffer_locked(cbInfo, hnd->stride, hnd->height);
cbuffer = mmap(NULL, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED, cbInfo->fd, 0);
if (cbuffer != MAP_FAILED) {
@@ -698,7 +654,7 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOv
munmap(cbuffer, hnd->size);
DTRACE("setCursor ok");
} else {
- ETRACE("buffer mmap fail");
+ ETRACE("Cursor display buffer mmap fail!");
}
}
cursorShow = true;
@@ -708,7 +664,7 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOv
if (mRenderMode == GLES_COMPOSE_MODE) {
//if no layers to compose, post blank op to osd.
- if (mHwcGlesLayers.size() == 0) {
+ if (mPreviousRenderMode != GLES_COMPOSE_MODE && mHwcGlesLayers.size() == 0) {
mClientTargetHnd = NULL;
}
} else if (mRenderMode == DIRECT_COMPOSE_MODE) { // if only one layer exists, let hwc do her work.
@@ -721,25 +677,8 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOv
#endif
mFbSyncRequest.type = mRenderMode;
- bool needBlankFb0 = false;
- uint32_t layerNum = mHwcLayers.size();
- if (hasVideoOverlay && (layerNum == 1 || (layerNum == 2 && haveCursorLayer)))
- needBlankFb0 = true;
-
- if (bUseHwcPost) {
- // bit 0 is osd blank flag.
- if (needBlankFb0) {
- mFbSyncRequest.op |= OSD_BLANK_OP_BIT;
- } else {
- mFbSyncRequest.op &= ~(OSD_BLANK_OP_BIT);
- }
- mFramebufferContext->setStatus(needBlankFb0);
- } else {
- setOSD0Blank(needBlankFb0);
- }
-
if (!mClientTargetHnd || private_handle_t::validate(mClientTargetHnd) < 0 || mPowerMode == HWC2_POWER_MODE_OFF) {
- ETRACE("Post blank to screen, mClientTargetHnd(%p, %d), mTargetAcquireFence(%d)",
+ DTRACE("Post blank to screen, mClientTargetHnd(%p, %d), mTargetAcquireFence(%d)",
mClientTargetHnd, private_handle_t::validate(mClientTargetHnd), mTargetAcquireFence);
*outRetireFence = HwcFenceControl::merge(String8("ScreenBlank"), mPriorFrameRetireFence, mPriorFrameRetireFence);
HwcFenceControl::closeFd(mTargetAcquireFence);
@@ -768,6 +707,14 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOv
HwcFenceControl::closeFd(mPriorFrameRetireFence);
mPriorFrameRetireFence = -1;
+ bool needBlankFb0 = false;
+ uint32_t layerNum = mHwcLayers.size();
+ if (hasVideoOverlay
+ && (layerNum == 1
+ || (layerNum == 2
+ && haveCursorLayer))) {
+ needBlankFb0 = true;
+ }
// real post framebuffer here.
DTRACE("render type: %d", mFbSyncRequest.type);
@@ -778,8 +725,16 @@ int32_t PhysicalDevice::postFramebuffer(int32_t* outRetireFence, bool hasVideoOv
#endif
if (!bUseHwcPost) {
+ setOSD0Blank(needBlankFb0);
mPriorFrameRetireFence = fb_post_with_fence_locked(&fbInfo, mClientTargetHnd, mTargetAcquireFence);
} else {
+ // bit 0 is osd blank flag.
+ if (needBlankFb0) {
+ mFbSyncRequest.op |= OSD_BLANK_OP_BIT;
+ } else {
+ mFbSyncRequest.op &= ~(OSD_BLANK_OP_BIT);
+ }
+ mFramebufferContext->setStatus(needBlankFb0);
// acquire fence.
mFbSyncRequest.in_fen_fd = mTargetAcquireFence;
mPriorFrameRetireFence = hwc_fb_post_with_fence_locked(&fbInfo, &mFbSyncRequest, mClientTargetHnd);
@@ -834,7 +789,8 @@ int32_t PhysicalDevice::setOSD0Blank(bool blank) {
return HWC2_ERROR_NONE;
}
-int32_t PhysicalDevice::presentDisplay(int32_t* outRetireFence) {
+int32_t PhysicalDevice::presentDisplay(
+ int32_t* outRetireFence) {
int32_t err = HWC2_ERROR_NONE;
HwcLayer* layer = NULL;
bool hasVideoOverlay = false;
@@ -842,11 +798,16 @@ int32_t PhysicalDevice::presentDisplay(int32_t* outRetireFence) {
if (mIsValidated) {
// TODO: need improve the way to set video axis.
#if WITH_LIBPLAYER_MODULE
+ bool bPresent = true;
+ if (mHwcSecureLayers.indexOfKey(mVideoOverlayLayerId) >= 0) {
+ bPresent = false;
+ }
+
ssize_t index = mHwcLayers.indexOfKey(mVideoOverlayLayerId);
if (index >= 0) {
layer = mHwcLayers.valueFor(mVideoOverlayLayerId);
if (layer != NULL) {
- layer->presentOverlay();
+ layer->presentOverlay(bPresent);
hasVideoOverlay = true;
if (mGE2DClearVideoRegionCount < 3) {
mGE2DClearVideoRegionCount++;
@@ -861,17 +822,7 @@ int32_t PhysicalDevice::presentDisplay(int32_t* outRetireFence) {
err = HWC2_ERROR_NOT_VALIDATED;
}
- // reset layers' acquire fence.
- for (uint32_t i=0; i<mHwcLayers.size(); i++) {
- hwc2_layer_t layerId = mHwcLayers.keyAt(i);
- layer = mHwcLayers.valueAt(i);
- if (layer != NULL) {
- layer->resetAcquireFence();
- }
- }
-
- mClientTargetHnd = NULL;
-
+ finishCompose();
return err;
}
@@ -880,8 +831,9 @@ int32_t PhysicalDevice::setActiveConfig(
Mutex::Autolock _l(mLock);
int32_t err = mDisplayHdmi->setActiveConfig(config);
- if (err == HWC2_ERROR_NONE)
- mVsyncObserver->setRefreshRate(mDisplayHdmi->getActiveRefreshRate());
+ if (err == HWC2_ERROR_NONE) {
+ updateActiveDisplayAttribute();
+ }
return err;
}
@@ -985,9 +937,13 @@ bool PhysicalDevice::layersStateCheck(int32_t renderMode,
layer[i] = composeLayers.valueAt(i);
sourceCrop[i] = layer[i]->getSourceCrop();
displayFrame[i] = layer[i]->getDisplayFrame();
- hnd[i] = reinterpret_cast<private_handle_t const*>(layer[i]->getBufferHandle());
+ hnd[i] = private_handle_t::dynamicCast(layer[i]->getBufferHandle());
if (hnd[i] == NULL) return false; // no buffer to process.
if (hnd[i]->share_fd == -1) return false; // no buffer to process.
+ if ((sourceCrop[i].right - sourceCrop[i].left > HWC2_HW_COMPOSE_WIDTH_MAX) ||
+ (sourceCrop[i].bottom - sourceCrop[i].top > HWC2_HW_COMPOSE_HEIGHT_MAX)) {
+ return false;
+ }
DTRACE("layer[%d] zorder: %d, blend: %d, PlaneAlpha: %f, "
"mColor: [%d, %d, %d, %d], mDataSpace: %d, format hnd[%d]: %x",
i, layer[i]->getZ(), layer[i]->getBlendMode(), layer[i]->getPlaneAlpha(),
@@ -1010,10 +966,8 @@ bool PhysicalDevice::layersStateCheck(int32_t renderMode,
return false;
break;
}
- if (layer[0]->isCropped()
- || layer[0]->isScaled()
- || layer[0]->isOffset()) {
- DTRACE("direct compose can not process!");
+ if (layer[0]->getTransform() != 0) {
+ //DTRACE("Direct composer can NOT support rotation now.");
return false;
}
}
@@ -1061,8 +1015,7 @@ bool PhysicalDevice::layersStateCheck(int32_t renderMode,
}
#endif
if (HWC2_TWO_LAYERS == layerNum
- && (!Utils::compareSize(sourceCrop[0], sourceCrop[1])
- || !Utils::compareSize(displayFrame[0], displayFrame[1]))) {
+ && (layer[0]->isScaled() || layer[1]->isScaled())) {
DTRACE("when 2 layer's size is difference, ge2d compose can not process!");
return false;
}
@@ -1076,8 +1029,7 @@ bool PhysicalDevice::layersStateCheck(int32_t renderMode,
* For direct framebuffer composer:
* 1) only support one layer.
* 2) layer format: rgba, rgbx,rgb565,bgra;
- * 3) layer no need scale to display;
- * 4) layer has no offset to display;
+ * 3) layer no rotation.
* For ge2d composer:
* 1) support layer format that direct composer can't support.
@@ -1151,95 +1103,187 @@ int32_t PhysicalDevice::composersFilter(
return GLES_COMPOSE_MODE;
}
-int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
- uint32_t* outNumRequests) {
+bool PhysicalDevice::calReverseScale() {
+ static float fb_w = 1920; // Query activeConfig for FB size?
+ static float fb_h = 1080; // Query activeConfig for FB size?
+
+ mReverseScaleX = mReverseScaleY = 0.0f;
+ if (fb_w <= 0.01f || fb_h <= 0.01f)
+ return false;
+
+ float display_w, display_h;
+ hwc2_config_t config;
+ if (HWC2_ERROR_NONE != mDisplayHdmi->getRealActiveConfig(&config))
+ return false;
+
+ int32_t tmpSize = 0.0f;
+ if ( mDisplayHdmi->getDisplayAttribute(config,
+ HWC2_ATTRIBUTE_WIDTH, &tmpSize) != NO_ERROR)
+ return false;
+ display_w = tmpSize;
+ if ( mDisplayHdmi->getDisplayAttribute(config,
+ HWC2_ATTRIBUTE_HEIGHT, &tmpSize) != NO_ERROR)
+ return false;
+ display_h = tmpSize;
+
+ if (display_w <= 0.01f || display_h <= 0.01f)
+ return false;
+
+ mReverseScaleX = fb_w / display_w;
+ mReverseScaleY = fb_h /display_h;
+ return false;
+}
+
+int32_t PhysicalDevice::preValidate() {
+ bool bScale = (mReverseScaleX >= 0.01f && mReverseScaleX >= 0.01f) ? true : false;
HwcLayer* layer = NULL;
- bool istvp = false;
- KeyedVector<hwc2_layer_t, HwcLayer*> composeLayers;
- composeLayers.clear();
+ //find out video layer first.
+ for (uint32_t i=0; i<mHwcLayers.size(); i++) {
+ hwc2_layer_t layerId = mHwcLayers.keyAt(i);
+ layer = mHwcLayers.valueAt(i);
+ if (!layer) {
+ ETRACE("Meet empty layer, id(%lld)", layerId);
+ continue;
+ }
- mRenderMode = GLES_COMPOSE_MODE;
- mVideoOverlayLayerId = 0;
- mIsContinuousBuf = true;
+ if (bScale && (layer->getDisplayFrame().right >= 3800))
+ layer->reverseScaledFrame(mReverseScaleX, mReverseScaleY);
+
+ private_handle_t const* hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
+ if (hnd && !((hnd->flags & private_handle_t::PRIV_FLAGS_CONTINUOUS_BUF)
+ || (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY))) {
+ mIsContinuousBuf = false;
+ }
+
+ if ((hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) &&
+ (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE)) ||
+ (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND
+ && layer->getSidebandStream())) {
+ if (mVideoOverlayLayerId != 0) {
+ ETRACE("ERROR: Find two video layer, should never get here !!");
+ }
+ mVideoOverlayLayerId = layerId;
+ }
+ }
+
+ return HWC2_ERROR_NONE;
+}
+
+int32_t PhysicalDevice::beginCompose() {
swapReleaseFence();
- memset(&mFbSyncRequest, 0, sizeof(mFbSyncRequest));
+ // reset layer changed or requested size to zero.
+ mHwcLayersChangeType.clear();
+ mHwcLayersChangeRequest.clear();
mHwcGlesLayers.clear();
+ // deal non secure display device.
+ mHwcSecureLayers.clear();
+
+ memset(&mFbSyncRequest, 0, sizeof(mFbSyncRequest));
+ mFbSyncRequest.in_fen_fd = -1;
+
+ mVideoOverlayLayerId = 0;
+ mIsContinuousBuf = true;
mIsValidated = false;
+ mRenderMode = GLES_COMPOSE_MODE;
+ return HWC2_ERROR_NONE;
+}
+
+int32_t PhysicalDevice::finishCompose() {
+ HwcLayer* layer = NULL;
+ // reset layers' acquire fence.
for (uint32_t i=0; i<mHwcLayers.size(); i++) {
hwc2_layer_t layerId = mHwcLayers.keyAt(i);
layer = mHwcLayers.valueAt(i);
if (layer != NULL) {
- // Physical Display.
- private_handle_t const* hnd =
- reinterpret_cast<private_handle_t const*>(layer->getBufferHandle());
- if (hnd) {
- // continous buffer.
- if (!(hnd->flags & private_handle_t::PRIV_FLAGS_CONTINUOUS_BUF
- || hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY)) {
- DTRACE("continous buffer flag is not set, bufhnd: 0x%" PRIxPTR "", intptr_t(layer->getBufferHandle()));
- mIsContinuousBuf = false;
- }
-#ifdef HWC_ENABLE_SECURE_LAYER
- // secure or protected layer.
- if (!mSecure && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_PROTECTED)) {
- ETRACE("layer's secure or protected buffer flag is set!");
- if (layer->getCompositionType() != HWC2_COMPOSITION_DEVICE) {
- mHwcLayersChangeType.add(layerId, layer);
- }
- mHwcSecureLayers.add(layerId, layer);
- continue;
- }
-#endif
- if (layer->getCompositionType() == HWC2_COMPOSITION_DEVICE) {
- // video overlay.
- if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OMX) {
- set_omx_pts((char*)hnd->base, &Amvideo_Handle);
- istvp = true;
- }
- if (hnd->flags & private_handle_t::PRIV_FLAGS_VIDEO_OVERLAY) {
- DTRACE("PRIV_FLAGS_VIDEO_OVERLAY!!!!");
- mVideoOverlayLayerId = layerId;
- mHwcLayersChangeRequest.add(layerId, layer);
- continue;
- }
+ layer->resetAcquireFence();
+ }
+ }
- composeLayers.add(layerId, layer);
- continue;
- }
- }
+ mClientTargetHnd = NULL;
+ mPreviousRenderMode = mRenderMode;
+ return HWC2_ERROR_NONE;
+}
- // cursor layer.
- if (layer->getCompositionType() == HWC2_COMPOSITION_CURSOR) {
- DTRACE("This is a Cursor layer!");
- mHwcLayersChangeRequest.add(layerId, layer);
- continue;
- }
+int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
+ uint32_t* outNumRequests) {
+ HwcLayer* layer = NULL, *videoLayer = NULL;
+ hwc_rect_t videoRect;
+ KeyedVector<hwc2_layer_t, HwcLayer*> composeLayers;
+ composeLayers.clear();
- // sideband stream.
- if (layer->getCompositionType() == HWC2_COMPOSITION_SIDEBAND
- && layer->getSidebandStream()) {
- // TODO: we just transact SIDEBAND to OVERLAY for now;
- DTRACE("get HWC_SIDEBAND layer, just change to overlay");
- mHwcLayersChangeRequest.add(layerId, layer);
+ beginCompose();
+
+ if (preValidate() != HWC2_ERROR_NONE) {
+ return HWC2_ERROR_BAD_LAYER;
+ }
+
+ if (mVideoOverlayLayerId) {
+ videoLayer = mHwcLayers.valueFor(mVideoOverlayLayerId);
+ videoRect = videoLayer->getDisplayFrame();
+ }
+
+ for (uint32_t i=0; i<mHwcLayers.size(); i++) {
+ int overlapType = Utils::OVERLAP_EMPTY;
+ hwc2_layer_t layerId = mHwcLayers.keyAt(i);
+ layer = mHwcLayers.valueAt(i);
+ if (!layer)
+ continue;
+
+ private_handle_t const* hnd = private_handle_t::dynamicCast(layer->getBufferHandle());
+
+#ifdef HWC_SUPPORT_SECURE_LAYER
+ // secure or protected layer.
+ if (!mSecure && hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_PROTECTED)) {
+ DTRACE("layer's secure or protected buffer flag is set! usage (%x)", hnd->flags);
+ if (layer->getCompositionType() != HWC2_COMPOSITION_DEVICE) {
mHwcLayersChangeType.add(layerId, layer);
- mVideoOverlayLayerId = layerId;
- continue;
}
+ mHwcSecureLayers.add(layerId, layer);
+ continue;
+ }
+#endif
- // solid color.
- if (layer->getCompositionType() == HWC2_COMPOSITION_SOLID_COLOR) {
- DTRACE("This is a Solid Color layer!");
- // mHwcLayersChangeRequest.add(layerId, layer);
- // mHwcLayersChangeType.add(layerId, layer);
- composeLayers.add(layerId, layer);
- continue;
- }
+ if (videoLayer && (layer->getZ() < videoLayer->getZ())) {
+ DTRACE("Layer covered by video layer.");
+ hwc_rect_t layerRect = layer->getDisplayFrame();
+ overlapType = Utils::rectOverlap(layerRect, videoRect);
+ }
- if (layer->getCompositionType() == HWC2_COMPOSITION_CLIENT) {
+ switch (layer->getCompositionType()) {
+ case HWC2_COMPOSITION_CLIENT:
mHwcGlesLayers.add(layerId, layer);
DTRACE("Meet a client layer!");
- }
+ break;
+ case HWC2_COMPOSITION_DEVICE:
+ if (layerId == mVideoOverlayLayerId) {
+ mHwcLayersChangeRequest.add(layerId, layer);
+ } else {
+ composeLayers.add(layerId, layer);
+ }
+ break;
+ case HWC2_COMPOSITION_SOLID_COLOR:
+ if (overlapType != Utils::OVERLAP_FULL) {
+ mHwcGlesLayers.add(layerId, layer);
+ mHwcLayersChangeType.add(layerId, layer);
+ }
+ break;
+ case HWC2_COMPOSITION_CURSOR:
+ DTRACE("This is a Cursor layer!");
+ mHwcLayersChangeRequest.add(layerId, layer);
+ break;
+ case HWC2_COMPOSITION_SIDEBAND:
+ if (layerId == mVideoOverlayLayerId) {
+ DTRACE("get HWC_SIDEBAND layer, just change to overlay");
+ mHwcLayersChangeRequest.add(layerId, layer);
+ mHwcLayersChangeType.add(layerId, layer);
+ } else {
+ ETRACE("SIDEBAND not handled.");
+ }
+ break;
+ default:
+ ETRACE("get layer of unknown composition type (%d)", layer->getCompositionType());
+ break;
}
}
@@ -1261,17 +1305,12 @@ int32_t PhysicalDevice::validateDisplay(uint32_t* outNumTypes,
mDirectComposeFrameCount = 0;
}
- //DEVICE_COMPOSE layers set to CLIENT_COMPOSE layers.
+ // DEVICE_COMPOSE layers set to CLIENT_COMPOSE layers.
for (int i=0; i<composeLayers.size(); i++) {
mHwcLayersChangeType.add(composeLayers.keyAt(i), composeLayers.valueAt(i));
mHwcGlesLayers.add(composeLayers.keyAt(i), composeLayers.valueAt(i));
}
- if (istvp == false && Amvideo_Handle!=0) {
- closeamvideo();
- Amvideo_Handle = 0;
- }
-
if (mHwcLayersChangeRequest.size() > 0) {
DTRACE("There are %d layer requests.", mHwcLayersChangeRequest.size());
*outNumRequests = mHwcLayersChangeRequest.size();
@@ -1300,11 +1339,7 @@ int32_t PhysicalDevice::setCursorPosition(hwc2_layer_t layerId, int32_t x, int32
cinfo.hot.y = y;
DTRACE("setCursorPosition x_pos=%d, y_pos=%d", cinfo.hot.x, cinfo.hot.y);
- // from kernel 4.9 use FBIOPUT_OSD_CURSOR instead of FBIO_CURSOR
- if (mUsingPutCurosr)
- ioctl(cbInfo->fd, FBIOPUT_OSD_CURSOR, &cinfo);
- else
- ioctl(cbInfo->fd, FBIO_CURSOR, &cinfo);
+ ioctl(cbInfo->fd, FBIOPUT_OSD_CURSOR, &cinfo);
}
} else {
ETRACE("setCursorPosition bad layer.");
@@ -1319,8 +1354,6 @@ int32_t PhysicalDevice::setCursorPosition(hwc2_layer_t layerId, int32_t x, int32
Operater of framebuffer
*/
int32_t PhysicalDevice::initDisplay() {
- if (mIsConnected) return 0;
-
Mutex::Autolock _l(mLock);
if (!mFramebufferHnd) {
@@ -1363,8 +1396,6 @@ int32_t PhysicalDevice::initDisplay() {
bufferSize, usage);
}
- mIsConnected = true;
-
// init cursor framebuffer
mCursorContext = new FBContext();
framebuffer_info_t* cbInfo = mCursorContext->getInfo();
@@ -1397,86 +1428,71 @@ int32_t PhysicalDevice::initDisplay() {
return 0;
}
-bool PhysicalDevice::updateDisplayConfigs() {
- Mutex::Autolock _l(mLock);
- bool ret;
-
- if (!mIsConnected) {
- ETRACE("disp: %llu is not connected", mId);
- return false;
+void PhysicalDevice::updateActiveDisplayAttribute() {
+ hwc2_config_t config;
+ if (HWC2_ERROR_NONE == mDisplayHdmi->getRealActiveConfig(&config)) {
+ int32_t period = 0;
+ mDisplayHdmi->getDisplayAttribute(config, HWC2_ATTRIBUTE_VSYNC_PERIOD, &period);
+ mVsyncObserver->setRefreshPeriod(period);
}
+ calReverseScale();
+}
+
+bool PhysicalDevice::updateDisplayConfigs() {
+ Mutex::Autolock _l(mLock);
framebuffer_info_t* fbinfo = mFramebufferContext->getInfo();
- ret = Utils::checkVinfo(fbinfo);
- if (!ret) {
- ETRACE("checkVinfo fail");
+ mDisplayHdmi->updateHotplug(mConnectorPresent, *fbinfo);
+
+ if (mConnectorPresent) {
+ updateActiveDisplayAttribute();
+ } else {
+ ETRACE("disp: %llu is not connected, should change mode to null", mId);
+ // mDisplayHdmi->setBestDisplayMode();
return false;
}
- mDisplayHdmi->updateHotplug(mIsConnected, fbinfo, mFramebufferHnd);
- if (mIsConnected)
- mVsyncObserver->setRefreshRate(mDisplayHdmi->getActiveRefreshRate());
- //ETRACE("updateDisplayConfigs rate:%d", mDisplayHdmi->getActiveRefreshRate());
-
- // check hdcp authentication status when hotplug is happen.
- int status = 0;
- bool trebleSystemControlEnable = property_get_bool("persist.system_control.treble", true);
- sp<ISystemControl> trebleSystemControl;
- if (trebleSystemControlEnable) {
- ITRACE("ISystemControl::getService");
- trebleSystemControl = ISystemControl::getService();
- if (trebleSystemControl != NULL) {
- ITRACE("Link to system service death notification successful");
-
- Result ret = trebleSystemControl->isHDCPTxAuthSuccess();
- if (Result::OK == ret) {
- status = 1;
- }
- }
- else
- ETRACE("ISystemControl::getService fail");
- }
- else {
- sp<IServiceManager> sm = defaultServiceManager();
- if (sm == NULL) {
- ETRACE("Couldn't get default ServiceManager\n");
- return NULL;
- }
- sp<IBinder> binder = sm->getService(String16("system_control"));
- sp<ISystemControlService> sc = interface_cast<ISystemControlService>(binder);
- sc->isHDCPTxAuthSuccess(status);
+ // update HDR info.
+ if (!mHdrCapabilities.init) {
+ ETRACE("update hdr infomation.");
+ parseHdrCapabilities();
+ mHdrCapabilities.init = true;
}
- DTRACE("hdcp status: %d", status);
- mSecure = (status == 1) ? true : false;
-
+ mSecure = mDisplayHdmi->isSecure();
return true;
}
-sp<ISystemControlService> PhysicalDevice::getSystemControlService()
-{
- sp<IServiceManager> sm = defaultServiceManager();
- if (sm == NULL) {
- ETRACE("Couldn't get default ServiceManager\n");
- return NULL;
- }
- sp<IBinder> binder = sm->getService(String16("system_control"));
- sp<ISystemControlService> sc = interface_cast<ISystemControlService>(binder);
-
- return sc;
-}
-
void PhysicalDevice::onVsync(int64_t timestamp) {
RETURN_VOID_IF_NOT_INIT();
ATRACE("timestamp = %lld", timestamp);
- if (!mIsConnected)
+ if (!mConnectorPresent)
return;
// notify hwc
mHwc.vsync(mId, timestamp);
}
+void PhysicalDevice::onHotplug(int disp, bool connected) {
+ RETURN_VOID_IF_NOT_INIT();
+ ETRACE("connect status = (%d)", connected);
+
+ if (!mGetInitState) {
+ mGetInitState = true;
+ if (mDisplayHdmi->chkPresent()) {
+ updateHotplugState(true);
+ }
+ }
+
+ if (!updateDisplayConfigs())
+ ETRACE("failed to update display config");
+
+ // notify hwc
+ if (connected)
+ mHwc.hotplug(disp, connected);
+}
+
int32_t PhysicalDevice::createVirtualDisplay(
uint32_t width,
uint32_t height,
@@ -1501,25 +1517,25 @@ int32_t PhysicalDevice::setOutputBuffer(
void PhysicalDevice::updateHotplugState(bool connected) {
Mutex::Autolock _l(mLock);
- mIsConnected = connected;
- //if plug out, need reinit
+ mConnectorPresent = connected;
+ // if plug out, need reinit
if (!connected)
- mHdrCapabilities.init = false;
+ memset(&mHdrCapabilities, 0, sizeof(hdr_capabilities_t));
}
int32_t PhysicalDevice::getLineValue(const char *lineStr, const char *magicStr) {
int len = 0;
char value[100] = {0};
- char *pos = NULL;
+ const char *pos = NULL;
if ((NULL == lineStr) || (NULL == magicStr)) {
ETRACE("line string: %s, magic string: %s\n", lineStr, magicStr);
return 0;
}
- if (NULL != (pos = strstr((char *)lineStr, magicStr))) {
+ if (NULL != (pos = strstr(lineStr, magicStr))) {
pos = pos + strlen(magicStr);
- char* start = pos;
+ const char* start = pos;
while (*start != '\n' && (strlen(start) > 0))
start++;
@@ -1532,30 +1548,30 @@ int32_t PhysicalDevice::getLineValue(const char *lineStr, const char *magicStr)
return 0;
}
-/*
-cat /sys/class/amhdmitx/amhdmitx0/hdr_cap
-Supported EOTF:
- Traditional SDR: 1
- Traditional HDR: 0
- SMPTE ST 2084: 1
- Future EOTF: 0
-Supported SMD type1: 1
-Luminance Data
- Max: 0
- Avg: 0
- Min: 0
-cat /sys/class/amhdmitx/amhdmitx0/dv_cap
-DolbyVision1 RX support list:
- 2160p30hz: 1
- global dimming
- colorimetry
- IEEEOUI: 0x00d046
- DM Ver: 1
-*/
+/*******************************************
+* cat /sys/class/amhdmitx/amhdmitx0/hdr_cap
+* Supported EOTF:
+* Traditional SDR: 1
+* Traditional HDR: 0
+* SMPTE ST 2084: 1
+* Future EOTF: 0
+* Supported SMD type1: 1
+* Luminance Data
+* Max: 0
+* Avg: 0
+* Min: 0
+* cat /sys/class/amhdmitx/amhdmitx0/dv_cap
+* DolbyVision1 RX support list:
+* 2160p30hz: 1
+* global dimming
+* colorimetry
+* IEEEOUI: 0x00d046
+* DM Ver: 1
+*******************************************/
int32_t PhysicalDevice::parseHdrCapabilities() {
- //DolbyVision1
+ // DolbyVision1
const char *DV_PATH = "/sys/class/amhdmitx/amhdmitx0/dv_cap";
- //HDR
+ // HDR
const char *HDR_PATH = "/sys/class/amhdmitx/amhdmitx0/hdr_cap";
char buf[1024+1] = {0};
@@ -1577,7 +1593,7 @@ int32_t PhysicalDevice::parseHdrCapabilities() {
if ((NULL != strstr(pos, "2160p30hz")) || (NULL != strstr(pos, "2160p60hz")))
mHdrCapabilities.dvSupport = true;
- //dobly version parse end
+ // dobly version parse end
memset(buf, 0, 1024);
if ((fd = open(HDR_PATH, O_RDONLY)) < 0) {
@@ -1611,10 +1627,15 @@ void PhysicalDevice::dump(Dump& d) {
Mutex::Autolock _l(mLock);
d.append("-------------------------------------------------------------"
"----------------------------------------------------------------\n");
- d.append("Device Name: %s (%s)\n", mName,
- mIsConnected ? "connected" : "disconnected");
+ d.append("Device Name: %s (%s), (%f, %f)\n", mName,
+ mConnectorPresent ? "connected" : "disconnected",
+ mReverseScaleX, mReverseScaleY);
+
+ d.append("isSecure : %s\n", mSecure ? "TRUE" : "FALSE");
+
mDisplayHdmi->dump(d);
+#if 0 //all the info already dumped by SurfaceFlinger, comment it.
// dump layer list
d.append(" Layers state:\n");
d.append(" numLayers=%zu\n", mHwcLayers.size());
@@ -1633,6 +1654,7 @@ void PhysicalDevice::dump(Dump& d) {
if (layer) layer->dump(d);
}
}
+#endif
// HDR info
d.append(" HDR Capabilities:\n");
diff --git a/hwc2/common/devices/PrimaryDevice.cpp b/hwc2/common/devices/PrimaryDevice.cpp
index eca8957..11dfad8 100644
--- a/hwc2/common/devices/PrimaryDevice.cpp
+++ b/hwc2/common/devices/PrimaryDevice.cpp
@@ -70,21 +70,12 @@ void PrimaryDevice::hotplugEventListener(void *data, bool status)
void PrimaryDevice::hotplugListener(bool connected)
{
CTRACE();
-
ETRACE("hotpug event: %d", connected);
updateHotplugState(connected);
- // update display configs
- if (connected) {
- if (!updateDisplayConfigs()) {
- ETRACE("failed to update display config");
- return;
- }
- if (getDisplayId() == HWC_DISPLAY_EXTERNAL) {
- getDevice().hotplug(getDisplayId(), connected);
- }
- }
+ // update display configs
+ onHotplug(getDisplayId(), connected);
}
} // namespace amlogic
diff --git a/hwc2/common/devices/VirtualDevice.cpp b/hwc2/common/devices/VirtualDevice.cpp
index 24db6aa..b598edf 100644
--- a/hwc2/common/devices/VirtualDevice.cpp
+++ b/hwc2/common/devices/VirtualDevice.cpp
@@ -390,10 +390,12 @@ int32_t VirtualDevice::validateDisplay(uint32_t* outNumTypes,
layer = mHwcLayers.valueAt(i);
if (layer) {
// Virtual Display.
- if (layer->getCompositionType() != HWC2_COMPOSITION_CLIENT) {
- // change all other device type to client.
- mHwcLayersChangeType.add(layerId, layer);
- continue;
+ if (mVirtualHnd && private_handle_t::validate(mVirtualHnd) >=0) {
+ if (layer->getCompositionType() != HWC2_COMPOSITION_CLIENT) {
+ // change all other device type to client.
+ mHwcLayersChangeType.add(layerId, layer);
+ continue;
+ }
}
}
}
@@ -428,6 +430,10 @@ void VirtualDevice::onVsync(int64_t timestamp) {
// dont need implement now.
}
+void VirtualDevice::onHotplug(int disp, bool connected) {
+ // dont need implement now.
+}
+
int32_t VirtualDevice::createVirtualDisplay(
uint32_t width,
uint32_t height,
diff --git a/hwc2/common/hdmi/DisplayHdmi.cpp b/hwc2/common/hdmi/DisplayHdmi.cpp
index 50cd93a..76b9e3d 100644
--- a/hwc2/common/hdmi/DisplayHdmi.cpp
+++ b/hwc2/common/hdmi/DisplayHdmi.cpp
@@ -1,68 +1,96 @@
+/*
+// Copyright (c) 2017 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+*/
+
//#define LOG_NDEBUG 0
#include <HwcTrace.h>
#include <binder/IServiceManager.h>
#include <utils/Tokenizer.h>
-#include <thread>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/ISurfaceComposer.h>
#include "DisplayHdmi.h"
#include <cutils/properties.h>
namespace android {
namespace amlogic {
-void DisplayHdmi::SystemControlDeathRecipient::serviceDied(
- uint64_t, const wp<::android::hidl::base::V1_0::IBase>&) {
- ETRACE("system_control died, need reconnect it\n");
-}
-
-DisplayHdmi::DisplayHdmi(hwc2_display_t id) {
- mDisplayId = id;
+#define DEFAULT_DISPMODE "1080p60hz"
+#define DEFAULT_DISPLAY_DPI 160
- mTrebleSystemControlEnable = property_get_bool("persist.system_control.treble", true);
-
- initModes();
+DisplayHdmi::DisplayHdmi()
+ : mFirstBootup(true)
+{
+ if (Utils::get_bool_prop("ro.sf.full_activemode")) {
+ mWorkMode = REAL_ACTIVEMODE;
+ } else {
+ mWorkMode = NONE_ACTIVEMODE;
+ }
}
DisplayHdmi::~DisplayHdmi() {
- mAllModes.clear();
}
-void DisplayHdmi::initBinderService() {
- mTrebleSystemControl = nullptr;
- sp<ISystemControl> control = nullptr;
-
- if (mTrebleSystemControlEnable) {
- control = ISystemControl::getService();
- mDeathRecipient = new SystemControlDeathRecipient();
- Return<bool> linked = control->linkToDeath(mDeathRecipient, /*cookie*/ 0);
- if (!linked.isOk()) {
- ETRACE("Transaction error in linking to system service death: %s", linked.description().c_str());
- } else if (!linked) {
- ETRACE("Unable to link to system service death notifications");
- } else {
- ITRACE("Link to system service death notification successful");
- }
+auto DisplayHdmi::getSystemControlService() {
+ static bool bGot = false;
+
+#if PLATFORM_SDK_VERSION >= 26
+ static auto systemControl = ISystemControl::getService();
- mTrebleSystemControl = control;
+ if (bGot)
+ return systemControl;
+ mDeathRecipient = new SystemControlDeathRecipient();
+ Return<bool> linked = systemControl->linkToDeath(mDeathRecipient, /*cookie*/ 0);
+ if (!linked.isOk()) {
+ ETRACE("Transaction error in linking to system service death: %s", linked.description().c_str());
+ } else if (!linked) {
+ ETRACE("Unable to link to system service death notifications");
+ } else {
+ ITRACE("Link to system service death notification successful");
}
- else {
- sp<IServiceManager> sm = defaultServiceManager();
- if (sm == NULL) {
- ETRACE("Couldn't get default ServiceManager\n");
- return ;
- }
- mSystemControlService = interface_cast<ISystemControlService>(sm->getService(String16("system_control")));
- if (mSystemControlService == NULL) {
- ETRACE("Couldn't get connection to SystemControlService\n");
- return ;
- }
+#else
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm == NULL) {
+ ETRACE("Couldn't get default ServiceManager\n");
+ return NULL;
+ }
+ static auto systemControl = interface_cast<ISystemControlService>(sm->getService(String16("system_control")));
+
+ if (bGot)
+ return systemControl;
+
+ if (systemControl == NULL) {
+ ETRACE("Couldn't get connection to SystemControlService\n");
+ return NULL;
}
+
+
+#endif
+
+ bGot = true;
+ return systemControl;
}
-void DisplayHdmi::initialize() {
+void DisplayHdmi::initialize(framebuffer_info_t& framebufferInfo) {
reset();
+ std::string dispMode;
+ calcDefaultMode(framebufferInfo, dispMode);
+ buildSingleConfigList(dispMode);
+ updateActiveConfig(dispMode);
+
+ mFbWidth = framebufferInfo.info.xres;
+ mFbHeight = framebufferInfo.info.yres;
}
void DisplayHdmi::deinitialize() {
@@ -70,273 +98,236 @@ void DisplayHdmi::deinitialize() {
}
void DisplayHdmi::reset() {
+ clearSupportedConfigs();
+ mActiveConfigStr.clear();
mConnected = false;
- mActiveDisplayConfigItem = 0;
- mActiveRefreshRate = 60;
- memset(mActiveDisplaymode, 0, HWC_DISPLAY_MODE_LENGTH);
- mSupportDispModes.clear();
- for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
- DisplayConfig *config = mDisplayConfigs[i];
- if (config)
- delete config;
- }
- mDisplayConfigs.clear();
+ mActiveConfigId = mRealActiveConfigId = VMODE_NULL;
+ mPhyWidth = mPhyHeight = 0;
}
bool DisplayHdmi::updateHotplug(bool connected,
- framebuffer_info_t * framebufferInfo,
- private_handle_t* framebufferHnd) {
+ framebuffer_info_t& framebufferInfo) {
bool ret = true;
int32_t rate;
- initBinderService();
-
mConnected = connected;
- if (!isConnected()) {
- ETRACE("disp: %d disconnect", (int32_t)mDisplayId);
+ if (!connected) {
+ DTRACE("hdmi disconnected, keep old display configs.");
return true;
}
- mFramebufferInfo = framebufferInfo;
- mFramebufferHnd = framebufferHnd;
+ updateDisplayAttributes(framebufferInfo);
- if (-1 == updateDisplayModeList()) {
- //hdmi plug out when system is starting up
- std::string dispMode;
- int width, height;
- if (mTrebleSystemControlEnable) {
- mTrebleSystemControl->getActiveDispMode([&dispMode](const Result &ret, const hidl_string& mode) {
- if (Result::OK == ret) {
- dispMode = mode.c_str();
- }
- });
- }
- else {
- mSystemControlService->getActiveDispMode(&dispMode);
- }
-
- ret = calcMode2Config(dispMode.c_str(), &rate, &width, &height);
- if (!ret) {
- dispMode = std::string("1080p60hz");
- rate = 60;
- }
- ETRACE("only init one display config: %s", dispMode.c_str());
- strcpy(mActiveDisplaymode, dispMode.c_str());
-
- // reset display configs
- for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
- DisplayConfig *config = mDisplayConfigs[i];
- if (config)
- delete config;
- }
- mDisplayConfigs.clear();
-
- // use active fb dimension as config width/height
- DisplayConfig *config = new DisplayConfig(mActiveDisplaymode,
- rate,
- mFramebufferInfo->info.xres,
- mFramebufferInfo->info.yres,
- mFramebufferInfo->xdpi,
- mFramebufferInfo->ydpi);
- // add it to the front of other configs
- mDisplayConfigs.push_back(config);
-
- // init the active display config
- mActiveDisplayConfigItem = 0;
- mActiveRefreshRate = rate;
- //ETRACE("Active display mode %s, refresh rate: %d", mActiveDisplaymode, rate);
- } else {
- //hdmi plug in when system is starting up
- updateActiveDisplayMode();
- updateDisplayConfigures();
- updateActiveDisplayConfigure();
-
- std::string strmode(mActiveDisplaymode);
- if (mTrebleSystemControlEnable) {
- hidl_string mode(strmode);
- Result ret = mTrebleSystemControl->setActiveDispMode(mode);
- if (Result::OK == ret) {
- }
- }
- else {
- mSystemControlService->setActiveDispMode(strmode);
- }
+ std::string activemode;
+ if (readHdmiDispMode(activemode) != HWC2_ERROR_NONE) {
+ ETRACE("get active display mode failed.");
+ return false;
}
- std::thread t1(&DisplayHdmi::setSurfaceFlingerActiveMode, this);
- t1.detach();
+ if (updateSupportedConfigs() != HWC2_ERROR_NONE) {
+ ETRACE("updateHotplug: No supported display list, set default configs.");
+ std::string dM (DEFAULT_DISPMODE);
+ buildSingleConfigList(dM);
+ }
+ updateActiveConfig(activemode);
+ // setBestDisplayMode();
return true;
}
-int DisplayHdmi::updateDisplayModeList() {
+int DisplayHdmi::updateSupportedConfigs() {
// clear display modes
- mSupportDispModes.clear();
-
- bool fullActiveMode = Utils::get_bool_prop("ro.sf.full_activemode");
- bool isConfiged = readConfigFile("/vendor/etc/displayModeList.cfg", &mSupportDispModes);
- if (isConfiged) {
- return 0;
- }
+ clearSupportedConfigs();
- if (!fullActiveMode) {
- ALOGD("Simple Active Mode!!!");
- return -1;
- }
-
- std::vector<std::string> getSupportDispModes;
+ std::vector<std::string> supportDispModes;
std::string::size_type pos;
- if (mTrebleSystemControlEnable) {
- mTrebleSystemControl->getSupportDispModeList(
- [&getSupportDispModes](const Result &ret, const hidl_vec<hidl_string>& modeList) {
- if (Result::OK == ret) {
- for (size_t i = 0; i < modeList.size(); i++) {
- getSupportDispModes.push_back(modeList[i]);
- }
- }
- });
- }
- else {
- mSystemControlService->getSupportDispModeList(&getSupportDispModes);
- }
+ std::string dM (DEFAULT_DISPMODE);
- if (getSupportDispModes.size() == 0) {
- ALOGD("SupportDispModeList null!!!");
- return -1;
- }
+ bool isConfiged = readConfigFile("/system/etc/displayModeList.cfg", &supportDispModes);
+ if (isConfiged) {
+ DTRACE("Read supported modes from cfg file.");
+ } else {
+ if (mWorkMode == NONE_ACTIVEMODE) {
+ DTRACE("Simple Active Mode!!!");
+ return BAD_VALUE;
+ }
- for (size_t i = 0; i < getSupportDispModes.size(); i++) {
- //ALOGD("get support display mode:%s", getSupportDispModes[i].c_str());
- while (!getSupportDispModes[i].empty()) {
- pos = getSupportDispModes[i].find('*');
- if (pos != std::string::npos) {
- getSupportDispModes[i].erase(pos, 1);
- //ALOGD("modify support display mode:%s", getSupportDispModes[i].c_str());
- } else {
- break;
- }
+ readEdidList(supportDispModes);
+ if (supportDispModes.size() == 0) {
+ ETRACE("SupportDispModeList null!!!");
+ return BAD_VALUE;
}
}
-
- for (size_t k = 0; k < mAllModes.size(); k++) {
- for (size_t j = 0; j < getSupportDispModes.size(); j++) {
- if (!getSupportDispModes[j].empty()) {
- if (mAllModes[k] == getSupportDispModes[j]) {
- mSupportDispModes.push_back(getSupportDispModes[j]);
- ALOGD("support display mode:%s", getSupportDispModes[j].c_str());
- }
+ for (size_t i = 0; i < supportDispModes.size(); i++) {
+ if (!supportDispModes[i].empty()) {
+ pos = supportDispModes[i].find('*');
+ if (pos != std::string::npos) {
+ supportDispModes[i].erase(pos, 1);
+ DTRACE("modify support display mode:%s", supportDispModes[i].c_str());
}
+
+ // skip default / fake active mode as we add it to the end
+ if (supportDispModes[i] != dM)
+ addSupportedConfig(supportDispModes[i]);
}
}
- return 0;
+ addSupportedConfig(dM);
+ return NO_ERROR;
}
-int DisplayHdmi::updateActiveDisplayMode() {
- std::string dispMode;
-
- if (mTrebleSystemControlEnable) {
- mTrebleSystemControl->getActiveDispMode([&dispMode](const Result &ret, const hidl_string& mode) {
- if (Result::OK == ret) {
- dispMode = mode.c_str();
- }
- });
- }
- else {
- mSystemControlService->getActiveDispMode(&dispMode);
+int DisplayHdmi::buildSingleConfigList(std::string& defaultMode) {
+ if (!isDispModeValid(defaultMode)) {
+ ETRACE("buildSingleConfigList with invalidate mode (%s)", defaultMode.c_str());
+ return false;
}
- strcpy(mActiveDisplaymode, dispMode.c_str());
-
- int refreshRate = 60;
- if (strstr(mActiveDisplaymode, "60hz") != NULL) {
- refreshRate = 60;
- } else if (strstr(mActiveDisplaymode, "50hz") != NULL) {
- refreshRate = 50;
- } else if (strstr(mActiveDisplaymode, "30hz") != NULL) {
- refreshRate = 30;
- } else if (strstr(mActiveDisplaymode, "25hz") != NULL) {
- refreshRate = 25;
- } else if ((strstr(mActiveDisplaymode, "24hz") != NULL)
- || (strstr(mActiveDisplaymode, "smpte") != NULL)) {
- refreshRate = 24;
- } else
- ETRACE("displaymode (%s) doesn't specify HZ", mActiveDisplaymode);
+ return addSupportedConfig(defaultMode);
+}
- ALOGD("Active display mode: (%s), refresh rate: (%d)", mActiveDisplaymode, refreshRate);
+int DisplayHdmi::calcDefaultMode(framebuffer_info_t& framebufferInfo,
+ std::string& defaultMode) {
+ const struct vinfo_s * mode =
+ findMatchedMode(framebufferInfo.info.xres, framebufferInfo.info.yres, 60);
+ if (mode == NULL) {
+ defaultMode = DEFAULT_DISPMODE;
+ } else {
+ defaultMode = mode->name;
+ }
- mActiveRefreshRate = refreshRate;
+ defaultMode = DEFAULT_DISPMODE;
- return 0;
+ DTRACE("calcDefaultMode %s", defaultMode.c_str());
+ return NO_ERROR;
}
-int DisplayHdmi::setDisplayMode(const char* displaymode) {
- ALOGD("setDisplayMode to %s", displaymode);
-
- std::string strmode(displaymode);
- if (mTrebleSystemControlEnable) {
- hidl_string mode(strmode);
- Result ret = mTrebleSystemControl->setActiveDispMode(mode);
- if (Result::OK == ret) {
+int DisplayHdmi::addSupportedConfig(std::string& mode) {
+ vmode_e vmode = vmode_name_to_mode(mode.c_str());
+ const struct vinfo_s* vinfo = get_tv_info(vmode);
+ if (vmode == VMODE_MAX || vinfo == NULL) {
+ ETRACE("addSupportedConfig meet error mode (%s, %d)", mode.c_str(), vmode);
+ return BAD_VALUE;
+ }
+
+ int dpiX = DEFAULT_DISPLAY_DPI, dpiY = DEFAULT_DISPLAY_DPI;
+ if (mPhyWidth > 16 && mPhyHeight > 9) {
+ dpiX = (vinfo->width * 25.4f) / mPhyWidth;
+ dpiY = (vinfo->height * 25.4f) / mPhyHeight;
+ }
+
+ DisplayConfig *config = new DisplayConfig(mode,
+ vinfo->sync_duration_num,
+ vinfo->width,
+ vinfo->height,
+ dpiX,
+ dpiY,
+ false);
+
+ // add normal refresh rate config, like 24hz, 30hz...
+ DTRACE("add display mode pair (%d, %s)", mSupportDispConfigs.size(), mode.c_str());
+ mSupportDispConfigs.add(mSupportDispConfigs.size(), config);
+
+ if (mWorkMode == REAL_ACTIVEMODE) {
+ // add frac refresh rate config, like 23.976hz, 29.97hz...
+ if (vinfo->sync_duration_num == REFRESH_24kHZ
+ || vinfo->sync_duration_num == REFRESH_30kHZ
+ || vinfo->sync_duration_num == REFRESH_60kHZ
+ || vinfo->sync_duration_num == REFRESH_120kHZ
+ || vinfo->sync_duration_num == REFRESH_240kHZ) {
+ DisplayConfig *fracConfig = new DisplayConfig(mode,
+ vinfo->sync_duration_num,
+ vinfo->width,
+ vinfo->height,
+ dpiX,
+ dpiY,
+ true);
+ mSupportDispConfigs.add(mSupportDispConfigs.size(), fracConfig);
}
}
- else {
- mSystemControlService->setActiveDispMode(strmode);
- }
- updateActiveDisplayMode();
-
- return 0;
+ return NO_ERROR;
}
-int DisplayHdmi::updateDisplayConfigures() {
- size_t i;
+int DisplayHdmi::updateActiveConfig(std::string& activeMode) {
+ mRealActiveConfigStr = activeMode;
+ for (size_t i = 0; i < mSupportDispConfigs.size(); i++) {
+ DisplayConfig * cfg = mSupportDispConfigs.valueAt(i);
+ if (activeMode == cfg->getDisplayMode()) {
+ mRealActiveConfigId = mSupportDispConfigs.keyAt(i);
+ DTRACE("updateRealActiveConfig to (%s, %d)", activeMode.c_str(), mRealActiveConfigId);
+ }
+ }
+ mActiveConfigId = mSupportDispConfigs.size()-1;
+ return NO_ERROR;
+}
- std::string dispMode;
- int refreshRate, width, height;
+status_t DisplayHdmi::setBestDisplayMode() {
+ std::string bM;
- // reset display configs
- for (i = 0; i < mDisplayConfigs.size(); i++) {
- DisplayConfig *config = mDisplayConfigs[i];
- if (config)
- delete config;
+ readBestHdmiOutputMode(bM);
+ if (mRealActiveConfigStr.compare(bM) || mFirstBootup) {
+ DTRACE("setBestDisplayMode to %s", bM.c_str());
+ setDisplayMode(bM);
}
- mDisplayConfigs.clear();
+ // update real active config.
+ updateActiveConfig(bM);
- for (i =0; i < mSupportDispModes.size(); i ++) {
- dispMode = mSupportDispModes[i];
- calcMode2Config(dispMode.c_str(), &refreshRate, &width, &height);
+ if (mFirstBootup) mFirstBootup = false;
+ return NO_ERROR;
+}
- // init dimension as config width/height, set xdpi/ydpi after
- DisplayConfig *config = new DisplayConfig(dispMode.c_str(),
- refreshRate, width, height,
- mFramebufferInfo->xdpi,
- mFramebufferInfo->ydpi);
- // add it to the front of other configs
- mDisplayConfigs.push_back(config);
+void DisplayHdmi::switchRatePolicy(bool fracRatePolicy) {
+/*
+TODO: need add new api for hdmi frac rate policy.
+*/
+#if 0
+ auto scs = getSystemControlService();
+ if (scs == NULL) {
+ ETRACE("switchRatePolicy FAIL.");
+ return;
+ }
+
+ if (fracRatePolicy) {
+ if (scs->writeSysfs(String16(HDMI_FRAC_RATE_POLICY), String16("1")))
+ ETRACE("Switch to frac rate policy SUCCESS.");
+ else
+ ETRACE("Switch to frac rate policy FAIL.");
+ } else {
+ if (scs->writeSysfs(String16(HDMI_FRAC_RATE_POLICY), String16("0")))
+ ETRACE("Switch to normal rate policy SUCCESS.");
+ else
+ ETRACE("Switch to normal rate policy FAIL.");
}
- return 0;
+#endif
}
-int DisplayHdmi::updateActiveDisplayConfigure() {
- size_t i;
+int DisplayHdmi::setDisplayMode(std::string& dm, bool policy) {
+ DTRACE("setDisplayMode to %s", dm.c_str());
+ switchRatePolicy(policy);
+ writeHdmiDispMode(dm);
+ updateActiveConfig(dm);
+ return NO_ERROR;
+}
- DisplayConfig *dispConfig = NULL;
- for (i = 0; i < mDisplayConfigs.size(); i++) {
- dispConfig = mDisplayConfigs[i];
- if (!dispConfig) {
- continue;
- }
- if (0 == strncmp(mActiveDisplaymode, dispConfig->getDisplayMode(),
- HWC_DISPLAY_MODE_LENGTH-1)) {
- mActiveDisplayConfigItem = i;
- ALOGD("updateActiveDisplayConfigure to config(%d)", mActiveDisplayConfigItem);
- dispConfig->setDpi(mFramebufferInfo->xdpi, mFramebufferInfo->ydpi);
- break;
+status_t DisplayHdmi::readHdmiPhySize(framebuffer_info_t& fbInfo) {
+ struct fb_var_screeninfo vinfo;
+ if ((fbInfo.fd >= 0) && (ioctl(fbInfo.fd, FBIOGET_VSCREENINFO, &vinfo) == 0)) {
+ if (int32_t(vinfo.width) > 16 && int32_t(vinfo.height) > 9) {
+ mPhyWidth = vinfo.width;
+ mPhyHeight = vinfo.height;
}
+ return NO_ERROR;
}
- return 0;
+ return BAD_VALUE;
+}
+
+int DisplayHdmi::updateDisplayAttributes(framebuffer_info_t& framebufferInfo) {
+ if (readHdmiPhySize(framebufferInfo) != NO_ERROR) {
+ mPhyWidth = mPhyHeight = 0;
+ }
+ DTRACE("updateDisplayAttributes physical size (%d x %d)", mPhyWidth, mPhyHeight);
+ return NO_ERROR;
}
int DisplayHdmi::getDisplayConfigs(uint32_t* outNumConfigs,
@@ -344,50 +335,68 @@ int DisplayHdmi::getDisplayConfigs(uint32_t* outNumConfigs,
size_t i;
if (!isConnected()) {
- //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ ETRACE("hdmi is not connected.");
}
- for (i = 0; i < mDisplayConfigs.size(); i++) {
- if (NULL != outConfigs)
- outConfigs[i] = i;
+ size_t configsNum = mSupportDispConfigs.size();
+ *outNumConfigs = configsNum;
+ if (NULL != outConfigs) {
+ for (i = 0; i < configsNum; i++) {
+ outConfigs[i] = mSupportDispConfigs.keyAt(i);
+ }
}
- *outNumConfigs = i;
-
- return HWC2_ERROR_NONE;
+ return NO_ERROR;
}
int DisplayHdmi::getDisplayAttribute(hwc2_config_t config,
int32_t /*hwc2_attribute_t*/ attribute,
int32_t* outValue) {
-
if (!isConnected()) {
- //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ ETRACE("hdmi is not connected.");
}
- DisplayConfig *configChosen = mDisplayConfigs[config];
- if (!configChosen) {
+ DisplayConfig *configChosen = NULL;
+ int modeIdx = mSupportDispConfigs.indexOfKey((vmode_e)config);
+ if (modeIdx >= 0)
+ configChosen = mSupportDispConfigs.valueAt(modeIdx);
+ if (!configChosen) {
ETRACE("failed to get display config: %d", config);
- return HWC2_ERROR_NONE;
+ return BAD_VALUE;
}
switch (attribute) {
case HWC2_ATTRIBUTE_VSYNC_PERIOD:
- if (configChosen->getRefreshRate()) {
- *outValue = 1e9 / configChosen->getRefreshRate();
+ if (mWorkMode == REAL_ACTIVEMODE) {
+ if (configChosen->getRefreshRate()) {
+ *outValue = 1e9 / configChosen->getRefreshRate();
+ }
+ } else if (mWorkMode == LOGIC_ACTIVEMODE ||
+ mWorkMode == NONE_ACTIVEMODE) {
+ *outValue = 1e9 / 60;
}
break;
case HWC2_ATTRIBUTE_WIDTH:
- *outValue = configChosen->getWidth();
+ if (mWorkMode == REAL_ACTIVEMODE) {
+ *outValue = configChosen->getWidth();
+ } else if (mWorkMode == LOGIC_ACTIVEMODE ||
+ mWorkMode == NONE_ACTIVEMODE) {
+ *outValue = mFbWidth;
+ }
break;
case HWC2_ATTRIBUTE_HEIGHT:
- *outValue = configChosen->getHeight();
+ if (mWorkMode == REAL_ACTIVEMODE) {
+ *outValue = configChosen->getHeight();
+ } else if (mWorkMode == LOGIC_ACTIVEMODE ||
+ mWorkMode == NONE_ACTIVEMODE) {
+ *outValue = mFbHeight;
+ }
break;
case HWC2_ATTRIBUTE_DPI_X:
*outValue = configChosen->getDpiX() * 1000.0f;
break;
case HWC2_ATTRIBUTE_DPI_Y:
- *outValue = configChosen->getDpiY() * 1000.0f;
+ *outValue = configChosen->getDpiY() * 1000.0f;
break;
default:
ETRACE("unknown display attribute %u", attribute);
@@ -395,96 +404,48 @@ int DisplayHdmi::getDisplayAttribute(hwc2_config_t config,
break;
}
- return HWC2_ERROR_NONE;
+ return NO_ERROR;
}
int DisplayHdmi::getActiveConfig(hwc2_config_t* outConfig) {
if (!isConnected()) {
- //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ ETRACE("hdmi is not connected.");
}
- //ALOGD("getActiveConfig to config(%d).", mActiveDisplayConfigItem);
- *outConfig = mActiveDisplayConfigItem;
-
- return HWC2_ERROR_NONE;
+ // DTRACE("getActiveConfig to config(%d).", mActiveConfigId);
+ *outConfig = mActiveConfigId;
+ return NO_ERROR;
}
-int DisplayHdmi::setActiveConfig(int id) {
- DisplayConfig *dispConfig = NULL;
- char *dispMode = NULL;
-
+int DisplayHdmi::getRealActiveConfig(hwc2_config_t* outConfig) {
if (!isConnected()) {
- //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
- }
-
- ALOGD("setActiveConfig to config(%d).", id);
- mActiveDisplayConfigItem = id;
- dispConfig = mDisplayConfigs[id];
- if (!dispConfig) {
- ETRACE("failed to get display config: %d", id);
- return HWC2_ERROR_BAD_CONFIG;
- }
-
- dispConfig->setDpi(mFramebufferInfo->xdpi,
- mFramebufferInfo->ydpi);
-
- dispMode = dispConfig->getDisplayMode();
- if (!dispMode) {
- ETRACE("failed to get display mode by config: %d", id);
- return HWC2_ERROR_BAD_CONFIG;
+ ETRACE("hdmi is not connected.");
}
-
- setDisplayMode(dispMode);
-
- return HWC2_ERROR_NONE;
+ // DTRACE("getActiveConfig to config(%d).", mActiveConfigId);
+ *outConfig = mRealActiveConfigId;
+ return NO_ERROR;
}
-bool DisplayHdmi::calcMode2Config(const char *dispMode, int* refreshRate,
- int* width, int* height) {
-
- if (NULL == dispMode) {
- ETRACE("dispMode is NULL");
- return false;
+int DisplayHdmi::setActiveConfig(int modeId) {
+ if (!isConnected()) {
+ ETRACE("hdmi display is not connected.");
}
- if (strstr(dispMode, "60hz") != NULL) {
- *refreshRate = 60;
- } else if (strstr(dispMode, "50hz") != NULL) {
- *refreshRate = 50;
- } else if (strstr(dispMode, "30hz") != NULL) {
- *refreshRate = 30;
- } else if (strstr(dispMode, "25hz") != NULL) {
- *refreshRate = 25;
- } else if ((strstr(dispMode, "24hz") != NULL)
- || (strstr(dispMode, "smpte") != NULL)) {
- *refreshRate = 24;
- } else {
- ETRACE("displaymode (%s) doesn't specify HZ", dispMode);
- return false;
- }
+ DTRACE("setActiveConfig to mode(%d).", modeId);
+ int modeIdx = mSupportDispConfigs.indexOfKey((const vmode_e)modeId);
+ if (modeIdx >= 0) {
+ DisplayConfig* cfg = mSupportDispConfigs.valueAt(modeIdx);
+ std::string dM = cfg->getDisplayMode();
- if (strstr(dispMode, "2160") != NULL) {
- *width = 3840;
- *height = 2160;
- } else if (strstr(dispMode, "1080") != NULL) {
- *width = 1920;
- *height = 1080;
- } else if (strstr(dispMode, "720") != NULL) {
- *width = 1280;
- *height = 720;
- } else if (strstr(dispMode, "576") != NULL) {
- *width = 720;
- *height = 576;
- } else if (strstr(dispMode, "480") != NULL) {
- *width = 640;
- *height = 480;
+ DTRACE("setActiveConfig to (%d, %s).", modeId, dM.c_str());
+ setDisplayMode(dM, cfg->getFracRatePolicy());
+
+ // update real active config.
+ updateActiveConfig(dM);
+ return NO_ERROR;
} else {
- // smpte and panle imcomplete!!!!!
- ETRACE("calcMode2Config displaymode (%s) doesn't specify HZ", dispMode);
- return false;
+ ETRACE("set invalild active config (%d)", modeId);
+ return BAD_VALUE;
}
-
- //DTRACE("calcMode2Config (%s) refreshRate(%d), (%dx%d)", dispMode, *refreshRate, *width, *height);
- return true;
}
bool DisplayHdmi::readConfigFile(const char* configPath, std::vector<std::string>* supportDispModes) {
@@ -522,44 +483,194 @@ bool DisplayHdmi::readConfigFile(const char* configPath, std::vector<std::string
}
}
-void DisplayHdmi::setSurfaceFlingerActiveMode() {
- /*
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
+int DisplayHdmi::clearSupportedConfigs() {
+ // reset display configs
+ for (size_t i = 0; i < mSupportDispConfigs.size(); i++) {
+ DisplayConfig *config = mSupportDispConfigs.valueAt(i);
+ if (config)
+ delete config;
+ }
+ mSupportDispConfigs.clear();
+ return NO_ERROR;
+}
+
+bool DisplayHdmi::chkPresent() {
+ bool bConnect = false;
+ std::string dispMode;
+ if (!readHdmiDispMode(dispMode)) {
+ bConnect = isDispModeValid(dispMode);
+ }
+
+ DTRACE("chkPresent %s", bConnect ? "connected" : "disconnected");
+ return bConnect;
+}
+
+bool DisplayHdmi::isDispModeValid(std::string & dispmode){
+ if (dispmode.empty())
+ return false;
+
+ vmode_e mode = vmode_name_to_mode(dispmode.c_str());
+ // DTRACE("isDispModeValid get mode (%d)", mode);
+ if (mode == VMODE_MAX)
+ return false;
+
+ if (want_hdmi_mode(mode) == 0)
+ return false;
+
+ return true;
+}
+
+int DisplayHdmi::readHdmiDispMode(std::string &dispmode) {
+ auto scs = getSystemControlService();
+ if (scs == NULL) {
+ ETRACE("syscontrol::readHdmiDispMode FAIL.");
+ return FAILED_TRANSACTION;
+ }
+
+#if PLATFORM_SDK_VERSION >= 26
+ scs->getActiveDispMode([&dispmode](const Result &ret, const hidl_string& mode) {
+ if (Result::OK == ret) {
+ dispmode = mode.c_str();
+ } else {
+ dispmode.clear();
+ }
+ });
+
+ if (dispmode.empty()) {
+ ETRACE("syscontrol::getActiveDispMode FAIL.");
+ return FAILED_TRANSACTION;
+ }
+#else
+ if (scs->getActiveDispMode(&dispmode)) {
+ } else {
+ ETRACE("syscontrol::getActiveDispMode FAIL.");
+ return FAILED_TRANSACTION;
+ }
+#endif
+
+ DTRACE("get current displaymode %s", dispmode.c_str());
+ if (!isDispModeValid(dispmode)) {
+ DTRACE("active mode %s not valid", dispmode.c_str());
+ return BAD_VALUE;
+ }
+
+ return NO_ERROR;
+}
+
+int DisplayHdmi::writeHdmiDispMode(std::string &dispmode) {
+ auto scs = getSystemControlService();
+ if (scs == NULL) {
+ ETRACE("syscontrol::writeHdmiDispMode FAIL.");
+ return FAILED_TRANSACTION;
+ }
- SurfaceComposerClient::setActiveConfig(dtoken, mDisplayConfigs.size()-mActiveDisplayConfigItem-1);
- */
+#if PLATFORM_SDK_VERSION >= 26
+ Result rtn = scs->setActiveDispMode(dispmode);
+ if (rtn == Result::OK) {
+ return NO_ERROR;
+ }
+#else
+ if (scs->setActiveDispMode(dispmode)) {
+ return NO_ERROR;
+ }
+#endif
+
+ ETRACE("syscontrol::setActiveDispMode FAIL.");
+ return FAILED_TRANSACTION;
}
-void DisplayHdmi::initModes() {
- //mAllModes.push_back("480p60hz");
- //mAllModes.push_back("576p50hz");
- //mAllModes.push_back("720p50hz");
- //mAllModes.push_back("720p60hz");
- mAllModes.push_back("1080p60hz");
- mAllModes.push_back("1080p50hz");
- mAllModes.push_back("1080p30hz");
- mAllModes.push_back("1080p25hz");
- mAllModes.push_back("1080p24hz");
- //mAllModes.push_back("2160p24hz");
- //mAllModes.push_back("2160p25hz");
- //mAllModes.push_back("2160p30hz");
- //mAllModes.push_back("2160p50hz");
- //mAllModes.push_back("2160p60hz");
+int DisplayHdmi::readEdidList(std::vector<std::string>& edidlist) {
+ auto scs = getSystemControlService();
+ if (scs == NULL) {
+ ETRACE("syscontrol::readEdidList FAIL.");
+ return FAILED_TRANSACTION;
+ }
+
+#if PLATFORM_SDK_VERSION >= 26
+ scs->getSupportDispModeList([&edidlist](const Result &ret, const hidl_vec<hidl_string> supportDispModes) {
+ if (Result::OK == ret) {
+ for (size_t i = 0; i < supportDispModes.size(); i++) {
+ edidlist.push_back(supportDispModes[i]);
+ }
+ } else {
+ edidlist.clear();
+ }
+ });
+
+ if (edidlist.empty()) {
+ ETRACE("syscontrol::readEdidList FAIL.");
+ return FAILED_TRANSACTION;
+ }
+
+ return NO_ERROR;
+#else
+ if (scs->getSupportDispModeList(&edidlist)) {
+ return NO_ERROR;
+ } else {
+ ETRACE("syscontrol::readEdidList FAIL.");
+ return FAILED_TRANSACTION;
+ }
+#endif
+}
+
+int DisplayHdmi::readBestHdmiOutputMode(std::string &dispmode) {
+#if 0
+ auto scs = getSystemControlService();
+ if (scs == NULL) {
+ ETRACE("syscontrol::readEdidList FAIL.");
+ return FAILED_TRANSACTION;
+ }
+
+ if (scs->getBestHdmiOutputMode(&dispmode)) {
+ DTRACE("get best displaymode %s", dispmode.c_str());
+ if (!isDispModeValid(dispmode)) {
+ ETRACE("best mode %s not valid", dispmode.c_str());
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+ }
+#endif
+
+ return NO_ERROR;
+}
+
+bool DisplayHdmi::isSecure() {
+ auto scs = getSystemControlService();
+ if (scs == NULL) {
+ ETRACE("syscontrol::isHDCPTxAuthSuccess FAIL.");
+ return false;
+ }
+
+#if PLATFORM_SDK_VERSION >= 26
+ Result rtn = scs->isHDCPTxAuthSuccess();
+ DTRACE("hdcp status: %d", status);
+ return rtn == Result::OK ? true : false;
+#else
+ int status = 0;
+ scs->isHDCPTxAuthSuccess(status);
+ DTRACE("hdcp status: %d", status);
+ return status == 1 ? true : false;
+#endif
+
}
void DisplayHdmi::dump(Dump& d) {
+ d.append("Connector (HDMI, %s, %d, %d)\n",
+ mRealActiveConfigStr.c_str(),
+ mRealActiveConfigId,
+ mWorkMode);
d.append(" CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |"
" DPI_X | DPI_Y \n");
d.append("------------+------------------+-----------+------------+"
"-----------+-----------\n");
- for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
- DisplayConfig *config = mDisplayConfigs[i];
+ for (size_t i = 0; i < mSupportDispConfigs.size(); i++) {
+ int mode = mSupportDispConfigs.keyAt(i);
+ DisplayConfig *config = mSupportDispConfigs.valueAt(i);
if (config) {
- d.append("%s %2d | %4d | %5d | %4d |"
+ d.append("%s %2d | %.3f | %5d | %5d |"
" %3d | %3d \n",
- (i == (size_t)mActiveDisplayConfigItem) ? "* " : " ",
- i,
+ (mode == (int)mActiveConfigId) ? "* " : " ",
+ mode,
config->getRefreshRate(),
config->getWidth(),
config->getHeight(),
diff --git a/hwc2/common/hdmi/DisplayHdmi.h b/hwc2/common/hdmi/DisplayHdmi.h
index 785b40b..284570b 100644
--- a/hwc2/common/hdmi/DisplayHdmi.h
+++ b/hwc2/common/hdmi/DisplayHdmi.h
@@ -1,8 +1,26 @@
+/*
+// Copyright (c) 2017 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+*/
+
#ifndef AML_DISPLAY_HDMI_H
#define AML_DISPLAY_HDMI_H
#include <gralloc_priv.h>
#include <utils/String8.h>
+#include <utils/Errors.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
@@ -15,47 +33,66 @@
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <Hwcomposer.h>
-#include <SoftVsyncObserver.h>
#include <Utils.h>
#include <ISystemControlService.h>
#include <gui/SurfaceComposerClient.h>
+#include <AmVinfo.h>
-#include <vendor/amlogic/hardware/systemcontrol/1.0/ISystemControl.h>
-
-#define HWC_DISPLAY_MODE_LENGTH 32
+#define HDMI_FRAC_RATE_POLICY "/sys/class/amhdmitx/amhdmitx0/frac_rate_policy"
+#if PLATFORM_SDK_VERSION >= 26
+#include <vendor/amlogic/hardware/systemcontrol/1.0/ISystemControl.h>
using ::vendor::amlogic::hardware::systemcontrol::V1_0::ISystemControl;
using ::vendor::amlogic::hardware::systemcontrol::V1_0::Result;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::hardware::Return;
+#endif
namespace android {
namespace amlogic {
+// refresh rates.
+enum {
+ REFRESH_24kHZ = 24,
+ REFRESH_30kHZ = 30,
+ REFRESH_60kHZ = 60,
+ REFRESH_120kHZ = 120,
+ REFRESH_240kHZ = 240
+};
+
// display config
class DisplayConfig {
public:
- DisplayConfig(const char* dm,
- int rr,
- int w = 0,
- int h = 0,
- int dpix = 0,
- int dpiy = 0)
- : mRefreshRate(rr),
+ DisplayConfig(const std::string dm,
+ int rr,
+ int w = 0,
+ int h = 0,
+ int dpix = 0,
+ int dpiy = 0,
+ bool frac = false)
+ : mDisplayMode(dm),
+ mRefreshRate(rr),
mWidth(w),
mHeight(h),
mDpiX(dpix),
- mDpiY(dpiy)
- {
- memset(mDisplayMode, 0, HWC_DISPLAY_MODE_LENGTH);
- int length = strlen(dm);
- length = (length <= HWC_DISPLAY_MODE_LENGTH-1)?length:(HWC_DISPLAY_MODE_LENGTH-1);
- memcpy(mDisplayMode, dm, length);
- }
+ mDpiY(dpiy),
+ mFracRate(frac)
+ {}
public:
- char* getDisplayMode() const { return (char*)(&mDisplayMode[0]); };
- int getRefreshRate() const { return mRefreshRate; };
+ std::string getDisplayMode() const { return mDisplayMode; };
+ float getRefreshRate() const {
+ float actualRate = 0.0f;
+
+ if (mRefreshRate) {
+ if (mFracRate) {
+ actualRate = (mRefreshRate * 1000) / (float)1001;
+ } else {
+ actualRate = mRefreshRate;
+ }
+ }
+ return actualRate;
+ };
int getWidth() const { return mWidth; };
int getHeight() const { return mHeight; };
int getDpiX() const { return mDpiX; };
@@ -64,77 +101,112 @@ public:
mDpiX = dpix;
mDpiY = dpiy;
};
+ bool getFracRatePolicy() { return mFracRate; };
private:
- char mDisplayMode[HWC_DISPLAY_MODE_LENGTH];
+ std::string mDisplayMode;
int mRefreshRate;
int mWidth;
int mHeight;
int mDpiX;
int mDpiY;
+ bool mFracRate;
};
class DisplayHdmi {
public:
- DisplayHdmi(hwc2_display_t id);
+ DisplayHdmi();
~DisplayHdmi();
- void initialize();
+ void initialize(framebuffer_info_t& framebufferInfo);
void deinitialize();
- void reset();
- bool updateHotplug(bool connected, framebuffer_info_t * framebufferInfo,
- private_handle_t* framebufferHnd);
- int updateDisplayModeList();
- int updateActiveDisplayMode();
- int setDisplayMode(const char* displaymode);
- int updateDisplayConfigures();
- int updateActiveDisplayConfigure();
-
- int getDisplayConfigs(uint32_t* outNumConfigs, hwc2_config_t* outConfigs);
- int getDisplayAttribute(hwc2_config_t config, int32_t attribute, int32_t* outValue);
- int getActiveConfig(hwc2_config_t* outConfig);
- int setActiveConfig(int id);
- //int setPowerMode(int power) {return 0;};
+ bool updateHotplug(bool connected, framebuffer_info_t& framebufferInfo);
+ status_t setBestDisplayMode();
+
+ status_t getDisplayConfigs(uint32_t* outNumConfigs, hwc2_config_t* outConfigs);
+ status_t getDisplayAttribute(hwc2_config_t config, int32_t attribute, int32_t* outValue);
+ status_t getActiveConfig(hwc2_config_t* outConfig);
+ status_t getRealActiveConfig(hwc2_config_t* outConfig);
+ status_t setActiveConfig(int modeId);
+ // int setPowerMode(int power) {return 0;};
+ int getDisplayWorkMode() const { return mWorkMode; };
inline bool isConnected() {return mConnected;};
- int getActiveRefreshRate() {return mActiveRefreshRate;};
- bool calcMode2Config(const char *dispMode, int* refreshRate, int* width, int* height);
- bool readConfigFile(const char* configPath, std::vector<std::string>* supportDispModes);
- void setSurfaceFlingerActiveMode();
- void initModes();
+ bool chkPresent();
+
+ bool isSecure();
void dump(Dump& d);
+protected:
+ /* hdmi operations:
+ * TODO: need move all these operations to HAL.
+ */
+ auto getSystemControlService();
+ status_t readEdidList(std::vector<std::string> &edidlist);
+ status_t writeHdmiDispMode(std::string &dispmode);
+ status_t readHdmiDispMode(std::string &dispmode);
+ status_t readHdmiPhySize(framebuffer_info_t& fbInfo);
+ status_t readBestHdmiOutputMode(std::string &dispmode);
+
+ void switchRatePolicy(bool fracRatePolicy);
+ void reset();
+
+ // operations on mSupportDispModes
+ status_t clearSupportedConfigs();
+ status_t updateSupportedConfigs();
+ status_t updateDisplayAttributes(framebuffer_info_t& framebufferInfo);
+ status_t addSupportedConfig(std::string& mode);
+
+ // ensure the active mode equals the current displaymode.
+ status_t updateActiveConfig(std::string& activeMode);
+
+ status_t setDisplayMode(std::string& dispmode, bool policy = false);
+ bool isDispModeValid(std::string& dispmode);
+
+ bool readConfigFile(const char* configPath, std::vector<std::string>* supportDispModes);
+
+ status_t calcDefaultMode(framebuffer_info_t& framebufferInfo, std::string& defaultMode);
+ status_t buildSingleConfigList(std::string& defaultMode);
+
+ bool checkVinfo(framebuffer_info_t *fbInfo);
+
private:
- void initBinderService();
- struct SystemControlDeathRecipient : public android::hardware::hidl_death_recipient
- {
+ bool mConnected;
+
+#if PLATFORM_SDK_VERSION >= 26
+ struct SystemControlDeathRecipient : public android::hardware::hidl_death_recipient {
// hidl_death_recipient interface
virtual void serviceDied(uint64_t cookie,
- const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override;
+ const ::android::wp<::android::hidl::base::V1_0::IBase>& who) override{};
};
-
- hwc2_display_t mDisplayId; //0-primary 1-external
- bool mConnected;
- bool mTrebleSystemControlEnable;
- sp<ISystemControlService> mSystemControlService;
- sp<ISystemControl> mTrebleSystemControl;
sp<SystemControlDeathRecipient> mDeathRecipient = nullptr;
- sp<SurfaceComposerClient> mComposerClient;
-
- //display outputmode as 4k20hz, 1080p60hz, panel. etc.
- std::vector<std::string> mAllModes;
- std::vector<std::string> mSupportDispModes;
- char mActiveDisplaymode[HWC_DISPLAY_MODE_LENGTH];
- int mActiveRefreshRate;
-
- std::vector<DisplayConfig*> mDisplayConfigs;
- hwc2_config_t mActiveDisplayConfigItem;
+#endif
- framebuffer_info_t *mFramebufferInfo;
- private_handle_t *mFramebufferHnd;
+ // configures variables.
+ hwc2_config_t mActiveConfigId; // for amlogic, it is vmode_e.
+ std::string mActiveConfigStr;
+ hwc2_config_t mRealActiveConfigId;
+ std::string mRealActiveConfigStr;
+ KeyedVector<int, DisplayConfig*> mSupportDispConfigs;
+
+ // physical size in mm.
+ int mPhyWidth;
+ int mPhyHeight;
+ // framebuffer size.
+ int mFbWidth;
+ int mFbHeight;
+
+ // work modes
+ enum {
+ REAL_ACTIVEMODE = 0,
+ LOGIC_ACTIVEMODE, // return the logic size which is framebuffer size.
+ NONE_ACTIVEMODE // no active mode list, always return a default config.
+ };
+ int mWorkMode;
+ // first boot up flag.
+ bool mFirstBootup;
};
-
} // namespace amlogic
} // namespace android
diff --git a/hwc2/common/observers/SoftVsyncObserver.cpp b/hwc2/common/observers/SoftVsyncObserver.cpp
index 6347b8d..f739add 100644
--- a/hwc2/common/observers/SoftVsyncObserver.cpp
+++ b/hwc2/common/observers/SoftVsyncObserver.cpp
@@ -31,7 +31,6 @@ namespace amlogic {
SoftVsyncObserver::SoftVsyncObserver(IDisplayDevice& disp)
: mDisplayDevice(disp),
mEnabled(false),
- mRefreshRate(60), // default 60 frames per second
mRefreshPeriod(0),
mLock(),
mCondition(),
@@ -55,8 +54,7 @@ bool SoftVsyncObserver::initialize()
mExitThread = false;
mEnabled = false;
- mRefreshRate = 60;
- mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
+ mRefreshPeriod = nsecs_t(1e9 / 60);
mThread = new VsyncEventPollThread(this);
if (!mThread.get()) {
DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
@@ -83,16 +81,15 @@ void SoftVsyncObserver::deinitialize()
mInitialized = false;
}
-void SoftVsyncObserver::setRefreshRate(int rate)
+void SoftVsyncObserver::setRefreshPeriod(nsecs_t period)
{
Mutex::Autolock _l(mLock);
- if (rate < 1 || rate > 120) {
- WTRACE("invalid refresh rate %d", rate);
- } else if (mRefreshRate != rate) {
- mRefreshRate = rate;
+ if (period <= 0) {
+ WTRACE("invalid refresh period %lld", period);
+ } else if (mRefreshPeriod != period) {
+ mRefreshPeriod = period;
if (mEnabled) {
- mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
mNextFakeVSync = systemTime(CLOCK_MONOTONIC) + mRefreshPeriod;
}
}
@@ -108,7 +105,6 @@ bool SoftVsyncObserver::control(bool enabled)
}
if (enabled) {
- mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
mNextFakeVSync = systemTime(CLOCK_MONOTONIC) + mRefreshPeriod;
}
mEnabled = enabled;
@@ -129,11 +125,11 @@ bool SoftVsyncObserver::threadLoop()
}
}
-
const nsecs_t period = mRefreshPeriod;
const nsecs_t now = systemTime(CLOCK_MONOTONIC);
nsecs_t next_vsync = mNextFakeVSync;
nsecs_t sleep = next_vsync - now;
+ //DTRACE("Softvync (%lld), refresh (%lld)", period, nsecs_t(1e9/period));
if (sleep < 0) {
// we missed, find where the next vsync should be
sleep = (period - ((now - next_vsync) % period));
diff --git a/hwc2/common/observers/SoftVsyncObserver.h b/hwc2/common/observers/SoftVsyncObserver.h
index 1a7be89..94e63fa 100644
--- a/hwc2/common/observers/SoftVsyncObserver.h
+++ b/hwc2/common/observers/SoftVsyncObserver.h
@@ -34,7 +34,7 @@ public:
public:
virtual bool initialize();
virtual void deinitialize();
- virtual void setRefreshRate(int rate);
+ virtual void setRefreshPeriod(nsecs_t period);
virtual bool control(bool enabled);
virtual nsecs_t getRefreshPeriod() const { return mRefreshPeriod; }
@@ -42,7 +42,6 @@ private:
IDisplayDevice& mDisplayDevice;
int mDevice;
bool mEnabled;
- int mRefreshRate;
nsecs_t mRefreshPeriod;
mutable Mutex mLock;
Condition mCondition;
diff --git a/hwc2/common/observers/UeventObserver.cpp b/hwc2/common/observers/UeventObserver.cpp
index 7590bcd..7f6bbc1 100644
--- a/hwc2/common/observers/UeventObserver.cpp
+++ b/hwc2/common/observers/UeventObserver.cpp
@@ -192,7 +192,7 @@ void UeventObserver::onUevent()
DTRACE("onUevent: %s", mUeventMessage);
for (uint32_t i=0; i<mListeners.size(); i++) {
const char *envelope = mListeners.keyAt(i).string();
- if (strncmp(msg, envelope, strlen(envelope)) == 0) {
+ if (strncmp(msg, envelope, UEVENT_MSG_LEN) == 0) {
listener = mListeners.valueAt(i);
break;
} else {
diff --git a/hwc2/common/utils/AmVideo.cpp b/hwc2/common/utils/AmVideo.cpp
new file mode 100644
index 0000000..15db0c9
--- a/dev/null
+++ b/hwc2/common/utils/AmVideo.cpp
@@ -0,0 +1,109 @@
+/*
+// Copyright (c) 2017 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+*/
+
+#define LOG_TAG "AmVideo"
+//#define LOG_NDEBUG 0
+#include <cutils/log.h>
+
+#include <AmVideo.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+//#define AMVIDEO_DEBUG
+
+using namespace android;
+
+#define AM_VIDEO_DEV "/dev/amvideo"
+
+#define AMSTREAM_IOC_MAGIC 'S'
+#define AMSTREAM_IOC_GLOBAL_GET_VIDEO_OUTPUT _IOR(AMSTREAM_IOC_MAGIC, 0x21, int)
+#define AMSTREAM_IOC_GLOBAL_SET_VIDEO_OUTPUT _IOW(AMSTREAM_IOC_MAGIC, 0x22, int)
+
+AmVideo* AmVideo::mInstance = NULL;
+Mutex AmVideo::mLock;
+
+AmVideo::AmVideo() {
+ mDevFd = open(AM_VIDEO_DEV, O_RDWR | O_NONBLOCK);
+ if (mDevFd < 0) {
+ ALOGE("Open %s Failed. ", AM_VIDEO_DEV);
+ }
+
+ if (getVideoPresent(mVideoPresent) != 0) {
+ ALOGE("Get video mute failed.");
+ mVideoPresent = true;
+ }
+}
+
+AmVideo::~AmVideo() {
+ if (mDevFd >= 0) {
+ close(mDevFd);
+ mDevFd = -1;
+ }
+}
+
+AmVideo* AmVideo::getInstance() {
+ if (mInstance == NULL) {
+ Mutex::Autolock _l(mLock);
+ if (mInstance == NULL) {
+ mInstance = new AmVideo();
+ }
+ }
+
+ return mInstance;
+}
+
+int AmVideo::presentVideo(bool bPresent) {
+ if (mDevFd < 0)
+ return -EBADF;
+
+ if (mVideoPresent != bPresent) {
+ ALOGD("muteVideo to %d", bPresent);
+ uint32_t val = bPresent ? 1 : 0;
+ if (ioctl(mDevFd, AMSTREAM_IOC_GLOBAL_SET_VIDEO_OUTPUT, val) != 0) {
+ ALOGE("AMSTREAM_SET_VIDEO_OUTPUT ioctl (%d) return(%d)", bPresent, errno);
+ return -EINVAL;
+ }
+ mVideoPresent = bPresent;
+ } else {
+ #ifdef AMVIDEO_DEBUG
+ bool val = true;
+ getVideoPresent(val);
+ if (mVideoPresent != val) {
+ ALOGE("presentVideo (%d) vs (%d)", mVideoPresent, val);
+ }
+ ALOGD("Already set video to (%d)", bPresent);
+ #endif
+ }
+
+ return 0;
+}
+
+int AmVideo::getVideoPresent(bool& output) {
+ if (mDevFd < 0)
+ return -EBADF;
+
+ uint32_t val = 1;
+ if (ioctl(mDevFd, AMSTREAM_IOC_GLOBAL_GET_VIDEO_OUTPUT, &val) != 0) {
+ ALOGE("AMSTREAM_GET_VIDEO_OUTPUT ioctl fail(%d)", errno);
+ return -EINVAL;
+ }
+
+ output = (val ==0) ? false : true;
+ return 0;
+}
+
diff --git a/hwc2/common/utils/AmVinfo.cpp b/hwc2/common/utils/AmVinfo.cpp
new file mode 100644
index 0000000..4bc2420
--- a/dev/null
+++ b/hwc2/common/utils/AmVinfo.cpp
@@ -0,0 +1,928 @@
+/*
+// Copyright (c) 2017 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+*/
+
+/*
+* !!!ATTENTATION:
+* MOST COPY FROM KERNEL, DONT MODIFY.
+*/
+
+#include <AmVinfo.h>
+#include <string.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+/*
+* COPY FROM Vinfo.c
+*/
+
+struct vmode_match_s {
+ char *name;
+ enum vmode_e mode;
+};
+
+static struct vmode_match_s vmode_match_table[] = {
+ {"480i60hz", VMODE_480I},
+ {"480irpt", VMODE_480I_RPT},
+ {"480cvbs", VMODE_480CVBS},
+ {"480p60hz", VMODE_480P},
+ {"480prtp", VMODE_480P_RPT},
+ {"576i50hz", VMODE_576I},
+ {"576irpt", VMODE_576I_RPT},
+ {"576cvbs", VMODE_576CVBS},
+ {"576p50hz", VMODE_576P},
+ {"576prpt", VMODE_576P_RPT},
+ {"720p60hz", VMODE_720P},
+ {"720p50hz", VMODE_720P_50HZ},
+ {"768p60hz", VMODE_768P},
+ {"768p50hz", VMODE_768P_50HZ},
+ {"1080i60hz", VMODE_1080I},
+ {"1080i50hz", VMODE_1080I_50HZ},
+ {"1080p60hz", VMODE_1080P},
+ {"1080p25hz", VMODE_1080P_25HZ},
+ {"1080p30hz", VMODE_1080P_30HZ},
+ {"1080p50hz", VMODE_1080P_50HZ},
+ {"1080p24hz", VMODE_1080P_24HZ},
+ {"2160p30hz", VMODE_4K2K_30HZ},
+ {"2160p25hz", VMODE_4K2K_25HZ},
+ {"2160p24hz", VMODE_4K2K_24HZ},
+ {"smpte24hz", VMODE_4K2K_SMPTE},
+ {"smpte25hz", VMODE_4K2K_SMPTE_25HZ},
+ {"smpte30hz", VMODE_4K2K_SMPTE_30HZ},
+ {"smpte50hz420", VMODE_4K2K_SMPTE_50HZ_Y420},
+ {"smpte50hz", VMODE_4K2K_SMPTE_50HZ},
+ {"smpte60hz420", VMODE_4K2K_SMPTE_60HZ_Y420},
+ {"smpte60hz", VMODE_4K2K_SMPTE_60HZ},
+ {"4k2k5g", VMODE_4K2K_FAKE_5G},
+ {"2160p60hz420", VMODE_4K2K_60HZ_Y420},
+ {"2160p60hz", VMODE_4K2K_60HZ},
+ {"2160p50hz420", VMODE_4K2K_50HZ_Y420},
+ {"2160p50hz", VMODE_4K2K_50HZ},
+ {"2160p5g", VMODE_4K2K_5G},
+ {"4k1k120hz420", VMODE_4K1K_120HZ_Y420},
+ {"4k1k120hz", VMODE_4K1K_120HZ},
+ {"4k1k100hz420", VMODE_4K1K_100HZ_Y420},
+ {"4k1k100hz", VMODE_4K1K_100HZ},
+ {"4k05k240hz420", VMODE_4K05K_240HZ_Y420},
+ {"4k05k240hz", VMODE_4K05K_240HZ},
+ {"4k05k200hz420", VMODE_4K05K_200HZ_Y420},
+ {"4k05k200hz", VMODE_4K05K_200HZ},
+ {"panel", VMODE_LCD},
+ {"invalid", VMODE_INIT_NULL},
+};
+
+/*
+* Modified.
+*/
+enum vmode_e vmode_name_to_mode(const char *str)
+{
+ int i;
+ enum vmode_e vmode = VMODE_MAX;
+
+ for (i = 0; i < ARRAY_SIZE(vmode_match_table); i++) {
+ if (strstr(str, vmode_match_table[i].name)) {
+ vmode = vmode_match_table[i].mode;
+ break;
+ }
+#if 0
+ if (strcmp(vmode_match_table[i].name, str) == 0) {
+ vmode = vmode_match_table[i].mode;
+ break;
+ }
+#endif
+ }
+
+ return vmode;
+}
+
+const char *vmode_mode_to_name(enum vmode_e vmode)
+{
+ int i;
+ char *str = "invalid";
+
+ for (i = 0; i < ARRAY_SIZE(vmode_match_table); i++) {
+ if (vmode == vmode_match_table[i].mode) {
+ str = vmode_match_table[i].name;
+ break;
+ }
+ }
+
+ return str;
+}
+
+
+/*
+* COPY FROM TV_VOUT.h/TV_VOUT.c
+*/
+static const struct vinfo_s tv_info[] = {
+ { /* VMODE_480I */
+ .name = "480i60hz",
+ .mode = VMODE_480I,
+ .width = 720,
+ .height = 480,
+ .field_height = 240,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_480I_RPT */
+ .name = "480i_rpt",
+ .mode = VMODE_480I_RPT,
+ .width = 720,
+ .height = 480,
+ .field_height = 240,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_480CVBS*/
+ .name = "480cvbs",
+ .mode = VMODE_480CVBS,
+ .width = 720,
+ .height = 480,
+ .field_height = 240,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_480P */
+ .name = "480p60hz",
+ .mode = VMODE_480P,
+ .width = 720,
+ .height = 480,
+ .field_height = 480,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_480P_RPT */
+ .name = "480p_rpt",
+ .mode = VMODE_480P_RPT,
+ .width = 720,
+ .height = 480,
+ .field_height = 480,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_576I */
+ .name = "576i50hz",
+ .mode = VMODE_576I,
+ .width = 720,
+ .height = 576,
+ .field_height = 288,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_576I_RPT */
+ .name = "576i_rpt",
+ .mode = VMODE_576I_RPT,
+ .width = 720,
+ .height = 576,
+ .field_height = 288,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_576I */
+ .name = "576cvbs",
+ .mode = VMODE_576CVBS,
+ .width = 720,
+ .height = 576,
+ .field_height = 288,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_576P */
+ .name = "576p50hz",
+ .mode = VMODE_576P,
+ .width = 720,
+ .height = 576,
+ .field_height = 576,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_576P_RPT */
+ .name = "576p_rpt",
+ .mode = VMODE_576P_RPT,
+ .width = 720,
+ .height = 576,
+ .field_height = 576,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 27000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_720P */
+ .name = "720p60hz",
+ .mode = VMODE_720P,
+ .width = 1280,
+ .height = 720,
+ .field_height = 720,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080I */
+ .name = "1080i60hz",
+ .mode = VMODE_1080I,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 540,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080P */
+ .name = "1080p60hz",
+ .mode = VMODE_1080P,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_720P_50hz */
+ .name = "720p50hz",
+ .mode = VMODE_720P_50HZ,
+ .width = 1280,
+ .height = 720,
+ .field_height = 720,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080I_50HZ */
+ .name = "1080i50hz",
+ .mode = VMODE_1080I_50HZ,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 540,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080P_30HZ */
+ .name = "1080p30hz",
+ .mode = VMODE_1080P_30HZ,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 30,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080P_50HZ */
+ .name = "1080p50hz",
+ .mode = VMODE_1080P_50HZ,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080P_25HZ */
+ .name = "1080p25hz",
+ .mode = VMODE_1080P_25HZ,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 25,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080P_24HZ */
+ .name = "1080p24hz",
+ .mode = VMODE_1080P_24HZ,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 24,
+ .sync_duration_den = 1,
+ .video_clk = 74250000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_30HZ */
+ .name = "2160p30hz",
+ .mode = VMODE_4K2K_30HZ,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 30,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_25HZ */
+ .name = "2160p25hz",
+ .mode = VMODE_4K2K_25HZ,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 25,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_24HZ */
+ .name = "2160p24hz",
+ .mode = VMODE_4K2K_24HZ,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 24,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE */
+ .name = "smpte24hz",
+ .mode = VMODE_4K2K_SMPTE,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 256,
+ .aspect_ratio_den = 135,
+ .sync_duration_num = 24,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE_25HZ */
+ .name = "smpte25hz",
+ .mode = VMODE_4K2K_SMPTE_25HZ,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 256,
+ .aspect_ratio_den = 135,
+ .sync_duration_num = 25,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE_30HZ */
+ .name = "smpte30hz",
+ .mode = VMODE_4K2K_SMPTE_30HZ,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 256,
+ .aspect_ratio_den = 135,
+ .sync_duration_num = 30,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE_50HZ */
+ .name = "smpte50hz",
+ .mode = VMODE_4K2K_SMPTE_50HZ,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 256,
+ .aspect_ratio_den = 135,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE_60HZ */
+ .name = "smpte60hz",
+ .mode = VMODE_4K2K_SMPTE_60HZ,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 256,
+ .aspect_ratio_den = 135,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_FAKE_5G */
+ .name = "4k2k5g",
+ .mode = VMODE_4K2K_FAKE_5G,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 495000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_60HZ_Y420 */
+ .name = "2160p60hz420",
+ .mode = VMODE_4K2K_60HZ_Y420,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE_60HZ_Y420 */
+ .name = "smpte60hz420",
+ .mode = VMODE_4K2K_SMPTE_60HZ_Y420,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_60HZ */
+ .name = "2160p60hz",
+ .mode = VMODE_4K2K_60HZ,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K1K_100HZ_Y420 */
+ .name = "4k1k100hz420",
+ .mode = VMODE_4K1K_100HZ_Y420,
+ .width = 3840,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 32,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 100,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K1K_100HZ */
+ .name = "4k1k100hz",
+ .mode = VMODE_4K1K_100HZ,
+ .width = 3840,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 32,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 100,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K1K_120HZ_Y420 */
+ .name = "4k1k120hz420",
+ .mode = VMODE_4K1K_120HZ_Y420,
+ .width = 3840,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 32,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 120,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K1K_120HZ */
+ .name = "4k1k120hz",
+ .mode = VMODE_4K1K_120HZ,
+ .width = 3840,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 32,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 120,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K05K_200HZ_Y420 */
+ .name = "4k05k200hz420",
+ .mode = VMODE_4K05K_200HZ_Y420,
+ .width = 3840,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 64,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 200,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K05K_200HZ */
+ .name = "4k05k200hz",
+ .mode = VMODE_4K05K_200HZ,
+ .width = 3840,
+ .height = 540,
+ .field_height = 540,
+ .aspect_ratio_num = 64,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 200,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K05K_240HZ_Y420 */
+ .name = "4k05k240hz420",
+ .mode = VMODE_4K05K_240HZ_Y420,
+ .width = 3840,
+ .height = 540,
+ .field_height = 540,
+ .aspect_ratio_num = 64,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 240,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K05K_240HZ */
+ .name = "4k05k240hz",
+ .mode = VMODE_4K05K_240HZ,
+ .width = 3840,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 64,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 240,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_50HZ_Y420 */
+ .name = "2160p50hz420",
+ .mode = VMODE_4K2K_50HZ_Y420,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_SMPTE_50HZ_Y420 */
+ .name = "smpte50hz420",
+ .mode = VMODE_4K2K_SMPTE_50HZ_Y420,
+ .width = 4096,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_4K2K_50HZ */
+ .name = "2160p50hz",
+ .mode = VMODE_4K2K_50HZ,
+ .width = 3840,
+ .height = 2160,
+ .field_height = 2160,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 594000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_vga */
+ .name = "vga",
+ .mode = VMODE_VGA,
+ .width = 640,
+ .height = 480,
+ .field_height = 240,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 25175000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_SVGA */
+ .name = "svga",
+ .mode = VMODE_SVGA,
+ .width = 800,
+ .height = 600,
+ .field_height = 600,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 40000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_XGA */
+ .name = "xga",
+ .mode = VMODE_XGA,
+ .width = 1024,
+ .height = 768,
+ .field_height = 768,
+ .aspect_ratio_num = 4,
+ .aspect_ratio_den = 3,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 65000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_sxga */
+ .name = "sxga",
+ .mode = VMODE_SXGA,
+ .width = 1280,
+ .height = 1024,
+ .field_height = 1024,
+ .aspect_ratio_num = 5,
+ .aspect_ratio_den = 4,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 108000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_wsxga */
+ .name = "wsxga",
+ .mode = VMODE_WSXGA,
+ .width = 1440,
+ .height = 900,
+ .field_height = 900,
+ .aspect_ratio_num = 8,
+ .aspect_ratio_den = 5,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 88750000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_fhdvga */
+ .name = "fhdvga",
+ .mode = VMODE_FHDVGA,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+/* VMODE for 3D Frame Packing */
+ { /* VMODE_1080FP60HZ */
+ .name = "1080fp60hz",
+ .mode = VMODE_1080FP60HZ,
+ .width = 1920,
+ .height = 1080 + 1125,
+ .field_height = 1080 + 1125,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080FP50HZ */
+ .name = "1080fp50hz",
+ .mode = VMODE_1080FP50HZ,
+ .width = 1920,
+ .height = 1080 + 1125,
+ .field_height = 1080 + 1125,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 297000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080FP30HZ */
+ .name = "1080fp30hz",
+ .mode = VMODE_1080FP30HZ,
+ .width = 1920,
+ .height = 1080 + 1125,
+ .field_height = 1080 + 1125,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 30,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080FP25HZ */
+ .name = "1080fp25hz",
+ .mode = VMODE_1080FP25HZ,
+ .width = 1920,
+ .height = 1080 + 1125,
+ .field_height = 1080 + 1125,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 25,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_1080FP24HZ */
+ .name = "1080fp24hz",
+ .mode = VMODE_1080FP24HZ,
+ .width = 1920,
+ .height = 1080 + 1125,
+ .field_height = 1080 + 1125,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 24,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_720FP60HZ */
+ .name = "720fp60hz",
+ .mode = VMODE_720FP60HZ,
+ .width = 1280,
+ .height = 720 + 750,
+ .field_height = 720 + 750,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+ { /* VMODE_720FP50HZ */
+ .name = "720fp50hz",
+ .mode = VMODE_720FP50HZ,
+ .width = 1280,
+ .height = 720 + 750,
+ .field_height = 720 + 750,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 50,
+ .sync_duration_den = 1,
+ .video_clk = 148500000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+/* VMODE for 3D Frame Packing END */
+ { /* NULL mode, used as temporary witch mode state */
+ .name = "null",
+ .mode = VMODE_NULL,
+ .width = 1920,
+ .height = 1080,
+ .field_height = 1080,
+ .aspect_ratio_num = 16,
+ .aspect_ratio_den = 9,
+ .sync_duration_num = 60,
+ .sync_duration_den = 1,
+ .video_clk = 1485000000,
+ .viu_color_fmt = TVIN_YUV444,
+ },
+};
+
+const struct vinfo_s *get_tv_info(enum vmode_e mode)
+{
+ int i = 0;
+ for (i = 0; i < ARRAY_SIZE(tv_info); i++) {
+ if (mode == tv_info[i].mode)
+ return &tv_info[i];
+ }
+ return NULL;
+}
+
+/* for hdmi (un)plug during fps automation */
+int want_hdmi_mode(enum vmode_e mode)
+{
+ int ret = 0;
+ if ((mode == VMODE_480I)
+ || (mode == VMODE_480I_RPT)
+ || (mode == VMODE_480P)
+ || (mode == VMODE_480P_RPT)
+ || (mode == VMODE_576I)
+ || (mode == VMODE_576I_RPT)
+ || (mode == VMODE_576P)
+ || (mode == VMODE_576P_RPT)
+ || (mode == VMODE_720P)
+ || (mode == VMODE_720P_50HZ)
+ || (mode == VMODE_1080I)
+ || (mode == VMODE_1080I_50HZ)
+ || (mode == VMODE_1080P)
+ || (mode == VMODE_1080P_50HZ)
+ || (mode == VMODE_1080P_30HZ)
+ || (mode == VMODE_1080P_24HZ)
+ || (mode == VMODE_4K2K_24HZ)
+ || (mode == VMODE_4K2K_25HZ)
+ || (mode == VMODE_4K2K_30HZ)
+ || (mode == VMODE_4K2K_SMPTE)
+ || (mode == VMODE_4K2K_SMPTE_25HZ)
+ || (mode == VMODE_4K2K_SMPTE_30HZ)
+ || (mode == VMODE_4K2K_SMPTE_50HZ)
+ || (mode == VMODE_4K2K_SMPTE_60HZ)
+ || (mode == VMODE_4K2K_SMPTE_50HZ_Y420)
+ || (mode == VMODE_4K2K_SMPTE_60HZ_Y420)
+ || (mode == VMODE_4K2K_FAKE_5G)
+ || (mode == VMODE_4K2K_5G)
+ || (mode == VMODE_4K2K_50HZ)
+ || (mode == VMODE_4K2K_50HZ_Y420)
+ || (mode == VMODE_4K2K_60HZ)
+ || (mode == VMODE_4K2K_60HZ_Y420)
+ )
+ ret = 1;
+ return ret;
+}
+
+
+/*
+* NEW ADDED
+*/
+//search
+const struct vinfo_s * findMatchedMode(u32 width, u32 height, u32 refreshrate) {
+ int i = 0;
+ for (i = 0; i < ARRAY_SIZE(tv_info); i++) {
+ if (tv_info[i].width == width && tv_info[i].height == height &&
+ tv_info[i].field_height == height && tv_info[i].sync_duration_num == refreshrate) {
+ return &(tv_info[i]);
+ }
+ }
+ return NULL;
+}
+
diff --git a/hwc2/common/utils/Utils.cpp b/hwc2/common/utils/Utils.cpp
index 53eed8d..7d9ebfe 100644
--- a/hwc2/common/utils/Utils.cpp
+++ b/hwc2/common/utils/Utils.cpp
@@ -1,7 +1,21 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
+
#include <hardware/hardware.h>
#include <HwcTrace.h>
@@ -40,11 +54,11 @@ bool Utils::get_bool_prop(const char* prop) {
int Utils::get_int_prop(const char* prop) {
char val[PROPERTY_VALUE_MAX];
memset(val, 0, sizeof(val));
- if (property_get(prop, val, "2")) {
- //VTRACE("prop: %s is %s",prop, val);
+ if (property_get(prop, val, "0")) {
+ VTRACE("prop: %s is %s",prop, val);
return atoi(val);
}
- return 0;
+ return -1;
}
int Utils::getSysfsInt(const char* syspath, int def) {
@@ -52,7 +66,7 @@ int Utils::getSysfsInt(const char* syspath, int def) {
char valstr[64];
if (getSysfsStr(syspath, valstr, sizeof(valstr)) == 0) {
val = atoi(valstr);
- //DTRACE("sysfs(%s) read int (%s)=(%d)", syspath, valstr, val);
+ DTRACE("sysfs(%s) read int (%d)", syspath, val);
}
return val;
}
@@ -176,42 +190,9 @@ bool Utils::checkSysfsStatus(const char* sysfstr, char* lastr, int32_t size) {
}
#endif
-bool Utils::checkVinfo(framebuffer_info_t *fbInfo) {
- if (fbInfo != NULL && fbInfo->fd >= 0) {
- struct fb_var_screeninfo vinfo;
- if (ioctl(fbInfo->fd, FBIOGET_VSCREENINFO, &vinfo) == -1)
- {
- ETRACE("FBIOGET_VSCREENINFO error!!!");
- return -errno;
- }
-
- if (vinfo.xres != fbInfo->info.xres
- || vinfo.yres != fbInfo->info.yres
- || vinfo.width != fbInfo->info.width
- || vinfo.height != fbInfo->info.height) {
- if (int32_t(vinfo.width) <= 16 || int32_t(vinfo.height) <= 9) {
- // the driver doesn't return that information
- // default to 160 dpi
- vinfo.width = ((vinfo.xres * 25.4f)/160.0f + 0.5f);
- vinfo.height = ((vinfo.yres * 25.4f)/160.0f + 0.5f);
- }
- fbInfo->xdpi = (vinfo.xres * 25.4f) / vinfo.width;
- fbInfo->ydpi = (vinfo.yres * 25.4f) / vinfo.height;
-
- fbInfo->info.xres = vinfo.xres;
- fbInfo->info.yres = vinfo.yres;
- fbInfo->info.width = vinfo.width;
- fbInfo->info.height = vinfo.height;
- }
- return true;
- }
-
- return false;
-}
-
const char* Utils::getHotplugUeventEnvelope()
{
- return "change@/devices/virtual/switch/hdmi_audio";
+ return "change@/devices/virtual/switch/hdmi_delay";
}
const char* Utils::getHdcpUeventEnvelope()
@@ -229,5 +210,35 @@ const char* Utils::getSwitchState1()
return "SWITCH_STATE=1";
}
+
+bool Utils::rectEmpty(hwc_rect_t& rect) {
+ if ((rect.right - rect.left <= 0) ||(rect.bottom - rect.top <= 0))
+ return true;
+ else
+ return false;
+}
+
+bool Utils::rectIntersect(hwc_rect_t& source, hwc_rect_t& dest, hwc_rect_t& result) {
+ result.left = max(source.left, dest.left);
+ result.top = max(source.top, dest.top);
+ result.right = min(source.right, dest.right);
+ result.bottom = min(source.bottom, dest.bottom);
+ return !rectEmpty(result);
+}
+
+Utils::OVERLAP_TYPE Utils::rectOverlap(hwc_rect_t& source, hwc_rect_t& dest) {
+ hwc_rect_t result;
+ if (!rectIntersect(source, dest, result)) {
+ return OVERLAP_EMPTY;
+ } else {
+ if (compareRect(result, source) == true) {
+ return OVERLAP_FULL;
+ } else {
+ return OVERLAP_PART;
+ }
+ }
+}
+
+
} // namespace amlogic
} // namespace android
diff --git a/hwc2/common/utils/Utils.h b/hwc2/common/utils/Utils.h
index 53a55d0..4ae0302 100644
--- a/hwc2/common/utils/Utils.h
+++ b/hwc2/common/utils/Utils.h
@@ -1,5 +1,18 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
#ifndef UTILS_H_
@@ -9,6 +22,7 @@
#if WITH_LIBPLAYER_MODULE
#include <Amavutils.h>
#endif
+#include <hardware/hwcomposer_defs.h>
#define DISPLAY_HPD_STATE "/sys/class/amhdmitx/amhdmitx0/hpd_state"
#define DISPLAY_HDMI_EDID "/sys/class/amhdmitx/amhdmitx0/disp_cap"
@@ -47,8 +61,6 @@ public:
#if WITH_LIBPLAYER_MODULE
static bool checkSysfsStatus(const char* sysfstr, char* lastr, int32_t size);
#endif
- static bool checkOutputMode(char* curmode, int32_t* rate);
- static bool checkVinfo(framebuffer_info_t *fbinfo);
static const char* getHotplugUeventEnvelope();
static const char* getHdcpUeventEnvelope();
@@ -92,6 +104,18 @@ public:
b = t;
}
+ /*
+ * hwc_rect_t operation
+ */
+ enum OVERLAP_TYPE{
+ OVERLAP_EMPTY = 0,
+ OVERLAP_PART,
+ OVERLAP_FULL
+ };
+
+ static bool rectEmpty(hwc_rect_t& rect);
+ static bool rectIntersect(hwc_rect_t& source, hwc_rect_t& dest, hwc_rect_t& result);
+ static OVERLAP_TYPE rectOverlap(hwc_rect_t& source, hwc_rect_t& dest);
};
} // namespace amlogic
diff --git a/hwc2/include/AmVideo.h b/hwc2/include/AmVideo.h
new file mode 100644
index 0000000..4d2c8e8
--- a/dev/null
+++ b/hwc2/include/AmVideo.h
@@ -0,0 +1,45 @@
+/*
+// Copyright (c) 2017 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+*/
+#ifndef AML_VIDEO_H_
+#define AML_VIDEO_H_
+
+#include <utils/Mutex.h>
+
+namespace android {
+class AmVideo {
+public:
+ static AmVideo* getInstance();
+ int presentVideo(bool bPresent);
+ bool isVideoPresent() {return mVideoPresent;}
+
+protected:
+ AmVideo();
+ ~AmVideo();
+
+ int getVideoPresent(bool& output);
+
+private:
+ static AmVideo* mInstance;
+ static Mutex mLock;
+
+ int mDevFd;
+ bool mVideoPresent;
+};
+
+}
+#endif//AML_VIDEO_H_
+
diff --git a/hwc2/include/AmVinfo.h b/hwc2/include/AmVinfo.h
new file mode 100644
index 0000000..3f25184
--- a/dev/null
+++ b/hwc2/include/AmVinfo.h
@@ -0,0 +1,221 @@
+/*
+// Copyright (c) 2017 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+*/
+
+#ifndef AM_VINFO_H_
+#define AM_VINFO_H_
+#include <sys/types.h>
+
+/*
+ * !!!ATTENTATION:
+ * MOST COPY FROM KERNEL, DONT MODIFY.
+ */
+
+/*
+ * from kernel/include/driver/vout/vinfo.h
+ */
+enum vmode_e {
+ VMODE_480I = 0,
+ VMODE_480I_RPT,
+ VMODE_480CVBS,
+ VMODE_480P,
+ VMODE_480P_RPT,
+ VMODE_576I,
+ VMODE_576I_RPT,
+ VMODE_576CVBS,
+ VMODE_576P,
+ VMODE_576P_RPT,
+ VMODE_720P,
+ VMODE_720P_50HZ,
+ VMODE_768P,
+ VMODE_768P_50HZ,
+ VMODE_1080I,
+ VMODE_1080I_50HZ,
+ VMODE_1080P,
+ VMODE_1080P_30HZ,
+ VMODE_1080P_50HZ,
+ VMODE_1080P_25HZ,
+ VMODE_1080P_24HZ,
+ VMODE_4K2K_30HZ,
+ VMODE_4K2K_25HZ,
+ VMODE_4K2K_24HZ,
+ VMODE_4K2K_SMPTE,
+ VMODE_4K2K_SMPTE_25HZ,
+ VMODE_4K2K_SMPTE_30HZ,
+ VMODE_4K2K_SMPTE_50HZ,
+ VMODE_4K2K_SMPTE_50HZ_Y420,
+ VMODE_4K2K_SMPTE_60HZ,
+ VMODE_4K2K_SMPTE_60HZ_Y420,
+ VMODE_4K2K_FAKE_5G,
+ VMODE_4K2K_60HZ,
+ VMODE_4K2K_60HZ_Y420,
+ VMODE_4K2K_50HZ,
+ VMODE_4K2K_50HZ_Y420,
+ VMODE_4K2K_5G,
+ VMODE_4K1K_120HZ,
+ VMODE_4K1K_120HZ_Y420,
+ VMODE_4K1K_100HZ,
+ VMODE_4K1K_100HZ_Y420,
+ VMODE_4K05K_240HZ,
+ VMODE_4K05K_240HZ_Y420,
+ VMODE_4K05K_200HZ,
+ VMODE_4K05K_200HZ_Y420,
+ VMODE_VGA,
+ VMODE_SVGA,
+ VMODE_XGA,
+ VMODE_SXGA,
+ VMODE_WSXGA,
+ VMODE_FHDVGA,
+ VMODE_720FP50HZ, /* Extra VMODE for 3D Frame Packing */
+ VMODE_720FP60HZ,
+ VMODE_1080FP24HZ,
+ VMODE_1080FP25HZ,
+ VMODE_1080FP30HZ,
+ VMODE_1080FP50HZ,
+ VMODE_1080FP60HZ,
+ VMODE_LCD,
+ VMODE_NULL, /* null mode is used as temporary witch mode state */
+ VMODE_MAX,
+ VMODE_INIT_NULL,
+ VMODE_MASK = 0xFF,
+};
+
+enum tvmode_e {
+ TVMODE_480I = 0,
+ TVMODE_480I_RPT,
+ TVMODE_480CVBS,
+ TVMODE_480P,
+ TVMODE_480P_RPT,
+ TVMODE_576I,
+ TVMODE_576I_RPT,
+ TVMODE_576CVBS,
+ TVMODE_576P,
+ TVMODE_576P_RPT,
+ TVMODE_720P,
+ TVMODE_720P_50HZ,
+ TVMODE_768P,
+ TVMODE_768P_50HZ,
+ TVMODE_1080I,
+ TVMODE_1080I_50HZ,
+ TVMODE_1080P,
+ TVMODE_1080P_30HZ,
+ TVMODE_1080P_50HZ,
+ TVMODE_1080P_25HZ,
+ TVMODE_1080P_24HZ,
+ TVMODE_4K2K_30HZ,
+ TVMODE_4K2K_25HZ,
+ TVMODE_4K2K_24HZ,
+ TVMODE_4K2K_SMPTE,
+ TVMODE_4K2K_SMPTE_25HZ,
+ TVMODE_4K2K_SMPTE_30HZ,
+ TVMODE_4K2K_SMPTE_50HZ,
+ TVMODE_4K2K_SMPTE_50HZ_Y420,
+ TVMODE_4K2K_SMPTE_60HZ,
+ TVMODE_4K2K_SMPTE_60HZ_Y420,
+ TVMODE_4K2K_FAKE_5G,
+ TVMODE_4K2K_60HZ,
+ TVMODE_4K2K_60HZ_Y420,
+ TVMODE_4K2K_50HZ,
+ TVMODE_4K2K_50HZ_Y420,
+ TVMODE_4K2K_5G,
+ TVMODE_4K1K_120HZ,
+ TVMODE_4K1K_120HZ_Y420,
+ TVMODE_4K1K_100HZ,
+ TVMODE_4K1K_100HZ_Y420,
+ TVMODE_4K05K_240HZ,
+ TVMODE_4K05K_240HZ_Y420,
+ TVMODE_4K05K_200HZ,
+ TVMODE_4K05K_200HZ_Y420,
+ TVMODE_VGA ,
+ TVMODE_SVGA,
+ TVMODE_XGA,
+ TVMODE_SXGA,
+ TVMODE_WSXGA,
+ TVMODE_FHDVGA,
+ TVMODE_720FP50HZ, /* Extra TVMODE for 3D Frame Packing */
+ TVMODE_720FP60HZ,
+ TVMODE_1080FP24HZ,
+ TVMODE_1080FP25HZ,
+ TVMODE_1080FP30HZ,
+ TVMODE_1080FP50HZ,
+ TVMODE_1080FP60HZ,
+ TVMODE_NULL, /* null mode is used as temporary witch mode state */
+ TVMODE_MAX,
+};
+
+enum tvin_color_fmt_e {
+ TVIN_RGB444 = 0,
+ TVIN_YUV422, /* 1 */
+ TVIN_YUV444, /* 2 */
+ TVIN_YUYV422, /* 3 */
+ TVIN_YVYU422, /* 4 */
+ TVIN_UYVY422, /* 5 */
+ TVIN_VYUY422, /* 6 */
+ TVIN_NV12, /* 7 */
+ TVIN_NV21, /* 8 */
+ TVIN_BGGR, /* 9 raw data */
+ TVIN_RGGB, /* 10 raw data */
+ TVIN_GBRG, /* 11 raw data */
+ TVIN_GRBG, /* 12 raw data */
+ TVIN_COLOR_FMT_MAX,
+};
+
+enum tvin_color_fmt_range_e {
+ TVIN_FMT_RANGE_NULL = 0, /* depend on vedio fromat */
+ TVIN_RGB_FULL, /* 1 */
+ TVIN_RGB_LIMIT, /* 2 */
+ TVIN_YUV_FULL, /* 3 */
+ TVIN_YUV_LIMIT, /* 4 */
+ TVIN_COLOR_FMT_RANGE_MAX,
+};
+
+typedef uint32_t u32;
+
+/*
+* The commented memebers are not need now.
+*/
+struct vinfo_s {
+ char *name;
+ enum vmode_e mode;
+ u32 width;
+ u32 height;
+ u32 field_height;
+ u32 aspect_ratio_num;
+ u32 aspect_ratio_den;
+ u32 sync_duration_num;
+ u32 sync_duration_den;
+// u32 screen_real_width;
+// u32 screen_real_height;
+ u32 video_clk;
+ enum tvin_color_fmt_e viu_color_fmt;
+
+// struct hdr_info hdr_info;
+// struct master_display_info_s
+// master_display_info;
+// const struct dv_info *dv_info;
+ /* update hdmitx hdr packet, if data is NULL, disalbe packet */
+// void (*fresh_tx_hdr_pkt)(struct master_display_info_s *data);
+ /* tunnel_mode: 1: tunneling mode, RGB 8bit 0: YCbCr422 12bit mode */
+// void (*fresh_tx_vsif_pkt)(enum eotf_type type, uint8_t tunnel_mode);
+};
+
+
+enum vmode_e vmode_name_to_mode(const char *str);
+const struct vinfo_s *get_tv_info(enum vmode_e mode);
+int want_hdmi_mode(enum vmode_e mode);
+const struct vinfo_s * findMatchedMode(u32 width, u32 height, u32 refreshrate);
+
+#endif //AML_VOUT_H_
diff --git a/hwc2/include/HwcFenceControl.h b/hwc2/include/HwcFenceControl.h
index 1a32749..ec02500 100644
--- a/hwc2/include/HwcFenceControl.h
+++ b/hwc2/include/HwcFenceControl.h
@@ -1,5 +1,18 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
#ifndef HWC_FENCE_H
diff --git a/hwc2/include/IComposer.h b/hwc2/include/IComposer.h
index 011faa6..4ccafa7 100644
--- a/hwc2/include/IComposer.h
+++ b/hwc2/include/IComposer.h
@@ -1,6 +1,20 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
+
#ifndef ICOMPOSER_H
#define ICOMPOSER_H
diff --git a/hwc2/include/IComposerFactory.h b/hwc2/include/IComposerFactory.h
index 856e44c..ba86ccb 100644
--- a/hwc2/include/IComposerFactory.h
+++ b/hwc2/include/IComposerFactory.h
@@ -1,6 +1,20 @@
/*
-// Copyright(c) 2016 Amlogic Corporation
+// Copyright (c) 2016 Amlogic
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
*/
+
#ifndef ICOMPOSER_FACTORY_H_
#define ICOMPOSER_FACTORY_H_
diff --git a/hwc2/include/IDisplayDevice.h b/hwc2/include/IDisplayDevice.h
index 7395b4a..0e78bdf 100644
--- a/hwc2/include/IDisplayDevice.h
+++ b/hwc2/include/IDisplayDevice.h
@@ -29,13 +29,6 @@ namespace android {
namespace amlogic {
enum {
- LAYER_MAX_NUM_SECURE_PROTECTED = 5,
- LAYER_MAX_NUM_CHANGE_REQUEST = 8,
- LAYER_MAX_NUM_CHANGE_TYPE = 16,
- LAYER_MAX_NUM_SUPPORT = LAYER_MAX_NUM_CHANGE_TYPE,
-};
-
-enum {
HWC2_NO_LAYER = 0,
HWC2_ONE_LAYER = 1,
HWC2_TWO_LAYERS = 2,
@@ -44,6 +37,9 @@ enum {
};
+#define HWC2_HW_COMPOSE_WIDTH_MAX (1920)
+#define HWC2_HW_COMPOSE_HEIGHT_MAX (1080)
+
// display device interface
class IDisplayDevice {
public:
@@ -120,11 +116,9 @@ public:
virtual HwcLayer* getLayerById(hwc2_layer_t layerId) = 0;
- virtual bool updateDisplayConfigs() = 0;
-
- //events
+ // events
virtual void onVsync(int64_t timestamp) = 0;
-
+ virtual void onHotplug(int disp, bool connected) = 0;
virtual void dump(Dump& d) = 0;
};
diff --git a/hwc2/include/PhysicalDevice.h b/hwc2/include/PhysicalDevice.h
index 07767a1..d3c3ab6 100644
--- a/hwc2/include/PhysicalDevice.h
+++ b/hwc2/include/PhysicalDevice.h
@@ -25,7 +25,6 @@
#include <HwcLayer.h>
#include <IComposer.h>
#include <DisplayHdmi.h>
-
#include <systemcontrol/ISystemControlService.h>
#include <systemcontrol/DisplayMode.h>
#include <binder/Binder.h>
@@ -82,8 +81,6 @@ public:
friend class Hwcomposer;
friend class HwcLayer;
- // typedef sp<ISystemControlService> IScs;
-
// Required by HWC2
virtual int32_t acceptDisplayChanges();
virtual bool createLayer(hwc2_layer_t* outLayer);
@@ -129,7 +126,7 @@ public:
// Other Display methods
virtual Hwcomposer& getDevice() const { return mHwc; }
virtual hwc2_display_t getId() const { return mId; }
- virtual bool isConnected() const { return mIsConnected; }
+ virtual bool isConnected() const { return mConnectorPresent; }
virtual void updateHotplugState(bool connected);
// device related operations
@@ -142,9 +139,11 @@ public:
// display config operations
virtual bool updateDisplayConfigs();
+ virtual void updateActiveDisplayAttribute();
- //events
+ // events
virtual void onVsync(int64_t timestamp);
+ virtual void onHotplug(int disp, bool connected);
virtual void dump(Dump& d);
DisplayHdmi* getDisplayHdmi() const { return mDisplayHdmi; };
@@ -154,6 +153,8 @@ private:
int32_t postFramebuffer(int32_t* outRetireFence, bool hasVideoOverlay);
int32_t getLineValue(const char *lineStr, const char *magicStr);
+ int32_t clearLayersStats();
+ int32_t preValidate();
int32_t parseHdrCapabilities();
void directCompose(framebuffer_info_t * fbInfo);
void ge2dCompose(framebuffer_info_t * fbInfo, bool hasVideoOverlay);
@@ -161,6 +162,9 @@ private:
bool layersStateCheck(int32_t renderMode, KeyedVector<hwc2_layer_t, HwcLayer*> & composeLayers);
int32_t composersFilter(KeyedVector<hwc2_layer_t, HwcLayer*>& composeLayers);
+ int32_t beginCompose();
+ int32_t finishCompose();
+
//swap the mHwcCurReleaseFence and mHwcPriorReleaseFence;
void swapReleaseFence();
//this function will take contorl of fencefd, if you need use it also, please dup it before call.
@@ -171,10 +175,12 @@ private:
void dumpLayers(KeyedVector<hwc2_layer_t, HwcLayer*> layers);
void clearFramebuffer();
- sp<ISystemControlService> getSystemControlService();
static void hdcpEventListener(void *data, bool status);
void setSecureStatus(bool status);
+ // for vpp post scale.
+ bool calReverseScale();
+
template <typename T, typename S>
static inline bool compareSize(T a, S b) {
if ((int32_t)(a.right - a.left) == (int32_t)(b.right - b.left)
@@ -187,13 +193,12 @@ private:
// Member variables
hwc2_display_t mId;
const char *mName;
- bool mIsConnected;
bool mSecure;
Hwcomposer& mHwc;
DisplayHdmi* mDisplayHdmi;
DeviceControlFactory *mControlFactory;
-
SoftVsyncObserver *mVsyncObserver;
+
IComposer *mComposer;
// DeviceControlFactory *mControlFactory;
@@ -218,6 +223,7 @@ private:
int32_t mDirectComposeFrameCount;
int32_t mPriorFrameRetireFence;
int32_t mRenderMode;
+ int32_t mPreviousRenderMode;
bool mIsValidated;
bool mIsContinuousBuf;
@@ -234,9 +240,7 @@ private:
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayersChangeRequest;
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcGlesLayers;
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayers;
-#ifdef HWC_ENABLE_SECURE_LAYER
KeyedVector<hwc2_layer_t, HwcLayer*> mHwcSecureLayers;
-#endif
// HDR Capabilities
hdr_capabilities_t mHdrCapabilities;
@@ -252,7 +256,14 @@ private:
// lock
Mutex mLock;
bool mInitialized;
- bool mUsingPutCurosr;
+
+ // status of display connector.(hdmi, cvbs, panel)
+ bool mGetInitState;
+ bool mConnectorPresent;
+
+ //rever the scaled displayframe, for we use the vpp scale.
+ float mReverseScaleX;
+ float mReverseScaleY;
};
diff --git a/hwc2/include/VirtualDevice.h b/hwc2/include/VirtualDevice.h
index 65aeb40..553d03c 100644
--- a/hwc2/include/VirtualDevice.h
+++ b/hwc2/include/VirtualDevice.h
@@ -93,6 +93,7 @@ public:
//events
virtual void onVsync(int64_t timestamp);
+ virtual void onHotplug(int disp, bool connected);
virtual void dump(Dump& d);
private:
diff --git a/hwc2/platforms/Android.mk b/hwc2/platforms/Android.mk
index 76782d6..e15d556 100644
--- a/hwc2/platforms/Android.mk
+++ b/hwc2/platforms/Android.mk
@@ -29,7 +29,9 @@ LOCAL_SRC_FILES := \
../common/composers/Composers.cpp \
../common/composers/GE2DComposer.cpp \
../common/utils/Utils.cpp \
- ../common/utils/Dump.cpp
+ ../common/utils/Dump.cpp \
+ ../common/utils/AmVinfo.cpp \
+ ../common/utils/AmVideo.cpp
LOCAL_SRC_FILES += \
PlatFactory.cpp
@@ -110,7 +112,7 @@ LOCAL_CFLAGS += -DUSE_CONTINOUS_BUFFER_COMPOSER
endif
ifeq ($(TARGET_SUPPORT_SECURE_LAYER),true)
-LOCAL_CFLAGS += -DHWC_ENABLE_SECURE_LAYER
+LOCAL_CFLAGS += -DHWC_SUPPORT_SECURE_LAYER
endif
WITH_LIBPLAYER_MODULE := true
diff --git a/tvp/LICENSE b/tvp/LICENSE
new file mode 100644
index 0000000..44c49b9
--- a/dev/null
+++ b/tvp/LICENSE
@@ -0,0 +1,23 @@
+// Copyright (C) 2014 Amlogic, Inc. All rights reserved.
+//
+// All information contained herein is Amlogic confidential.
+//
+// This software is provided to you pursuant to Software License
+// Agreement (SLA) with Amlogic Inc ("Amlogic"). This software may be
+// used only in accordance with the terms of this agreement.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification is strictly prohibited without prior written permission
+// from Amlogic.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tvp/OmxUtil.cpp b/tvp/OmxUtil.cpp
index 31ffcd2..06233ea 100644
--- a/tvp/OmxUtil.cpp
+++ b/tvp/OmxUtil.cpp
@@ -1,12 +1,14 @@
/*
- * AMLOGIC IOCTL WRAPPER
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the BSD Licence, GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ * AMLOGIC OMX IOCTL WRAPPER
*/
+
#define LOG_NDEBUG 0
#define LOG_TAG "omxutil"
@@ -23,6 +25,8 @@ static int amvideo_handle = 0;
#define TVP_SECRET "amlogic_omx_decoder,pts="
#define TVP_SECRET_RENDER "is rendered = true"
+#define TVP_SECRET_VERSION "version="
+#define TVP_SECRET_FRAME_NUM "frame_num="
int openamvideo() {
amvideo_handle = open("/dev/amvideo",O_RDWR | O_NONBLOCK);
@@ -46,6 +50,10 @@ int setomxpts(int time_video) {
return ioctl(amvideo_handle, AMSTREAM_IOC_SET_OMX_VPTS, (unsigned long)&time_video);
}
+int setomxpts(uint32_t* omx_info) {
+ return ioctl(amvideo_handle, AMSTREAM_IOC_SET_OMX_VPTS, (unsigned long)omx_info);
+}
+
void set_omx_pts(char* data, int* handle) {
if (data == NULL) {
ALOGE("hnd->base is NULL!!!!");
@@ -57,12 +65,38 @@ void set_omx_pts(char* data, int* handle) {
if (*handle == 0)
ALOGW("can not open amvideo");
}
+ uint32_t omx_version = 0;
if (strncmp(data+sizeof(TVP_SECRET)+sizeof(signed long long), TVP_SECRET_RENDER, strlen(TVP_SECRET_RENDER)) != 0) {
signed long long time;
- memcpy(&time, (char*)data+sizeof(TVP_SECRET), sizeof(signed long long));
+ int offset = 0;
+ offset += sizeof(TVP_SECRET);
+ memcpy(&time, (char*)data+offset, sizeof(signed long long));
+ offset += sizeof(signed long long);
int time_video = time * 9 / 100 + 1;
//ALOGW("render____time=%lld,time_video=%d",time,time_video);
- int ret = setomxpts(time_video);
+ uint32_t frame_num = 0;
+ if (strncmp(data+offset, TVP_SECRET_VERSION, strlen(TVP_SECRET_VERSION)) == 0) {
+ offset += sizeof(TVP_SECRET_VERSION);
+ memcpy(&omx_version, (char*)data+offset, sizeof(uint32_t));
+ offset += sizeof(uint32_t);
+ }
+ int ret = 0;
+ if (omx_version >= 2) {
+ if (strncmp(data+offset, TVP_SECRET_FRAME_NUM, strlen(TVP_SECRET_FRAME_NUM)) == 0) {
+ offset += sizeof(TVP_SECRET_FRAME_NUM);
+ memcpy(&frame_num, (char*)data+offset, sizeof(uint32_t));
+ offset += sizeof(uint32_t);
+ }
+ uint32_t omx_info[6];
+ omx_info[0] = time_video;
+ omx_info[1] = omx_version;
+ omx_info[2] = 1; // set by hw
+ omx_info[3] = frame_num;
+ omx_info[4] = 0; // 0:need reset omx_pts;1:do not need reset omx_pts
+ omx_info[5] = 0; // Reserved
+ ret = setomxpts(omx_info);
+ } else
+ ret = setomxpts(time_video);
if (ret < 0) {
ALOGW("setomxpts error, ret =%d",ret);
}
diff --git a/tvp/OmxUtil.h b/tvp/OmxUtil.h
index 846c9aa..1df46a9 100644
--- a/tvp/OmxUtil.h
+++ b/tvp/OmxUtil.h
@@ -1,16 +1,19 @@
/*
- * AMLOGIC IOCTL WRAPPER
+ * Copyright (c) 2014 Amlogic, Inc. All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the BSD Licence, GNU General Public License
- * as published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ * AMLOGIC OMX IOCTL WRAPPER
*/
+
int openamvideo();
void closeamvideo();
int setomxdisplaymode();
int setomxpts(int time_video);
+int setomxpts(uint32_t* omx_info);
void set_omx_pts(char* data, int* handle);