diff options
author | Haixia Shi <hshi@chromium.org> | 2015-09-09 12:08:20 -0700 |
---|---|---|
committer | Haixia Shi <hshi@chromium.org> | 2015-09-09 13:54:36 -0700 |
commit | 1034bb7eef0582d8a641e455a6867aa5c99eaf2d (patch) | |
tree | 7e19e74cae18dc47a22f1e60df50922375587664 /hwcomposer.cpp | |
parent | 2143d3bc9da37525cacd432cd51b6e4f459c47a2 (diff) | |
download | drm_hwcomposer-1034bb7eef0582d8a641e455a6867aa5c99eaf2d.tar.gz |
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
Diffstat (limited to 'hwcomposer.cpp')
-rw-r--r-- | hwcomposer.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/hwcomposer.cpp b/hwcomposer.cpp index 88f13c3..060a955 100644 --- a/hwcomposer.cpp +++ b/hwcomposer.cpp @@ -197,6 +197,7 @@ static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays, 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 @@ static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays, 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 @@ static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays, 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(); |