summaryrefslogtreecommitdiff
authorsky zhou <sky.zhou@amlogic.com>2017-09-12 05:29:27 (GMT)
committer sky zhou <sky.zhou@amlogic.com>2017-09-13 14:27:04 (GMT)
commit36253d31fbd9c0dab05617ff2173d7eba425929f (patch)
treedef1acdcd7590ed00a92f6407333601b1caa54ba
parent9e8e2d682e5da747c61d7ae1ef36f7a783f9ba3b (diff)
downloadhwcomposer-36253d31fbd9c0dab05617ff2173d7eba425929f.zip
hwcomposer-36253d31fbd9c0dab05617ff2173d7eba425929f.tar.gz
hwcomposer-36253d31fbd9c0dab05617ff2173d7eba425929f.tar.bz2
hwc2: sync with android N. [1/1]
PD#150918 sync commits from n-amlogic branch: commit 3473e99f904b15df0c72a6e4391831a9f691d950 commit 8613bdf8bb61bc2a0a853494d23c275d0fb30d34 commit a6ec14f8575f4eef2e6fe9a0b213fbe19577570c commit ff7d696c55392c58f6d924155549de5332e1f7c3 commit f6e57e9d2687c3c85e8203e9fd7bd5613528a142 commit 2da9fc4474ba15ecc471c70be6ed6c7cfcf463bd commit 722c94698ff687e9e0618abcc72388ea5c95cf51 commit 2cf8c7f75f4afba96ab9ab50bd4e0f27ef936802 commit d47383b0bec31ec1d3b5a55fdb3cdd1210f744d6 commit 4ec85b5030ea5341d91ea877b94aaca706583ffd commit dcfe04d859812de3348a77ab9089b6642b4e1c74 commit 417626c29da884a0581202a563d6539fd9e6f94e commit 259e67caeaa2c1978f5c1155212eb7ad93aacb91 commit 1a4e652bd0e4cb80356ca93d131cf952b3a7a235 commit 6437231c2ec81cc2745feff59398588240d856da commit 387bc77b420d41e97894000ff17c369e658bd09c commit e708c8627db0569e73f1c9dd43cf429e00114f17 Change-Id: I53f7ae50697c25c66df46f7ed5e21b5742441705
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);