Changeset 245205 in webkit


Ignore:
Timestamp:
May 11, 2019 10:35:30 AM (5 years ago)
Author:
Simon Fraser
Message:

Backing-sharing layers with transforms render incorrectly
https://bugs.webkit.org/show_bug.cgi?id=197692
<rdar://problem/50652127>

Reviewed by Antti Koivisto.
Source/WebCore:

Layers that paint into shared backing need to enter the RenderLayer painting code
in a way that paints the filters, transforms, opacity and blending.

RenderLayerBacking::paintIntoLayer() normally enters at paintLayerContents(), because
the effects are rendered via the GraphicsLayer, but shared layers will paint effects.
Note that if the backing-provider has effects, it will be the stacking context
for the shared layers, so it's correct that sharing layers are impacted by effects
on the backing-provider.

In addition, we have to ensure that we don't over-eagerly make layers shared.
Consider:

<div class="clipping">

<div class="sharing">

<div class="inner">
</div>

</div>

</div>

Here "clipping" is the provider layer, "sharing" paints into shared backing, but
we don't want to also mark "inner" as sharing, since "sharing" will just paint it.
This is akin to avoiding unnecessary compositing of z-order descendants when they can just
paint.

To do this we need to ensure that sharing layers are treated like compositing layers
in the overlap map, i.e. when a layer is sharing, we call overlapMap.pushCompositingContainer(),
and later overlapMap.popCompositingContainer().

Tests: compositing/shared-backing/nested-shared-layers-with-opacity.html

compositing/shared-backing/shared-layer-has-blending.html
compositing/shared-backing/shared-layer-has-filter.html
compositing/shared-backing/shared-layer-has-opacity.html
compositing/shared-backing/shared-layer-has-reflection.html
compositing/shared-backing/shared-layer-has-transform.html
compositing/shared-backing/shared-layer-isolates-blending.html
compositing/shared-backing/shared-transformed-layer-bounds.html
compositing/shared-backing/sharing-layer-becomes-non-scrollable.html
compositing/shared-backing/sharing-layer-has-effect.html

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::paintLayer):
(WebCore::RenderLayer::paintLayerWithEffects):

  • rendering/RenderLayer.h:
  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::paintIntoLayer):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::CompositingState::stateForPaintOrderChildren const):
(WebCore::backingProviderLayerCanIncludeLayer):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::traverseUnchangedSubtree):

LayoutTests:

Ref tests for effects on sharing layers. The references make "clipping" be stacking context via z-index,
which eliminates sharing.

  • compositing/shared-backing/nested-shared-layers-with-opacity-expected.html: Added.
  • compositing/shared-backing/nested-shared-layers-with-opacity.html: Added.
  • compositing/shared-backing/shared-layer-has-blending-expected.html: Added.
  • compositing/shared-backing/shared-layer-has-blending.html: Added.
  • compositing/shared-backing/shared-layer-has-filter-expected.html: Added.
  • compositing/shared-backing/shared-layer-has-filter.html: Added.
  • compositing/shared-backing/shared-layer-has-opacity-expected.html: Added.
  • compositing/shared-backing/shared-layer-has-opacity.html: Added.
  • compositing/shared-backing/shared-layer-has-reflection-expected.html: Added.
  • compositing/shared-backing/shared-layer-has-reflection.html: Added.
  • compositing/shared-backing/shared-layer-has-transform-expected.html: Added.
  • compositing/shared-backing/shared-layer-has-transform.html: Added.
  • compositing/shared-backing/shared-layer-isolates-blending-expected.html: Added.
  • compositing/shared-backing/shared-layer-isolates-blending.html: Added.
