summaryrefslogtreecommitdiff
path: root/drmdisplaycomposition.cpp
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2015-10-27 16:18:06 -0700
committerZach Reizner <zachr@google.com>2015-11-06 17:41:28 -0800
commitdb81fce67419d82d828eebec25e57284e90dd93a (patch)
tree9036edcf0ef24f4ad2dc1e49ad2b4242d15f5c78 /drmdisplaycomposition.cpp
parentaa2f4a5eec7f4117b9487a415739634007254822 (diff)
downloaddrm_hwcomposer-db81fce67419d82d828eebec25e57284e90dd93a.tar.gz
drm_hwcomposer-db81fce67419d82d828eebec25e57284e90dd93a.tar.xz
drm_hwcomposer: always put protected layers on hardware planes
Protected layers will not work inside of the GLWorker, so we are forced to put them into planes directly. Because we can now receive display contents which can never be properly composited (e.g. 4 protected layers on hardware with only 3 planes), some compromises had to be made for the composition planning algorithm. First all protected layers are given a plane. Then the remaining planes are used by the remaining layers, pre-composite buffer, and squash buffer. In the case where there are too few planes for both a pre-composite buffer and squash buffer, everything gets pushed into the pre-composite buffer and the squash buffer will not be composited onto the screen. Another major limitation is that any unprotected layers appearing behind a protected layer will actually appear on top of that protected layer. BUG=chrome-os-partner:43674 TEST=run protected content with lots of other layers Change-Id: I94620d93f68ca14dc1966422dc89035ab84e3ff4
Diffstat (limited to 'drmdisplaycomposition.cpp')
-rw-r--r--drmdisplaycomposition.cpp66
1 files changed, 49 insertions, 17 deletions
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index e712b64..9e591ea 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -154,6 +154,20 @@ static DrmPlane *TakePlane(DrmCrtc *crtc,
return TakePlane(crtc, overlay_planes);
}
+void DrmDisplayComposition::EmplaceCompositionPlane(
+ size_t source_layer, std::vector<DrmPlane *> *primary_planes,
+ std::vector<DrmPlane *> *overlay_planes) {
+ DrmPlane *plane = TakePlane(crtc_, primary_planes, overlay_planes);
+ if (plane == NULL) {
+ ALOGE(
+ "Failed to add composition plane because there are no planes "
+ "remaining");
+ return;
+ }
+ composition_planes_.emplace_back(
+ DrmCompositionPlane{plane, crtc_, source_layer});
+}
+
static std::vector<size_t> SetBitsToVector(uint64_t in, size_t *index_map) {
std::vector<size_t> out;
size_t msb = sizeof(in) * 8 - 1;
@@ -324,49 +338,64 @@ int DrmDisplayComposition::Plan(SquashState *squash,
}
}
+ // All protected layers get first usage of planes
std::vector<size_t> layers_remaining;
for (size_t layer_index = 0; layer_index < layers_.size(); layer_index++) {
- // Skip layers that were completely squashed
- if (layer_squash_area[layer_index] >=
- layers_[layer_index].display_frame.area()) {
+ if (!layers_[layer_index].protected_usage() || planes_can_use == 0) {
+ layers_remaining.push_back(layer_index);
continue;
}
+ EmplaceCompositionPlane(layer_index, primary_planes, overlay_planes);
+ planes_can_use--;
+ }
- layers_remaining.push_back(layer_index);
+ if (planes_can_use == 0 && layers_remaining.size() > 0) {
+ ALOGE("Protected layers consumed all hardware planes");
+ return CreateAndAssignReleaseFences();
}
- if (use_squash_framebuffer)
- planes_can_use--;
+ std::vector<size_t> layers_remaining_if_squash;
+ for (size_t layer_index : layers_remaining) {
+ if (layer_squash_area[layer_index] <
+ layers_[layer_index].display_frame.area())
+ layers_remaining_if_squash.push_back(layer_index);
+ }
+
+ if (use_squash_framebuffer) {
+ if (planes_can_use > 1 || layers_remaining_if_squash.size() == 0) {
+ layers_remaining = std::move(layers_remaining_if_squash);
+ planes_can_use--; // Reserve plane for squashing
+ } else {
+ use_squash_framebuffer = false; // The squash buffer is still rendered
+ }
+ }
if (layers_remaining.size() > planes_can_use)
- planes_can_use--;
+ planes_can_use--; // Reserve one for pre-compositing
+ // Whatever planes that are not reserved get assigned a layer
size_t last_composition_layer = 0;
for (last_composition_layer = 0;
last_composition_layer < layers_remaining.size() && planes_can_use > 0;
last_composition_layer++, planes_can_use--) {
- composition_planes_.emplace_back(
- DrmCompositionPlane{TakePlane(crtc_, primary_planes, overlay_planes),
- crtc_, layers_remaining[last_composition_layer]});
+ EmplaceCompositionPlane(layers_remaining[last_composition_layer],
+ primary_planes, overlay_planes);
}
layers_remaining.erase(layers_remaining.begin(),
layers_remaining.begin() + last_composition_layer);
if (layers_remaining.size() > 0) {
- composition_planes_.emplace_back(
- DrmCompositionPlane{TakePlane(crtc_, primary_planes, overlay_planes),
- crtc_, DrmCompositionPlane::kSourcePreComp});
-
+ EmplaceCompositionPlane(DrmCompositionPlane::kSourcePreComp, primary_planes,
+ overlay_planes);
SeparateLayers(layers_.data(), layers_remaining.data(),
layers_remaining.size(), exclude_rects.data(),
exclude_rects.size(), pre_comp_regions_);
}
if (use_squash_framebuffer) {
- composition_planes_.emplace_back(
- DrmCompositionPlane{TakePlane(crtc_, primary_planes, overlay_planes),
- crtc_, DrmCompositionPlane::kSourceSquash});
+ EmplaceCompositionPlane(DrmCompositionPlane::kSourceSquash, primary_planes,
+ overlay_planes);
}
return CreateAndAssignReleaseFences();
@@ -485,6 +514,9 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const {
DumpBuffer(layer.buffer, out);
+ if (layer.protected_usage())
+ *out << " protected";
+
*out << " transform=" << TransformToString(layer.transform)
<< " blending[a=" << (int)layer.alpha
<< "]=" << BlendingToString(layer.blending) << " source_crop";