From: Harish Krupo Date: Fri, 1 Jun 2018 08:32:22 +0000 (+0530) Subject: Apply damage transformations in GetLayerDamage X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=145bf9c5853cb5b0de0136a076d1a8b9b0b1c8dc;p=android-x86%2Fexternal-IA-Hardware-Composer.git Apply damage transformations in GetLayerDamage 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 --- diff --git a/common/core/hwclayer.cpp b/common/core/hwclayer.cpp index 6dab385..5f36612 100644 --- a/common/core/hwclayer.cpp +++ b/common/core/hwclayer.cpp @@ -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& 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(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& old_rect, - const HwcRect& newrect, - bool same_rect) { - if (current_rendering_damage_.empty()) { - current_rendering_damage_ = old_rect; +const HwcRect& 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& HwcLayer::GetLayerDamage() { return current_rendering_damage_; } diff --git a/public/hwclayer.h b/public/hwclayer.h index e713739..c0ee229 100644 --- a/public/hwclayer.h +++ b/public/hwclayer.h @@ -255,9 +255,6 @@ struct HwcLayer { private: void Validate(); - void UpdateRenderingDamage(const HwcRect& old_rect, - const HwcRect& 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 diff --git a/public/hwcutils.h b/public/hwcutils.h index 4142a04..fc3ca92 100644 --- a/public/hwcutils.h +++ b/public/hwcutils.h @@ -88,6 +88,43 @@ inline OverlapType AnalyseOverlap(const hwcomposer::HwcRect& rect, } } +inline HwcRect TranslateRect(HwcRect rect, int x, int y) { + HwcRect 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 Intersection(const hwcomposer::HwcRect& rect1, + const hwcomposer::HwcRect& rect2) { + HwcRect 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. */