// it.
bool fall_back = FallbacktoGPU(plane, layer, commit_planes);
test_commit_done = true;
- if (!fall_back || prefer_seperate_plane) {
- if (validate_final_layers)
- validate_final_layers = fall_back;
+ bool force_separate = false;
+ if (fall_back && !prefer_seperate_plane && !composition.empty()) {
+ force_separate =
+ ForceSeparatePlane(layers, composition.back(), layer);
+ }
+
+ if (!fall_back || prefer_seperate_plane || force_separate) {
+ if (validate_final_layers)
+ validate_final_layers = fall_back;
composition.emplace_back(plane, layer, layer->GetZorder(),
display_transform_);
#endif
composition.back().AddLayer(layer);
while (SquashPlanesAsNeeded(layers, composition, commit_planes,
- &validate_final_layers)) {
+ mark_later, &validate_final_layers)) {
j--;
plane = j->get();
}
if (composition.back().NeedsOffScreenComposition()) {
while (SquashPlanesAsNeeded(layers, composition, commit_planes,
- &validate_final_layers)) {
+ mark_later, &validate_final_layers)) {
continue;
}
DisplayPlaneState &squashed_plane = composition.back();
#endif
last_plane->AddLayer(cursor_layer);
while (SquashPlanesAsNeeded(all_layers, composition, commit_planes,
- validate_final_layers)) {
+ mark_later, validate_final_layers)) {
continue;
}
cursor_layer->SetLayerComposition(OverlayLayer::kGpu);
last_layer = cursor_layer;
while (SquashPlanesAsNeeded(all_layers, composition, commit_planes,
- validate_final_layers)) {
+ mark_later, validate_final_layers)) {
continue;
}
commit_planes.emplace_back(
OverlayPlane(temp.GetDisplayPlane(), temp.GetOverlayLayer()));
- if (temp.NeedsOffScreenComposition()) {
- render = true;
+ if (temp.Scanout()) {
+ continue;
}
+
+ render = true;
}
if (re_validate_commit) {
bool DisplayPlaneManager::SquashPlanesAsNeeded(
const std::vector<OverlayLayer> &layers, DisplayPlaneStateList &composition,
- std::vector<OverlayPlane> &commit_planes, bool *validate_final_layers) {
+ std::vector<OverlayPlane> &commit_planes,
+ std::vector<NativeSurface *> &mark_later, bool *validate_final_layers) {
bool status = false;
if (composition.size() > 1) {
DisplayPlaneState &last_plane = composition.back();
DisplayPlaneState &scanout_plane = composition.at(composition.size() - 2);
#ifdef SURFACE_TRACING
- ISURFACETRACE("ANALAYZE: %d %d \n",
+ ISURFACETRACE("ANALAYZE scanout_plane: %d %d \n",
scanout_plane.NeedsOffScreenComposition(),
scanout_plane.IsCursorPlane(), scanout_plane.IsVideoPlane());
- if (!scanout_plane.NeedsOffScreenComposition() &&
- !scanout_plane.IsCursorPlane() && !scanout_plane.IsVideoPlane()) {
+
+ ISURFACETRACE("ANALAYZE last_plane: %d %d \n",
+ last_plane.NeedsOffScreenComposition(),
+ last_plane.IsCursorPlane(), last_plane.IsVideoPlane());
+
+ if (!scanout_plane.IsCursorPlane() && !scanout_plane.IsVideoPlane()) {
ISURFACETRACE("ANALAYZE %d \n",
AnalyseOverlap(scanout_plane.GetDisplayFrame(),
last_plane.GetDisplayFrame()));
#endif
const HwcRect<int> &display_frame = scanout_plane.GetDisplayFrame();
const HwcRect<int> &target_frame = last_plane.GetDisplayFrame();
- if (!scanout_plane.NeedsOffScreenComposition() &&
- !scanout_plane.IsCursorPlane() && !scanout_plane.IsVideoPlane() &&
+ if (!scanout_plane.IsCursorPlane() && !scanout_plane.IsVideoPlane() &&
(AnalyseOverlap(display_frame, target_frame) != kOutside)) {
- const std::vector<size_t> &new_layers = last_plane.GetSourceLayers();
- bool squash = false;
- uint32_t total_width = 0;
- uint32_t total_height = 0;
- for (const size_t &index : new_layers) {
- const OverlayLayer &layer = layers.at(index);
- total_width = std::max(total_width, layer.GetDisplayFrameWidth());
- total_height = std::max(total_height, layer.GetDisplayFrameHeight());
- }
-
- const OverlayLayer *target_layer = scanout_plane.GetOverlayLayer();
- if (((target_frame.left + total_width) <
- target_layer->GetDisplayFrameWidth()) ||
- ((target_frame.top + total_height) <
- target_layer->GetDisplayFrameHeight())) {
- uint32_t target_width = target_frame.right - target_frame.left;
- uint32_t target_height = target_frame.bottom - target_frame.top;
- if ((total_width != target_width) || (total_height != target_height)) {
- squash = true;
- }
- }
-
- if (squash) {
+ if (ForceSeparatePlane(layers, last_plane, NULL)) {
#ifdef SURFACE_TRACING
ISURFACETRACE("Squasing planes. \n");
#endif
+ const std::vector<size_t> &new_layers = last_plane.GetSourceLayers();
for (const size_t &index : new_layers) {
scanout_plane.AddLayer(&(layers.at(index)));
}
last_plane.GetDisplayPlane()->SetInUse(false);
+ MarkSurfacesForRecycling(&last_plane, mark_later, true);
composition.pop_back();
status = true;
- }
- DisplayPlaneState &squashed_plane = composition.back();
- if (squashed_plane.NeedsSurfaceAllocation()) {
+ DisplayPlaneState &squashed_plane = composition.back();
if (squashed_plane.NeedsSurfaceAllocation()) {
- SetOffScreenPlaneTarget(squashed_plane);
- }
+ if (squashed_plane.NeedsSurfaceAllocation()) {
+ SetOffScreenPlaneTarget(squashed_plane);
+ }
- *validate_final_layers = true;
- }
+ *validate_final_layers = true;
+ }
- if (!commit_planes.empty()) {
- // Layer for the plane should have changed, reset commit planes.
- std::vector<OverlayPlane>().swap(commit_planes);
- for (DisplayPlaneState &temp : composition) {
- commit_planes.emplace_back(
- OverlayPlane(temp.GetDisplayPlane(), temp.GetOverlayLayer()));
+ if (!commit_planes.empty()) {
+ // Layer for the plane should have changed, reset commit planes.
+ std::vector<OverlayPlane>().swap(commit_planes);
+ for (DisplayPlaneState &temp : composition) {
+ commit_planes.emplace_back(
+ OverlayPlane(temp.GetDisplayPlane(), temp.GetOverlayLayer()));
+ }
}
}
}
return status;
}
+bool DisplayPlaneManager::ForceSeparatePlane(
+ const std::vector<OverlayLayer> &layers,
+ const DisplayPlaneState &last_plane, const OverlayLayer *target_layer) {
+ const std::vector<size_t> &new_layers = last_plane.GetSourceLayers();
+ const HwcRect<int> &display_frame = last_plane.GetDisplayFrame();
+ HwcRect<int> target_display_frame = display_frame;
+ uint32_t total_width = 0;
+ uint32_t total_height = 0;
+ if (target_layer) {
+ total_width = target_layer->GetDisplayFrameWidth();
+ total_height = target_layer->GetDisplayFrameHeight();
+ target_display_frame = target_layer->GetDisplayFrame();
+ CalculateRect(display_frame, target_display_frame);
+ }
+
+ bool force_separate = false;
+ for (const size_t &index : new_layers) {
+ const OverlayLayer &layer = layers.at(index);
+ total_width = std::max(total_width, layer.GetDisplayFrameWidth());
+ total_height = std::max(total_height, layer.GetDisplayFrameHeight());
+ }
+
+ uint32_t target_width =
+ target_display_frame.right - target_display_frame.left;
+ uint32_t target_height =
+ target_display_frame.bottom - target_display_frame.top;
+ if ((total_width != target_width) || (total_height != target_height)) {
+ force_separate = true;
+ }
+
+ return force_separate;
+}
+
} // namespace hwcomposer
std::vector<OverlayPlane> temp;
while (display_plane_manager_->SquashPlanesAsNeeded(
- layers, *composition, temp, &plane_validation)) {
+ layers, *composition, temp, surfaces_not_inuse_,
+ &plane_validation)) {
continue;
}
DisplayPlaneState& squashed_plane = composition->back();
}
if (update_rect || refresh_surfaces || !surface_damage.empty()) {
+ needs_gpu_composition = true;
if (target_plane.NeedsSurfaceAllocation()) {
display_plane_manager_->SetOffScreenPlaneTarget(target_plane);
} else if (refresh_surfaces || reset_plane) {
} else if (!update_rect && !surface_damage.empty()) {
target_plane.UpdateDamage(surface_damage);
}
- }
-
- if (!needs_gpu_composition)
- needs_gpu_composition = !target_plane.SurfaceRecycled();
- std::vector<OverlayPlane> temp;
- bool planes_squashed = false;
- while (display_plane_manager_->SquashPlanesAsNeeded(
- layers, *composition, temp, &plane_validation)) {
- planes_squashed = true;
- continue;
- }
+ if (refresh_surfaces || reset_plane || update_rect) {
+ std::vector<OverlayPlane> temp;
+ bool squashed = display_plane_manager_->SquashPlanesAsNeeded(
+ layers, *composition, temp, surfaces_not_inuse_,
+ &plane_validation);
+ if (squashed) {
+ // We squashed planes and it's not the last one.
+ // We might have messed up with plane order, let's
+ // force full validation.
+ if (previous_size != previous_plane_state_.size()) {
+ *force_full_validation = true;
+ *can_ignore_commit = false;
+ return;
+ } else {
+ while (display_plane_manager_->SquashPlanesAsNeeded(
+ layers, *composition, temp, surfaces_not_inuse_,
+ &plane_validation)) {
+ continue;
+ }
+ }
+ }
+ }
- if (planes_squashed && composition->size() > 1 &&
- (previous_size != previous_plane_state_.size())) {
- *force_full_validation = true;
- *can_ignore_commit = false;
- return;
+ composition->back().SwapSurfaceIfNeeded();
+ } else {
+ if (!needs_gpu_composition)
+ needs_gpu_composition = !target_plane.SurfaceRecycled();
}
reset_composition_regions = false;
source_layers.at(0), size - 1, size - 2);
#endif
const OverlayLayer* layer = &(layers.at(source_layers.at(0)));
+ if (display_plane_manager_->ForceSeparatePlane(layers, old_plane,
+ layer)) {
+ return;
+ }
+
old_plane.AddLayer(layer);
// Let's allocate an offscreen surface if needed.