diff options
-rw-r--r-- | libhwc2.1/libdevice/ExynosDevice.cpp | 2 | ||||
-rw-r--r-- | libhwc2.1/libdevice/ExynosDevice.h | 2 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp | 21 |
3 files changed, 24 insertions, 1 deletions
diff --git a/libhwc2.1/libdevice/ExynosDevice.cpp b/libhwc2.1/libdevice/ExynosDevice.cpp index 6fe24a0..4e58705 100644 --- a/libhwc2.1/libdevice/ExynosDevice.cpp +++ b/libhwc2.1/libdevice/ExynosDevice.cpp @@ -187,6 +187,8 @@ ExynosDevice::ExynosDevice() } } } + + mDisplayOffAsync = property_get_bool("vendor.display.async_off.supported", false); } void ExynosDevice::initDeviceInterface(uint32_t interfaceType) diff --git a/libhwc2.1/libdevice/ExynosDevice.h b/libhwc2.1/libdevice/ExynosDevice.h index 73c6a77..dd5dfe6 100644 --- a/libhwc2.1/libdevice/ExynosDevice.h +++ b/libhwc2.1/libdevice/ExynosDevice.h @@ -332,6 +332,7 @@ class ExynosDevice { int32_t registerHwc3Callback(uint32_t descriptor, hwc2_callback_data_t callbackData, hwc2_function_pointer_t point); void onVsyncIdle(hwc2_display_t displayId); + bool isDispOffAsyncSupported() { return mDisplayOffAsync; }; protected: void initDeviceInterface(uint32_t interfaceType); @@ -351,6 +352,7 @@ class ExynosDevice { private: bool mIsInTUI; + bool mDisplayOffAsync; }; #endif //_EXYNOSDEVICE_H diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp index c217175..73b327a 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp @@ -1927,6 +1927,8 @@ int32_t ExynosDisplayDrmInterface::clearDisplayPlanes(DrmModeAtomicReq &drmReq) int32_t ExynosDisplayDrmInterface::clearDisplay(bool needModeClear) { + ExynosDevice *exynosDevice = mExynosDisplay->mDevice; + const bool isAsyncOff = needModeClear && exynosDevice->isDispOffAsyncSupported(); int ret = NO_ERROR; DrmModeAtomicReq drmReq(this); @@ -1947,7 +1949,7 @@ int32_t ExynosDisplayDrmInterface::clearDisplay(bool needModeClear) } /* Disable ModeSet */ - if (needModeClear) { + if (needModeClear && !isAsyncOff) { if ((ret = clearDisplayMode(drmReq)) < 0) { HWC_LOGE(mExynosDisplay, "%s: Failed to apply display mode", __func__); return ret; @@ -1961,6 +1963,23 @@ int32_t ExynosDisplayDrmInterface::clearDisplay(bool needModeClear) return ret; } + /* During async off we're clearing planes within a single refresh cycle + * and then offloading display off asynchronously. + */ + if (isAsyncOff) { + if ((ret = clearDisplayMode(drmReq)) < 0) { + HWC_LOGE(mExynosDisplay, "%s: Failed to apply display mode", __func__); + return ret; + } + + ret = drmReq.commit(DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, true); + if (ret) { + HWC_LOGE(mExynosDisplay, "%s:: Failed to commit pset ret=%d in clearDisplay()\n", + __func__, ret); + return ret; + } + } + if (needModeClear) mActiveModeState.forceModeSet(); return NO_ERROR; |