OSDN Git Service

Revalidate layers when rects change and using scalar.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 17 Dec 2017 06:13:49 +0000 (22:13 -0800)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Wed, 20 Dec 2017 23:19:47 +0000 (15:19 -0800)
When using plane scalar, we need to ensure when either
display frame or source rect change the commit can still pass.
Instead of doing full validation, we first do a test commit to
check if the combination is still valid. If the test commit
fails than we fall back to full validation of layers.

Jira: None.
Test: No new regressions on Android.

Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
common/core/overlaylayer.cpp
common/core/overlaylayer.h
common/display/displayplanemanager.cpp
common/display/displayplanemanager.h
common/display/displayqueue.cpp
common/display/displayqueue.h

index 42a4ccc..db29c49 100644 (file)
@@ -351,6 +351,11 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
     state_ |= kSourceRectChanged;
 
   display_scaled_ = rhs->display_scaled_;
+  if (display_scaled_ && (source_rect_changed | rect_changed)) {
+    state_ |= kNeedsReValidation;
+  }
+
+  state_ &= ~kLayerAttributesChanged;
 
   // We expect cursor plane to support alpha always.
   if (rhs->gpu_rendered_ || (type_ == kLayerCursor)) {
@@ -361,18 +366,24 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
     // supporting XRGB format might not necessarily support
     // transparent planes. We assume plane supporting
     // ARGB will support XRGB.
-    if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_))
+    if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_)) {
+      state_ |= kNeedsReValidation;
       return;
+    }
 
-    if (blending_ != rhs->blending_)
+    if (blending_ != rhs->blending_) {
+      state_ |= kNeedsReValidation;
       return;
+    }
 
     if (rect_changed || layer->HasLayerAttributesChanged()) {
       if (layer->IsValidated()) {
+        state_ |= kNeedsReValidation;
         return;
       }
 
       if (rhs->transform_ != transform_) {
+        state_ |= kNeedsReValidation;
         return;
       }
 
@@ -380,6 +391,7 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
           (rhs->display_frame_.right != display_frame_.right) ||
           (rhs->display_frame_.top != display_frame_.top) ||
           (rhs->display_frame_.bottom != display_frame_.bottom)) {
+        state_ |= kNeedsReValidation;
         return;
       }
     }
@@ -389,12 +401,12 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
       // shouldn't impact the plane composition results.
       if ((source_crop_width_ != rhs->source_crop_width_) ||
           (source_crop_height_ != rhs->source_crop_height_)) {
+        state_ |= kNeedsReValidation;
         return;
       }
     }
   }
 
