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

Side by Side Diff: Source/core/rendering/RenderLayerClipper.cpp

Issue 211683003: Return an infinite rect when calling RenderLayerClipper::parentClipRects on the root context layer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed nit. Created 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderLayerClipper.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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 tempContext.clipRectsType = TemporaryClipRects; 64 tempContext.clipRectsType = TemporaryClipRects;
65 ClipRects clipRects; 65 ClipRects clipRects;
66 calculateClipRects(tempContext, clipRects); 66 calculateClipRects(tempContext, clipRects);
67 ASSERT(clipRects == *m_clipRectsCache->getClipRects(clipRectsType, clipR ectsContext.respectOverflowClip).get()); 67 ASSERT(clipRects == *m_clipRectsCache->getClipRects(clipRectsType, clipR ectsContext.respectOverflowClip).get());
68 #endif 68 #endif
69 return; // We have the correct cached value. 69 return; // We have the correct cached value.
70 } 70 }
71 71
72 // For transformed layers, the root layer was shifted to be us, so there is no need to 72 // For transformed layers, the root layer was shifted to be us, so there is no need to
73 // examine the parent. We want to cache clip rects with us as the root. 73 // examine the parent. We want to cache clip rects with us as the root.
74 RenderLayer* parentLayer = clipRectsContext.rootLayer != m_renderer->layer() ? m_renderer->layer()->parent() : 0; 74 RenderLayer* parentLayer = !isClippingRootForContext(clipRectsContext) ? m_r enderer->layer()->parent() : 0;
75 if (parentLayer) 75 if (parentLayer)
76 parentLayer->clipper().updateClipRects(clipRectsContext); 76 parentLayer->clipper().updateClipRects(clipRectsContext);
77 77
78 ClipRects clipRects; 78 ClipRects clipRects;
79 calculateClipRects(clipRectsContext, clipRects); 79 calculateClipRects(clipRectsContext, clipRects);
80 80
81 if (!m_clipRectsCache) 81 if (!m_clipRectsCache)
82 m_clipRectsCache = adoptPtr(new ClipRectsCache); 82 m_clipRectsCache = adoptPtr(new ClipRectsCache);
83 83
84 if (parentLayer && parentLayer->clipper().clipRects(clipRectsContext) && cli pRects == *parentLayer->clipper().clipRects(clipRectsContext)) 84 if (parentLayer && parentLayer->clipper().clipRects(clipRectsContext) && cli pRects == *parentLayer->clipper().clipRects(clipRectsContext))
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 LayoutPoint clippingRootOffset; 162 LayoutPoint clippingRootOffset;
163 m_renderer->layer()->convertToLayerCoords(clippingRootLayer, clippingRootOff set); 163 m_renderer->layer()->convertToLayerCoords(clippingRootLayer, clippingRootOff set);
164 clipRect.moveBy(-clippingRootOffset); 164 clipRect.moveBy(-clippingRootOffset);
165 165
166 return clipRect; 166 return clipRect;
167 } 167 }
168 168
169 void RenderLayerClipper::calculateRects(const ClipRectsContext& clipRectsContext , const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, 169 void RenderLayerClipper::calculateRects(const ClipRectsContext& clipRectsContext , const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
170 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, c onst LayoutPoint* offsetFromRoot) const 170 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, c onst LayoutPoint* offsetFromRoot) const
171 { 171 {
172 if (clipRectsContext.rootLayer != m_renderer->layer() && m_renderer->layer() ->parent()) { 172 bool isClippingRoot = isClippingRootForContext(clipRectsContext);
173
174 if (!isClippingRoot && m_renderer->layer()->parent()) {
173 backgroundRect = backgroundClipRect(clipRectsContext); 175 backgroundRect = backgroundClipRect(clipRectsContext);
174 backgroundRect.move(roundedIntSize(clipRectsContext.subPixelAccumulation )); 176 backgroundRect.move(roundedIntSize(clipRectsContext.subPixelAccumulation ));
175 backgroundRect.intersect(paintDirtyRect); 177 backgroundRect.intersect(paintDirtyRect);
176 } else { 178 } else {
177 backgroundRect = paintDirtyRect; 179 backgroundRect = paintDirtyRect;
178 } 180 }
179 181
180 foregroundRect = backgroundRect; 182 foregroundRect = backgroundRect;
181 outlineRect = backgroundRect; 183 outlineRect = backgroundRect;
182 184
183 LayoutPoint offset; 185 LayoutPoint offset;
184 if (offsetFromRoot) 186 if (offsetFromRoot)
185 offset = *offsetFromRoot; 187 offset = *offsetFromRoot;
186 else 188 else
187 m_renderer->layer()->convertToLayerCoords(clipRectsContext.rootLayer, of fset); 189 m_renderer->layer()->convertToLayerCoords(clipRectsContext.rootLayer, of fset);
188 layerBounds = LayoutRect(offset, m_renderer->layer()->size()); 190 layerBounds = LayoutRect(offset, m_renderer->layer()->size());
189 191
190 // Update the clip rects that will be passed to child layers. 192 // Update the clip rects that will be passed to child layers.
191 if (m_renderer->hasOverflowClip()) { 193 if (m_renderer->hasOverflowClip()) {
192 // This layer establishes a clip of some kind. 194 // This layer establishes a clip of some kind.
193 if (m_renderer->layer() != clipRectsContext.rootLayer || clipRectsContex t.respectOverflowClip == RespectOverflowClip) { 195 if (!isClippingRoot || clipRectsContext.respectOverflowClip == RespectOv erflowClip) {
194 foregroundRect.intersect(toRenderBox(m_renderer)->overflowClipRect(o ffset, clipRectsContext.overlayScrollbarSizeRelevancy)); 196 foregroundRect.intersect(toRenderBox(m_renderer)->overflowClipRect(o ffset, clipRectsContext.overlayScrollbarSizeRelevancy));
195 if (m_renderer->style()->hasBorderRadius()) 197 if (m_renderer->style()->hasBorderRadius())
196 foregroundRect.setHasRadius(true); 198 foregroundRect.setHasRadius(true);
197 } 199 }
198 200
199 // If we establish an overflow clip at all, then go ahead and make sure our background 201 // If we establish an overflow clip at all, then go ahead and make sure our background
200 // rect is intersected with our layer's bounds including our visual over flow, 202 // rect is intersected with our layer's bounds including our visual over flow,
201 // since any visual overflow like box-shadow or border-outset is not cli pped by overflow:auto/hidden. 203 // since any visual overflow like box-shadow or border-outset is not cli pped by overflow:auto/hidden.
202 if (toRenderBox(m_renderer)->hasVisualOverflow()) { 204 if (toRenderBox(m_renderer)->hasVisualOverflow()) {
203 // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though 205 // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though
204 // we may need to inflate our clip specifically for shadows o r outsets. 206 // we may need to inflate our clip specifically for shadows o r outsets.
205 // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the 207 // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
206 // individual region boxes as overflow. 208 // individual region boxes as overflow.
207 LayoutRect layerBoundsWithVisualOverflow = toRenderBox(m_renderer)-> visualOverflowRect(); 209 LayoutRect layerBoundsWithVisualOverflow = toRenderBox(m_renderer)-> visualOverflowRect();
208 toRenderBox(m_renderer)->flipForWritingMode(layerBoundsWithVisualOve rflow); // Layers are in physical coordinates, so the overflow has to be flipped . 210 toRenderBox(m_renderer)->flipForWritingMode(layerBoundsWithVisualOve rflow); // Layers are in physical coordinates, so the overflow has to be flipped .
209 layerBoundsWithVisualOverflow.moveBy(offset); 211 layerBoundsWithVisualOverflow.moveBy(offset);
210 if (m_renderer->layer() != clipRectsContext.rootLayer || clipRectsCo ntext.respectOverflowClip == RespectOverflowClip) 212 if (!isClippingRoot || clipRectsContext.respectOverflowClip == Respe ctOverflowClip)
211 backgroundRect.intersect(layerBoundsWithVisualOverflow); 213 backgroundRect.intersect(layerBoundsWithVisualOverflow);
212 } else { 214 } else {
213 LayoutRect bounds = toRenderBox(m_renderer)->borderBoxRect(); 215 LayoutRect bounds = toRenderBox(m_renderer)->borderBoxRect();
214 bounds.moveBy(offset); 216 bounds.moveBy(offset);
215 if (m_renderer->layer() != clipRectsContext.rootLayer || clipRectsCo ntext.respectOverflowClip == RespectOverflowClip) 217 if (!isClippingRoot || clipRectsContext.respectOverflowClip == Respe ctOverflowClip)
216 backgroundRect.intersect(bounds); 218 backgroundRect.intersect(bounds);
217 } 219 }
218 } 220 }
219 221
220 // CSS clip (different than clipping due to overflow) can clip to any box, e ven if it falls outside of the border box. 222 // CSS clip (different than clipping due to overflow) can clip to any box, e ven if it falls outside of the border box.
221 if (m_renderer->hasClip()) { 223 if (m_renderer->hasClip()) {
222 // Clip applies to *us* as well, so go ahead and update the damageRect. 224 // Clip applies to *us* as well, so go ahead and update the damageRect.
223 LayoutRect newPosClip = toRenderBox(m_renderer)->clipRect(offset); 225 LayoutRect newPosClip = toRenderBox(m_renderer)->clipRect(offset);
224 backgroundRect.intersect(newPosClip); 226 backgroundRect.intersect(newPosClip);
225 foregroundRect.intersect(newPosClip); 227 foregroundRect.intersect(newPosClip);
226 outlineRect.intersect(newPosClip); 228 outlineRect.intersect(newPosClip);
227 } 229 }
228 } 230 }
229 231
230 void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsCon text, ClipRects& clipRects) const 232 void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsCon text, ClipRects& clipRects) const
231 { 233 {
232 if (!m_renderer->layer()->parent()) { 234 if (!m_renderer->layer()->parent()) {
233 // The root layer's clip rect is always infinite. 235 // The root layer's clip rect is always infinite.
234 clipRects.reset(PaintInfo::infiniteRect()); 236 clipRects.reset(PaintInfo::infiniteRect());
235 return; 237 return;
236 } 238 }
237 239
238 ClipRectsType clipRectsType = clipRectsContext.clipRectsType; 240 ClipRectsType clipRectsType = clipRectsContext.clipRectsType;
239 bool useCached = clipRectsType != TemporaryClipRects; 241 bool useCached = clipRectsType != TemporaryClipRects;
240 242
243 bool isClippingRoot = isClippingRootForContext(clipRectsContext);
244
241 // For transformed layers, the root layer was shifted to be us, so there is no need to 245 // For transformed layers, the root layer was shifted to be us, so there is no need to
242 // examine the parent. We want to cache clip rects with us as the root. 246 // examine the parent. We want to cache clip rects with us as the root.
243 RenderLayer* parentLayer = clipRectsContext.rootLayer != m_renderer->layer() ? m_renderer->layer()->parent() : 0; 247 RenderLayer* parentLayer = !isClippingRoot ? m_renderer->layer()->parent() : 0;
244 248
245 // Ensure that our parent's clip has been calculated so that we can examine the values. 249 // Ensure that our parent's clip has been calculated so that we can examine the values.
246 if (parentLayer) { 250 if (parentLayer) {
247 if (useCached && parentLayer->clipper().clipRects(clipRectsContext)) { 251 if (useCached && parentLayer->clipper().clipRects(clipRectsContext)) {
248 clipRects = *parentLayer->clipper().clipRects(clipRectsContext); 252 clipRects = *parentLayer->clipper().clipRects(clipRectsContext);
249 } else { 253 } else {
250 ClipRectsContext parentContext(clipRectsContext); 254 ClipRectsContext parentContext(clipRectsContext);
251 parentContext.overlayScrollbarSizeRelevancy = IgnoreOverlayScrollbar Size; // FIXME: why? 255 parentContext.overlayScrollbarSizeRelevancy = IgnoreOverlayScrollbar Size; // FIXME: why?
252 parentLayer->clipper().calculateClipRects(parentContext, clipRects); 256 parentLayer->clipper().calculateClipRects(parentContext, clipRects);
253 } 257 }
254 } else { 258 } else {
255 clipRects.reset(PaintInfo::infiniteRect()); 259 clipRects.reset(PaintInfo::infiniteRect());
256 } 260 }
257 261
258 // A fixed object is essentially the root of its containing block hierarchy, so when 262 // A fixed object is essentially the root of its containing block hierarchy, so when
259 // we encounter such an object, we reset our clip rects to the fixedClipRect . 263 // we encounter such an object, we reset our clip rects to the fixedClipRect .
260 if (m_renderer->style()->position() == FixedPosition) { 264 if (m_renderer->style()->position() == FixedPosition) {
261 clipRects.setPosClipRect(clipRects.fixedClipRect()); 265 clipRects.setPosClipRect(clipRects.fixedClipRect());
262 clipRects.setOverflowClipRect(clipRects.fixedClipRect()); 266 clipRects.setOverflowClipRect(clipRects.fixedClipRect());
263 clipRects.setFixed(true); 267 clipRects.setFixed(true);
264 } else if (m_renderer->style()->hasInFlowPosition()) { 268 } else if (m_renderer->style()->hasInFlowPosition()) {
265 clipRects.setPosClipRect(clipRects.overflowClipRect()); 269 clipRects.setPosClipRect(clipRects.overflowClipRect());
266 } else if (m_renderer->style()->position() == AbsolutePosition) { 270 } else if (m_renderer->style()->position() == AbsolutePosition) {
267 clipRects.setOverflowClipRect(clipRects.posClipRect()); 271 clipRects.setOverflowClipRect(clipRects.posClipRect());
268 } 272 }
269 273
270 // Update the clip rects that will be passed to child layers. 274 // Update the clip rects that will be passed to child layers.
271 if ((m_renderer->hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || m_renderer->layer() != clipRectsContext.rootLayer)) || m_renderer->hasClip()) { 275 if ((m_renderer->hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || !isClippingRoot)) || m_renderer->hasClip()) {
272 // This layer establishes a clip of some kind. 276 // This layer establishes a clip of some kind.
273 277
274 // This offset cannot use convertToLayerCoords, because sometimes our ro otLayer may be across 278 // This offset cannot use convertToLayerCoords, because sometimes our ro otLayer may be across
275 // some transformed layer boundary, for example, in the RenderLayerCompo sitor overlapMap, where 279 // some transformed layer boundary, for example, in the RenderLayerCompo sitor overlapMap, where
276 // clipRects are needed in view space. 280 // clipRects are needed in view space.
277 LayoutPoint offset; 281 LayoutPoint offset;
278 offset = roundedLayoutPoint(m_renderer->localToContainerPoint(FloatPoint (), clipRectsContext.rootLayer->renderer())); 282 offset = roundedLayoutPoint(m_renderer->localToContainerPoint(FloatPoint (), clipRectsContext.rootLayer->renderer()));
279 RenderView* view = m_renderer->view(); 283 RenderView* view = m_renderer->view();
280 ASSERT(view); 284 ASSERT(view);
281 if (view && clipRects.fixed() && clipRectsContext.rootLayer->renderer() == view) { 285 if (view && clipRects.fixed() && clipRectsContext.rootLayer->renderer() == view) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 RenderView* view = m_renderer->view(); 342 RenderView* view = m_renderer->view();
339 ASSERT(view); 343 ASSERT(view);
340 344
341 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. 345 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
342 if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect()) 346 if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect())
343 backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition( )); 347 backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition( ));
344 348
345 return backgroundClipRect; 349 return backgroundClipRect;
346 } 350 }
347 351
352 bool RenderLayerClipper::isClippingRootForContext(const ClipRectsContext& clipRe ctsContext) const
353 {
354 return clipRectsContext.rootLayer == m_renderer->layer();
355 }
356
348 void RenderLayerClipper::parentClipRects(const ClipRectsContext& clipRectsContex t, ClipRects& clipRects) const 357 void RenderLayerClipper::parentClipRects(const ClipRectsContext& clipRectsContex t, ClipRects& clipRects) const
349 { 358 {
359 // The root is not clipped.
360 if (isClippingRootForContext(clipRectsContext)) {
361 clipRects.reset(PaintInfo::infiniteRect());
362 return;
363 }
364
350 ASSERT(m_renderer->layer()->parent()); 365 ASSERT(m_renderer->layer()->parent());
351 366
352 RenderLayerClipper& parentClipper = m_renderer->layer()->parent()->clipper() ; 367 RenderLayerClipper& parentClipper = m_renderer->layer()->parent()->clipper() ;
353 if (clipRectsContext.clipRectsType == TemporaryClipRects) { 368 if (clipRectsContext.clipRectsType == TemporaryClipRects) {
354 parentClipper.calculateClipRects(clipRectsContext, clipRects); 369 parentClipper.calculateClipRects(clipRectsContext, clipRects);
355 return; 370 return;
356 } 371 }
357 372
358 parentClipper.updateClipRects(clipRectsContext); 373 parentClipper.updateClipRects(clipRectsContext);
359 clipRects = *parentClipper.clipRects(clipRectsContext); 374 clipRects = *parentClipper.clipRects(clipRectsContext);
(...skipping 13 matching lines...) Expand all
373 ASSERT(current); 388 ASSERT(current);
374 if (current->transform() || (current->compositingState() == PaintsIntoOw nBacking) || current->groupedMapping()) 389 if (current->transform() || (current->compositingState() == PaintsIntoOw nBacking) || current->groupedMapping())
375 return const_cast<RenderLayer*>(current); 390 return const_cast<RenderLayer*>(current);
376 } 391 }
377 392
378 ASSERT_NOT_REACHED(); 393 ASSERT_NOT_REACHED();
379 return 0; 394 return 0;
380 } 395 }
381 396
382 } // namespace WebCore 397 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderLayerClipper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698