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);
}
}
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)) {
(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) {
}
state_ |= kSurfaceDamageChanged;
+ damage_dirty_ = true;
- UpdateRenderingDamage(surface_damage_, rect, false);
surface_damage_ = rect;
}
}
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) &&
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())
if (z_order_ != static_cast<int>(order)) {
z_order_ = order;
state_ |= kZorderChanged;
- UpdateRenderingDamage(display_frame_, visible_rect_, false);
}
}
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_;
}
}
}
+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.
*/