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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp

Issue 2678263002: Plumb border radius through when computing clip visual rects. (Closed)
Patch Set: none Created 3 years, 10 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/graphics/paint/GeometryMapper.h" 5 #include "platform/graphics/paint/GeometryMapper.h"
6 6
7 #include "platform/RuntimeEnabledFeatures.h" 7 #include "platform/RuntimeEnabledFeatures.h"
8 #include "platform/geometry/LayoutRect.h" 8 #include "platform/geometry/LayoutRect.h"
9 9
10 namespace blink { 10 namespace blink {
11 11
12 FloatRect GeometryMapper::sourceToDestinationVisualRect( 12 FloatClipRect GeometryMapper::sourceToDestinationVisualRect(
13 const FloatRect& rect, 13 const FloatRect& rect,
14 const PropertyTreeState& sourceState, 14 const PropertyTreeState& sourceState,
15 const PropertyTreeState& destinationState) { 15 const PropertyTreeState& destinationState) {
16 bool success = false; 16 bool success = false;
17 FloatRect result = sourceToDestinationVisualRectInternal( 17 FloatClipRect result = sourceToDestinationVisualRectInternal(
18 rect, sourceState, destinationState, success); 18 rect, sourceState, destinationState, success);
19 DCHECK(success); 19 DCHECK(success);
20 return result; 20 return result;
21 } 21 }
22 22
23 FloatRect GeometryMapper::sourceToDestinationVisualRectInternal( 23 FloatClipRect GeometryMapper::sourceToDestinationVisualRectInternal(
24 const FloatRect& rect, 24 const FloatRect& rect,
25 const PropertyTreeState& sourceState, 25 const PropertyTreeState& sourceState,
26 const PropertyTreeState& destinationState, 26 const PropertyTreeState& destinationState,
27 bool& success) { 27 bool& success) {
28 FloatRect result = localToAncestorVisualRectInternal( 28 FloatClipRect result = localToAncestorVisualRectInternal(
29 rect, sourceState, destinationState, success); 29 rect, sourceState, destinationState, success);
30 // Success if destinationState is an ancestor state. 30 // Success if destinationState is an ancestor state.
31 if (success) 31 if (success)
32 return result; 32 return result;
33 33
34 // Otherwise first map to the lowest common ancestor, then map to destination. 34 // Otherwise first map to the lowest common ancestor, then map to destination.
35 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( 35 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor(
36 sourceState.transform(), destinationState.transform()); 36 sourceState.transform(), destinationState.transform());
37 DCHECK(lcaTransform); 37 DCHECK(lcaTransform);
38 38
39 // Assume that the clip of destinationState is an ancestor of the clip of 39 // Assume that the clip of destinationState is an ancestor of the clip of
40 // sourceState and is under the space of lcaTransform. Otherwise 40 // sourceState and is under the space of lcaTransform. Otherwise
41 // localToAncestorVisualRect() will fail. 41 // localToAncestorVisualRect() will fail.
42 PropertyTreeState lcaState = destinationState; 42 PropertyTreeState lcaState = destinationState;
43 lcaState.setTransform(lcaTransform); 43 lcaState.setTransform(lcaTransform);
44 44
45 FloatRect lcaVisualRect = 45 result =
46 localToAncestorVisualRectInternal(rect, sourceState, lcaState, success); 46 localToAncestorVisualRectInternal(rect, sourceState, lcaState, success);
47 if (!success) 47 if (!success)
48 return lcaVisualRect; 48 return result;
49 return ancestorToLocalRect(lcaVisualRect, lcaTransform, 49 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform,
50 destinationState.transform()); 50 destinationState.transform());
51 result.setRect(final);
52 return result;
51 } 53 }
52 54
53 FloatRect GeometryMapper::sourceToDestinationRect( 55 FloatRect GeometryMapper::sourceToDestinationRect(
54 const FloatRect& rect, 56 const FloatRect& rect,
55 const TransformPaintPropertyNode* sourceTransformNode, 57 const TransformPaintPropertyNode* sourceTransformNode,
56 const TransformPaintPropertyNode* destinationTransformNode) { 58 const TransformPaintPropertyNode* destinationTransformNode) {
57 bool success = false; 59 bool success = false;
58 FloatRect result = localToAncestorRectInternal( 60 FloatRect result = localToAncestorRectInternal(
59 rect, sourceTransformNode, destinationTransformNode, success); 61 rect, sourceTransformNode, destinationTransformNode, success);
60 // Success if destinationTransformNode is an ancestor of sourceTransformNode. 62 // Success if destinationTransformNode is an ancestor of sourceTransformNode.
61 if (success) 63 if (success)
62 return result; 64 return result;
63 65
64 // Otherwise first map to the least common ancestor, then map to destination. 66 // Otherwise first map to the least common ancestor, then map to destination.
65 const TransformPaintPropertyNode* lcaTransform = 67 const TransformPaintPropertyNode* lcaTransform =
66 lowestCommonAncestor(sourceTransformNode, destinationTransformNode); 68 lowestCommonAncestor(sourceTransformNode, destinationTransformNode);
67 DCHECK(lcaTransform); 69 DCHECK(lcaTransform);
68 70
69 FloatRect lcaRect = 71 FloatRect lcaRect =
70 localToAncestorRect(rect, sourceTransformNode, lcaTransform); 72 localToAncestorRect(rect, sourceTransformNode, lcaTransform);
71 return ancestorToLocalRect(lcaRect, lcaTransform, destinationTransformNode); 73 return ancestorToLocalRect(lcaRect, lcaTransform, destinationTransformNode);
72 } 74 }
73 75
74 FloatRect GeometryMapper::localToAncestorVisualRect( 76 FloatClipRect GeometryMapper::localToAncestorVisualRect(
75 const FloatRect& rect, 77 const FloatRect& rect,
76 const PropertyTreeState& localState, 78 const PropertyTreeState& localState,
77 const PropertyTreeState& ancestorState) { 79 const PropertyTreeState& ancestorState) {
78 bool success = false; 80 bool success = false;
79 FloatRect result = localToAncestorVisualRectInternal(rect, localState, 81 FloatClipRect result = localToAncestorVisualRectInternal(
80 ancestorState, success); 82 rect, localState, ancestorState, success);
81 DCHECK(success); 83 DCHECK(success);
82 return result; 84 return result;
83 } 85 }
84 86
85 FloatRect GeometryMapper::localToAncestorVisualRectInternal( 87 FloatClipRect GeometryMapper::localToAncestorVisualRectInternal(
86 const FloatRect& rect, 88 const FloatRect& rect,
87 const PropertyTreeState& localState, 89 const PropertyTreeState& localState,
88 const PropertyTreeState& ancestorState, 90 const PropertyTreeState& ancestorState,
89 bool& success) { 91 bool& success) {
90 if (localState == ancestorState) { 92 if (localState == ancestorState) {
91 success = true; 93 success = true;
92 return rect; 94 return rect;
93 } 95 }
94 96
95 const auto& transformMatrix = localToAncestorMatrixInternal( 97 const auto& transformMatrix = localToAncestorMatrixInternal(
96 localState.transform(), ancestorState.transform(), success); 98 localState.transform(), ancestorState.transform(), success);
97 if (!success) 99 if (!success)
98 return rect; 100 return rect;
99 101
100 FloatRect mappedRect = transformMatrix.mapRect(rect); 102 FloatRect mappedRect = transformMatrix.mapRect(rect);
101 103
102 const auto clipRect = 104 FloatClipRect clipRect =
103 localToAncestorClipRectInternal(localState, ancestorState, success); 105 localToAncestorClipRectInternal(localState, ancestorState, success);
104 106
105 if (success) { 107 if (success) {
106 mappedRect.intersect(clipRect); 108 clipRect.intersect(mappedRect);
107 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 109 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
108 // On SPv1 we may fail when the paint invalidation container creates an 110 // On SPv1 we may fail when the paint invalidation container creates an
109 // overflow clip (in ancestorState) which is not in localState of an 111 // overflow clip (in ancestorState) which is not in localState of an
110 // out-of-flow positioned descendant. See crbug.com/513108 and layout test 112 // out-of-flow positioned descendant. See crbug.com/513108 and layout test
111 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with 113 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with
112 // --enable-prefer-compositing-to-lcd-text) for details. 114 // --enable-prefer-compositing-to-lcd-text) for details.
113 // Ignore it for SPv1 for now. 115 // Ignore it for SPv1 for now.
114 success = true; 116 success = true;
115 } 117 }
116 118
117 return mappedRect; 119 return clipRect;
118 } 120 }
119 121
120 FloatRect GeometryMapper::localToAncestorRect( 122 FloatRect GeometryMapper::localToAncestorRect(
121 const FloatRect& rect, 123 const FloatRect& rect,
122 const TransformPaintPropertyNode* localTransformNode, 124 const TransformPaintPropertyNode* localTransformNode,
123 const TransformPaintPropertyNode* ancestorTransformNode) { 125 const TransformPaintPropertyNode* ancestorTransformNode) {
124 bool success = false; 126 bool success = false;
125 FloatRect result = localToAncestorRectInternal( 127 FloatRect result = localToAncestorRectInternal(
126 rect, localTransformNode, ancestorTransformNode, success); 128 rect, localTransformNode, ancestorTransformNode, success);
127 DCHECK(success); 129 DCHECK(success);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 const ClipPaintPropertyNode* clip) { 180 const ClipPaintPropertyNode* clip) {
179 PrecomputedDataForAncestor& precomputedData = 181 PrecomputedDataForAncestor& precomputedData =
180 getPrecomputedDataForAncestor(transform); 182 getPrecomputedDataForAncestor(transform);
181 183
182 auto addResult = precomputedData.precomputedClips.insert(clip, nullptr); 184 auto addResult = precomputedData.precomputedClips.insert(clip, nullptr);
183 if (addResult.isNewEntry) 185 if (addResult.isNewEntry)
184 addResult.storedValue->value = WTF::makeUnique<ClipCache>(); 186 addResult.storedValue->value = WTF::makeUnique<ClipCache>();
185 return *addResult.storedValue->value; 187 return *addResult.storedValue->value;
186 } 188 }
187 189
188 FloatRect GeometryMapper::localToAncestorClipRect( 190 FloatClipRect GeometryMapper::localToAncestorClipRect(
189 const PropertyTreeState& localState, 191 const PropertyTreeState& localState,
190 const PropertyTreeState& ancestorState) { 192 const PropertyTreeState& ancestorState) {
191 bool success = false; 193 bool success = false;
192 FloatRect result = 194 FloatClipRect result =
193 localToAncestorClipRectInternal(localState, ancestorState, success); 195 localToAncestorClipRectInternal(localState, ancestorState, success);
194 DCHECK(success); 196 DCHECK(success);
195 return result; 197 return result;
196 } 198 }
197 199
198 FloatRect GeometryMapper::localToAncestorClipRectInternal( 200 FloatClipRect GeometryMapper::localToAncestorClipRectInternal(
199 const PropertyTreeState& localState, 201 const PropertyTreeState& localState,
200 const PropertyTreeState& ancestorState, 202 const PropertyTreeState& ancestorState,
201 bool& success) { 203 bool& success) {
202 FloatRect clip(LayoutRect::infiniteIntRect()); 204 FloatClipRect clip(LayoutRect::infiniteIntRect());
203 if (localState.clip() == ancestorState.clip()) { 205 if (localState.clip() == ancestorState.clip()) {
204 success = true; 206 success = true;
205 return clip; 207 return clip;
206 } 208 }
207 209
208 ClipCache& clipCache = 210 ClipCache& clipCache =
209 getClipCache(ancestorState.transform(), ancestorState.clip()); 211 getClipCache(ancestorState.transform(), ancestorState.clip());
210 const ClipPaintPropertyNode* clipNode = localState.clip(); 212 const ClipPaintPropertyNode* clipNode = localState.clip();
211 Vector<const ClipPaintPropertyNode*> intermediateNodes; 213 Vector<const ClipPaintPropertyNode*> intermediateNodes;
212 214
(...skipping 17 matching lines...) Expand all
230 // computing and memoizing clip rects as we go. 232 // computing and memoizing clip rects as we go.
231 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 233 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
232 ++it) { 234 ++it) {
233 success = false; 235 success = false;
234 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( 236 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal(
235 (*it)->localTransformSpace(), ancestorState.transform(), success); 237 (*it)->localTransformSpace(), ancestorState.transform(), success);
236 if (!success) 238 if (!success)
237 return clip; 239 return clip;
238 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); 240 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect());
239 clip.intersect(mappedRect); 241 clip.intersect(mappedRect);
242 if ((*it)->clipRect().isRounded())
243 clip.setHasRadius(true);
240 clipCache.set(*it, clip); 244 clipCache.set(*it, clip);
241 } 245 }
242 246
243 success = true; 247 success = true;
244 return clipCache.find(localState.clip())->value; 248 return clipCache.find(localState.clip())->value;
245 } 249 }
246 250
247 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 251 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
248 const TransformPaintPropertyNode* localTransformNode, 252 const TransformPaintPropertyNode* localTransformNode,
249 const TransformPaintPropertyNode* ancestorTransformNode) { 253 const TransformPaintPropertyNode* ancestorTransformNode) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 const TransformPaintPropertyNode*, 358 const TransformPaintPropertyNode*,
355 const TransformPaintPropertyNode*); 359 const TransformPaintPropertyNode*);
356 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 360 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
357 const ClipPaintPropertyNode*, 361 const ClipPaintPropertyNode*,
358 const ClipPaintPropertyNode*); 362 const ClipPaintPropertyNode*);
359 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 363 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
360 const ScrollPaintPropertyNode*, 364 const ScrollPaintPropertyNode*,
361 const ScrollPaintPropertyNode*); 365 const ScrollPaintPropertyNode*);
362 366
363 } // namespace blink 367 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698