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); |