Commit 66eaa4ab authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Prepare LayoutShiftTracker for removal of FragmentData::VisualRect()

Add FragmentData::VisualRectIn2DTranslationRoot() for
LayoutShiftTracker. It's currently based on FragmentData::VisualRect()
and OffsetTo2DTranslationRoot(). When we remove VisualRect(), we'll
remove FragmentData::visual_rect_ and offset_to_2d_translation_root_,
and store visual_rect_in_2d_translation_root_ only. We don't need any
more change to LayoutShiftTracker when we remove Fragment::VisualRect().

Bug: 1107724
Change-Id: I8f6f7bfe8677180a2062fb7f67f73ff7ca6ce1b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2311676Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791082}
parent 79b3038c
......@@ -124,13 +124,10 @@ void LayoutShiftTracker::ObjectShifted(
const LayoutObject& source,
const PropertyTreeStateOrAlias& property_tree_state,
FloatRect old_rect,
FloatRect new_rect,
const FloatSize& paint_offset_delta) {
FloatRect new_rect) {
if (old_rect.IsEmpty() || new_rect.IsEmpty())
return;
old_rect.Move(paint_offset_delta);
if (EqualWithinMovementThreshold(LogicalStart(old_rect, source),
LogicalStart(new_rect, source), source))
return;
......@@ -279,14 +276,13 @@ void LayoutShiftTracker::MaybeRecordAttribution(
void LayoutShiftTracker::NotifyObjectPrePaint(
const LayoutObject& object,
const PropertyTreeStateOrAlias& property_tree_state,
const IntRect& old_visual_rect,
const IntRect& new_visual_rect,
const FloatSize& paint_offset_delta) {
const PhysicalRect& old_visual_rect,
const PhysicalRect& new_visual_rect) {
if (!IsActive())
return;
ObjectShifted(object, property_tree_state, FloatRect(old_visual_rect),
FloatRect(new_visual_rect), paint_offset_delta);
FloatRect(new_visual_rect));
}
double LayoutShiftTracker::SubframeWeightingFactor() const {
......
......@@ -17,12 +17,12 @@
namespace blink {
class IntRect;
class LayoutObject;
class LocalFrameView;
class PropertyTreeStateOrAlias;
class TracedValue;
class WebInputEvent;
struct PhysicalRect;
// Tracks "layout shifts" from layout objects changing their visual location
// between animation frames. See https://github.com/WICG/layout-instability.
......@@ -31,22 +31,24 @@ class CORE_EXPORT LayoutShiftTracker final
public:
explicit LayoutShiftTracker(LocalFrameView*);
~LayoutShiftTracker() = default;
// |paint_offset_diff| is an additional amount by which the paint offset
// shifted that is not tracked in visual rects. Visual rects are in the
// local transform space of the LayoutObject. Any time the transform space is
// changed, the offset of that rect to the "origin" is reset. This offset
// is also known as the paint offset.
// In cases where we can communicate paint offset diffs across transform
// space change boundaries, |paint_offset_diff| is how to do it. In
// particular, many transform spaces are artificial and are used as an
// implementation detail of compositing to make it easier to isolate state for
// composited layers. We can easily pass the paint offset diff across such
// boundaries.
// |old_visual_rect| and |new_visual_rect| are in the local transform space:
// |property_tree_state.Transform()|. As we don't save the old property tree
// state, the caller should adjust |old_rect| as if the difference between the
// old and the new local and ancestor transforms [1] caused the difference
// between the locations of |old_visual_rect| and |new_visual_rect|, so that
// we can calculate the shift caused by the changed transforms, in addition to
// the shift in the local transform space, by comparing locations of
// |old_visual_rect| and |new_visual_rect|.
//
// [1] We may stop at a certain ancestor transform and ignore changes of all
// higher transforms. This is how we ignore scrolls in layout shift tracking.
// We also can't accumulate offsets across non-2d-translation transforms.
// See PaintPropertyTreeBuilderFragmentContext::
// ContainingBlockContext::offset_to_2d_translation_root.
void NotifyObjectPrePaint(const LayoutObject& object,
const PropertyTreeStateOrAlias& property_tree_state,
const IntRect& old_visual_rect,
const IntRect& new_visual_rect,
const FloatSize& paint_offset_delta);
const PhysicalRect& old_visual_rect,
const PhysicalRect& new_visual_rect);
void NotifyPrePaintFinished();
void NotifyInput(const WebInputEvent&);
void NotifyScroll(mojom::blink::ScrollType, ScrollOffset delta);
......@@ -66,7 +68,6 @@ class CORE_EXPORT LayoutShiftTracker final
// rebuilt by Node::ReattachLayoutTree.
class ReattachHook : public GarbageCollected<ReattachHook> {
public:
ReattachHook() : scope_(nullptr) {}
void Trace(Visitor*) const;
class Scope {
......@@ -83,7 +84,7 @@ class CORE_EXPORT LayoutShiftTracker final
static void NotifyAttach(const Node&);
private:
Scope* scope_;
Scope* scope_ = nullptr;
HeapHashMap<Member<const Node>, IntRect> visual_rects_;
};
......@@ -91,8 +92,7 @@ class CORE_EXPORT LayoutShiftTracker final
void ObjectShifted(const LayoutObject&,
const PropertyTreeStateOrAlias&,
FloatRect old_rect,
FloatRect new_rect,
const FloatSize& paint_offset_delta);
FloatRect new_rect);
void ReportShift(double score_delta, double weighted_score_delta);
void TimerFired(TimerBase*) {}
std::unique_ptr<TracedValue> PerFrameTraceData(double score_delta,
......
......@@ -44,6 +44,15 @@ class CORE_EXPORT FragmentData {
offset_to_2d_translation_root_ = offset;
}
// This is for LayoutShiftTracker.
// TODO(crbug.com/1104064): Store this visual rect directly when we remove
// VisualRect().
PhysicalRect VisualRectIn2DTranslationRoot() const {
PhysicalRect rect(visual_rect_);
rect.Move(offset_to_2d_translation_root_);
return rect;
}
// The visual rect computed by the latest paint invalidation.
// It's location may be different from PaintOffset when there is visual (ink)
// overflow to the top and/or the left.
......
......@@ -230,7 +230,6 @@ void PaintInvalidator::UpdateVisualRect(const LayoutObject& object,
DCHECK(context.tree_builder_context_);
DCHECK(!pre_paint_info || &fragment_data == &pre_paint_info->fragment_data);
IntRect old_visual_rect = fragment_data.VisualRect();
IntRect new_visual_rect = ComputeVisualRect(object, pre_paint_info, context);
if (pre_paint_info && !object.IsBox()) {
DCHECK(object.IsInline());
......@@ -244,19 +243,23 @@ void PaintInvalidator::UpdateVisualRect(const LayoutObject& object,
DCHECK_EQ(context.tree_builder_context_->current.paint_offset,
fragment_data.PaintOffset());
}
fragment_data.SetVisualRect(new_visual_rect);
fragment_data.SetOffsetTo2DTranslationRoot(
context.tree_builder_context_->current.offset_to_2d_translation_root);
// Adjust old_visual_rect so that LayoutShiftTracker can see the change of
// offset caused by change of transforms below the 2d translation root.
PhysicalRect old_visual_rect = fragment_data.VisualRectIn2DTranslationRoot();
old_visual_rect.Move(
-context.tree_builder_context_->current.offset_to_2d_translation_root);
object.GetFrameView()->GetLayoutShiftTracker().NotifyObjectPrePaint(
object,
PropertyTreeStateOrAlias(
*context.tree_builder_context_->current.transform,
*context.tree_builder_context_->current.clip,
*context.tree_builder_context_->current_effect),
old_visual_rect, new_visual_rect,
FloatSize(context.old_offset_to_2d_translation_root -
fragment_data.OffsetTo2DTranslationRoot()));
old_visual_rect, PhysicalRect(new_visual_rect));
fragment_data.SetVisualRect(new_visual_rect);
fragment_data.SetOffsetTo2DTranslationRoot(
context.tree_builder_context_->current.offset_to_2d_translation_root);
// For performance, we ignore subpixel movement of composited layers for paint
// invalidation. This will result in imperfect pixel-snapped painting.
......@@ -326,12 +329,6 @@ bool PaintInvalidator::InvalidatePaint(
if (pre_paint_info) {
FragmentData& fragment_data = pre_paint_info->fragment_data;
if (!object.IsBox()) {
context.old_offset_to_2d_translation_root = PhysicalOffset();
} else {
context.old_offset_to_2d_translation_root =
fragment_data.OffsetTo2DTranslationRoot();
}
context.fragment_data = &fragment_data;
#if DCHECK_IS_ON()
......@@ -356,8 +353,6 @@ bool PaintInvalidator::InvalidatePaint(
for (auto* fragment_data = &object.GetMutableForPainting().FirstFragment();
fragment_data;
fragment_data = fragment_data->NextFragment(), tree_builder_index++) {
context.old_offset_to_2d_translation_root =
fragment_data->OffsetTo2DTranslationRoot();
context.fragment_data = fragment_data;
DCHECK(!tree_builder_context ||
......
......@@ -124,9 +124,8 @@ struct CORE_EXPORT PaintInvalidatorContext {
PaintLayer* painting_layer = nullptr;
// The previous PaintOffset and OffsetTo2DTranslationRoot of FragmentData.
// The previous PaintOffset of FragmentData.
PhysicalOffset old_paint_offset;
PhysicalOffset old_offset_to_2d_translation_root;
const FragmentData* fragment_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment