hwc: Simulate composition strategy

Provide support to simulate composition strategy tree to execute
and test multiple strategy combinations across test cases.

Change-Id: I5011fad32f8f45ecef47b6df513f9d72343697d2
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 540a8e7..5be06a9 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -42,6 +42,7 @@
 bool MDPComp::sDebugLogs = false;
 bool MDPComp::sEnabled = false;
 bool MDPComp::sEnableMixedMode = true;
+int MDPComp::sSimulationFlags = 0;
 int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
 bool MDPComp::sEnable4k2kYUVSplit = false;
 bool MDPComp::sSrcSplitEnabled = false;
@@ -710,6 +711,10 @@
 }
 
 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+
+    if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
+        return false;
+
     //Will benefit presentation / secondary-only layer.
     if((mDpy > HWC_DISPLAY_PRIMARY) &&
             (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
@@ -742,7 +747,8 @@
         reset(ctx);
         return false;
     }
-
+    ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
+             __FUNCTION__);
     return true;
 }
 
@@ -767,6 +773,9 @@
 
 bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
+    if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
+        return false;
+
     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
     mCurrentFrame.reset(numAppLayers);
     updateLayerCache(ctx, list);
@@ -811,12 +820,17 @@
         reset(ctx);
         return false;
     }
+    ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
+             __FUNCTION__);
 
     return true;
 }
 
 bool MDPComp::loadBasedComp(hwc_context_t *ctx,
         hwc_display_contents_1_t* list) {
+    if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
+        return false;
+
     if(not isLoadBasedCompDoable(ctx)) {
         return false;
     }
@@ -888,7 +902,9 @@
 
         if(postHeuristicsHandling(ctx, list)) {
             ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
-                    __FUNCTION__);
+                     __FUNCTION__);
+            ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
+                     __FUNCTION__);
             return true;
         }
 
@@ -927,6 +943,8 @@
 
 bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
         hwc_display_contents_1_t* list, bool secureOnly) {
+    if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
+        return false;
     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
 
     mCurrentFrame.reset(numAppLayers);
@@ -959,6 +977,8 @@
         return false;
     }
 
+    ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
+             __FUNCTION__);
     return true;
 }
 
@@ -1360,6 +1380,16 @@
 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
     int ret = 0;
     const int numLayers = ctx->listStats[mDpy].numAppLayers;
+    char property[PROPERTY_VALUE_MAX];
+
+    if(property_get("debug.hwc.simulate", property, NULL) > 0) {
+        int currentFlags = atoi(property);
+        if(currentFlags != sSimulationFlags) {
+            sSimulationFlags = currentFlags;
+            ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
+                    sSimulationFlags, sSimulationFlags);
+        }
+    }
 
     //Do not cache the information for next draw cycle.
     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {