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();