OSDN Git Service

Apply damage transformations in GetLayerDamage
authorHarish Krupo <harish.krupo.kps@intel.com>
Fri, 1 Jun 2018 08:32:22 +0000 (14:02 +0530)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Mon, 4 Jun 2018 00:39:51 +0000 (17:39 -0700)
This patch drops UpdateRenderingDamage() call and
instead applies the required transformations in
GetLayerDamage() and intersects it with the visible
region (if set) to calculate the layer's damage.

Jira: None
Test: The full ball is rendered correctly when
      weston-simple-damage application is run.
      No regressions on Android and Linux.

Signed-off-by: Harish Krupo <harish.krupo.kps@intel.com>
common/core/hwclayer.cpp
public/hwclayer.h
public/hwcutils.h

index 6dab385..5f36612 100644 (file)
@@ -40,21 +40,18 @@ void HwcLayer::SetTransform(int32_t transform) {
   if (transform != transform_) {
     layer_cache_ |= kLayerAttributesChanged;
     transform_ = transform;
-    UpdateRenderingDamage(display_frame_, display_frame_, true);
   }
 }
 
 void HwcLayer::SetAlpha(uint8_t alpha) {
   if (alpha_ != alpha) {
     alpha_ = alpha;
-    UpdateRenderingDamage(display_frame_, display_frame_, true);
   }
 }
 
 void HwcLayer::SetBlending(HWCBlending blending) {
   if (blending != blending_) {
     blending_ = blending;
-    UpdateRenderingDamage(display_frame_, display_frame_, true);
   }
 }
 
@@ -84,11 +81,11 @@ void HwcLayer::SetDisplayFrame(const HwcRect<int>& display_frame,
     frame.right += translate_x_pos;
     frame.top += translate_y_pos;
     frame.bottom += translate_y_pos;
-    UpdateRenderingDamage(display_frame_, frame, false);
 
     display_frame_ = frame;
     display_frame_width_ = display_frame_.right - display_frame_.left;
     display_frame_height_ = display_frame_.bottom - display_frame_.top;
+    damage_dirty_ = true;
   }
 
   if (!(state_ & kVisibleRegionSet)) {
@@ -106,8 +103,10 @@ void HwcLayer::SetSurfaceDamage(const HwcRegion& surface_damage) {
         (rect.right == 0)) {
       state_ &= ~kLayerContentChanged;
       state_ &= ~kSurfaceDamageChanged;
-      UpdateRenderingDamage(rect, rect, true);
-      surface_damage_.reset();
+      if (!surface_damage_.empty()) {
+        damage_dirty_ = true;
+        surface_damage_.reset();
+      }
       return;
     }
   } else if (rects == 0) {
@@ -122,8 +121,8 @@ void HwcLayer::SetSurfaceDamage(const HwcRegion& surface_damage) {
   }
 
   state_ |= kSurfaceDamageChanged;
+  damage_dirty_ = true;
 
-  UpdateRenderingDamage(surface_damage_, rect, false);
   surface_damage_ = rect;
 }
 
@@ -150,7 +149,7 @@ void HwcLayer::SetVisibleRegion(const HwcRegion& visible_region) {
   }
 
   state_ |= kVisibleRegionChanged;
