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

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

Issue 2802443002: Compute rounded-ness of visual rects (Closed)
Patch Set: none 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
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 const TransformationMatrix& GeometryMapper::identityMatrix() { 12 const TransformationMatrix& GeometryMapper::identityMatrix() {
13 DEFINE_STATIC_LOCAL(TransformationMatrix, identity, (TransformationMatrix())); 13 DEFINE_STATIC_LOCAL(TransformationMatrix, identity, (TransformationMatrix()));
14 return identity; 14 return identity;
15 } 15 }
16 16
17 const FloatClipRect& GeometryMapper::infiniteClip() { 17 const FloatClipRect& GeometryMapper::infiniteClip() {
18 DEFINE_STATIC_LOCAL(FloatClipRect, infinite, (FloatClipRect())); 18 DEFINE_STATIC_LOCAL(FloatClipRect, infinite, (FloatClipRect()));
19 return infinite; 19 return infinite;
20 } 20 }
21 21
22 FloatClipRect& GeometryMapper::tempRect() { 22 FloatClipRect& GeometryMapper::tempRect() {
23 DEFINE_STATIC_LOCAL(FloatClipRect, temp, (FloatClipRect())); 23 DEFINE_STATIC_LOCAL(FloatClipRect, temp, (FloatClipRect()));
24 return temp; 24 return temp;
25 } 25 }
26 26
27 void GeometryMapper::sourceToDestinationVisualRect( 27 void GeometryMapper::sourceToDestinationVisualRect(
28 const PropertyTreeState& sourceState, 28 const PropertyTreeState& sourceState,
29 const PropertyTreeState& destinationState, 29 const PropertyTreeState& destinationState,
30 FloatRect& rect) { 30 FloatClipRect& rect) {
31 bool success = false; 31 bool success = false;
32 sourceToDestinationVisualRectInternal(sourceState, destinationState, rect, 32 sourceToDestinationVisualRectInternal(sourceState, destinationState, rect,
33 success); 33 success);
34 DCHECK(success); 34 DCHECK(success);
35 } 35 }
36 36
37 void GeometryMapper::sourceToDestinationVisualRectInternal( 37 void GeometryMapper::sourceToDestinationVisualRectInternal(
38 const PropertyTreeState& sourceState, 38 const PropertyTreeState& sourceState,
39 const PropertyTreeState& destinationState, 39 const PropertyTreeState& destinationState,
40 FloatRect& mappingRect, 40 FloatClipRect& mappingRect,
41 bool& success) { 41 bool& success) {
42 localToAncestorVisualRectInternal(sourceState, destinationState, mappingRect, 42 localToAncestorVisualRectInternal(sourceState, destinationState, mappingRect,
43 success); 43 success);
44 // Success if destinationState is an ancestor state. 44 // Success if destinationState is an ancestor state.
45 if (success) 45 if (success)
46 return; 46 return;
47 47
48 // Otherwise first map to the lowest common ancestor, then map to destination. 48 // Otherwise first map to the lowest common ancestor, then map to destination.
49 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( 49 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor(
50 sourceState.transform(), destinationState.transform()); 50 sourceState.transform(), destinationState.transform());
51 DCHECK(lcaTransform); 51 DCHECK(lcaTransform);
52 52
53 // Assume that the clip of destinationState is an ancestor of the clip of 53 // Assume that the clip of destinationState is an ancestor of the clip of
54 // sourceState and is under the space of lcaTransform. Otherwise 54 // sourceState and is under the space of lcaTransform. Otherwise
55 // localToAncestorVisualRect() will fail. 55 // localToAncestorVisualRect() will fail.
56 PropertyTreeState lcaState = destinationState; 56 PropertyTreeState lcaState = destinationState;
57 lcaState.setTransform(lcaTransform); 57 lcaState.setTransform(lcaTransform);
58 58
59 localToAncestorVisualRectInternal(sourceState, lcaState, mappingRect, 59 localToAncestorVisualRectInternal(sourceState, lcaState, mappingRect,
60 success); 60 success);
61 if (!success) 61 if (!success)
62 return; 62 return;
63 63
64 ancestorToLocalRect(lcaTransform, destinationState.transform(), mappingRect); 64 ancestorToLocalRect(lcaTransform, destinationState.transform(),
65 mappingRect.rect());
65 } 66 }
66 67
67 void GeometryMapper::sourceToDestinationRect( 68 void GeometryMapper::sourceToDestinationRect(
68 const TransformPaintPropertyNode* sourceTransformNode, 69 const TransformPaintPropertyNode* sourceTransformNode,
69 const TransformPaintPropertyNode* destinationTransformNode, 70 const TransformPaintPropertyNode* destinationTransformNode,
70 FloatRect& mappingRect) { 71 FloatRect& mappingRect) {
71 bool success = false; 72 bool success = false;
72 localToAncestorRectInternal(sourceTransformNode, destinationTransformNode, 73 localToAncestorRectInternal(sourceTransformNode, destinationTransformNode,
73 mappingRect, success); 74 mappingRect, success);
74 // Success if destinationTransformNode is an ancestor of sourceTransformNode. 75 // Success if destinationTransformNode is an ancestor of sourceTransformNode.
75 if (success) 76 if (success)
76 return; 77 return;
77 78
78 // Otherwise first map to the least common ancestor, then map to destination. 79 // Otherwise first map to the least common ancestor, then map to destination.
79 const TransformPaintPropertyNode* lcaTransform = 80 const TransformPaintPropertyNode* lcaTransform =
80 lowestCommonAncestor(sourceTransformNode, destinationTransformNode); 81 lowestCommonAncestor(sourceTransformNode, destinationTransformNode);
81 DCHECK(lcaTransform); 82 DCHECK(lcaTransform);
82 83
83 localToAncestorRect(sourceTransformNode, lcaTransform, mappingRect); 84 localToAncestorRect(sourceTransformNode, lcaTransform, mappingRect);
84 ancestorToLocalRect(lcaTransform, destinationTransformNode, mappingRect); 85 ancestorToLocalRect(lcaTransform, destinationTransformNode, mappingRect);
85 } 86 }
86 87
87 void GeometryMapper::localToAncestorVisualRect( 88 void GeometryMapper::localToAncestorVisualRect(
88 const PropertyTreeState& localState, 89 const PropertyTreeState& localState,
89 const PropertyTreeState& ancestorState, 90 const PropertyTreeState& ancestorState,
90 FloatRect& mappingRect) { 91 FloatClipRect& mappingRect) {
91 bool success = false; 92 bool success = false;
92 localToAncestorVisualRectInternal(localState, ancestorState, mappingRect, 93 localToAncestorVisualRectInternal(localState, ancestorState, mappingRect,
93 success); 94 success);
94 DCHECK(success); 95 DCHECK(success);
95 } 96 }
96 97
97 void GeometryMapper::localToAncestorVisualRectInternal( 98 void GeometryMapper::localToAncestorVisualRectInternal(
98 const PropertyTreeState& localState, 99 const PropertyTreeState& localState,
99 const PropertyTreeState& ancestorState, 100 const PropertyTreeState& ancestorState,
100 FloatRect& rectToMap, 101 FloatClipRect& rectToMap,
101 bool& success) { 102 bool& success) {
102 if (localState == ancestorState) { 103 if (localState == ancestorState) {
103 success = true; 104 success = true;
104 return; 105 return;
105 } 106 }
106 107
107 if (localState.effect() != ancestorState.effect()) { 108 if (localState.effect() != ancestorState.effect()) {
108 slowLocalToAncestorVisualRectWithEffects(localState, ancestorState, 109 slowLocalToAncestorVisualRectWithEffects(localState, ancestorState,
109 rectToMap, success); 110 rectToMap, success);
110 return; 111 return;
111 } 112 }
112 113
113 const auto& transformMatrix = localToAncestorMatrixInternal( 114 const auto& transformMatrix = localToAncestorMatrixInternal(
114 localState.transform(), ancestorState.transform(), success); 115 localState.transform(), ancestorState.transform(), success);
115 if (!success) { 116 if (!success) {
116 return; 117 return;
117 } 118 }
118 119
119 FloatRect mappedRect = transformMatrix.mapRect(rectToMap); 120 FloatRect mappedRect = transformMatrix.mapRect(rectToMap.rect());
120 121
121 const FloatClipRect& clipRect = 122 FloatClipRect clipRect =
122 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), 123 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(),
123 ancestorState.transform(), success); 124 ancestorState.transform(), success);
124 125
125 if (success) { 126 if (success) {
126 rectToMap = clipRect.rect(); 127 // This is where we propagate the rounded-ness of |clipRect| to
128 // |rectToMap|.
129 rectToMap = clipRect;
127 rectToMap.intersect(mappedRect); 130 rectToMap.intersect(mappedRect);
128 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 131 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
129 // On SPv1 we may fail when the paint invalidation container creates an 132 // On SPv1 we may fail when the paint invalidation container creates an
130 // overflow clip (in ancestorState) which is not in localState of an 133 // overflow clip (in ancestorState) which is not in localState of an
131 // out-of-flow positioned descendant. See crbug.com/513108 and layout test 134 // out-of-flow positioned descendant. See crbug.com/513108 and layout test
132 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with 135 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with
133 // --enable-prefer-compositing-to-lcd-text) for details. 136 // --enable-prefer-compositing-to-lcd-text) for details.
134 // Ignore it for SPv1 for now. 137 // Ignore it for SPv1 for now.
135 success = true; 138 success = true;
136 } 139 }
137 } 140 }
138 141
139 void GeometryMapper::slowLocalToAncestorVisualRectWithEffects( 142 void GeometryMapper::slowLocalToAncestorVisualRectWithEffects(
140 const PropertyTreeState& localState, 143 const PropertyTreeState& localState,
141 const PropertyTreeState& ancestorState, 144 const PropertyTreeState& ancestorState,
142 FloatRect& mappingRect, 145 FloatClipRect& mappingRect,
143 bool& success) { 146 bool& success) {
144 PropertyTreeState lastTransformAndClipState(localState.transform(), 147 PropertyTreeState lastTransformAndClipState(localState.transform(),
145 localState.clip(), nullptr); 148 localState.clip(), nullptr);
146 149
147 for (const auto* effect = localState.effect(); 150 for (const auto* effect = localState.effect();
148 effect && effect != ancestorState.effect(); effect = effect->parent()) { 151 effect && effect != ancestorState.effect(); effect = effect->parent()) {
149 if (!effect->hasFilterThatMovesPixels()) 152 if (!effect->hasFilterThatMovesPixels())
150 continue; 153 continue;
151 154
152 PropertyTreeState transformAndClipState(effect->localTransformSpace(), 155 PropertyTreeState transformAndClipState(effect->localTransformSpace(),
153 effect->outputClip(), nullptr); 156 effect->outputClip(), nullptr);
154 sourceToDestinationVisualRectInternal( 157 sourceToDestinationVisualRectInternal(
155 lastTransformAndClipState, transformAndClipState, mappingRect, success); 158 lastTransformAndClipState, transformAndClipState, mappingRect, success);
156 if (!success) 159 if (!success)
157 return; 160 return;
158 161
159 mappingRect = effect->mapRect(mappingRect); 162 mappingRect.setRect(effect->mapRect(mappingRect.rect()));
160 lastTransformAndClipState = transformAndClipState; 163 lastTransformAndClipState = transformAndClipState;
161 } 164 }
162 165
163 PropertyTreeState finalTransformAndClipState(ancestorState.transform(), 166 PropertyTreeState finalTransformAndClipState(ancestorState.transform(),
164 ancestorState.clip(), nullptr); 167 ancestorState.clip(), nullptr);
165 sourceToDestinationVisualRectInternal(lastTransformAndClipState, 168 sourceToDestinationVisualRectInternal(lastTransformAndClipState,
166 finalTransformAndClipState, mappingRect, 169 finalTransformAndClipState, mappingRect,
167 success); 170 success);
168 } 171 }
169 172
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 const TransformPaintPropertyNode*, 468 const TransformPaintPropertyNode*,
466 const TransformPaintPropertyNode*); 469 const TransformPaintPropertyNode*);
467 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 470 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
468 const ClipPaintPropertyNode*, 471 const ClipPaintPropertyNode*,
469 const ClipPaintPropertyNode*); 472 const ClipPaintPropertyNode*);
470 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 473 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
471 const ScrollPaintPropertyNode*, 474 const ScrollPaintPropertyNode*,
472 const ScrollPaintPropertyNode*); 475 const ScrollPaintPropertyNode*);
473 476
474 } // namespace blink 477 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698