drm_hwcomposer: add properties to disable overlays or to use HWC_FRAMEBUFFER

To use SurfaceFlinger's GL compositor, use the setprop command:
$ adb shell setprop hwc.drm.use_framebuffer_target 1

A side effect of using the above property is that drm_hwcomposer will only be
compositing one primary plane.

To disable overlays (to force the GL compositor to be used more often):
$ adb shell setprop hwc.drm.use_overlay_planes 0

The default behavior is the opposite of the above properties.

Change-Id: I86afb533c10a8caa15931e8c292f52bb94e5f6c5
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
index a00c95f..88f13c3 100644
--- a/hwcomposer.cpp
+++ b/hwcomposer.cpp
@@ -60,7 +60,7 @@
   typedef std::map<int, hwc_drm_display_t> DisplayMap;
   typedef DisplayMap::iterator DisplayMapIter;
 
-  hwc_context_t() : procs(NULL), importer(NULL) {
+  hwc_context_t() : procs(NULL), importer(NULL), use_framebuffer_target(false) {
   }
 
   ~hwc_context_t() {
@@ -73,6 +73,7 @@
   DisplayMap displays;
   DrmResources drm;
   Importer *importer;
+  bool use_framebuffer_target;
 };
 
 static void hwc_dump(struct hwc_composer_device_1 *dev, char *buff,
@@ -88,6 +89,15 @@
 static int hwc_prepare(hwc_composer_device_1_t *dev, size_t num_displays,
                        hwc_display_contents_1_t **display_contents) {
   struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common;
+
+  char use_framebuffer_target[PROPERTY_VALUE_MAX];
+  property_get("hwc.drm.use_framebuffer_target", use_framebuffer_target, "0");
+  bool new_use_framebuffer_target = atoi(use_framebuffer_target);
+  if (ctx->use_framebuffer_target != new_use_framebuffer_target)
+    ALOGW("Starting to %s HWC_FRAMEBUFFER_TARGET",
+          new_use_framebuffer_target ? "use" : "not use");
+  ctx->use_framebuffer_target = new_use_framebuffer_target;
+
   for (int i = 0; i < (int)num_displays; ++i) {
     if (!display_contents[i])
       continue;
@@ -102,8 +112,19 @@
     for (int j = 0; j < num_layers; j++) {
       hwc_layer_1_t *layer = &display_contents[i]->hwLayers[j];
 
-      if (layer->compositionType == HWC_FRAMEBUFFER)
-        layer->compositionType = HWC_OVERLAY;
+      if (!ctx->use_framebuffer_target) {
+        if (layer->compositionType == HWC_FRAMEBUFFER)
+          layer->compositionType = HWC_OVERLAY;
+      } else {
+        switch (layer->compositionType) {
+          case HWC_OVERLAY:
+          case HWC_BACKGROUND:
+          case HWC_SIDEBAND:
+          case HWC_CURSOR_OVERLAY:
+            layer->compositionType = HWC_FRAMEBUFFER;
+            break;
+        }
+      }
     }
   }
 
@@ -180,8 +201,21 @@
       hwc_layer_1_t *layer = &dc->hwLayers[j];
       if (layer->flags & HWC_SKIP_LAYER)
         continue;
-      if (layer->compositionType == HWC_OVERLAY)
-        indices_to_composite.push_back(j);
+      if (!ctx->use_framebuffer_target) {
+        if (layer->compositionType == HWC_OVERLAY)
+          indices_to_composite.push_back(j);
+      } else {
+        if (layer->compositionType == HWC_FRAMEBUFFER_TARGET)
+          indices_to_composite.push_back(j);
+      }
+    }
+    if (ctx->use_framebuffer_target) {
+      if (indices_to_composite.size() != 1) {
+        ALOGE("Expected 1 (got %d) layer with HWC_FRAMEBUFFER_TARGET",
+              indices_to_composite.size());
+        hwc_set_cleanup(num_displays, display_contents);
+        return -EINVAL;
+      }
     }
 
     map.num_layers = indices_to_composite.size();