| Index: Source/core/rendering/compositing/CompositingReasonFinder.cpp
|
| diff --git a/Source/core/rendering/compositing/CompositingReasonFinder.cpp b/Source/core/rendering/compositing/CompositingReasonFinder.cpp
|
| index 4a1613a74dc17a88fd34aa59b9a906896da76d94..b0ecb32a2b5f900abed73e086c34a4d824dd8994 100644
|
| --- a/Source/core/rendering/compositing/CompositingReasonFinder.cpp
|
| +++ b/Source/core/rendering/compositing/CompositingReasonFinder.cpp
|
| @@ -49,6 +49,11 @@ CompositingReasons CompositingReasonFinder::directReasons(const RenderLayer* lay
|
| {
|
| ASSERT(potentialCompositingReasonsFromStyle(layer->renderer()) == layer->potentialCompositingReasonsFromStyle());
|
| CompositingReasons styleDeterminedDirectCompositingReasons = layer->potentialCompositingReasonsFromStyle() & CompositingReasonComboAllDirectStyleDeterminedReasons;
|
| +
|
| + // Apply optimizations for scroll-blocks-on which require comparing style between objects.
|
| + if ((styleDeterminedDirectCompositingReasons & CompositingReasonScrollBlocksOn) && !requiresCompositingForScrollBlocksOn(layer->renderer()))
|
| + styleDeterminedDirectCompositingReasons &= ~CompositingReasonScrollBlocksOn;
|
| +
|
| return styleDeterminedDirectCompositingReasons | nonStyleDeterminedDirectReasons(layer);
|
| }
|
|
|
| @@ -93,6 +98,12 @@ CompositingReasons CompositingReasonFinder::potentialCompositingReasonsFromStyle
|
| if (style->hasPerspective())
|
| reasons |= CompositingReasonPerspectiveWith3DDescendants;
|
|
|
| + // Ignore scroll-blocks-on on the document element, because it will get propagated to
|
| + // the RenderView (by Document::inheritHtmlAndBodyElementStyles) and we don't want to
|
| + // create two composited layers.
|
| + if (style->hasScrollBlocksOn() && !renderer->isDocumentElement())
|
| + reasons |= CompositingReasonScrollBlocksOn;
|
| +
|
| // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
|
| ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || style->hasBlendMode()) == renderer->createsGroup());
|
|
|
| @@ -122,7 +133,7 @@ CompositingReasons CompositingReasonFinder::potentialCompositingReasonsFromStyle
|
| bool CompositingReasonFinder::requiresCompositingForTransform(RenderObject* renderer) const
|
| {
|
| // Note that we ask the renderer if it has a transform, because the style may have transforms,
|
| - // but the renderer may be an inline that doesn't suppport them.
|
| + // but the renderer may be an inline that doesn't support them.
|
| return renderer->hasTransformRelatedProperty() && renderer->style()->transform().has3DOperation();
|
| }
|
|
|
| @@ -170,4 +181,42 @@ bool CompositingReasonFinder::requiresCompositingForPositionFixed(const RenderLa
|
| return layer->scrollsWithViewport() && m_renderView.frameView()->isScrollable();
|
| }
|
|
|
| +bool CompositingReasonFinder::requiresCompositingForScrollBlocksOn(const RenderObject* renderer) const
|
| +{
|
| + // Note that the other requires* functions run at RenderObject::styleDidChange time and so can rely
|
| + // only on the style of their object. This function runs at CompositingRequirementsUpdater::update
|
| + // time, and so can consider the style of other objects.
|
| + RenderStyle* style = renderer->style();
|
| +
|
| + // We should only get here by CompositingReasonScrollBlocksOn being a potential compositing reason.
|
| + ASSERT(style->hasScrollBlocksOn() && !renderer->isDocumentElement());
|
| +
|
| + // scroll-blocks-on style is propagated from the document element to the document.
|
| + ASSERT(!renderer->isRenderView()
|
| + || !renderer->document().documentElement()
|
| + || !renderer->document().documentElement()->renderer()
|
| + || renderer->document().documentElement()->renderer()->style()->scrollBlocksOn() == style->scrollBlocksOn());
|
| +
|
| + // When a scroll occurs, it's the union of all bits set on the target element's containing block
|
| + // chain that determines the behavior. Thus we really only need a new layer if this object contains
|
| + // additional bits from those set by all objects in it's containing block chain. But determining
|
| + // this fully is probably more expensive than it's worth. Instead we just have fast-paths here for
|
| + // the most common cases of unnecessary layer creation.
|
| + // Optimizing this fully would avoid layer explosion in pathological cases like '*' rules.
|
| + // We could consider tracking the current state in CompositingRequirementsUpdater::update.
|
| +
|
| + // Ensure iframes don't get composited when they require no more blocking than the root.
|
| + if (renderer->isRenderView()) {
|
| + if (const FrameView* parentFrame = toRenderView(renderer)->frameView()->parentFrameView()) {
|
| + if (const RenderView* parentRenderer = parentFrame->renderView()) {
|
| + // Does this frame contain only blocks-on bits already present in the parent frame?
|
| + if (!(style->scrollBlocksOn() & ~parentRenderer->style()->scrollBlocksOn()))
|
| + return false;
|
| + }
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| }
|
|
|