Merge "h/q/d: Add binder-api support to change refresh-rate."
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index b77b997..975c195 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1975,7 +1975,8 @@
#ifdef DYNAMIC_FPS
//For primary display, set the dynamic refreshrate
- if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
+ if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
+ ctx->mUseMetaDataRefreshRate) {
FrameInfo frame;
frame.reset(mCurrentFrame.layerCount);
memset(&frame.drop, 0, sizeof(frame.drop));
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 398995a..b0ebb3a 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -34,6 +34,7 @@
#include <hwc_mdpcomp.h>
#include <hwc_virtual.h>
#include <overlay.h>
+#include <display_config.h>
#define QCLIENT_DEBUG 0
@@ -175,13 +176,13 @@
dpy, getExternalDisplayState(status));
if(dpy > HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
- if(dpy == HWC_DISPLAY_VIRTUAL && status == EXTERNAL_OFFLINE) {
+ if(dpy == HWC_DISPLAY_VIRTUAL && status == qdutils::EXTERNAL_OFFLINE) {
ctx->mWfdSyncLock.lock();
ctx->mWfdSyncLock.signal();
ctx->mWfdSyncLock.unlock();
- } else if(status == EXTERNAL_PAUSE) {
+ } else if(status == qdutils::EXTERNAL_PAUSE) {
handle_pause(ctx, dpy);
- } else if(status == EXTERNAL_RESUME) {
+ } else if(status == qdutils::EXTERNAL_RESUME) {
handle_resume(ctx, dpy);
}
} else {
@@ -263,6 +264,48 @@
}
}
+static void configureDynRefreshRate(hwc_context_t* ctx,
+ const Parcel* inParcel) {
+ uint32_t op = (uint32_t)inParcel->readInt32();
+ uint32_t refresh_rate = (uint32_t)inParcel->readInt32();
+ MDPVersion& mdpHw = MDPVersion::getInstance();
+ uint32_t dpy = HWC_DISPLAY_PRIMARY;
+
+ if(mdpHw.isDynFpsSupported()) {
+ Locker::Autolock _sl(ctx->mDrawLock);
+
+ switch (op) {
+ case DISABLE_METADATA_DYN_REFRESH_RATE:
+ ctx->mUseMetaDataRefreshRate = false;
+ setRefreshRate(ctx, dpy, ctx->dpyAttr[dpy].refreshRate);
+ break;
+ case ENABLE_METADATA_DYN_REFRESH_RATE:
+ ctx->mUseMetaDataRefreshRate = true;
+ setRefreshRate(ctx, dpy, ctx->dpyAttr[dpy].refreshRate);
+ break;
+ case SET_BINDER_DYN_REFRESH_RATE:
+ if(ctx->mUseMetaDataRefreshRate)
+ ALOGW("%s: Ignoring binder request to change refresh-rate",
+ __FUNCTION__);
+ else {
+ uint32_t rate = roundOff(refresh_rate);
+ if((rate >= mdpHw.getMinFpsSupported() &&
+ rate <= mdpHw.getMaxFpsSupported())) {
+ setRefreshRate(ctx, dpy, rate);
+ } else {
+ ALOGE("%s: Requested refresh-rate should be between \
+ (%d) and (%d). Given (%d)", __FUNCTION__,
+ mdpHw.getMinFpsSupported(),
+ mdpHw.getMaxFpsSupported(), rate);
+ }
+ }
+ break;
+ default:
+ ALOGE("%s: Invalid op %d",__FUNCTION__,op);
+ }
+ }
+}
+
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -314,6 +357,9 @@
case IQService::TOGGLE_BWC:
toggleBWC(mHwcContext, inParcel);
break;
+ case IQService::CONFIGURE_DYN_REFRESH_RATE:
+ configureDynRefreshRate(mHwcContext, inParcel);
+ break;
default:
ret = NO_ERROR;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 9d53bda..ace0017 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -406,6 +406,12 @@
ctx->mWindowboxFeature = true;
}
+ ctx->mUseMetaDataRefreshRate = true;
+ if(property_get("persist.metadata_dynfps.disable", value, "false")
+ && !strcmp(value, "true")) {
+ ctx->mUseMetaDataRefreshRate = false;
+ }
+
memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
ALOGI("Initializing Qualcomm Hardware Composer");
ALOGI("MDP version: %d", ctx->mMDP.version);
@@ -465,7 +471,7 @@
}
//Helper to roundoff the refreshrates
-static uint32_t roundOff(uint32_t refreshRate) {
+uint32_t roundOff(uint32_t refreshRate) {
int count = (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
uint32_t rate = refreshRate;
for(int i=0; i< count; i++) {
@@ -1057,7 +1063,7 @@
ctx->listStats[dpy].preMultipliedAlpha = true;
#ifdef DYNAMIC_FPS
- if (dpy == HWC_DISPLAY_PRIMARY && mdpHw.isDynFpsSupported()) {
+ if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
//dyn fps: get refreshrate from metadata
//Support multiple refresh rates if they are same
//else set to default
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index f629574..286ae22 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -326,6 +326,8 @@
void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
hwc_rect_t& inRect, hwc_rect_t& outRect);
+uint32_t roundOff(uint32_t refreshRate);
+
void setRefreshRate(hwc_context_t *ctx, int dpy, uint32_t refreshRate);
bool isPrimaryPortrait(hwc_context_t *ctx);
@@ -640,6 +642,8 @@
float mAspectRatioToleranceLevel;
// Runtime switch for BWC for targets that support it
bool mBWCEnabled;
+ // Provides a way for OEM's to disable setting dynfps via metadata.
+ bool mUseMetaDataRefreshRate;
};
namespace qhwc {
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 4fdf19e..03a7046 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -152,6 +152,24 @@
return err;
}
+int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(op);
+ inParcel.writeInt32(refreshRate);
+
+ if(binder != NULL) {
+ err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE,
+ &inParcel, &outParcel);
+ }
+
+ if(err)
+ ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err);
+
+ return err;
+}
+
}; //namespace
// ----------------------------------------------------------------------------
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index 9b6ab56..8bafe91 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -39,6 +39,12 @@
namespace qdutils {
+
+/* TODO: Have all the common enums that need be exposed to clients and which
+ * are also needed in hwc defined here. Remove such definitions we have in
+ * hwc_utils.h
+ */
+
// Use this enum to specify the dpy parameters where needed
enum {
DISPLAY_PRIMARY = 0,
@@ -55,6 +61,12 @@
EXTERNAL_RESUME,
};
+enum {
+ DISABLE_METADATA_DYN_REFRESH_RATE = 0,
+ ENABLE_METADATA_DYN_REFRESH_RATE,
+ SET_BINDER_DYN_REFRESH_RATE,
+};
+
// Display Attributes that are available to clients of this library
// Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
struct DisplayAttributes_t {
@@ -89,4 +101,7 @@
// Set the secondary display status(pause/resume/offline etc.,)
int setSecondaryDisplayStatus(int dpy, uint32_t status);
+
+// Enable/Disable/Set refresh rate dynamically
+int configureDynRefreshRate(uint32_t op, uint32_t refreshRate);
}; //namespace
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index ea40334..683c93c 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -55,6 +55,8 @@
DYNAMIC_DEBUG = 15, // Enable more logging on the fly
SET_IDLE_TIMEOUT = 16, // Set idle timeout for GPU fallback
TOGGLE_BWC = 17, // Toggle BWC On/Off on targets that support
+ /* Enable/Disable/Set refresh rate dynamically */
+ CONFIGURE_DYN_REFRESH_RATE = 18,
COMMAND_LIST_END = 400,
};