OSDN Git Service

Check if a layer is better off on a separate plane.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Wed, 7 Mar 2018 07:12:05 +0000 (23:12 -0800)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Wed, 7 Mar 2018 11:25:46 +0000 (03:25 -0800)
Jira: None.
Test: No new flickers seen on Android.
Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
common/display/displayplanemanager.cpp
common/display/displayplanemanager.h
common/display/displayqueue.cpp

index 5265bbd..7192a7b 100644 (file)
@@ -182,9 +182,15 @@ bool DisplayPlaneManager::ValidateLayers(
         // 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_);
@@ -250,7 +256,7 @@ bool DisplayPlaneManager::ValidateLayers(
 #endif
             composition.back().AddLayer(layer);
             while (SquashPlanesAsNeeded(layers, composition, commit_planes,
-                                        &validate_final_layers)) {
+                                        mark_later, &validate_final_layers)) {
               j--;
               plane = j->get();
             }
@@ -286,7 +292,7 @@ bool DisplayPlaneManager::ValidateLayers(
 
       if (composition.back().NeedsOffScreenComposition()) {
         while (SquashPlanesAsNeeded(layers, composition, commit_planes,
-                                    &validate_final_layers)) {
+                                    mark_later, &validate_final_layers)) {
           continue;
         }
         DisplayPlaneState &squashed_plane = composition.back();
@@ -485,7 +491,7 @@ void DisplayPlaneManager::ValidateCursorLayer(
 #endif
       last_plane->AddLayer(cursor_layer);
       while (SquashPlanesAsNeeded(all_layers, composition, commit_planes,
-                                  validate_final_layers)) {
+                                  mark_later, validate_final_layers)) {
         continue;
       }
 
@@ -542,7 +548,7 @@ void DisplayPlaneManager::ValidateCursorLayer(
     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;
     }
 
@@ -903,9 +909,11 @@ bool DisplayPlaneManager::ReValidatePlanes(
     commit_planes.emplace_back(
         OverlayPlane(temp.GetDisplayPlane(), temp.GetOverlayLayer()));
 
-    if (temp.NeedsOffScreenComposition()) {
-      render = true;
+    if (temp.Scanout()) {
+      continue;
     }
+
+    render = true;
   }
 
   if (re_validate_commit) {
@@ -1074,17 +1082,22 @@ void DisplayPlaneManager::FinalizeValidation(
 
 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()));
@@ -1102,59 +1115,38 @@ bool DisplayPlaneManager::SquashPlanesAsNeeded(
 #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()));
+          }
         }
       }
     }
@@ -1163,4 +1155,37 @@ bool DisplayPlaneManager::SquashPlanesAsNeeded(
   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
index 0370862..f2f41db 100644 (file)
@@ -94,8 +94,16 @@ class DisplayPlaneManager {
   bool SquashPlanesAsNeeded(const std::vector<OverlayLayer> &layers,
                             DisplayPlaneStateList &composition,
                             std::vector<OverlayPlane> &commit_planes,
+                            std::vector<NativeSurface *> &mark_later,
                             bool *validate_final_layers);
 
+  // Returns true if we want to force target_layer to a separate plane than
+  // adding it to
+  // last_plane.
+  bool ForceSeparatePlane(const std::vector<OverlayLayer> &layers,
+                          const DisplayPlaneState &last_plane,
+                          const OverlayLayer *target_layer);
+
  private:
   struct LayerResultCache {
     uint32_t last_transform_ = 0;
index 61f4c6c..8bac7fa 100644 (file)
@@ -225,7 +225,8 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
 
         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();
@@ -298,6 +299,7 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
       }
 
       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) {
@@ -305,24 +307,34 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
         } 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;
@@ -391,6 +403,11 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
             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.