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

Side by Side Diff: Source/core/paint/DeprecatedPaintLayerClipper.cpp

Issue 1307203004: Revert "Reworks the clipping logic" and follow-up. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « Source/core/paint/DeprecatedPaintLayerClipper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 43
44 #include "config.h" 44 #include "config.h"
45 #include "core/paint/DeprecatedPaintLayerClipper.h" 45 #include "core/paint/DeprecatedPaintLayerClipper.h"
46 46
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/DeprecatedPaintLayer.h" 49 #include "core/paint/DeprecatedPaintLayer.h"
50 50
51 namespace blink { 51 namespace blink {
52 52
53 static void adjustClipRectsForChildren(const LayoutObject& layoutObject, ClipRec ts& clipRects)
54 {
55 EPosition position = layoutObject.style()->position();
56 // 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 if (position == FixedPosition) {
59 clipRects.setPosClipRect(clipRects.fixedClipRect());
60 clipRects.setOverflowClipRect(clipRects.fixedClipRect());
61 clipRects.setFixed(true);
62 } else if (position == RelativePosition) {
63 clipRects.setPosClipRect(clipRects.overflowClipRect());
64 } else if (position == AbsolutePosition) {
65 clipRects.setOverflowClipRect(clipRects.posClipRect());
66 }
67 }
68 static void applyClipRects(const ClipRectsContext& context, LayoutObject& layout Object, LayoutPoint offset, ClipRects& clipRects)
69 {
70 ASSERT(layoutObject.hasOverflowClip() || layoutObject.hasClip());
71 LayoutView* view = layoutObject.view();
72 ASSERT(view);
73 if (clipRects.fixed() && context.rootLayer->layoutObject() == view)
74 offset -= toIntSize(view->frameView()->scrollPosition());
75 if (layoutObject.hasOverflowClip()) {
76 ClipRect newOverflowClip = toLayoutBox(layoutObject).overflowClipRect(of fset, context.scrollbarRelevancy);
77 newOverflowClip.setHasRadius(layoutObject.style()->hasBorderRadius());
78 clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.ov erflowClipRect()));
79 if (layoutObject.isPositioned())
80 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.pos ClipRect()));
81 if (layoutObject.isLayoutView())
82 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.f ixedClipRect()));
83 }
84 if (layoutObject.hasClip()) {
85 LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset);
86 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())) ;
87 clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowCl ipRect()));
88 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect ()));
89 }
90 }
91
53 DeprecatedPaintLayerClipper::DeprecatedPaintLayerClipper(LayoutBoxModelObject& l ayoutObject) 92 DeprecatedPaintLayerClipper::DeprecatedPaintLayerClipper(LayoutBoxModelObject& l ayoutObject)
54 : m_layoutObject(layoutObject) 93 : m_layoutObject(layoutObject)
55 { 94 {
56 } 95 }
57 96
97 ClipRects* DeprecatedPaintLayerClipper::clipRectsIfCached(const ClipRectsContext & context) const
98 {
99 ASSERT(context.usesCache());
100 if (!m_cache)
101 return 0;
102 ClipRectsCache::Entry& entry = m_cache->get(context.cacheSlot());
103 // 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
105 // http://crbug.com/366118 for an example.
106 if (context.rootLayer != entry.root)
107 return 0;
108 ASSERT(entry.scrollbarRelevancy == context.scrollbarRelevancy);
109 #ifdef CHECK_CACHED_CLIP_RECTS
110 // This code is useful to check cached clip rects, but is too expensive to l eave enabled in debug builds by default.
111 ClipRectsContext tempContext(context);
112 tempContext.cacheSlot = UncachedClipRects;
113 RefPtr<ClipRects> clipRects = ClipRects::create();
114 calculateClipRects(tempContext, *clipRects);
115 ASSERT(clipRects == *entry.clipRects);
116 #endif
117 return entry.clipRects.get();
118 }
119 ClipRects* DeprecatedPaintLayerClipper::storeClipRectsInCache(const ClipRectsCon text& context, ClipRects* parentClipRects, const ClipRects& clipRects) const
120 {
121 ClipRectsCache::Entry& entry = cache().get(context.cacheSlot());
122 entry.root = context.rootLayer;
123 #if ENABLE(ASSERT)
124 entry.scrollbarRelevancy = context.scrollbarRelevancy;
125 #endif
126 if (parentClipRects) {
127 // If our clip rects match the clip rects of our parent, we share storag e.
128 if (clipRects == *parentClipRects) {
129 entry.clipRects = parentClipRects;
130 return parentClipRects;
131 }
132 }
133 entry.clipRects = ClipRects::create(clipRects);
134 return entry.clipRects.get();
135 }
136 ClipRects* DeprecatedPaintLayerClipper::getClipRects(const ClipRectsContext& con text) const
137 {
138 if (ClipRects* result = clipRectsIfCached(context))
139 return result;
140 // Note that it's important that we call getClipRects on our parent
141 // before we call calculateClipRects so that calculateClipRects will hit
142 // the cache.
143 ClipRects* parentClipRects = 0;
144 if (context.rootLayer != m_layoutObject.layer() && m_layoutObject.layer()->p arent())
145 parentClipRects = m_layoutObject.layer()->parent()->clipper().getClipRec ts(context);
146 RefPtr<ClipRects> clipRects = ClipRects::create();
147 calculateClipRects(context, *clipRects);
148 return storeClipRectsInCache(context, parentClipRects, *clipRects);
149 }
150
58 void DeprecatedPaintLayerClipper::clearClipRectsIncludingDescendants() 151 void DeprecatedPaintLayerClipper::clearClipRectsIncludingDescendants()
59 { 152 {
153 m_cache = nullptr;
154
60 for (DeprecatedPaintLayer* layer = m_layoutObject.layer()->firstChild(); lay er; layer = layer->nextSibling()) { 155 for (DeprecatedPaintLayer* layer = m_layoutObject.layer()->firstChild(); lay er; layer = layer->nextSibling()) {
61 for (int i = 0; i < NumberOfClipRectsCacheSlots; i++)
62 layer->clipper().m_clips[i] = nullptr;
63 layer->clipper().clearClipRectsIncludingDescendants(); 156 layer->clipper().clearClipRectsIncludingDescendants();
64 } 157 }
65 } 158 }
66 159
67 void DeprecatedPaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCa cheSlot cacheSlot) 160 void DeprecatedPaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCa cheSlot cacheSlot)
68 { 161 {
162 if (m_cache)
163 m_cache->clear(cacheSlot);
164
69 for (DeprecatedPaintLayer* layer = m_layoutObject.layer()->firstChild(); lay er; layer = layer->nextSibling()) { 165 for (DeprecatedPaintLayer* layer = m_layoutObject.layer()->firstChild(); lay er; layer = layer->nextSibling()) {
70 layer->clipper().m_clips[cacheSlot] = nullptr;
71 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); 166 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot);
72 } 167 }
73 } 168 }
74 169
75 LayoutRect DeprecatedPaintLayerClipper::childrenClipRect() const 170 LayoutRect DeprecatedPaintLayerClipper::childrenClipRect() const
76 { 171 {
77 // FIXME: border-radius not accounted for. 172 // FIXME: border-radius not accounted for.
78 // FIXME: Flow thread based columns not accounted for. 173 // FIXME: Flow thread based columns not accounted for.
79 DeprecatedPaintLayer* clippingRootLayer = clippingRootForPainting(); 174 DeprecatedPaintLayer* clippingRootLayer = clippingRootForPainting();
80 LayoutRect layerBounds; 175 LayoutRect layerBounds;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // CSS clip (different than clipping due to overflow) can clip to any box, e ven if it falls outside of the border box. 258 // CSS clip (different than clipping due to overflow) can clip to any box, e ven if it falls outside of the border box.
164 if (m_layoutObject.hasClip()) { 259 if (m_layoutObject.hasClip()) {
165 // Clip applies to *us* as well, so go ahead and update the damageRect. 260 // Clip applies to *us* as well, so go ahead and update the damageRect.
166 LayoutRect newPosClip = toLayoutBox(m_layoutObject).clipRect(offset); 261 LayoutRect newPosClip = toLayoutBox(m_layoutObject).clipRect(offset);
167 backgroundRect.intersect(newPosClip); 262 backgroundRect.intersect(newPosClip);
168 foregroundRect.intersect(newPosClip); 263 foregroundRect.intersect(newPosClip);
169 outlineRect.intersect(newPosClip); 264 outlineRect.intersect(newPosClip);
170 } 265 }
171 } 266 }
172 267
173 void precalculate(const ClipRectsContext& context) 268 void DeprecatedPaintLayerClipper::calculateClipRects(const ClipRectsContext& con text, ClipRects& clipRects) const
174 {
175 bool isComputingPaintingRect = context.isComputingPaintingRect();
176 ClipRectComputationState rects;
177 const DeprecatedPaintLayer* rootLayer = context.rootLayer;
178 if (isComputingPaintingRect) {
179 // Starting arbitrarily in the tree when calculating painting clipRects will
180 // not allow you to fill in all layers cache because some intermediate l ayer
181 // may need clips with respect to an ancestor further up. For efficiency we
182 // start at the top in order to fill in the cache for all layers.
183 rootLayer = context.rootLayer->layoutObject()->view()->layer();
184 rects.stackingContextClipRects.setRootLayer(rootLayer);
185 }
186 rects.currentClipRects.setRootLayer(rootLayer);
187
188 rootLayer->clipper().calculateClipRects(context, rects);
189 }
190
191 void DeprecatedPaintLayerClipper::precalculateAbsoluteClipRects()
192 {
193 ASSERT(m_layoutObject.layer()->isRootLayer());
194 // The absolute rectangles rely on layout sizes and position only.
195 ASSERT(m_layoutObject.document().lifecycle().state() >= DocumentLifecycle::L ayoutClean);
196 precalculate(ClipRectsContext(m_layoutObject.layer(), AbsoluteClipRects));
197 }
198
199 // Calculates clipRect for each element in the section of the tree starting with context.rootLayer
200 // For painting, context.rootLayer is ignored and the entire tree is calculated.
201 // TODO(chadarmstrong): When using the cache context shouldn't be able to specif y the rootLayer. This affects
202 // what is stored in the 5 caches, and should therefore be enforced internally. Currently
203 // different callers have different ideas of what the rootLayer should be for a particular
204 // cacheSlot, which can fill the cache with bad data. If this can be made consis tent it should
205 // be possible to eliminate rootLayer.
206 ClipRect DeprecatedPaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const
207 {
208 ASSERT(m_layoutObject.layer()->parent());
209 ASSERT(m_layoutObject.view());
210
211 // Ideally backgroundClipRect would not be called with itself as the rootLay er.
212 // This behavior can be seen in the following test
213 // LayoutTests/compositing/squashing/abspos-under-abspos-overflow-scroll.htm l
214 if (m_layoutObject.layer() == context.rootLayer)
215 return LayoutRect(LayoutRect::infiniteIntRect());
216
217 // TODO(chadarmstrong): If possible, all queries should use one of the clipR ectsCacheSlots.
218 // Without caching this operation involves walking all the way to rootLayer.
219 if (!context.usesCache())
220 return uncachedBackgroundClipRect(context);
221
222 // TODO(chadarmstrong): precalculation for painting should be moved to updat eLifecyclePhasesInternal
223 // and precalculation could be done for all hit testing. This would let us a void clearing the cache
224 if (!m_clips[context.cacheSlot()]) {
225 // AbsoluteClipRects should have been updated during compositing updates so we shouldn't miss here.
226 ASSERT(context.cacheSlot() != AbsoluteClipRects);
227 precalculate(context);
228 }
229
230 // TODO(chadarmstrong): eliminate this if possible.
231 // It is necessary only because of a seemingly atypical use of rootLayer tha t
232 // can be seen in LayoutTests/fullscreen/full-screen-line-boxes-crash.html a nd
233 // fast/block/multicol-paint-invalidation-assert.html.
234 if (!m_clips[context.cacheSlot()])
235 return uncachedBackgroundClipRect(context);
236 // As soon as crbug.com/517173 is resolved this assert should be enabled in place of the check
237 // ASSERT(m_clips[context.cacheSlot()]->rootLayer() == context.rootLayer);
238 if (m_clips[context.cacheSlot()]->rootLayer() != context.rootLayer)
239 return uncachedBackgroundClipRect(context);
240
241
242 return *m_clips[context.cacheSlot()];
243 }
244
245 static bool shouldStopClipRectCalculation(LayoutBoxModelObject& layoutObject, co nst ClipRectsContext& context)
246 {
247 // The entire tree is calculated for both painting and absolutClipRects
248 if (context.cacheSlot() == PaintingClipRectsIgnoringOverflowClip || context. cacheSlot() == PaintingClipRects || context.cacheSlot() == AbsoluteClipRects)
249 return false;
250 DeprecatedPaintLayer* layer = layoutObject.layer();
251 return layer->transform() || layer == layer->enclosingPaginationLayer();
252 }
253
254 // Updates clipRects so that descendants can calculate
255 // clipping relative to different root layers.
256 static void resetPaintRects(LayoutBoxModelObject& layoutObject, ClipRectComputat ionState& rects, ClipRectsCacheSlot slot)
257 {
258 const DeprecatedPaintLayer* layer = layoutObject.layer();
259 if (layer->isPaintInvalidationContainer() || layer->transform()) {
260 // If this element is hardware accelerated, we let the compositor handle the
261 // clipping (in case we want to paint bigger than a scrollable area for smooth
262 // scrolling) so we reset the clip rects.
263 // If the element has a transform, the clip rect could become a quad so we
264 // reset the layer and let the paint code apply the CTM during paint to
265 // transform the clip during paint.
266 rects.currentClipRects.reset(LayoutRect(LayoutRect::infiniteIntRect()));
267 rects.currentClipRects.setRootLayer(layoutObject.layer());
268 rects.currentClipRects.setFixed(false);
269 }
270 if (layer->stackingNode()->isStackingContext()) {
271 rects.stackingContextClipRects = rects.currentClipRects;
272 }
273 }
274
275 void DeprecatedPaintLayerClipper::addClipsFromThisObject(const ClipRectsContext& context, ClipRects& clipRects) const
276 {
277 LayoutView* view = m_layoutObject.view();
278 ASSERT(view);
279 // This offset cannot use convertToLayerCoords, because sometimes our rootLa yer may be across
280 // some transformed layer boundary, for example, in the DeprecatedPaintLayer Compositor overlapMap, where
281 // clipRects are needed in view space.
282 LayoutPoint offset = roundedLayoutPoint(m_layoutObject.localToContainerPoint (FloatPoint(), context.rootLayer->layoutObject()));
283 if (clipRects.fixed() && context.rootLayer->layoutObject() == view)
284 offset -= toIntSize(view->frameView()->scrollPosition());
285
286 // The condition for hasClip here seems wrong. See https://crbug.com/504577
287 // (overflowClips can be applied even when shouldRespectOverflowClip returns false)
288 if (m_layoutObject.hasOverflowClip() && (shouldRespectOverflowClip(context) || m_layoutObject.hasClip())) {
289 ClipRect newOverflowClip = toLayoutBox(m_layoutObject).overflowClipRect( offset, context.scrollbarRelevancy);
290 newOverflowClip.setHasRadius(m_layoutObject.style()->hasBorderRadius());
291 clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.ov erflowClipRect()));
292 if (m_layoutObject.isPositioned())
293 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.pos ClipRect()));
294 if (m_layoutObject.isLayoutView())
295 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.f ixedClipRect()));
296 }
297
298 if (m_layoutObject.hasClip())
299 clipRects.setFixedClipRect(intersection(toLayoutBox(m_layoutObject).clip Rect(offset), clipRects.fixedClipRect()));
300 }
301
302 void DeprecatedPaintLayerClipper::calculateClipRects(const ClipRectsContext& con text, ClipRectComputationState& rects) const
303 {
304 bool isComputingPaintingRect = context.isComputingPaintingRect();
305
306 // backgroundClipRect does not include clips from yourself
307 ClipRectsContext current = context;
308 current.rootLayer = rects.currentClipRects.rootLayer();
309 addClipsFromThisObject(current, rects.currentClipRects);
310 if (isComputingPaintingRect) {
311 current.rootLayer = rects.stackingContextClipRects.rootLayer();
312 addClipsFromThisObject(current, rects.stackingContextClipRects);
313 }
314
315 for (DeprecatedPaintLayer* child = m_layoutObject.layer()->firstChild(); chi ld; child = child->nextSibling()) {
316 child->clipper().setClipRect(context, rects);
317 }
318 }
319
320 // This function propagate the appropriate clip down to descendants. It is requi red
321 // as CSS overflow clips are inherited based on the containing blocks chain:
322 // ['overflow'] "affects the clipping of all of the element's content
323 // except any descendant elements (and their respective content and descendants)
324 // whose containing block is the viewport or an ancestor of the element."
325 void DeprecatedPaintLayerClipper::updateClipRectBasedOnPosition(ClipRects* clipR ects) const
326 {
327 switch (m_layoutObject.style()->position()) {
328 case FixedPosition:
329 // Clip is applied to all descendants but overflow does not propogate to fixed
330 // position elements.
331 clipRects->setPosClipRect(ClipRect(LayoutRect(LayoutRect::infiniteIntRec t())));
332 clipRects->setOverflowClipRect(ClipRect(LayoutRect(LayoutRect::infiniteI ntRect())));
333 clipRects->setFixed(true);
334 break;
335 case AbsolutePosition:
336 // Overflow clips from staticly positioned elements can be escaped by ab solute and fixed
337 // position elements.
338 clipRects->setOverflowClipRect(clipRects->posClipRect());
339 break;
340 case RelativePosition:
341 // Overflow clips that apply to a relative position element are not esca ped by absolute
342 // position elements further down the tree. (Because the relative posit ion element is a
343 // containing block.
344 clipRects->setPosClipRect(clipRects->overflowClipRect());
345 break;
346 case StaticPosition:
347 case StickyPosition:
348 // TODO(flakr): Position sticky should inherit the clip like relative po sition does (crbug.com/231752).
349 break;
350 }
351 }
352
353 void DeprecatedPaintLayerClipper::setClipRect(const ClipRectsContext& context, c onst ClipRectComputationState& parentRects) const
354 {
355 bool isComputingPaintingRect = context.isComputingPaintingRect();
356 ClipRectComputationState rects;
357 rects.currentClipRects = parentRects.currentClipRects;
358 if (isComputingPaintingRect)
359 rects.stackingContextClipRects = parentRects.stackingContextClipRects;
360 updateClipRectBasedOnPosition(&rects.currentClipRects);
361 if (isComputingPaintingRect)
362 updateClipRectBasedOnPosition(&rects.stackingContextClipRects);
363 ClipRects* clipRects;
364 if (isComputingPaintingRect && (m_layoutObject.isPositioned() || m_layoutObj ect.layer()->transform()))
365 clipRects = &rects.stackingContextClipRects;
366 else
367 clipRects = &rects.currentClipRects;
368
369 m_clips[context.cacheSlot()] = ClipRect::create(intersection(clipRects->over flowClipRect(), clipRects->fixedClipRect()));
370 m_clips[context.cacheSlot()]->setRootLayer(clipRects->rootLayer());
371 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
372 if (clipRects->fixed() && clipRects->rootLayer()->layoutObject() == m_layout Object.view() && *m_clips[context.cacheSlot()] != LayoutRect(LayoutRect::infinit eIntRect()))
373 m_clips[context.cacheSlot()]->move(toIntSize(m_layoutObject.view()->fram eView()->scrollPosition()));
374
375 if (shouldStopClipRectCalculation(m_layoutObject, context))
376 return;
377 if (isComputingPaintingRect)
378 resetPaintRects(m_layoutObject, rects, context.cacheSlot());
379
380 calculateClipRects(context, rects);
381 }
382
383 ClipRect DeprecatedPaintLayerClipper::uncachedBackgroundClipRect(const ClipRects Context& context) const
384 {
385 ClipRects clipRects;
386 m_layoutObject.layer()->parent()->clipper().uncachedCalculateClipRects(conte xt, clipRects);
387
388 updateClipRectBasedOnPosition(&clipRects);
389 ClipRect result(intersection(clipRects.overflowClipRect(), clipRects.fixedCl ipRect()));
390
391 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
392 if (clipRects.fixed() && context.rootLayer->layoutObject() == m_layoutObject .view() && result != LayoutRect(LayoutRect::infiniteIntRect()))
393 result.move(toIntSize(m_layoutObject.view()->frameView()->scrollPosition ()));
394
395 return result;
396 }
397
398 void DeprecatedPaintLayerClipper::uncachedCalculateClipRects(const ClipRectsCont ext& context, ClipRects& clipRects) const
399 { 269 {
400 bool rootLayerScrolls = m_layoutObject.document().settings() && m_layoutObje ct.document().settings()->rootLayerScrolls(); 270 bool rootLayerScrolls = m_layoutObject.document().settings() && m_layoutObje ct.document().settings()->rootLayerScrolls();
401 if (!m_layoutObject.layer()->parent() && !rootLayerScrolls) { 271 if (!m_layoutObject.layer()->parent() && !rootLayerScrolls) {
402 // The root layer's clip rect is always infinite. 272 // The root layer's clip rect is always infinite.
403 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); 273 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect()));
404 return; 274 return;
405 } 275 }
406 276
407 bool isClippingRoot = m_layoutObject.layer() == context.rootLayer; 277 bool isClippingRoot = m_layoutObject.layer() == context.rootLayer;
408 278
409 // For transformed layers, the root layer was shifted to be us, so there is no need to 279 // For transformed layers, the root layer was shifted to be us, so there is no need to
410 // examine the parent. We want to cache clip rects with us as the root. 280 // examine the parent. We want to cache clip rects with us as the root.
411 DeprecatedPaintLayer* parentLayer = !isClippingRoot ? m_layoutObject.layer() ->parent() : 0; 281 DeprecatedPaintLayer* parentLayer = !isClippingRoot ? m_layoutObject.layer() ->parent() : 0;
412
413 // Ensure that our parent's clip has been calculated so that we can examine the values. 282 // Ensure that our parent's clip has been calculated so that we can examine the values.
414 if (parentLayer) { 283 if (parentLayer) {
415 parentLayer->clipper().uncachedCalculateClipRects(context, clipRects); 284 // FIXME: Why don't we just call getClipRects here?
285 if (context.usesCache() && parentLayer->clipper().cachedClipRects(contex t)) {
286 clipRects = *parentLayer->clipper().cachedClipRects(context);
287 } else {
288 parentLayer->clipper().calculateClipRects(context, clipRects);
289 }
416 } else { 290 } else {
417 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); 291 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect()));
418 } 292 }
419 293
420 updateClipRectBasedOnPosition(&clipRects); 294 adjustClipRectsForChildren(m_layoutObject, clipRects);
421 addClipsFromThisObject(context, clipRects); 295
296 if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || m_layoutObject.hasClip()) {
297 // This offset cannot use convertToLayerCoords, because sometimes our ro otLayer may be across
298 // some transformed layer boundary, for example, in the DeprecatedPaintL ayerCompositor overlapMap, where
299 // clipRects are needed in view space.
300 applyClipRects(context, m_layoutObject, roundedLayoutPoint(m_layoutObjec t.localToContainerPoint(FloatPoint(), context.rootLayer->layoutObject())), clipR ects);
301 }
422 } 302 }
423 303
424 // TODO(chadarmstrong): Clipping roots should be consistent for a given clipRect sCacheSlot 304 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPos ition position)
425 // As things are, different callers clash over the same slot because they use 305 {
426 // different root layers. 306 if (position == FixedPosition)
307 return parentRects.fixedClipRect();
308
309 if (position == AbsolutePosition)
310 return parentRects.posClipRect();
311
312 return parentRects.overflowClipRect();
313 }
314
315 ClipRect DeprecatedPaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const
316 {
317 ASSERT(m_layoutObject.layer()->parent());
318 ASSERT(m_layoutObject.view());
319
320 RefPtr<ClipRects> parentClipRects = ClipRects::create();
321 if (m_layoutObject.layer() == context.rootLayer)
322 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect()));
323 else
324 m_layoutObject.layer()->parent()->clipper().getOrCalculateClipRects(cont ext, *parentClipRects);
325
326 ClipRect result = backgroundClipRectForPosition(*parentClipRects, m_layoutOb ject.style()->position());
327
328 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
329 if (parentClipRects->fixed() && context.rootLayer->layoutObject() == m_layou tObject.view() && result != LayoutRect(LayoutRect::infiniteIntRect()))
330 result.move(toIntSize(m_layoutObject.view()->frameView()->scrollPosition ()));
331
332 return result;
333 }
334
335 void DeprecatedPaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext & context, ClipRects& clipRects) const
336 {
337 if (context.usesCache())
338 clipRects = *getClipRects(context);
339 else
340 calculateClipRects(context, clipRects);
341 }
342
427 DeprecatedPaintLayer* DeprecatedPaintLayerClipper::clippingRootForPainting() con st 343 DeprecatedPaintLayer* DeprecatedPaintLayerClipper::clippingRootForPainting() con st
428 { 344 {
429 const DeprecatedPaintLayer* current = m_layoutObject.layer(); 345 const DeprecatedPaintLayer* current = m_layoutObject.layer();
430 // FIXME: getting rid of current->hasCompositedDeprecatedPaintLayerMapping() here breaks the 346 // FIXME: getting rid of current->hasCompositedDeprecatedPaintLayerMapping() here breaks the
431 // compositing/backing/no-backing-for-clip.html layout test, because there i s a 347 // compositing/backing/no-backing-for-clip.html layout test, because there i s a
432 // "composited but paints into ancestor" layer involved. However, it doesn't make sense that 348 // "composited but paints into ancestor" layer involved. However, it doesn't make sense that
433 // that check would be appropriate here but not inside the while loop below. 349 // that check would be appropriate here but not inside the while loop below.
434 if (current->isPaintInvalidationContainer() || current->hasCompositedDepreca tedPaintLayerMapping()) 350 if (current->isPaintInvalidationContainer() || current->hasCompositedDepreca tedPaintLayerMapping())
435 return const_cast<DeprecatedPaintLayer*>(current); 351 return const_cast<DeprecatedPaintLayer*>(current);
436 352
(...skipping 20 matching lines...) Expand all
457 if (context.respectOverflowClip == IgnoreOverflowClip) 373 if (context.respectOverflowClip == IgnoreOverflowClip)
458 return false; 374 return false;
459 375
460 if (layer->isRootLayer() && context.respectOverflowClipForViewport == Ignore OverflowClip) 376 if (layer->isRootLayer() && context.respectOverflowClipForViewport == Ignore OverflowClip)
461 return false; 377 return false;
462 378
463 return true; 379 return true;
464 } 380 }
465 381
466 } // namespace blink 382 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/paint/DeprecatedPaintLayerClipper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698