summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc131
1 files changed, 101 insertions, 30 deletions
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
index 325f8c5af37..a79f58d730d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -6,31 +6,25 @@
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
+#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h"
+#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
namespace blink {
-CullRect::CullRect(const CullRect& cull_rect, const IntPoint& offset) {
- rect_ = cull_rect.rect_;
- rect_.MoveBy(offset);
+bool CullRect::Intersects(const IntRect& rect) const {
+ return IsInfinite() || rect.Intersects(rect_);
}
-CullRect::CullRect(const CullRect& cull_rect, const IntSize& offset) {
- rect_ = cull_rect.rect_;
- rect_.Move(offset);
+bool CullRect::Intersects(const LayoutRect& rect) const {
+ return IsInfinite() || rect_.Intersects(EnclosingIntRect(rect));
}
-bool CullRect::IntersectsCullRect(const IntRect& bounding_box) const {
- return bounding_box.Intersects(rect_);
-}
-
-bool CullRect::IntersectsCullRect(const AffineTransform& transform,
- const FloatRect& bounding_box) const {
- return transform.MapRect(bounding_box).Intersects(rect_);
-}
-
-bool CullRect::IntersectsCullRect(const LayoutRect& rect_arg) const {
- return rect_.Intersects(EnclosingIntRect(rect_arg));
+bool CullRect::IntersectsTransformed(const AffineTransform& transform,
+ const FloatRect& rect) const {
+ return IsInfinite() || transform.MapRect(rect).Intersects(rect_);
}
bool CullRect::IntersectsHorizontalRange(LayoutUnit lo, LayoutUnit hi) const {
@@ -41,23 +35,100 @@ bool CullRect::IntersectsVerticalRange(LayoutUnit lo, LayoutUnit hi) const {
return !(lo >= rect_.MaxY() || hi <= rect_.Y());
}
-void CullRect::UpdateCullRect(
- const AffineTransform& local_to_parent_transform) {
- if (rect_ != LayoutRect::InfiniteIntRect())
- rect_ = local_to_parent_transform.Inverse().MapRect(rect_);
+void CullRect::MoveBy(const IntPoint& offset) {
+ if (!IsInfinite())
+ rect_.MoveBy(offset);
+}
+
+void CullRect::Move(const IntSize& offset) {
+ if (!IsInfinite())
+ rect_.Move(offset);
+}
+
+CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
+ const TransformPaintPropertyNode* transform) {
+ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (const auto* scroll = transform->ScrollNode()) {
+ rect_.Intersect(scroll->ContainerRect());
+ if (rect_.IsEmpty())
+ return kNotExpanded;
+ rect_ = transform->Matrix().Inverse().MapRect(rect_);
+
+ // Expand the cull rect for scrolling contents in case of composited
+ // scrolling.
+ // TODO(wangxianzhu): options for non-composited-scrolling contents:
+ // 1. to use non-composted-scrolling heuristics to avoid expansion;
+ // 2. to reduce the 4000px distance, no matter if the contents with be
+ // composited scrolling.
+ // 3. mixed method of 1 and 2, e.g. the distance could be a function of
+ // confidence that the contents will be composited scrolling.
+ static const int kPixelDistanceToExpand = 4000;
+ rect_.Inflate(kPixelDistanceToExpand);
+ // Don't clip the cull rect by contents size to let ChangedEnough() work
+ // even if the new cull rect exceeds the bounds of contents rect.
+ return rect_.Contains(IntRect(IntPoint(), scroll->ContentsSize()))
+ ? kExpandedForWholeScrollingContents
+ : kExpandedForPartialScrollingContents;
+ }
+ }
+
+ if (!IsInfinite())
+ rect_ = transform->Matrix().Inverse().MapRect(rect_);
+ return kNotExpanded;
}
-void CullRect::UpdateForScrollingContents(
- const IntRect& overflow_clip_rect,
- const AffineTransform& local_to_parent_transform) {
+void CullRect::ApplyTransforms(const TransformPaintPropertyNode* source,
+ const TransformPaintPropertyNode* destination,
+ const base::Optional<CullRect>& old_cull_rect) {
DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
- rect_.Intersect(overflow_clip_rect);
- UpdateCullRect(local_to_parent_transform);
- // TODO(wangxianzhu, chrishtr): How about non-composited scrolling contents?
- // The distance to expand the cull rect for scrolling contents.
- static const int kPixelDistanceToExpand = 4000;
- rect_.Inflate(kPixelDistanceToExpand);
+ Vector<const TransformPaintPropertyNode*> scroll_translations;
+ for (const auto* t = destination; t != source; t = t->Parent()) {
+ if (!t) {
+ // |source| is not an ancestor of |destination|. Simply map.
+ GeometryMapper::SourceToDestinationRect(source, destination, rect_);
+ return;
+ }
+ if (t->ScrollNode())
+ scroll_translations.push_back(t);
+ }
+
+ const auto* last_transform = source;
+ ApplyTransformResult last_scroll_translation_result = kNotExpanded;
+ for (auto it = scroll_translations.rbegin(); it != scroll_translations.rend();
+ ++it) {
+ const auto* scroll_translation = *it;
+ if (!IsInfinite()) {
+ GeometryMapper::SourceToDestinationRect(
+ last_transform, scroll_translation->Parent(), rect_);
+ }
+ last_scroll_translation_result = ApplyTransformInternal(scroll_translation);
+ last_transform = scroll_translation;
+ }
+
+ if (!IsInfinite())
+ GeometryMapper::SourceToDestinationRect(last_transform, destination, rect_);
+
+ if (last_scroll_translation_result == kExpandedForPartialScrollingContents &&
+ old_cull_rect && !ChangedEnough(*old_cull_rect))
+ rect_ = old_cull_rect->Rect();
+}
+
+bool CullRect::ChangedEnough(const CullRect& old_cull_rect) const {
+ DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+
+ const auto& new_rect = Rect();
+ const auto& old_rect = old_cull_rect.Rect();
+ if (old_rect == new_rect || (old_rect.IsEmpty() && new_rect.IsEmpty()))
+ return false;
+
+ if (old_rect.IsEmpty())
+ return true;
+
+ auto expanded_old_rect = old_rect;
+ static const int kChangedEnoughMinimumDistance = 512;
+ expanded_old_rect.Inflate(kChangedEnoughMinimumDistance);
+ return !expanded_old_rect.Contains(new_rect);
}
} // namespace blink