Changeset 206639 in webkit
- Timestamp:
- Sep 30, 2016 9:52:47 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r206638 r206639 1 2016-09-30 Zalan Bujtas <zalan@apple.com> 2 3 RenderLayer::clipRects may return nullptr. 4 https://bugs.webkit.org/show_bug.cgi?id=162729 5 6 Reviewed by Chris Dumez. 7 8 This patch refactors RenderLayer::updateClipRects(), parentClipRects() and backgroundClipRect() 9 so that we don't have to rely on this seemingly unsafe line: clipRects = *parent()->clipRects(clipRectsContext); 10 Now updateClipRects() returns the computed/cached clip rects as opposed to update and refetch them. 11 While this patch makes the code look more readable/safer, it also eliminates cached item tripple retrievals. 12 13 No change in functionality. 14 15 * rendering/RenderLayer.cpp: 16 (WebCore::ClipRectsCache::getClipRects): 17 (WebCore::ClipRectsCache::setClipRects): 18 (WebCore::RenderLayer::updateClipRects): 19 (WebCore::RenderLayer::clipRects): 20 (WebCore::RenderLayer::calculateClipRects): 21 * rendering/RenderLayer.h: 22 1 23 2016-09-30 Youenn Fablet <youenn@apple.com> 2 24 -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r206188 r206639 233 233 } 234 234 235 PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; }236 void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects; }235 ClipRects* getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)].get(); } 236 void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, RefPtr<ClipRects>&& clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = WTFMove(clipRects); } 237 237 238 238 #ifndef NDEBUG … … 5406 5406 } 5407 5407 5408 voidRenderLayer::updateClipRects(const ClipRectsContext& clipRectsContext)5408 Ref<ClipRects> RenderLayer::updateClipRects(const ClipRectsContext& clipRectsContext) 5409 5409 { 5410 5410 ClipRectsType clipRectsType = clipRectsContext.clipRectsType; 5411 5411 ASSERT(clipRectsType < NumCachedClipRectsTypes); 5412 if (m_clipRectsCache && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) { 5413 ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]); 5414 ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy); 5412 if (m_clipRectsCache) { 5413 if (auto* clipRects = m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) { 5414 ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]); 5415 ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy); 5415 5416 5416 5417 #ifdef CHECK_CACHED_CLIP_RECTS 5417 // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default.5418 ClipRectsContext tempContext(clipRectsContext);5419 tempContext.clipRectsType = TemporaryClipRects;5420 ClipRects clipRects;5421 calculateClipRects(tempContext, clipRects);5422 ASSERT(clipRects == *m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip).get());5418 // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. 5419 ClipRectsContext tempContext(clipRectsContext); 5420 tempContext.clipRectsType = TemporaryClipRects; 5421 ClipRects tempClipRects; 5422 calculateClipRects(tempContext, tempClipRects); 5423 ASSERT(tempClipRects == *clipRects); 5423 5424 #endif 5424 return; // We have the correct cached value. 5425 } 5426 5427 // For transformed layers, the root layer was shifted to be us, so there is no need to 5428 // examine the parent. We want to cache clip rects with us as the root. 5429 RenderLayer* parentLayer = clipRectsContext.rootLayer != this ? parent() : nullptr; 5430 if (parentLayer) 5431 parentLayer->updateClipRects(clipRectsContext); 5432 5433 ClipRects clipRects; 5434 calculateClipRects(clipRectsContext, clipRects); 5435 5425 return *clipRects; // We have the correct cached value. 5426 } 5427 } 5428 5436 5429 if (!m_clipRectsCache) 5437 5430 m_clipRectsCache = std::make_unique<ClipRectsCache>(); 5438 5439 if (parentLayer && parentLayer->clipRects(clipRectsContext) && clipRects == *parentLayer->clipRects(clipRectsContext))5440 m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentLayer->clipRects(clipRectsContext));5441 else5442 m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, ClipRects::create(clipRects));5443 5444 5431 #ifndef NDEBUG 5445 5432 m_clipRectsCache->m_clipRectsRoot[clipRectsType] = clipRectsContext.rootLayer; 5446 5433 m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] = clipRectsContext.overlayScrollbarSizeRelevancy; 5447 5434 #endif 5435 5436 RefPtr<ClipRects> parentClipRects; 5437 // For transformed layers, the root layer was shifted to be us, so there is no need to 5438 // examine the parent. We want to cache clip rects with us as the root. 5439 if (auto* parentLayer = (clipRectsContext.rootLayer != this ? parent() : nullptr)) 5440 parentClipRects = parentLayer->updateClipRects(clipRectsContext); 5441 5442 auto clipRects = ClipRects::create(); 5443 calculateClipRects(clipRectsContext, clipRects); 5444 5445 if (parentClipRects && *parentClipRects == clipRects) { 5446 m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentClipRects.copyRef()); 5447 return parentClipRects.releaseNonNull(); 5448 } 5449 m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, clipRects.copyRef()); 5450 return clipRects; 5448 5451 } 5449 5452 … … 5483 5486 { 5484 5487 ASSERT(context.clipRectsType < NumCachedClipRectsTypes); 5485 return m_clipRectsCache ? m_clipRectsCache->getClipRects(context.clipRectsType, context.respectOverflowClip).get() : nullptr; 5488 if (!m_clipRectsCache) 5489 return nullptr; 5490 return m_clipRectsCache->getClipRects(context.clipRectsType, context.respectOverflowClip); 5486 5491 } 5487 5492 … … 5558 5563 } 5559 5564 5560 void RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const5565 Ref<ClipRects> RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext) const 5561 5566 { 5562 5567 ASSERT(parent()); 5563 if (renderer().isRenderNamedFlowThread() && mapLayerClipRectsToFragmentationLayer(clipRects)) 5564 return; 5568 if (renderer().isRenderNamedFlowThread()) { 5569 auto parentClipRects = ClipRects::create(); 5570 if (mapLayerClipRectsToFragmentationLayer(parentClipRects)) 5571 return parentClipRects; 5572 } 5565 5573 5566 5574 if (clipRectsContext.clipRectsType == TemporaryClipRects) { 5567 parent()->calculateClipRects(clipRectsContext, clipRects);5568 return;5569 }5570 5571 parent()->updateClipRects(clipRectsContext); 5572 clipRects = *parent()->clipRects(clipRectsContext);5575 auto parentClipRects = ClipRects::create(); 5576 parent()->calculateClipRects(clipRectsContext, parentClipRects); 5577 return parentClipRects; 5578 } 5579 5580 return parent()->updateClipRects(clipRectsContext); 5573 5581 } 5574 5582 … … 5587 5595 { 5588 5596 ASSERT(parent()); 5589 5590 ClipRects parentRects; 5591 5592 // If we cross into a different pagination context, then we can't rely on the cache. 5593 // Just switch over to using TemporaryClipRects. 5594 if (clipRectsContext.clipRectsType != TemporaryClipRects && parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers)) { 5595 ClipRectsContext tempContext(clipRectsContext); 5596 tempContext.clipRectsType = TemporaryClipRects; 5597 parentClipRects(tempContext, parentRects); 5598 } else 5599 parentClipRects(clipRectsContext, parentRects); 5600 5597 auto computeParentRects = [this, &clipRectsContext] () { 5598 // If we cross into a different pagination context, then we can't rely on the cache. 5599 // Just switch over to using TemporaryClipRects. 5600 if (clipRectsContext.clipRectsType != TemporaryClipRects 5601 && parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers)) { 5602 ClipRectsContext tempContext(clipRectsContext); 5603 tempContext.clipRectsType = TemporaryClipRects; 5604 return parentClipRects(tempContext); 5605 } 5606 return parentClipRects(clipRectsContext); 5607 }; 5608 5609 auto parentRects = computeParentRects(); 5601 5610 ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer().style().position()); 5602 5611 RenderView& view = renderer().view(); 5603 5604 5612 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. 5605 if (parentRects .fixed() && &clipRectsContext.rootLayer->renderer() == &view && !backgroundClipRect.isInfinite())5613 if (parentRects->fixed() && &clipRectsContext.rootLayer->renderer() == &view && !backgroundClipRect.isInfinite()) 5606 5614 backgroundClipRect.moveBy(view.frameView().scrollPositionForFixedPosition()); 5607 5608 5615 return backgroundClipRect; 5609 5616 } … … 6069 6076 else { 6070 6077 ASSERT(typeToClear < NumCachedClipRectsTypes); 6071 RefPtr<ClipRects> dummy; 6072 m_clipRectsCache->setClipRects(typeToClear, RespectOverflowClip, dummy); 6073 m_clipRectsCache->setClipRects(typeToClear, IgnoreOverflowClip, dummy); 6078 m_clipRectsCache->setClipRects(typeToClear, RespectOverflowClip, nullptr); 6079 m_clipRectsCache->setClipRects(typeToClear, IgnoreOverflowClip, nullptr); 6074 6080 } 6075 6081 } -
trunk/Source/WebCore/rendering/RenderLayer.h
r204717 r206639 696 696 }; 697 697 698 // Compute and cache clip rects computed with the given layer as the root699 voidupdateClipRects(const ClipRectsContext&);698 // Compute, cache and return clip rects computed with the given layer as the root. 699 Ref<ClipRects> updateClipRects(const ClipRectsContext&); 700 700 // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors 701 701 // (rather than computing them all from scratch up the parent chain). … … 934 934 #endif 935 935 936 void parentClipRects(const ClipRectsContext&, ClipRects&) const;936 Ref<ClipRects> parentClipRects(const ClipRectsContext&) const; 937 937 ClipRect backgroundClipRect(const ClipRectsContext&) const; 938 938
Note: See TracChangeset
for help on using the changeset viewer.