Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: third_party/WebKit/Source/core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h

Issue 2732573003: Skip paint property update and visual rect update if no geometry change (Closed)
Patch Set: - Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FindPaintOffsetAndVisualRectNeedingUpdate_h
6 #define FindPaintOffsetAndVisualRectNeedingUpdate_h
7
8 #if DCHECK_IS_ON()
9
10 #include "core/layout/LayoutObject.h"
11 #include "core/paint/FindPropertiesNeedingUpdate.h"
12 #include "core/paint/ObjectPaintInvalidator.h"
13 #include "core/paint/PaintInvalidator.h"
14 #include "core/paint/PaintLayer.h"
15 #include "core/paint/PaintPropertyTreeBuilder.h"
16
17 namespace blink {
18
19 // This file contains scope classes for catching cases where paint offset or
20 // visual rect needed an update but were not marked as such. If paint offset or
21 // any visual rect (including visual rect of the object itself, scroll controls,
22 // caret, selection, etc.) will change, the object must be marked as such by
23 // LayoutObject::setNeedsPaintOffsetAndVisualRectUpdate() (which is a private
24 // function called by several public paint-invalidation-flag setting functions).
25
26 class FindPaintOffsetNeedingUpdateScope {
27 public:
28 FindPaintOffsetNeedingUpdateScope(
29 const LayoutObject& object,
30 const PaintPropertyTreeBuilderContext& context)
31 : m_object(object),
32 m_context(context),
33 m_oldPaintOffset(object.paintOffset()) {
34 if (object.paintProperties() &&
35 object.paintProperties()->paintOffsetTranslation()) {
36 m_oldPaintOffsetTranslation =
37 object.paintProperties()->paintOffsetTranslation()->clone();
38 }
39 }
40
41 ~FindPaintOffsetNeedingUpdateScope() {
42 if (m_context.isActuallyNeeded)
43 return;
44 DCHECK_OBJECT_PROPERTY_EQ(m_object, &m_oldPaintOffset,
45 &m_object.paintOffset());
46 const auto* paintOffsetTranslation =
47 m_object.paintProperties()
48 ? m_object.paintProperties()->paintOffsetTranslation()
49 : nullptr;
50 DCHECK_OBJECT_PROPERTY_EQ(m_object, m_oldPaintOffsetTranslation.get(),
51 paintOffsetTranslation);
52 }
53
54 private:
55 const LayoutObject& m_object;
56 const PaintPropertyTreeBuilderContext& m_context;
57 LayoutPoint m_oldPaintOffset;
58 RefPtr<const TransformPaintPropertyNode> m_oldPaintOffsetTranslation;
59 };
60
61 class FindVisualRectNeedingUpdateScopeBase {
62 protected:
63 FindVisualRectNeedingUpdateScopeBase(const LayoutObject& object,
64 const PaintInvalidatorContext& context,
65 const LayoutRect& oldVisualRect)
66 : m_object(object),
67 m_context(context),
68 m_oldVisualRect(oldVisualRect),
69 m_neededVisualRectUpdate(context.needsVisualRectUpdate(object)) {
70 if (m_neededVisualRectUpdate) {
71 DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ||
72 (context.m_treeBuilderContext &&
73 context.m_treeBuilderContext->isActuallyNeeded));
74 return;
75 }
76 context.m_forceVisualRectUpdateForChecking = true;
77 DCHECK(context.needsVisualRectUpdate(object));
78 }
79
80 ~FindVisualRectNeedingUpdateScopeBase() {
81 m_context.m_forceVisualRectUpdateForChecking = false;
82 DCHECK_EQ(m_neededVisualRectUpdate,
83 m_context.needsVisualRectUpdate(m_object));
84 }
85
86 static LayoutRect inflatedRect(const LayoutRect& r) {
87 LayoutRect result = r;
88 result.inflate(1);
89 return result;
90 }
91
92 void checkVisualRect(const LayoutRect& newVisualRect) {
93 if (m_neededVisualRectUpdate)
94 return;
95 DCHECK((m_oldVisualRect.isEmpty() && newVisualRect.isEmpty()) ||
96 m_object.enclosingLayer()->subtreeIsInvisible() ||
97 m_oldVisualRect == newVisualRect ||
98 // The following check is to tolerate the differences caused by
99 // pixel snapping that may happen for one rect but not for another
100 // while we need neither paint invalidation nor raster invalidation
101 // for the change. This may miss some real subpixel changes of visual
102 // rects. TODO(wangxianzhu): Look into whether we can tighten this
103 // for SPv2.
104 inflatedRect(m_oldVisualRect).contains(newVisualRect) ||
105 inflatedRect(newVisualRect).contains(m_oldVisualRect))
106 << "Visual rect changed without needing update"
107 << " object=" << m_object.debugName()
108 << " old=" << m_oldVisualRect.toString()
109 << " new=" << newVisualRect.toString();
110 }
111
112 const LayoutObject& m_object;
113 const PaintInvalidatorContext& m_context;
114 LayoutRect m_oldVisualRect;
115 bool m_neededVisualRectUpdate;
116 };
117
118 // For updates of visual rects (e.g. of scroll controls, caret, selection,etc.)
119 // contained by an object.
120 class FindVisualRectNeedingUpdateScope : FindVisualRectNeedingUpdateScopeBase {
121 public:
122 FindVisualRectNeedingUpdateScope(const LayoutObject& object,
123 const PaintInvalidatorContext& context,
124 const LayoutRect& oldVisualRect,
125 // Must be a reference to a rect that
126 // outlives this scope.
127 const LayoutRect& newVisualRect)
128 : FindVisualRectNeedingUpdateScopeBase(object, context, oldVisualRect),
129 m_newVisualRectRef(newVisualRect) {}
130
131 ~FindVisualRectNeedingUpdateScope() { checkVisualRect(m_newVisualRectRef); }
132
133 private:
134 const LayoutRect& m_newVisualRectRef;
135 };
136
137 // For updates of object visual rect and location.
138 class FindObjectVisualRectNeedingUpdateScope
139 : FindVisualRectNeedingUpdateScopeBase {
140 public:
141 FindObjectVisualRectNeedingUpdateScope(const LayoutObject& object,
142 const PaintInvalidatorContext& context)
143 : FindVisualRectNeedingUpdateScopeBase(object,
144 context,
145 object.visualRect()),
146 m_oldLocation(ObjectPaintInvalidator(object).locationInBacking()) {}
147
148 ~FindObjectVisualRectNeedingUpdateScope() {
149 checkVisualRect(m_object.visualRect());
150 checkLocation();
151 }
152
153 void checkLocation() {
154 if (m_neededVisualRectUpdate)
155 return;
156 LayoutPoint newLocation =
157 ObjectPaintInvalidator(m_object).locationInBacking();
158 // Location of LayoutText and non-root SVG is location of the visual rect
159 // which have been checked above.
160 DCHECK(m_object.isText() || m_object.isSVGChild() ||
161 newLocation == m_oldLocation ||
162 m_object.enclosingLayer()->subtreeIsInvisible() ||
163 // See checkVisualRect for the issue of approximation.
164 LayoutRect(-1, -1, 2, 2)
165 .contains(LayoutRect(LayoutPoint(newLocation - m_oldLocation),
166 LayoutSize())))
167 << "Location changed without needing update"
168 << " object=" << m_object.debugName()
169 << " old=" << m_oldLocation.toString()
170 << " new=" << newLocation.toString();
171 }
172
173 private:
174 LayoutPoint m_oldLocation;
175 };
176
177 } // namespace blink
178
179 #endif // DCHECK_IS_ON()
180
181 #endif // FindPaintOffsetAndVisualRectNeedingUpdate_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698