hwc: Trigger dynamic refresh-rate change for more usecases

* Until now it's been the case that refresh-rates were set to
the standard values of 24, 30, 48 and 60 for video playback
usecases. Since of the most panel vendors can only support
refresh-rates above 45, in many of the use-cases with fps < 45,
dynamic change in panel refresh rate doesn't happen.

* To address this, following are the changes done:
    1. Refresh-rate will no longer be limited to standard values
    for video-playback usecases and any value above the
    minfpsSupported which is advertised by the mdss driver will
    be considered.
    2. If the fps of the use-case is 'x' and it falls less than
    minfpsSupported, a multiple of it 'k*x' will be considered as
    the new refresh-rate, provided k*x < 60. If
    abs(k*x - stdRefreshRate) < 2, set the refresh-rate to the
    standard value rather than k*x.

* With the above two optimizations in place, if the panel has
a minfpsSupported value of 45, and if the use-case fps is 12,
the new refresh-rate would be set as 12 * 4(= 48) instead of 60
which had been the case.

* The above two optimizations will result in dynamic change in
refresh-rate happening more often, in local video and streaming
use-cases and will help in improving DOU(Days Of Use) metric.

Change-Id: I2051e4d91280867135bf592e8f561911adcb6228
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 8efe025..08a956c 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -554,7 +554,37 @@
     }
 }
 
-//Helper to roundoff the refreshrates
+uint32_t getRefreshRate(hwc_context_t* ctx, uint32_t requestedRefreshRate) {
+
+    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
+    int dpy = HWC_DISPLAY_PRIMARY;
+    uint32_t defaultRefreshRate = ctx->dpyAttr[dpy].refreshRate;
+    uint32_t rate = defaultRefreshRate;
+
+    if(!requestedRefreshRate)
+        return defaultRefreshRate;
+
+    uint32_t maxNumIterations =
+            (uint32_t)ceil(
+                    (float)mdpHw.getMaxFpsSupported()/
+                    (float)requestedRefreshRate);
+
+    for(uint32_t i = 1; i <= maxNumIterations; i++) {
+        rate = roundOff(i * requestedRefreshRate);
+        if(rate < mdpHw.getMinFpsSupported()) {
+            continue;
+        } else if((rate >= mdpHw.getMinFpsSupported() &&
+                   rate <= mdpHw.getMaxFpsSupported())) {
+            break;
+        } else {
+            rate = defaultRefreshRate;
+            break;
+        }
+    }
+    return rate;
+}
+
+//Helper to roundoff the refreshrates to the std refresh-rates
 uint32_t roundOff(uint32_t refreshRate) {
     int count =  (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
     uint32_t rate = refreshRate;
@@ -1175,21 +1205,18 @@
 
 #ifdef DYNAMIC_FPS
         if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
-            //dyn fps: get refreshrate from metadata
-            //Support multiple refresh rates if they are same
-            //else set to  default
+            /* Dyn fps: get refreshrate from metadata */
             MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
             if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
                 // Valid refreshRate in metadata and within the range
-                uint32_t rate = roundOff(mdata->refreshrate);
-                if((rate >= mdpHw.getMinFpsSupported() &&
-                                rate <= mdpHw.getMaxFpsSupported())) {
-                    if (!refreshRate) {
-                        refreshRate = rate;
-                    } else if(refreshRate != rate) {
-                        // multiple refreshrate requests, set to default
-                        refreshRate = ctx->dpyAttr[dpy].refreshRate;
-                    }
+                uint32_t rate = getRefreshRate(ctx, mdata->refreshrate);
+                if (!refreshRate) {
+                    refreshRate = rate;
+                } else if(refreshRate != rate) {
+                    /* Support multiple refresh rates if they are same
+                     * else set to default.
+                     */
+                    refreshRate = ctx->dpyAttr[dpy].refreshRate;
                 }
             }
         }