-  UpdateRenderingDamage(visible_rect_, new_visible_rect, false);
+  damage_dirty_ = true;
   visible_rect_ = new_visible_rect;
 
   if ((visible_rect_.top == 0) && (visible_rect_.bottom == 0) &&
@@ -201,22 +200,6 @@ void HwcLayer::Validate() {
     layer_cache_ &= ~kLayerAttributesChanged;
     layer_cache_ &= ~kDisplayFrameRectChanged;
     layer_cache_ &= ~kSourceRectChanged;
-
-    // From observation: In Android, when the source crop doesn't
-    // begin from (0, 0) the surface damage is already translated
-    // to global display co-ordinates
-    if (!surface_damage_.empty() &&
-        ((source_crop_.left == 0) && (source_crop_.top == 0))) {
-      current_rendering_damage_.left =
-          surface_damage_.left + display_frame_.left;
-      current_rendering_damage_.top = surface_damage_.top + display_frame_.top;
-      current_rendering_damage_.right =
-          surface_damage_.right + display_frame_.left;
-      current_rendering_damage_.bottom =
-          surface_damage_.bottom + display_frame_.top;
-    } else {
-      current_rendering_damage_ = surface_damage_;
-    }
   }
 
   if (left_constraint_.empty() && left_source_constraint_.empty())
@@ -243,7 +226,6 @@ void HwcLayer::SetLayerZOrder(uint32_t order) {
   if (z_order_ != static_cast<int>(order)) {
     z_order_ = order;
     state_ |= kZorderChanged;
-    UpdateRenderingDamage(display_frame_, visible_rect_, false);
   }
 }
 
@@ -343,22 +325,33 @@ bool HwcLayer::IsCursorLayer() const {
   return is_cursor_layer_;
 }
 
-void HwcLayer::UpdateRenderingDamage(const HwcRect<int>& old_rect,
-                                     const HwcRect<int>& newrect,
-                                     bool same_rect) {
-  if (current_rendering_damage_.empty()) {
-    current_rendering_damage_ = old_rect;
+const HwcRect<int>& HwcLayer::GetLayerDamage() {
+  if (!damage_dirty_) {
+    return current_rendering_damage_;
+  }
+
+  current_rendering_damage_.reset();
+
+  // From observation: In Android, when the source crop doesn't
+  // begin from (0, 0) the surface damage is already translated
+  // to global display co-ordinates
+  if (!surface_damage_.empty() &&
+      ((source_crop_.left == 0) && (source_crop_.top == 0))) {
+    // XXX/TODO: Apply other transformations here like rotation and scaling
+    // and remove the corresponding workarounds in overlaylayer.cpp
+    current_rendering_damage_ =
+        TranslateRect(surface_damage_, display_frame_.left, display_frame_.top);
   } else {
-    CalculateRect(old_rect, current_rendering_damage_);
+    current_rendering_damage_ = surface_damage_;
   }
 
-  if (same_rect)
-    return;
+  if (state_ & kVisibleRegionSet) {
+    current_rendering_damage_ =
+        Intersection(current_rendering_damage_, visible_rect_);
+  }
 
-  CalculateRect(newrect, current_rendering_damage_);
-}
+  damage_dirty_ = false;
 
-const HwcRect<int>& HwcLayer::GetLayerDamage() {
   return current_rendering_damage_;
 }
 
index e713739..c0ee229 100644 (file)
@@ -255,9 +255,6 @@ struct HwcLayer {
 
  private:
   void Validate();
-  void UpdateRenderingDamage(const HwcRect<int>& old_rect,
-                             const HwcRect<int>& newrect, bool same_rect);
-
   void SetTotalDisplays(uint32_t total_displays);
   friend class VirtualDisplay;
   friend class PhysicalDisplay;
@@ -304,6 +301,7 @@ struct HwcLayer {
       kVisible | kSurfaceDamageChanged | kVisibleRegionChanged | kZorderChanged;
   int layer_cache_ = kLayerAttributesChanged | kDisplayFrameRectChanged;
   bool is_cursor_layer_ = false;
+  bool damage_dirty_ = true;
 };
 
 }  // namespace hwcomposer
index 4142a04..fc3ca92 100644 (file)
@@ -88,6 +88,43 @@ inline OverlapType AnalyseOverlap(const hwcomposer::HwcRect<int>& rect,
   }
 }
 
+inline HwcRect<int> TranslateRect(HwcRect<int> rect, int x, int y) {
+  HwcRect<int> ret;
+  ret.left = rect.left + x;
+  ret.right = rect.right + x;
+  ret.top = rect.top + y;
+  ret.bottom = rect.bottom + y;
+  return ret;
+}
+
+inline HwcRect<int> Intersection(const hwcomposer::HwcRect<int>& rect1,
+                                 const hwcomposer::HwcRect<int>& rect2) {
+  HwcRect<int> rect = {0, 0, 0, 0};
+
+  int lmax = std::max(rect1.left, rect2.left);
+  int rmax = std::max(rect1.right, rect2.right);
+  int tmax = std::max(rect1.top, rect2.top);
+  int bmax = std::max(rect1.bottom, rect2.bottom);
+
+  int lmin = std::min(rect1.left, rect2.left);
+  int rmin = std::min(rect1.right, rect2.right);
+  int tmin = std::min(rect1.top, rect2.top);
+  int bmin = std::min(rect1.bottom, rect2.bottom);
+
+  if (lmax == rmax || tmax == bmax)
+    return rect;
+
+  if (lmin == rmin || tmin == bmin)
+    return rect;
+
+  rect.left = lmax;
+  rect.right = rmin;
+  rect.top = tmax;
+  rect.bottom = bmin;
+
+  return rect;
+}
+
 /**
  * Pretty-print HwcRect for debugging.
  */