drm_hwcomposer: use HWC_FRAMEBUFFER_TARGET if all HWC_OVERLAY layers are skipped

Apparently there are cases (such as during rotation) where SF will put content
in framebuffer target and set HWC_SKIP_LAYER on all other layers. In this case
we need to use the HWC_FRAMEBUFFER_TARGET layer.

BUG=23936827
TEST=verify on ryu that rotation works

Change-Id: Ice8ee5a023a92fc286dbf837a822fa6f6c0fde6b
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
index 88f13c3..060a955 100644
--- a/hwcomposer.cpp
+++ b/hwcomposer.cpp
@@ -197,6 +197,7 @@
 
     std::vector<size_t> indices_to_composite;
     unsigned num_dc_layers = dc->numHwLayers;
+    int framebuffer_target_index = -1;
     for (int j = 0; j < (int)num_dc_layers; ++j) {
       hwc_layer_1_t *layer = &dc->hwLayers[j];
       if (layer->flags & HWC_SKIP_LAYER)
@@ -204,6 +205,8 @@
       if (!ctx->use_framebuffer_target) {
         if (layer->compositionType == HWC_OVERLAY)
           indices_to_composite.push_back(j);
+        if (layer->compositionType == HWC_FRAMEBUFFER_TARGET)
+          framebuffer_target_index = j;
       } else {
         if (layer->compositionType == HWC_FRAMEBUFFER_TARGET)
           indices_to_composite.push_back(j);
@@ -216,6 +219,19 @@
         hwc_set_cleanup(num_displays, display_contents);
         return -EINVAL;
       }
+    } else {
+      if (indices_to_composite.empty() && framebuffer_target_index >= 0) {
+        // Fall back to use HWC_FRAMEBUFFER_TARGET if all HWC_OVERLAY layers
+        // are skipped.
+        hwc_layer_1_t *layer = &dc->hwLayers[framebuffer_target_index];
+        if (!layer->handle || (layer->flags & HWC_SKIP_LAYER)) {
+          ALOGE("Expected valid layer with HWC_FRAMEBUFFER_TARGET when all "
+                "HWC_OVERLAY layers are skipped.");
+          hwc_set_cleanup(num_displays, display_contents);
+          return -EINVAL;
+        }
+        indices_to_composite.push_back(framebuffer_target_index);
+      }
     }
 
     map.num_layers = indices_to_composite.size();