summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.cpp2
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.h2
-rw-r--r--libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp21
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;