-  state_ &= ~kLayerAttributesChanged;
   gpu_rendered_ = rhs->gpu_rendered_;
 
   if (!rect_changed) {
index 6ccfb6d..202ca79 100644 (file)
@@ -183,6 +183,15 @@ struct OverlayLayer {
     return state_ & kSourceRectChanged;
   }
 
+  // Returns true if this layer attributes
+  // have changed compared to last frame
+  // and needs to be re-tested to ensure
+  // we are able to show the layer on screen
+  // correctly.
+  bool NeedsRevalidation() const {
+    return state_ & kNeedsReValidation;
+  }
+
   /**
    * API for querying if Layer source position has
    * changed from last Present call to NativeDisplay.
@@ -200,7 +209,8 @@ struct OverlayLayer {
     kDimensionsChanged = 1 << 2,
     kClearSurface = 1 << 3,
     kInvisible = 1 << 4,
-    kSourceRectChanged = 1 << 5
+    kSourceRectChanged = 1 << 5,
+    kNeedsReValidation = 1 << 6
   };
 
   struct ImportedBuffer {
index 85d9127..7a36098 100644 (file)
@@ -120,7 +120,7 @@ bool DisplayPlaneManager::ValidateLayers(
   }
 
   if (render_layers)
-    ValidateForDisplayScaling(composition, commit_planes, primary_layer);
+    ValidateForDisplayScaling(composition.back(), commit_planes, primary_layer);
 
   // We are just compositing Primary layer and nothing else.
   if (layers.size() == 1) {
@@ -141,7 +141,8 @@ bool DisplayPlaneManager::ValidateLayers(
       if (previous_layer &&
           last_plane.GetCompositionState() ==
               DisplayPlaneState::State::kRender) {
-        ValidateForDisplayScaling(composition, commit_planes, previous_layer);
+        ValidateForDisplayScaling(composition.back(), commit_planes,
+                                  previous_layer);
         render_layers = true;
       }
 
@@ -201,7 +202,8 @@ bool DisplayPlaneManager::ValidateLayers(
           EnsureOffScreenTarget(last_plane);
         }
 
-        ValidateForDisplayScaling(composition, commit_planes, previous_layer);
+        ValidateForDisplayScaling(composition.back(), commit_planes,
+                                  previous_layer);
       }
 
       render_layers = true;
@@ -233,6 +235,53 @@ bool DisplayPlaneManager::ValidateLayers(
   return render_layers;
 }
 
+bool DisplayPlaneManager::ReValidateLayers(std::vector<OverlayLayer> &layers,
+                                           DisplayPlaneStateList &composition,
+                                           bool *request_full_validation) {
+  CTRACE();
+  // Let's mark all planes as free to be used.
+  for (auto j = overlay_planes_.begin(); j != overlay_planes_.end(); ++j) {
+    j->get()->SetInUse(false);
+  }
+
+  std::vector<OverlayPlane> commit_planes;
+  for (DisplayPlaneState &temp : composition) {
+    commit_planes.emplace_back(
+        OverlayPlane(temp.plane(), temp.GetOverlayLayer()));
+    // Check if we can still need/use scalar for this plane.
+    if (temp.IsUsingPlaneScalar()) {
+      size_t total_layers = temp.source_layers().size();
+      ValidateForDisplayScaling(
+          temp, commit_planes,
+          &(layers.at(temp.source_layers().at(total_layers - 1))));
+    }
+  }
+
+  bool render_layers = false;
+  // If this combination fails just fall back to 3D for all layers.
+  if (plane_handler_->TestCommit(commit_planes)) {
+    *request_full_validation = false;
+    for (DisplayPlaneState &plane : composition) {
+      if (plane.GetCompositionState() == DisplayPlaneState::State::kRender) {
+        render_layers = true;
+        const std::vector<size_t> &source_layers = plane.source_layers();
+        size_t layers_size = source_layers.size();
+        bool useplanescalar = plane.IsUsingPlaneScalar();
+        for (size_t i = 0; i < layers_size; i++) {
+          size_t source_index = source_layers.at(i);
+          OverlayLayer &layer = layers.at(source_index);
+          layer.GPURendered();
+          layer.UsePlaneScalar(useplanescalar);
+        }
+      }
+    }
+  } else {
+    *request_full_validation = true;
+  }
+
+  return render_layers;
+}
+
 DisplayPlaneState *DisplayPlaneManager::GetLastUsedOverlay(
     DisplayPlaneStateList &composition) {
   CTRACE();
@@ -341,13 +390,10 @@ bool DisplayPlaneManager::ValidateCursorLayer(
 }
 
 void DisplayPlaneManager::ValidateForDisplayScaling(
-    DisplayPlaneStateList &composition,
-    std::vector<OverlayPlane> &commit_planes, OverlayLayer *current_layer) {
-  DisplayPlaneState &last_plane = composition.back();
-  size_t total_layers = last_plane.source_layers().size() > 1;
-  // We may have cases where additional layers got added to this
-  // plane for composition. Reset the state in this case.
-  if (last_plane.IsUsingPlaneScalar() && total_layers > 1) {
+    DisplayPlaneState &last_plane, std::vector<OverlayPlane> &commit_planes,
+    OverlayLayer *current_layer) {
+  size_t total_layers = last_plane.source_layers().size();
+  if (last_plane.IsUsingPlaneScalar()) {
     last_plane.UsePlaneScalar(false);
     last_plane.ResetSourceRectToDisplayFrame();
     last_plane.GetOffScreenTarget()->ResetSourceCrop(
index 9299a5f..bc9dbe5 100644 (file)
@@ -48,6 +48,12 @@ class DisplayPlaneManager {
                       DisplayPlaneStateList &composition,
                       bool request_video_effect);
 
+  // This can be used to quickly check if the new DisplayPlaneStateList
+  // can be succefully commited before doing a full re-validation.
+  bool ReValidateLayers(std::vector<OverlayLayer> &layers,
+                        DisplayPlaneStateList &composition,
+                        bool *request_full_validation);
+
   // This should be called only in case of a new cursor layer
   // being added and all other layers are same as previous
   // frame.
@@ -91,7 +97,7 @@ class DisplayPlaneManager {
 
   void PreparePlaneForCursor(DisplayPlaneState *plane);
 
-  void ValidateForDisplayScaling(DisplayPlaneStateList &composition,
+  void ValidateForDisplayScaling(DisplayPlaneState &last_plane,
                                  std::vector<OverlayPlane> &commit_planes,
                                  OverlayLayer *current_layer);
 
index 242db28..3904364 100644 (file)
@@ -132,11 +132,12 @@ void DisplayQueue::RotateDisplay(HWCRotation rotation) {
 void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
                                    bool cursor_layer_removed,
                                    DisplayPlaneStateList* composition,
-                                   bool* render_layers,
-                                   bool* can_ignore_commit) {
+                                   bool* render_layers, bool* can_ignore_commit,
+                                   bool* re_validate_commit) {
   CTRACE();
   bool needs_gpu_composition = false;
   bool ignore_commit = true;
+  bool needs_revalidation = false;
   for (DisplayPlaneState& plane : previous_plane_state_) {
     bool plane_state_render =
         plane.GetCompositionState() == DisplayPlaneState::State::kRender;
@@ -164,6 +165,9 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
       for (size_t i = 0; i < layers_size; i++) {
         size_t source_index = source_layers.at(i);
         const OverlayLayer& layer = layers.at(source_index);
+        if (!needs_revalidation)
+          needs_revalidation = layer.NeedsRevalidation();
+
         if (layer.HasDimensionsChanged()) {
           last_plane.UpdateDisplayFrame(layer.GetDisplayFrame());
           clear_surface = true;
@@ -278,6 +282,10 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
       if (layer->HasLayerContentChanged() || layer->HasDimensionsChanged()) {
         ignore_commit = false;
       }
+
+      if (!needs_revalidation) {
+        needs_revalidation = layer->NeedsRevalidation();
+      }
     }
   }
 
@@ -286,6 +294,7 @@ void DisplayQueue::GetCachedLayers(const std::vector<OverlayLayer>& layers,
     ignore_commit = false;
 
   *can_ignore_commit = ignore_commit;
+  *re_validate_commit = needs_revalidation;
 }
 
 bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,
@@ -434,12 +443,23 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,
   // Validate Overlays and Layers usage.
   if (!validate_layers) {
     bool can_ignore_commit = false;
+    bool request_full_validation = false;
+    bool re_validate_commit = false;
     // Before forcing layer validation, check if content has changed
     // if not continue showing the current buffer.
     GetCachedLayers(layers, cursor_state_ & kIgnoredCursorLayer,
                     &current_composition_planes, &render_layers,
-                    &can_ignore_commit);
-    if (add_cursor_layer) {
+                    &can_ignore_commit, &re_validate_commit);
+
+    // Let's re-validate if their was a request for this.
+    if (re_validate_commit) {
+      display_plane_manager_->ReValidateLayers(
+          layers, current_composition_planes, &request_full_validation);
+    }
+
+    if (request_full_validation) {
+      validate_layers = true;
+    } else if (add_cursor_layer) {
       bool render_cursor = display_plane_manager_->ValidateCursorLayer(
           cursor_layers, current_composition_planes);
       if (!render_layers)
@@ -462,7 +482,9 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers,
       HandleCommitIgnored(current_composition_planes);
       return true;
     }
-  } else {
+  }
+
+  if (validate_layers) {
     if (!idle_frame)
       tracker.ResetTrackerState();
 
index 76a0aed..1073859 100644 (file)
@@ -230,7 +230,7 @@ class DisplayQueue {
   void GetCachedLayers(const std::vector<OverlayLayer>& layers,
                        bool cursor_layer_removed,
                        DisplayPlaneStateList* composition, bool* render_layers,
-                       bool* can_ignore_commit);
+                       bool* can_ignore_commit, bool* re_validate_commit);
   void SetReleaseFenceToLayers(int32_t fence,
                                std::vector<HwcLayer*>& source_layers) const;
   void UpdateSurfaceInUse(bool in_use,