summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWiwit Rifa'i <wiwitrifai@google.com>2022-01-25 21:28:50 +0800
committerWiwit Rifa'i <wiwitrifai@google.com>2023-02-10 14:53:58 +0800
commita220daa306bf1bbb027e2b63c5596d864d839b7d (patch)
tree1b0aab3b9f8da2bd9411e684b21afedf1ff15de5
parenteffac65ab3758f7896c5d9ed1aa00003dedef0d9 (diff)
downloadcommon-a220daa306bf1bbb027e2b63c5596d864d839b7d.tar.gz
libhwc2.1: enable dynamic recomposition based on sysprop
We can enable dynamic recomposition (DR) by default using sysprop "vendor.display.dynamic_recomposition". This prop should be an integer representing a bitmask of display indices that should enable DR, e.g: - 0 to disable DR for all displays - 1 to enable only for display with index 0 - 2 to enable only for display with index 1 - 3 to enable for displays with index 0 and index 1 We can also enable dynamic recomposition during runtime using ExynosHWCService: $ adb shell vndservice call Exynos.HWCService 11 i32 <display_id> \ i32 102 i32 <0:disable|1:enable> This will also change the update FPS threshold (condition for switching the mode to force CLIENT composition) from 5 Hz to 1/5 Hz. This will also fix layer FPS calculation so that it will not only be updated during setLayerBuffer but it will also be updated during the check in the dynamic recomposition thread. Bug: 267972056 Test: DR should be used when all layers have low fps Test: DR should not be used when there's front buffer or video layer Change-Id: I9c7259ad23d4b7eb23724ef284322ed9da488823
-rw-r--r--libhwc2.1/ExynosHWC.h3
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.cpp17
-rw-r--r--libhwc2.1/libdevice/ExynosDevice.h2
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.cpp122
-rw-r--r--libhwc2.1/libdevice/ExynosDisplay.h2
-rw-r--r--libhwc2.1/libdevice/ExynosLayer.cpp56
-rw-r--r--libhwc2.1/libdevice/ExynosLayer.h10
-rw-r--r--libhwc2.1/libhwcService/ExynosHWCService.cpp28
-rw-r--r--libhwc2.1/libhwcService/ExynosHWCService.h5
-rw-r--r--libhwc2.1/libhwcService/IExynosHWC.cpp50
-rw-r--r--libhwc2.1/libhwcService/IExynosHWC.h3
-rw-r--r--libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp8
12 files changed, 130 insertions, 176 deletions
diff --git a/libhwc2.1/ExynosHWC.h b/libhwc2.1/ExynosHWC.h
index 8d17a74..f1235d9 100644
--- a/libhwc2.1/ExynosHWC.h
+++ b/libhwc2.1/ExynosHWC.h
@@ -24,9 +24,6 @@
//#define DISABLE_FENCE
-#define HWC_FPS_TH 5 /* valid range 1 to 60 */
-#define VSYNC_INTERVAL (1000000000.0 / 60)
-
enum {
HWC_CTL_MAX_OVLY_CNT = 100,
HWC_CTL_VIDEO_OVLY_CNT = 101,
diff --git a/libhwc2.1/libdevice/ExynosDevice.cpp b/libhwc2.1/libdevice/ExynosDevice.cpp
index 620ff45..bc1058d 100644
--- a/libhwc2.1/libdevice/ExynosDevice.cpp
+++ b/libhwc2.1/libdevice/ExynosDevice.cpp
@@ -311,10 +311,10 @@ void *ExynosDevice::dynamicRecompositionThreadLoop(void *data)
event_cnt[i] = display[i]->mUpdateEventCnt;
/*
- * If there is no update for more than 100ms, favor the 3D composition mode.
- * If all other conditions are met, mode will be switched to 3D composition.
+ * If there is no update for more than 5s, favor the client composition mode.
+ * If all other conditions are met, mode will be switched to client composition.
*/
- usleep(100000);
+ usleep(5000000);
for (uint32_t i = 0; i < dev->mDisplays.size(); i++) {
if (display[i]->mDREnable &&
display[i]->mPlugState == true &&
@@ -729,7 +729,7 @@ void ExynosDevice::setHWCControl(uint32_t displayId, uint32_t ctrl, int32_t val)
break;
case HWC_CTL_DYNAMIC_RECOMP:
ALOGI("%s::HWC_CTL_DYNAMIC_RECOMP on/off = %d", __func__, val);
- setDynamicRecomposition((unsigned int)val);
+ setDynamicRecomposition(displayId, (unsigned int)val);
break;
case HWC_CTL_ENABLE_FENCE_TRACER:
ALOGI("%s::HWC_CTL_ENABLE_FENCE_TRACER on/off=%d", __func__, val);
@@ -754,9 +754,14 @@ void ExynosDevice::setDisplayMode(uint32_t displayMode)
exynosHWCControl.displayMode = displayMode;
}
-void ExynosDevice::setDynamicRecomposition(unsigned int on)
-{
+void ExynosDevice::setDynamicRecomposition(uint32_t displayId, unsigned int on) {
exynosHWCControl.useDynamicRecomp = on;
+ ExynosDisplay *display = getDisplay(displayId);
+ if (display) {
+ display->mDRDefault = on;
+ display->mDREnable = on;
+ onRefresh(displayId);
+ }
}
bool ExynosDevice::checkDisplayConnection(uint32_t displayId)
diff --git a/libhwc2.1/libdevice/ExynosDevice.h b/libhwc2.1/libdevice/ExynosDevice.h
index 7a5eee2..94f9619 100644
--- a/libhwc2.1/libdevice/ExynosDevice.h
+++ b/libhwc2.1/libdevice/ExynosDevice.h
@@ -298,7 +298,7 @@ class ExynosDevice {
void getCapabilities(uint32_t *outCount, int32_t* outCapabilities);
void setGeometryChanged(uint64_t changedBit) { mGeometryChanged|= changedBit;};
void clearGeometryChanged();
- void setDynamicRecomposition(unsigned int on);
+ void setDynamicRecomposition(uint32_t displayId, unsigned int on);
bool canSkipValidate();
bool validateFences(ExynosDisplay *display);
void compareVsyncPeriod();
diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp
index ebe86db..9b72986 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.cpp
+++ b/libhwc2.1/libdevice/ExynosDisplay.cpp
@@ -55,6 +55,8 @@ using ::aidl::google::hardware::power::extension::pixel::IPowerExt;
extern struct exynos_hwc_control exynosHWCControl;
extern struct update_time_info updateTimeInfo;
+constexpr float kDynamicRecompFpsThreshold = 1.0 / 5.0; // 1 frame update per 5 second
+
constexpr float nsecsPerSec = std::chrono::nanoseconds(1s).count();
constexpr int64_t nsecsIdleHintTimeout = std::chrono::nanoseconds(100ms).count();
@@ -970,7 +972,7 @@ ExynosDisplay::ExynosDisplay(uint32_t index, ExynosDevice *device)
mRenderingState(RENDERING_STATE_NONE),
mHWCRenderingState(RENDERING_STATE_NONE),
mDisplayBW(0),
- mDynamicReCompMode(NO_MODE_SWITCH),
+ mDynamicReCompMode(CLIENT_2_DEVICE),
mDREnable(false),
mDRDefault(false),
mLastFpsTime(0),
@@ -1091,7 +1093,7 @@ void ExynosDisplay::initDisplay() {
mGeometryChanged = 0x0;
mRenderingState = RENDERING_STATE_NONE;
mDisplayBW = 0;
- mDynamicReCompMode = NO_MODE_SWITCH;
+ mDynamicReCompMode = CLIENT_2_DEVICE;
mCursorIndex = -1;
mDpuData.reset();
@@ -1162,6 +1164,7 @@ int32_t ExynosDisplay::destroyLayer(hwc2_layer_t outLayer) {
* @return void
*/
void ExynosDisplay::destroyLayers() {
+ Mutex::Autolock lock(mDRMutex);
for (uint32_t index = 0; index < mLayers.size();) {
ExynosLayer *layer = mLayers[index];
mLayers.removeAt(index);
@@ -1194,6 +1197,7 @@ ExynosLayer *ExynosDisplay::checkLayer(hwc2_layer_t addr) {
}
void ExynosDisplay::checkIgnoreLayers() {
+ Mutex::Autolock lock(mDRMutex);
for (auto it = mIgnoreLayers.begin(); it != mIgnoreLayers.end();) {
ExynosLayer *layer = *it;
if ((layer->mLayerFlag & EXYNOS_HWC_IGNORE_LAYER) == 0) {
@@ -1297,16 +1301,15 @@ int ExynosDisplay::checkLayerFps() {
if (mDisplayControl.handleLowFpsLayers == false)
return NO_ERROR;
+ Mutex::Autolock lock(mDRMutex);
+
for (size_t i=0; i < mLayers.size(); i++) {
- if ((mLayers[i]->mOverlayPriority < ePriorityHigh) &&
- (mLayers[i]->getFps() < LOW_FPS_THRESHOLD)) {
- mLowFpsLayerInfo.addLowFpsLayer(i);
- } else {
- if (mLowFpsLayerInfo.mHasLowFpsLayer == true)
- break;
- else
- continue;
- }
+ if ((mLayers[i]->mOverlayPriority < ePriorityHigh) &&
+ (mLayers[i]->getFps() < LOW_FPS_THRESHOLD)) {
+ mLowFpsLayerInfo.addLowFpsLayer(i);
+ } else if (mLowFpsLayerInfo.mHasLowFpsLayer == true) {
+ break;
+ }
}
/* There is only one low fps layer, Overlay is better in this case */
if ((mLowFpsLayerInfo.mHasLowFpsLayer == true) &&
@@ -1316,91 +1319,92 @@ int ExynosDisplay::checkLayerFps() {
return NO_ERROR;
}
+int ExynosDisplay::switchDynamicReCompMode(dynamic_recomp_mode mode) {
+ if (mDynamicReCompMode == mode) return NO_MODE_SWITCH;
+
+ ATRACE_INT("Force client composition by DR", (mode == DEVICE_2_CLIENT));
+ mDynamicReCompMode = mode;
+ setGeometryChanged(GEOMETRY_DISPLAY_DYNAMIC_RECOMPOSITION);
+ return mode;
+}
+
/**
* @return int
*/
int ExynosDisplay::checkDynamicReCompMode() {
- unsigned int updateFps = 0;
- unsigned int lcd_size = mXres * mYres;
- uint64_t TimeStampDiff;
- uint64_t w = 0, h = 0, incomingPixels = 0;
- uint64_t maxFps = 0, layerFps = 0;
-
+ ATRACE_CALL();
Mutex::Autolock lock(mDRMutex);
if (!exynosHWCControl.useDynamicRecomp) {
mLastModeSwitchTimeStamp = 0;
- mDynamicReCompMode = NO_MODE_SWITCH;
- return 0;
+ return switchDynamicReCompMode(CLIENT_2_DEVICE);
}
/* initialize the Timestamps */
if (!mLastModeSwitchTimeStamp) {
mLastModeSwitchTimeStamp = mLastUpdateTimeStamp;
- mDynamicReCompMode = NO_MODE_SWITCH;
- return 0;
+ return switchDynamicReCompMode(CLIENT_2_DEVICE);
}
- /* If video layer is there, skip the mode switch */
+ /* Avoid to use DEVICE_2_CLIENT if there's a layer with priority >= ePriorityHigh such as:
+ * front buffer, video layer, HDR, DRM layer, etc.
+ */
for (size_t i = 0; i < mLayers.size(); i++) {
if ((mLayers[i]->mOverlayPriority >= ePriorityHigh) ||
mLayers[i]->mPreprocessedInfo.preProcessed) {
- if (mDynamicReCompMode != DEVICE_2_CLIENT) {
- return 0;
- } else {
- mDynamicReCompMode = CLIENT_2_DEVICE;
+ auto ret = switchDynamicReCompMode(CLIENT_2_DEVICE);
+ if (ret) {
mUpdateCallCnt = 0;
mLastModeSwitchTimeStamp = mLastUpdateTimeStamp;
DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] GLES_2_HWC by video layer");
- setGeometryChanged(GEOMETRY_DISPLAY_DYNAMIC_RECOMPOSITION);
- return CLIENT_2_DEVICE;
}
+ return ret;
}
}
+ unsigned int incomingPixels = 0;
for (size_t i = 0; i < mLayers.size(); i++) {
- w = WIDTH(mLayers[i]->mPreprocessedInfo.displayFrame);
- h = HEIGHT(mLayers[i]->mPreprocessedInfo.displayFrame);
+ auto w = WIDTH(mLayers[i]->mPreprocessedInfo.displayFrame);
+ auto h = HEIGHT(mLayers[i]->mPreprocessedInfo.displayFrame);
incomingPixels += w * h;
}
/* Mode Switch is not required if total pixels are not more than the threshold */
- if (incomingPixels <= lcd_size) {
- if (mDynamicReCompMode != DEVICE_2_CLIENT) {
- return 0;
- } else {
- mDynamicReCompMode = CLIENT_2_DEVICE;
+ unsigned int lcdSize = mXres * mYres;
+ if (incomingPixels <= lcdSize) {
+ auto ret = switchDynamicReCompMode(CLIENT_2_DEVICE);
+ if (ret) {
mUpdateCallCnt = 0;
mLastModeSwitchTimeStamp = mLastUpdateTimeStamp;
DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] GLES_2_HWC by BW check");
- setGeometryChanged(GEOMETRY_DISPLAY_DYNAMIC_RECOMPOSITION);
- return CLIENT_2_DEVICE;
}
+ return ret;
}
/*
* There will be at least one composition call per one minute (because of time update)
- * To minimize the analysis overhead, just analyze it once in a second
+ * To minimize the analysis overhead, just analyze it once in 5 second
*/
- TimeStampDiff = systemTime(SYSTEM_TIME_MONOTONIC) - mLastModeSwitchTimeStamp;
+ auto timeStampDiff = systemTime(SYSTEM_TIME_MONOTONIC) - mLastModeSwitchTimeStamp;
/*
- * previous CompModeSwitch was CLIENT_2_DEVICE: check fps every 250ms from mLastModeSwitchTimeStamp
+ * previous CompModeSwitch was CLIENT_2_DEVICE: check fps after 5s from mLastModeSwitchTimeStamp
* previous CompModeSwitch was DEVICE_2_CLIENT: check immediately
*/
- if ((mDynamicReCompMode != DEVICE_2_CLIENT) && (TimeStampDiff < (VSYNC_INTERVAL * 15)))
+ if ((mDynamicReCompMode != DEVICE_2_CLIENT) && (timeStampDiff < kLayerFpsStableTimeNs))
return 0;
mLastModeSwitchTimeStamp = mLastUpdateTimeStamp;
+ float updateFps = 0;
if ((mUpdateEventCnt != 1) &&
(mDynamicReCompMode == DEVICE_2_CLIENT) && (mUpdateCallCnt == 1)) {
DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] first frame after DEVICE_2_CLIENT");
- updateFps = HWC_FPS_TH;
+ updateFps = kDynamicRecompFpsThreshold + 1;
} else {
+ float maxFps = 0;
for (uint32_t i = 0; i < mLayers.size(); i++) {
- layerFps = mLayers[i]->getFps();
- if (maxFps < layerFps)
- maxFps = layerFps;
+ float layerFps = mLayers[i]->checkFps(/* increaseCount */ false);
+ if (maxFps < layerFps) maxFps = layerFps;
}
updateFps = maxFps;
}
@@ -1408,26 +1412,22 @@ int ExynosDisplay::checkDynamicReCompMode() {
/*
* FPS estimation.
- * If FPS is lower than HWC_FPS_TH, try to switch the mode to GLES
+ * If FPS is lower than kDynamicRecompFpsThreshold, try to switch the mode to GLES
*/
- if (updateFps < HWC_FPS_TH) {
- if (mDynamicReCompMode != DEVICE_2_CLIENT) {
- mDynamicReCompMode = DEVICE_2_CLIENT;
- DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] DEVICE_2_CLIENT by low FPS(%d)", updateFps);
- setGeometryChanged(GEOMETRY_DISPLAY_DYNAMIC_RECOMPOSITION);
- return DEVICE_2_CLIENT;
- } else {
- return 0;
+ if (updateFps < kDynamicRecompFpsThreshold) {
+ auto ret = switchDynamicReCompMode(DEVICE_2_CLIENT);
+ if (ret) {
+ DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] DEVICE_2_CLIENT by low FPS(%.2f)",
+ updateFps);
}
+ return ret;
} else {
- if (mDynamicReCompMode == DEVICE_2_CLIENT) {
- mDynamicReCompMode = CLIENT_2_DEVICE;
- DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] CLIENT_2_HWC by high FPS(%d)", updateFps);
- setGeometryChanged(GEOMETRY_DISPLAY_DYNAMIC_RECOMPOSITION);
- return CLIENT_2_DEVICE;
- } else {
- return 0;
+ auto ret = switchDynamicReCompMode(CLIENT_2_DEVICE);
+ if (ret) {
+ DISPLAY_LOGD(eDebugDynamicRecomp, "[DYNAMIC_RECOMP] CLIENT_2_HWC by high FPS((%.2f)",
+ updateFps);
}
+ return ret;
}
return 0;
diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h
index 8a47866..c5e9704 100644
--- a/libhwc2.1/libdevice/ExynosDisplay.h
+++ b/libhwc2.1/libdevice/ExynosDisplay.h
@@ -568,6 +568,8 @@ class ExynosDisplay {
int checkLayerFps();
+ int switchDynamicReCompMode(dynamic_recomp_mode mode);
+
int checkDynamicReCompMode();
int handleDynamicReCompMode();
diff --git a/libhwc2.1/libdevice/ExynosLayer.cpp b/libhwc2.1/libdevice/ExynosLayer.cpp
index 65eb687..f21e318 100644
--- a/libhwc2.1/libdevice/ExynosLayer.cpp
+++ b/libhwc2.1/libdevice/ExynosLayer.cpp
@@ -101,27 +101,43 @@ ExynosLayer::~ExynosLayer() {
}
/**
- * @return uint32_t
+ * @return float
*/
-uint32_t ExynosLayer::checkFps() {
+float ExynosLayer::checkFps(bool increaseCount) {
uint32_t frameDiff;
- bool wasLowFps = (mFps < LOW_FPS_THRESHOLD) ? true:false;
- if (mLastLayerBuffer != mLayerBuffer) {
- mFrameCount++;
- }
+ mFrameCount += increaseCount ? 1 : 0;
+
nsecs_t now = systemTime();
- nsecs_t diff = now - mLastFpsTime;
+ if (mLastFpsTime == 0) { // Initialize values
+ mLastFpsTime = now;
+ mNextLastFpsTime = now;
+ // TODO(b/268474771): set the initial FPS to the correct peak refresh rate
+ mFps = 120;
+ return mFps;
+ }
+
+ nsecs_t diff = now - mNextLastFpsTime;
+ // Update mLastFrameCount for every 5s, to ensure that FPS calculation is only based on
+ // frames in the past at most 10s.
+ if (diff >= kLayerFpsStableTimeNs) {
+ mLastFrameCount = mNextLastFrameCount;
+ mNextLastFrameCount = mFrameCount;
+
+ mLastFpsTime = mNextLastFpsTime;
+ mNextLastFpsTime = now;
+ }
+
+ bool wasLowFps = (mFps < LOW_FPS_THRESHOLD) ? true : false;
+
if (mFrameCount >= mLastFrameCount)
frameDiff = (mFrameCount - mLastFrameCount);
else
frameDiff = (mFrameCount + (UINT_MAX - mLastFrameCount));
- if (diff >= ms2ns(250)) {
- mFps = (uint32_t)(frameDiff * float(s2ns(1))) / diff;
- mLastFrameCount = mFrameCount;
- mLastFpsTime = now;
- }
- bool nowLowFps = (mFps < LOW_FPS_THRESHOLD) ? true:false;
+ diff = now - mLastFpsTime;
+ mFps = (frameDiff * float(s2ns(1))) / diff;
+
+ bool nowLowFps = (mFps < LOW_FPS_THRESHOLD) ? true : false;
if ((mDisplay->mDisplayControl.handleLowFpsLayers) &&
(wasLowFps != nowLowFps))
@@ -133,7 +149,7 @@ uint32_t ExynosLayer::checkFps() {
/**
* @return float
*/
-uint32_t ExynosLayer::getFps() {
+float ExynosLayer::getFps() {
return mFps;
}
@@ -397,7 +413,11 @@ int32_t ExynosLayer::setLayerBuffer(buffer_handle_t buffer, int32_t acquireFence
setGeometryChanged(GEOMETRY_LAYER_FRONT_BUFFER_USAGE_CHANGED);
}
- mLayerBuffer = buffer;
+ {
+ Mutex::Autolock lock(mDisplay->mDRMutex);
+ mLayerBuffer = buffer;
+ checkFps(mLastLayerBuffer != mLayerBuffer);
+ }
mPrevAcquireFence =
fence_close(mPrevAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
mAcquireFence = fence_close(mAcquireFence, mDisplay, FENCE_TYPE_SRC_ACQUIRE, FENCE_IP_UNDEFINED);
@@ -435,9 +455,6 @@ int32_t ExynosLayer::setLayerBuffer(buffer_handle_t buffer, int32_t acquireFence
"internal_format: 0x%" PRIx64 "",
mLayerBuffer, mDataSpace, mAcquireFence, mCompressed, internal_format);
- /* Update fps */
- checkFps();
-
return 0;
}
@@ -1094,7 +1111,8 @@ void ExynosLayer::printLayer()
mLayerBuffer, fd, fd1, fd2, mAcquireFence, mTransform, mCompressed, mDataSpace, getFormatStr(format, mCompressed? AFBC : 0).string());
result.appendFormat("\tblend: 0x%4x, planeAlpha: %3.1f, zOrder: %d, color[0x%2x, 0x%2x, 0x%2x, 0x%2x]\n",
mBlending, mPlaneAlpha, mZOrder, mColor.r, mColor.g, mColor.b, mColor.a);
- result.appendFormat("\tfps: %2d, priority: %d, windowIndex: %d\n", mFps, mOverlayPriority, mWindowIndex);
+ result.appendFormat("\tfps: %.2f, priority: %d, windowIndex: %d\n", mFps, mOverlayPriority,
+ mWindowIndex);
result.appendFormat("\tsourceCrop[%7.1f,%7.1f,%7.1f,%7.1f], dispFrame[%5d,%5d,%5d,%5d]\n",
mSourceCrop.left, mSourceCrop.top, mSourceCrop.right, mSourceCrop.bottom,
mDisplayFrame.left, mDisplayFrame.top, mDisplayFrame.right, mDisplayFrame.bottom);
diff --git a/libhwc2.1/libdevice/ExynosLayer.h b/libhwc2.1/libdevice/ExynosLayer.h
index 0838c0f..8168d16 100644
--- a/libhwc2.1/libdevice/ExynosLayer.h
+++ b/libhwc2.1/libdevice/ExynosLayer.h
@@ -41,6 +41,8 @@ using namespace android;
using namespace vendor::graphics;
using ::aidl::android::hardware::graphics::composer3::Composition;
+constexpr nsecs_t kLayerFpsStableTimeNs = s2ns(5);
+
class ExynosMPP;
enum overlay_priority {
@@ -127,7 +129,7 @@ class ExynosLayer : public ExynosMPPSource {
/**
* Update rate for using client composition.
*/
- uint32_t mFps;
+ float mFps;
/**
* Assign priority, when priority changing is needded by order infomation in mGeometryChanged
@@ -163,6 +165,8 @@ class ExynosLayer : public ExynosMPPSource {
uint32_t mFrameCount;
uint32_t mLastFrameCount;
nsecs_t mLastFpsTime;
+ uint32_t mNextLastFrameCount;
+ nsecs_t mNextLastFpsTime;
/**
* Previous buffer's handle
@@ -261,9 +265,9 @@ class ExynosLayer : public ExynosMPPSource {
*/
int32_t setCompositionType(int32_t type);
- uint32_t checkFps();
+ float checkFps(bool increaseCount);
- uint32_t getFps();
+ float getFps();
int32_t doPreProcess();
diff --git a/libhwc2.1/libhwcService/ExynosHWCService.cpp b/libhwc2.1/libhwcService/ExynosHWCService.cpp
index 33bb6d2..ba8f996 100644
--- a/libhwc2.1/libhwcService/ExynosHWCService.cpp
+++ b/libhwc2.1/libhwcService/ExynosHWCService.cpp
@@ -27,12 +27,8 @@ namespace android {
ANDROID_SINGLETON_STATIC_INSTANCE(ExynosHWCService);
-ExynosHWCService::ExynosHWCService() :
- mHWCService(NULL),
- mHWCCtx(NULL),
- bootFinishedCallback(NULL),
- doPSRExit(NULL)
-{
+ExynosHWCService::ExynosHWCService()
+ : mHWCService(NULL), mHWCCtx(NULL), bootFinishedCallback(NULL) {
ALOGD_IF(HWC_SERVICE_DEBUG, "ExynosHWCService Constructor is called");
}
@@ -322,6 +318,7 @@ int ExynosHWCService::setHWCCtl(uint32_t display, uint32_t ctrl, int32_t val)
case HWC_CTL_ENABLE_EARLY_START_MPP:
case HWC_CTL_DISPLAY_MODE:
case HWC_CTL_DDI_RESOLUTION_CHANGE:
+ case HWC_CTL_DYNAMIC_RECOMP:
case HWC_CTL_ENABLE_FENCE_TRACER:
case HWC_CTL_SYS_FENCE_LOGGING:
case HWC_CTL_DO_FENCE_FILE_DUMP:
@@ -352,25 +349,6 @@ int ExynosHWCService::setDDIScaler(uint32_t display_id, uint32_t width, uint32_t
}
}
-#if 0
-void ExynosHWCService::setPSRExitCallback(void (*callback)(exynos_hwc_composer_device_1_t *))
-{
- ALOGD_IF(HWC_SERVICE_DEBUG, "%s, callback %p", __func__, callback);
- doPSRExit = callback;
-}
-
-void ExynosHWCService::notifyPSRExit()
-{
- ALOGD_IF(HWC_SERVICE_DEBUG, "%s, doPSRExit %p", __func__, doPSRExit);
- if (doPSRExit != NULL) {
- ALOGD_IF(HWC_SERVICE_DEBUG, "%s, line %d", __func__, __LINE__);
- doPSRExit(mHWCCtx);
- }
- ALOGD_IF(HWC_SERVICE_DEBUG, "%s, line %d", __func__, __LINE__);
-}
-
-#endif
-
int ExynosHWCService::createServiceLocked()
{
ALOGD_IF(HWC_SERVICE_DEBUG, "%s::", __func__);
diff --git a/libhwc2.1/libhwcService/ExynosHWCService.h b/libhwc2.1/libhwcService/ExynosHWCService.h
index 8dd59c8..3400fcc 100644
--- a/libhwc2.1/libhwcService/ExynosHWCService.h
+++ b/libhwc2.1/libhwcService/ExynosHWCService.h
@@ -67,10 +67,6 @@ public:
virtual int setDDIScaler(uint32_t display_id, uint32_t width, uint32_t height);
virtual void setLbeCtrl(uint32_t display_id, uint32_t state, uint32_t lux) override;
-#if 0
- void setPSRExitCallback(void (*callback)(exynos_hwc_composer_device_1_t *));
- virtual void notifyPSRExit();
-#endif
virtual int32_t setDisplayDeviceMode(int32_t display_id, int32_t mode);
virtual int32_t setPanelGammaTableSource(int32_t display_id, int32_t type, int32_t source);
virtual int32_t setDisplayBrightness(int32_t display_id, float brightness);
@@ -91,7 +87,6 @@ private:
Mutex mLock;
ExynosHWCCtx *mHWCCtx;
void (*bootFinishedCallback)(ExynosHWCCtx *);
- void (*doPSRExit)(ExynosHWCCtx *ctx);
};
}
diff --git a/libhwc2.1/libhwcService/IExynosHWC.cpp b/libhwc2.1/libhwcService/IExynosHWC.cpp
index 816e1c1..e0867fa 100644
--- a/libhwc2.1/libhwcService/IExynosHWC.cpp
+++ b/libhwc2.1/libhwcService/IExynosHWC.cpp
@@ -50,9 +50,6 @@ enum {
SET_DDISCALER,
GET_EXTERNAL_HDR_CAPA,
SET_SCALE_DOWN_RATIO,
-#if 0
- NOTIFY_PSR_EXIT,
-#endif
SET_HWC_DEBUG = 105,
GET_HWC_DEBUG = 106,
SET_HWC_FENCE_DEBUG = 107,
@@ -379,15 +376,6 @@ public:
return result;
}
- /*
- virtual void notifyPSRExit()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
- remote()->transact(NOTIFY_PSR_EXIT, data, &reply);
- }
- */
-
int32_t setDisplayDeviceMode(int32_t display_id, int32_t mode)
{
ALOGD("null func: %s(%d %d)", __func__, display_id, mode);
@@ -643,44 +631,6 @@ status_t BnExynosHWCService::onTransact(
reply->writeInt32(error);
return NO_ERROR;
} break;
-
-#if 0
- case SET_HWC_CTL_MAX_OVLY_CNT: {
- CHECK_INTERFACE(IExynosHWCService, data, reply);
- int val = data.readInt32();
- setHWCCtl(SET_HWC_CTL_MAX_OVLY_CNT, val);
- return NO_ERROR;
- } break;
- case SET_HWC_CTL_VIDEO_OVLY_CNT: {
- CHECK_INTERFACE(IExynosHWCService, data, reply);
- int val = data.readInt32();
- setHWCCtl(SET_HWC_CTL_VIDEO_OVLY_CNT, val);
- return NO_ERROR;
- } break;
- case SET_HWC_CTL_DYNAMIC_RECOMP: {
- CHECK_INTERFACE(IExynosHWCService, data, reply);
- int val = data.readInt32();
- setHWCCtl(SET_HWC_CTL_DYNAMIC_RECOMP, val);
- return NO_ERROR;
- } break;
- case SET_HWC_CTL_SKIP_STATIC: {
- CHECK_INTERFACE(IExynosHWCService, data, reply);
- int val = data.readInt32();
- setHWCCtl(SET_HWC_CTL_SKIP_STATIC, val);
- return NO_ERROR;
- } break;
- case SET_HWC_CTL_SECURE_DMA: {
- CHECK_INTERFACE(IExynosHWCService, data, reply);
- int val = data.readInt32();
- setHWCCtl(SET_HWC_CTL_SECURE_DMA, val);
- return NO_ERROR;
- } break;
- case NOTIFY_PSR_EXIT: {
- CHECK_INTERFACE(IExynosHWCService, data, reply);
- notifyPSRExit();
- return NO_ERROR;
- }
-#endif
case SET_DISPLAY_DEVICE_MODE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int32_t display_id = data.readInt32();
diff --git a/libhwc2.1/libhwcService/IExynosHWC.h b/libhwc2.1/libhwcService/IExynosHWC.h
index 6bc5254..23cb113 100644
--- a/libhwc2.1/libhwcService/IExynosHWC.h
+++ b/libhwc2.1/libhwcService/IExynosHWC.h
@@ -67,9 +67,6 @@ public:
virtual int32_t setDisplayDeviceMode(int32_t display_id, int32_t mode) = 0;
virtual int32_t setPanelGammaTableSource(int32_t display_id, int32_t type, int32_t source) = 0;
virtual void setLbeCtrl(uint32_t display_id, uint32_t state, uint32_t lux) = 0;
- /*
- virtual void notifyPSRExit() = 0;
- */
virtual int32_t setDisplayBrightness(int32_t display_id, float brightness) = 0;
virtual int32_t setDisplayLhbm(int32_t display_id, uint32_t on) = 0;
virtual int32_t setMinIdleRefreshRate(uint32_t display_id, int32_t refresh_rate) = 0;
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
index 01575e8..c812836 100644
--- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
+++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp
@@ -91,6 +91,14 @@ ExynosPrimaryDisplay::ExynosPrimaryDisplay(uint32_t index, ExynosDevice *device)
mFramesToReachLhbmPeakBrightness =
property_get_int32("vendor.primarydisplay.lhbm.frames_to_reach_peak_brightness", 3);
+ // Allow to enable dynamic recomposition after every power on
+ // since it will always be disabled for every power off
+ // TODO(b/268474771): to enable DR by default if video mode panel is detected
+ if (property_get_int32("vendor.display.dynamic_recomposition", 0) & (1 << index)) {
+ mDRDefault = true;
+ mDREnable = true;
+ }
+
// Prepare multi resolution
// Will be exynosHWCControl.multiResoultion
mResolutionInfo.nNum = 1;