h/q/d: Add binder-api support to change refresh-rate.
** Now, there are two ways for the clients to request
change in the refresh-rate of the target.
(a) Using metadata of the input-buffer.
(b) Using binder api added as part of this change.
** configureDynRefreshRate binder api provides three
op-modes which can be used as following:
(a) "DISABLE_METADATA_DYN_REFRESH_RATE" can be used by the
clients, to disallow display-hal from honoring refresh-rate
change requests, made by video-clients using the metadata.
For ex: This can be used during streaming use-cases
(Dash-playback, playback at WFD-sink,etc) where the idea
is not to change the refresh-rate, though video-client
requests for it using metadata, as video-clients cannot
distinguish between streaming and non-streaming usecases.
Usage:
adb shell service call display.qservice 18 i32 0 i32 0
(b) "ENABLE_METADATA_DYN_REFRESH_RATE" can be used by the
clients after DISABLE_METADATA_DYN_REFRESH_RATE, to once
again allow display-hal to be able to change refresh-rate
based on requests made by the video-clients using metadata.
For ex: This can be used by clients( Dash-playback,
WFD, etc) once they are done with their use-case.
WFD-framework will also use this when the wfd-session is
paused.
Usage:
adb shell service call display.qservice 18 i32 1 i32 0
(c) "SET_BINDER_DYN_REFRESH_RATE" can be used by the clients
to change the refresh-rate of the target using binder-api,
provided they have disallowed display from honoring the
refresh-rate requests made using metadata.
In other words, changing refresh-rate through this binder
api and using metadata approach cannot co-exist together.
Usage:
adb shell service call display.qservice 18 i32 2 i32 45
-- The refresh-rate set here will correspond to 45fps.
** Added property "persist.metadata_dynfps.disable" that
can be used by OEM's, to disable setting of refresh-rate
using the metadata.
Change-Id: I767fa174dcf1cfd061a578e96cd68af28e7dd36b
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;
}