Location:
trunk
Files:
14 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245191 r245205  
     12019-05-11  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Backing-sharing layers with transforms render incorrectly
     4        https://bugs.webkit.org/show_bug.cgi?id=197692
     5        <rdar://problem/50652127>
     6
     7        Reviewed by Antti Koivisto.
     8       
     9        Ref tests for effects on sharing layers. The references make "clipping" be stacking context via z-index,
     10        which eliminates sharing.
     11
     12        * compositing/shared-backing/nested-shared-layers-with-opacity-expected.html: Added.
     13        * compositing/shared-backing/nested-shared-layers-with-opacity.html: Added.
     14        * compositing/shared-backing/shared-layer-has-blending-expected.html: Added.
     15        * compositing/shared-backing/shared-layer-has-blending.html: Added.
     16        * compositing/shared-backing/shared-layer-has-filter-expected.html: Added.
     17        * compositing/shared-backing/shared-layer-has-filter.html: Added.
     18        * compositing/shared-backing/shared-layer-has-opacity-expected.html: Added.
     19        * compositing/shared-backing/shared-layer-has-opacity.html: Added.
     20        * compositing/shared-backing/shared-layer-has-reflection-expected.html: Added.
     21        * compositing/shared-backing/shared-layer-has-reflection.html: Added.
     22        * compositing/shared-backing/shared-layer-has-transform-expected.html: Added.
     23        * compositing/shared-backing/shared-layer-has-transform.html: Added.
     24        * compositing/shared-backing/shared-layer-isolates-blending-expected.html: Added.
     25        * compositing/shared-backing/shared-layer-isolates-blending.html: Added.
     26
    1272019-05-10  Zalan Bujtas  <zalan@apple.com>
    228
  • trunk/Source/WebCore/ChangeLog

    r245200 r245205  
     12019-05-11  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Backing-sharing layers with transforms render incorrectly
     4        https://bugs.webkit.org/show_bug.cgi?id=197692
     5        <rdar://problem/50652127>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Layers that paint into shared backing need to enter the RenderLayer painting code
     10        in a way that paints the filters, transforms, opacity and blending.
     11       
     12        RenderLayerBacking::paintIntoLayer() normally enters at paintLayerContents(), because
     13        the effects are rendered via the GraphicsLayer, but shared layers will paint effects.
     14        Note that if the backing-provider has effects, it will be the stacking context
     15        for the shared layers, so it's correct that sharing layers are impacted by effects
     16        on the backing-provider.
     17
     18        In addition, we have to ensure that we don't over-eagerly make layers shared.
     19        Consider:
     20       
     21        <div class="clipping">
     22            <div class="sharing">
     23                <div class="inner">
     24                </div>
     25            </div>
     26        </div>
     27       
     28        Here "clipping" is the provider layer, "sharing" paints into shared backing, but
     29        we don't want to also mark "inner" as sharing, since "sharing" will just paint it.
     30        This is akin to avoiding unnecessary compositing of z-order descendants when they can just
     31        paint.
     32       
     33        To do this we need to ensure that sharing layers are treated like compositing layers
     34        in the overlap map, i.e. when a layer is sharing, we call overlapMap.pushCompositingContainer(),
     35        and later overlapMap.popCompositingContainer().
     36
     37        Tests: compositing/shared-backing/nested-shared-layers-with-opacity.html
     38               compositing/shared-backing/shared-layer-has-blending.html
     39               compositing/shared-backing/shared-layer-has-filter.html
     40               compositing/shared-backing/shared-layer-has-opacity.html
     41               compositing/shared-backing/shared-layer-has-reflection.html
     42               compositing/shared-backing/shared-layer-has-transform.html
     43               compositing/shared-backing/shared-layer-isolates-blending.html
     44               compositing/shared-backing/shared-transformed-layer-bounds.html
     45               compositing/shared-backing/sharing-layer-becomes-non-scrollable.html
     46               compositing/shared-backing/sharing-layer-has-effect.html
     47
     48        * rendering/RenderLayer.cpp:
     49        (WebCore::RenderLayer::paintLayer):
     50        (WebCore::RenderLayer::paintLayerWithEffects):
     51        * rendering/RenderLayer.h:
     52        * rendering/RenderLayerBacking.cpp:
     53        (WebCore::RenderLayerBacking::paintIntoLayer):
     54        * rendering/RenderLayerCompositor.cpp:
     55        (WebCore::RenderLayerCompositor::CompositingState::stateForPaintOrderChildren const):
     56        (WebCore::backingProviderLayerCanIncludeLayer):
     57        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
     58        (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
     59
    1602019-05-10  Youenn Fablet  <youenn@apple.com>
    261
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r245179 r245205  
    41014101    }
    41024102
     4103    paintLayerWithEffects(context, paintingInfo, paintFlags);
     4104}
     4105
     4106void RenderLayer::paintLayerWithEffects(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags)
     4107{
    41034108    // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
    41044109    if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
     
    41074112    if (shouldSuppressPaintingLayer(this))
    41084113        return;
    4109    
     4114
    41104115    // If this layer is totally invisible then there is nothing to paint.
    41114116    if (!renderer().opacity())
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r245170 r245205  
    10041004
    10051005    void paintLayer(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
     1006    void paintLayerWithEffects(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
     1007
    10061008    void paintLayerContentsAndReflection(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
    10071009    void paintLayerByApplyingTransform(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>, const LayoutSize& translationOffset = LayoutSize());
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r245175 r245205  
    26692669        RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
    26702670
    2671         layer.paintLayerContents(context, paintingInfo, paintFlags);
    2672 
    2673         if (layer.containsDirtyOverlayScrollbars())
    2674             layer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
     2671        if (&layer == &m_owningLayer) {
     2672            layer.paintLayerContents(context, paintingInfo, paintFlags);
     2673
     2674            if (layer.containsDirtyOverlayScrollbars())
     2675                layer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
     2676        } else
     2677            layer.paintLayerWithEffects(context, paintingInfo, paintFlags);
    26752678
    26762679        if (layer.isRenderViewLayer())
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r245181 r245205  
    242242            childState.stackingContextAncestor = stackingContextAncestor;
    243243
     244        childState.backingSharingAncestor = backingSharingAncestor;
    244245        childState.subtreeIsCompositing = false;
    245246        childState.testingOverlap = testingOverlap;
     
    269270
    270271    RenderLayer* compositingAncestor;
     272    RenderLayer* backingSharingAncestor { nullptr };
    271273    RenderLayer* stackingContextAncestor { nullptr };
    272274    bool subtreeIsCompositing { false };
     
    861863static bool backingProviderLayerCanIncludeLayer(const RenderLayer& sharedLayer, const RenderLayer& layer)
    862864{
     865    // Disable sharing when painting shared layers doesn't work correctly.
     866    if (layer.hasReflection())
     867        return false;
     868
    863869    return layer.ancestorLayerIsInContainingBlockChain(sharedLayer);
    864870}
     
    982988        LOG_WITH_STREAM(Compositing, stream << &layer << " is compositing - flushing sharing to " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
    983989        backingSharingState.resetBackingProviderCandidate();
     990    } else if (layerPaintsIntoProvidedBacking) {
     991        childState.backingSharingAncestor = &layer;
     992        overlapMap.pushCompositingContainer();
    984993    }
    985994
     
    10651074#endif
    10661075
    1067     if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
     1076    if ((childState.compositingAncestor == &layer && !layer.isRenderViewLayer()) || childState.backingSharingAncestor == &layer)
    10681077        overlapMap.popCompositingContainer();
    10691078
     
    12291238#endif
    12301239
    1231     if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
     1240    if ((childState.compositingAncestor == &layer && !layer.isRenderViewLayer()) || childState.backingSharingAncestor == &layer)
    12321241        overlapMap.popCompositingContainer();
    12331242
Note: See TracChangeset for help on using the changeset viewer.