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

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

Powered by Google App Engine
This is Rietveld 408576698