OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
5 * | 5 * |
6 * Other contributors: | 6 * Other contributors: |
7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
(...skipping 28 matching lines...) Expand all Loading... | |
39 * other provisions required by the MPL or the GPL, as the case may be. | 39 * other provisions required by the MPL or the GPL, as the case may be. |
40 * If you do not delete the provisions above, a recipient may use your | 40 * If you do not delete the provisions above, a recipient may use your |
41 * version of this file under any of the LGPL, the MPL or the GPL. | 41 * version of this file under any of the LGPL, the MPL or the GPL. |
42 */ | 42 */ |
43 | 43 |
44 #include "core/paint/PaintLayerClipper.h" | 44 #include "core/paint/PaintLayerClipper.h" |
45 | 45 |
46 #include "core/frame/FrameView.h" | 46 #include "core/frame/FrameView.h" |
47 #include "core/frame/Settings.h" | 47 #include "core/frame/Settings.h" |
48 #include "core/layout/LayoutView.h" | 48 #include "core/layout/LayoutView.h" |
49 #include "core/paint/ObjectPaintProperties.h" | |
49 #include "core/paint/PaintLayer.h" | 50 #include "core/paint/PaintLayer.h" |
50 | 51 |
51 namespace blink { | 52 namespace blink { |
52 | 53 |
53 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, ClipRects& clipRects) | 54 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, ClipRects& clipRects) |
54 { | 55 { |
55 EPosition position = layoutObject.styleRef().position(); | 56 EPosition position = layoutObject.styleRef().position(); |
56 // A fixed object is essentially the root of its containing block hierarchy, so when | 57 // A fixed object is essentially the root of its containing block hierarchy, so when |
57 // we encounter such an object, we reset our clip rects to the fixedClipRect . | 58 // we encounter such an object, we reset our clip rects to the fixedClipRect . |
58 if (position == FixedPosition) { | 59 if (position == FixedPosition) { |
(...skipping 28 matching lines...) Expand all Loading... | |
87 } | 88 } |
88 } | 89 } |
89 if (layoutObject.hasClip()) { | 90 if (layoutObject.hasClip()) { |
90 LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); | 91 LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); |
91 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect()). setIsClippedByClipCss()); | 92 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect()). setIsClippedByClipCss()); |
92 clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowCl ipRect()).setIsClippedByClipCss()); | 93 clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowCl ipRect()).setIsClippedByClipCss()); |
93 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect ()).setIsClippedByClipCss()); | 94 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect ()).setIsClippedByClipCss()); |
94 } | 95 } |
95 } | 96 } |
96 | 97 |
98 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer) | |
99 : m_layer(layer), m_geometryMapper(RuntimeEnabledFeatures::slimmingPaintV2En abled() ? new GeometryMapper : nullptr) | |
100 { } | |
101 | |
97 ClipRects* PaintLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const | 102 ClipRects* PaintLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const |
98 { | 103 { |
99 ASSERT(context.usesCache()); | 104 ASSERT(context.usesCache()); |
100 if (!m_layer.clipRectsCache()) | 105 if (!m_layer.clipRectsCache()) |
101 return nullptr; | 106 return nullptr; |
102 ClipRectsCache::Entry& entry = m_layer.clipRectsCache()->get(context.cacheSl ot()); | 107 ClipRectsCache::Entry& entry = m_layer.clipRectsCache()->get(context.cacheSl ot()); |
103 // FIXME: We used to ASSERT that we always got a consistent root layer. | 108 // FIXME: We used to ASSERT that we always got a consistent root layer. |
104 // We should add a test that has an inconsistent root. See | 109 // We should add a test that has an inconsistent root. See |
105 // http://crbug.com/366118 for an example. | 110 // http://crbug.com/366118 for an example. |
106 if (context.rootLayer != entry.root) | 111 if (context.rootLayer != entry.root) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 ClipRects* parentClipRects = nullptr; | 150 ClipRects* parentClipRects = nullptr; |
146 if (context.rootLayer != &m_layer && m_layer.parent()) | 151 if (context.rootLayer != &m_layer && m_layer.parent()) |
147 parentClipRects = &m_layer.parent()->clipper().getClipRects(context); | 152 parentClipRects = &m_layer.parent()->clipper().getClipRects(context); |
148 RefPtr<ClipRects> clipRects = ClipRects::create(); | 153 RefPtr<ClipRects> clipRects = ClipRects::create(); |
149 calculateClipRects(context, *clipRects); | 154 calculateClipRects(context, *clipRects); |
150 return storeClipRectsInCache(context, parentClipRects, *clipRects); | 155 return storeClipRectsInCache(context, parentClipRects, *clipRects); |
151 } | 156 } |
152 | 157 |
153 void PaintLayerClipper::clearClipRectsIncludingDescendants() | 158 void PaintLayerClipper::clearClipRectsIncludingDescendants() |
154 { | 159 { |
160 if (m_geometryMapper) | |
161 m_geometryMapper.reset(new GeometryMapper); | |
Xianzhu
2016/08/15 17:09:04
Can you give some performance analysis? Can we sha
chrishtr
2016/10/05 23:28:32
Don't have any yet. I'd prefer to commit this firs
| |
155 m_layer.clearClipRectsCache(); | 162 m_layer.clearClipRectsCache(); |
156 | 163 |
157 for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSib ling()) { | 164 for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSib ling()) { |
158 layer->clipper().clearClipRectsIncludingDescendants(); | 165 layer->clipper().clearClipRectsIncludingDescendants(); |
159 } | 166 } |
160 } | 167 } |
161 | 168 |
162 void PaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCacheSlot ca cheSlot) | 169 void PaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCacheSlot ca cheSlot) |
163 { | 170 { |
171 if (m_geometryMapper) | |
172 m_geometryMapper.reset(new GeometryMapper); | |
173 | |
164 if (ClipRectsCache* cache = m_layer.clipRectsCache()) | 174 if (ClipRectsCache* cache = m_layer.clipRectsCache()) |
165 cache->clear(cacheSlot); | 175 cache->clear(cacheSlot); |
166 | 176 |
167 for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSib ling()) { | 177 for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSib ling()) { |
168 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); | 178 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); |
169 } | 179 } |
170 } | 180 } |
171 | 181 |
172 LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) const | 182 LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) const |
173 { | 183 { |
184 ClipRectsContext context(clippingRootLayer, PaintingClipRects); | |
185 if (m_geometryMapper) { | |
186 ClipRect clipRect = clipRectWithGeometryMapper(context, false); | |
187 | |
188 // The rect now needs to be transformed to the local space of this Paint Layer. | |
189 bool success = false; | |
190 FloatRect clippedRectInLocalSpace = m_geometryMapper->mapRectToDestinati onSpace(FloatRect(clipRect.rect()), | |
191 clippingRootLayer->layoutObject()->objectPaintProperties()->localBor derBoxProperties()->propertyTreeState, | |
192 m_layer.layoutObject()->objectPaintProperties()->localBorderBoxPrope rties()->propertyTreeState, success); | |
193 DCHECK(success); | |
194 | |
195 return LayoutRect(clippedRectInLocalSpace); | |
196 } | |
197 | |
174 LayoutRect layerBounds; | 198 LayoutRect layerBounds; |
175 ClipRect backgroundRect, foregroundRect; | 199 ClipRect backgroundRect, foregroundRect; |
176 ClipRectsContext context(clippingRootLayer, PaintingClipRects); | |
177 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), layerBoun ds, backgroundRect, foregroundRect); | 200 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), layerBoun ds, backgroundRect, foregroundRect); |
178 | 201 |
179 LayoutRect clipRect = backgroundRect.rect(); | 202 LayoutRect clipRect = backgroundRect.rect(); |
180 // TODO(chrishtr): avoid converting to IntRect and back. | 203 // TODO(chrishtr): avoid converting to IntRect and back. |
181 if (clipRect == LayoutRect(LayoutRect::infiniteIntRect())) | 204 if (clipRect == LayoutRect(LayoutRect::infiniteIntRect())) |
182 return clipRect; | 205 return clipRect; |
183 | 206 |
184 LayoutPoint clippingRootOffset; | 207 LayoutPoint clippingRootOffset; |
185 m_layer.convertToLayerCoords(clippingRootLayer, clippingRootOffset); | 208 m_layer.convertToLayerCoords(clippingRootLayer, clippingRootOffset); |
186 clipRect.moveBy(-clippingRootOffset); | 209 clipRect.moveBy(-clippingRootOffset); |
187 | 210 |
188 return clipRect; | 211 return clipRect; |
189 } | 212 } |
190 | 213 |
191 void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const La youtRect& paintDirtyRect, LayoutRect& layerBounds, | 214 void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const La youtRect& paintDirtyRect, LayoutRect& layerBounds, |
192 ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offse tFromRoot) const | 215 ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offse tFromRoot) const |
193 { | 216 { |
217 if (m_geometryMapper) { | |
218 backgroundRect = clipRectWithGeometryMapper(context, false); | |
219 backgroundRect.move(context.subPixelAccumulation); // TODO(chrishtr): is this needed? | |
220 backgroundRect.intersect(paintDirtyRect); | |
221 | |
222 foregroundRect.move(context.subPixelAccumulation); // TODO(chrishtr): is this needed? | |
223 foregroundRect = clipRectWithGeometryMapper(context, true); | |
224 foregroundRect.intersect(paintDirtyRect); | |
225 return; | |
226 } | |
227 | |
194 bool isClippingRoot = &m_layer == context.rootLayer; | 228 bool isClippingRoot = &m_layer == context.rootLayer; |
195 LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); | 229 LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); |
196 | 230 |
197 if (!isClippingRoot && m_layer.parent()) { | 231 if (!isClippingRoot && m_layer.parent()) { |
198 backgroundRect = backgroundClipRect(context); | 232 backgroundRect = backgroundClipRect(context); |
199 backgroundRect.move(context.subPixelAccumulation); | 233 backgroundRect.move(context.subPixelAccumulation); |
200 backgroundRect.intersect(paintDirtyRect); | 234 backgroundRect.intersect(paintDirtyRect); |
201 } else { | 235 } else { |
202 backgroundRect = paintDirtyRect; | 236 backgroundRect = paintDirtyRect; |
203 } | 237 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
274 { | 308 { |
275 if (position == FixedPosition) | 309 if (position == FixedPosition) |
276 return parentRects.fixedClipRect(); | 310 return parentRects.fixedClipRect(); |
277 | 311 |
278 if (position == AbsolutePosition) | 312 if (position == AbsolutePosition) |
279 return parentRects.posClipRect(); | 313 return parentRects.posClipRect(); |
280 | 314 |
281 return parentRects.overflowClipRect(); | 315 return parentRects.overflowClipRect(); |
282 } | 316 } |
283 | 317 |
318 ClipRect PaintLayerClipper::clipRectWithGeometryMapper(const ClipRectsContext& c ontext, bool isForeground) const | |
319 { | |
320 DCHECK(m_geometryMapper); | |
321 LayoutRect source(LayoutRect::infiniteIntRect()); | |
322 bool success = false; | |
323 const ObjectPaintProperties* properties = m_layer.layoutObject()->objectPain tProperties(); | |
324 PropertyTreeState propertyTreeState = properties->localBorderBoxProperties() ->propertyTreeState; | |
325 if (isForeground) { | |
326 if (properties->cssClip()) | |
327 propertyTreeState.clip = properties->cssClip(); | |
328 else if (properties->overflowClip()) | |
329 propertyTreeState.clip = properties->overflowClip(); | |
330 } | |
331 | |
332 const ObjectPaintProperties* ancestorProperties = m_layer.layoutObject()->ob jectPaintProperties(); | |
333 PropertyTreeState destinationPropertyTreeState = ancestorProperties->localBo rderBoxProperties()->propertyTreeState; | |
334 if (!context.rootLayer->clipper().shouldRespectOverflowClip(context)) { | |
335 if (ancestorProperties->overflowClip()) | |
336 destinationPropertyTreeState.clip = ancestorProperties->overflowClip (); | |
337 } | |
338 | |
339 FloatRect clippedRectInRootLayerSpace = m_geometryMapper->mapToVisualRectInD estinationSpace( | |
340 FloatRect(source), propertyTreeState, destinationPropertyTreeState, succ ess); | |
341 DCHECK(success); | |
342 return ClipRect(LayoutRect(clippedRectInRootLayerSpace)); | |
343 } | |
344 | |
284 ClipRect PaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const | 345 ClipRect PaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const |
285 { | 346 { |
347 if (m_geometryMapper) { | |
348 return clipRectWithGeometryMapper(context, false); | |
349 } | |
350 | |
286 ASSERT(m_layer.parent()); | 351 ASSERT(m_layer.parent()); |
287 LayoutView* layoutView = m_layer.layoutObject()->view(); | 352 LayoutView* layoutView = m_layer.layoutObject()->view(); |
288 ASSERT(layoutView); | 353 ASSERT(layoutView); |
289 | 354 |
290 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 355 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
291 if (&m_layer == context.rootLayer) | 356 if (&m_layer == context.rootLayer) |
292 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 357 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
293 else | 358 else |
294 m_layer.parent()->clipper().getOrCalculateClipRects(context, *parentClip Rects); | 359 m_layer.parent()->clipper().getOrCalculateClipRects(context, *parentClip Rects); |
295 | 360 |
(...skipping 23 matching lines...) Expand all Loading... | |
319 return false; | 384 return false; |
320 | 385 |
321 if (m_layer.isRootLayer() && context.respectOverflowClipForViewport == Ignor eOverflowClip) | 386 if (m_layer.isRootLayer() && context.respectOverflowClipForViewport == Ignor eOverflowClip) |
322 return false; | 387 return false; |
323 | 388 |
324 return true; | 389 return true; |
325 } | 390 } |
326 | 391 |
327 ClipRects& PaintLayerClipper::paintingClipRects(const PaintLayer* rootLayer, Sho uldRespectOverflowClipType respectOverflowClip, const LayoutSize& subpixelAccumu lation) const | 392 ClipRects& PaintLayerClipper::paintingClipRects(const PaintLayer* rootLayer, Sho uldRespectOverflowClipType respectOverflowClip, const LayoutSize& subpixelAccumu lation) const |
328 { | 393 { |
394 DCHECK(!m_geometryMapper); | |
329 ClipRectsContext context(rootLayer, PaintingClipRects, IgnoreOverlayScrollba rSize, subpixelAccumulation); | 395 ClipRectsContext context(rootLayer, PaintingClipRects, IgnoreOverlayScrollba rSize, subpixelAccumulation); |
330 if (respectOverflowClip == IgnoreOverflowClip) | 396 if (respectOverflowClip == IgnoreOverflowClip) |
331 context.setIgnoreOverflowClip(); | 397 context.setIgnoreOverflowClip(); |
332 return getClipRects(context); | 398 return getClipRects(context); |
333 } | 399 } |
334 | 400 |
335 } // namespace blink | 401 } // namespace blink |
OLD | NEW |