Changeset 201785 in webkit


Ignore:
Timestamp:
Jun 7, 2016 7:07:34 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

The backdrop-filter property does not respect border-radius
https://bugs.webkit.org/show_bug.cgi?id=158483
<rdar://problem/24210257>

Patch by Antoine Quint <Antoine Quint> on 2016-06-07
Reviewed by Simon Fraser.

Source/WebCore:

In order to correctly support border-radius and backdrop-filter together, we change
the value set as the m_backdropFiltersRect from a FloatRect to FloatRoundedRect so
that it accounts for values set by the border-radius property. Then we add a new
m_backdropClippingLayer PlatformCALayer member to clip the backdrop layer in the
event that the border-radius is non-zero in updateBackdropFiltersRect(). Finally,
we follow the same pattern used for other PlatformCALayers owned by a GraphicsLayerCA
to support cloning of the new m_backdropClippingLayer.

Tests: css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add.html

css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove.html
css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection.html
css3/filters/backdrop/backdrop-filter-with-border-radius-value-change.html
css3/filters/backdrop/backdrop-filter-with-border-radius-value-remove.html
css3/filters/backdrop/backdrop-filter-with-border-radius.html

  • platform/graphics/GraphicsLayer.h:

(WebCore::GraphicsLayer::setBackdropFiltersRect):
(WebCore::GraphicsLayer::backdropFiltersRect):

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::willBeDestroyed):
(WebCore::GraphicsLayerCA::setBackdropFiltersRect):
(WebCore::GraphicsLayerCA::updateBackdropFiltersRect):
(WebCore::GraphicsLayerCA::dumpAdditionalProperties):

  • platform/graphics/ca/GraphicsLayerCA.h:
  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateBackdropFiltersGeometry):
Use a rounded rect if there is no clip and we have non-zero border-radius set on the renderer.

LayoutTests:

Adding new tests checking that border-radius correctly affects clipping of the backdrop layer
in a basic scenario, when we change border-radius to a different value, when we set border-radius
back to 0 and when we add a reflection.

  • css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add-expected.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-expected.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove-expected.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-expected.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-value-change-expected.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-value-change.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-value-remove-expected.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius-value-remove.html: Added.
  • css3/filters/backdrop/backdrop-filter-with-border-radius.html: Added.
Location:
trunk
Files:
12 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201781 r201785  
     12016-06-07  Antoine Quint  <graouts@apple.com>
     2
     3        The backdrop-filter property does not respect border-radius
     4        https://bugs.webkit.org/show_bug.cgi?id=158483
     5        <rdar://problem/24210257>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Adding new tests checking that border-radius correctly affects clipping of the backdrop layer
     10        in a basic scenario, when we change border-radius to a different value, when we set border-radius
     11        back to 0 and when we add a reflection.
     12
     13        * css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add-expected.html: Added.
     14        * css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add.html: Added.
     15        * css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-expected.html: Added.
     16        * css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove-expected.html: Added.
     17        * css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove.html: Added.
     18        * css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection.html: Added.
     19        * css3/filters/backdrop/backdrop-filter-with-border-radius-expected.html: Added.
     20        * css3/filters/backdrop/backdrop-filter-with-border-radius-value-change-expected.html: Added.
     21        * css3/filters/backdrop/backdrop-filter-with-border-radius-value-change.html: Added.
     22        * css3/filters/backdrop/backdrop-filter-with-border-radius-value-remove-expected.html: Added.
     23        * css3/filters/backdrop/backdrop-filter-with-border-radius-value-remove.html: Added.
     24        * css3/filters/backdrop/backdrop-filter-with-border-radius.html: Added.
     25
    1262016-06-07  Sam Weinig  <sam@webkit.org>
    227
  • trunk/Source/WebCore/ChangeLog

    r201784 r201785  
     12016-06-07  Antoine Quint  <graouts@apple.com>
     2
     3        The backdrop-filter property does not respect border-radius
     4        https://bugs.webkit.org/show_bug.cgi?id=158483
     5        <rdar://problem/24210257>
     6
     7        Reviewed by Simon Fraser.
     8
     9        In order to correctly support border-radius and backdrop-filter together, we change
     10        the value set as the m_backdropFiltersRect from a FloatRect to FloatRoundedRect so
     11        that it accounts for values set by the border-radius property. Then we add a new
     12        m_backdropClippingLayer PlatformCALayer member to clip the backdrop layer in the
     13        event that the border-radius is non-zero in updateBackdropFiltersRect(). Finally,
     14        we follow the same pattern used for other PlatformCALayers owned by a GraphicsLayerCA
     15        to support cloning of the new m_backdropClippingLayer.
     16
     17        Tests: css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-add.html
     18               css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection-remove.html
     19               css3/filters/backdrop/backdrop-filter-with-border-radius-and-reflection.html
     20               css3/filters/backdrop/backdrop-filter-with-border-radius-value-change.html
     21               css3/filters/backdrop/backdrop-filter-with-border-radius-value-remove.html
     22               css3/filters/backdrop/backdrop-filter-with-border-radius.html
     23
     24        * platform/graphics/GraphicsLayer.h:
     25        (WebCore::GraphicsLayer::setBackdropFiltersRect):
     26        (WebCore::GraphicsLayer::backdropFiltersRect):
     27        * platform/graphics/ca/GraphicsLayerCA.cpp:
     28        (WebCore::GraphicsLayerCA::willBeDestroyed):
     29        (WebCore::GraphicsLayerCA::setBackdropFiltersRect):
     30        (WebCore::GraphicsLayerCA::updateBackdropFiltersRect):
     31        (WebCore::GraphicsLayerCA::dumpAdditionalProperties):
     32        * platform/graphics/ca/GraphicsLayerCA.h:
     33        * rendering/RenderLayerBacking.cpp:
     34        (WebCore::RenderLayerBacking::updateBackdropFiltersGeometry):
     35        Use a rounded rect if there is no clip and we have non-zero border-radius set on the renderer.
     36
    1372016-06-07  Andreas Kling  <akling@apple.com>
    238
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.h

    r199046 r201785  
    378378    virtual bool setBackdropFilters(const FilterOperations& filters) { m_backdropFilters = filters; return true; }
    379379
    380     virtual void setBackdropFiltersRect(const FloatRect& backdropFiltersRect) { m_backdropFiltersRect = backdropFiltersRect; }
    381     FloatRect backdropFiltersRect() const { return m_backdropFiltersRect; }
     380    virtual void setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect) { m_backdropFiltersRect = backdropFiltersRect; }
     381    const FloatRoundedRect& backdropFiltersRect() const { return m_backdropFiltersRect; }
    382382
    383383#if ENABLE(CSS_COMPOSITING)
     
    646646    FloatSize m_contentsTilePhase;
    647647    FloatSize m_contentsTileSize;
    648     FloatRect m_backdropFiltersRect;
     648    FloatRoundedRect m_backdropFiltersRect;
    649649
    650650    int m_repaintCount;
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r201759 r201785  
    435435        m_backdropLayer->setOwner(nullptr);
    436436
     437    if (m_backdropClippingLayer)
     438        m_backdropClippingLayer->setOwner(nullptr);
     439
    437440    removeCloneLayers();
    438441
     
    772775}
    773776
    774 void GraphicsLayerCA::setBackdropFiltersRect(const FloatRect& backdropFiltersRect)
     777void GraphicsLayerCA::setBackdropFiltersRect(const FloatRoundedRect& backdropFiltersRect)
    775778{
    776779    if (backdropFiltersRect == m_backdropFiltersRect)
     
    19651968    if (!m_backdropLayer)
    19661969        return;
    1967     FloatRect contentBounds(0, 0, m_backdropFiltersRect.width(), m_backdropFiltersRect.height());
     1970
     1971    FloatRect contentBounds(0, 0, m_backdropFiltersRect.rect().width(), m_backdropFiltersRect.rect().height());
    19681972    m_backdropLayer->setBounds(contentBounds);
    1969     m_backdropLayer->setPosition(m_backdropFiltersRect.location());
    1970 
    1971     if (LayerMap* layerCloneMap = m_backdropLayerClones.get()) {
    1972         for (auto& clone : *layerCloneMap) {
    1973             PlatformCALayer* cloneLayer = clone.value.get();
    1974             cloneLayer->setBounds(contentBounds);
    1975             cloneLayer->setPosition(m_backdropFiltersRect.location());
     1973    m_backdropLayer->setPosition(m_backdropFiltersRect.rect().location());
     1974
     1975    updateClippingStrategy(*m_backdropLayer, m_backdropClippingLayer, m_backdropFiltersRect);
     1976
     1977    if (m_backdropLayerClones) {
     1978        for (auto& clone : *m_backdropLayerClones) {
     1979            PlatformCALayer* backdropCloneLayer = clone.value.get();
     1980            backdropCloneLayer->setBounds(contentBounds);
     1981            backdropCloneLayer->setPosition(m_backdropFiltersRect.rect().location());
     1982
     1983            CloneID cloneID = clone.key;
     1984            RefPtr<PlatformCALayer> backdropClippingLayerClone;
     1985            if (m_backdropClippingLayerClones)
     1986                backdropClippingLayerClone = m_backdropClippingLayerClones->get(cloneID);
     1987
     1988            bool hadBackdropClippingLayer = backdropClippingLayerClone;
     1989            updateClippingStrategy(*backdropCloneLayer, backdropClippingLayerClone, m_backdropFiltersRect);
     1990
     1991            if (!backdropClippingLayerClone && m_backdropClippingLayerClones)
     1992                m_backdropClippingLayerClones->remove(cloneID);
     1993            else if (backdropClippingLayerClone && !hadBackdropClippingLayer)
     1994                m_backdropClippingLayerClones->add(cloneID, backdropClippingLayerClone);
    19761995        }
    19771996    }
     
    34523471        dumpInnerLayer(textStream, "contents clipping layer", m_contentsClippingLayer.get(), indent, behavior);
    34533472        dumpInnerLayer(textStream, "shape mask layer", m_shapeMaskLayer.get(), indent, behavior);
     3473        dumpInnerLayer(textStream, "backdrop clipping layer", m_backdropClippingLayer.get(), indent, behavior);
    34543474        dumpInnerLayer(textStream, "contents layer", m_contentsLayer.get(), indent, behavior);
    34553475        dumpInnerLayer(textStream, "contents shape mask layer", m_contentsShapeMaskLayer.get(), indent, behavior);
     
    36103630
    36113631void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer,
    3612     RefPtr<PlatformCALayer>& contentsLayer, RefPtr<PlatformCALayer>& contentsClippingLayer, RefPtr<PlatformCALayer>& contentsShapeMaskLayer, RefPtr<PlatformCALayer>& shapeMaskLayer, RefPtr<PlatformCALayer>& backdropLayer, CloneLevel cloneLevel)
     3632    RefPtr<PlatformCALayer>& contentsLayer, RefPtr<PlatformCALayer>& contentsClippingLayer, RefPtr<PlatformCALayer>& contentsShapeMaskLayer, RefPtr<PlatformCALayer>& shapeMaskLayer, RefPtr<PlatformCALayer>& backdropLayer, RefPtr<PlatformCALayer>& backdropClippingLayer, CloneLevel cloneLevel)
    36133633{
    36143634    structuralLayer = nullptr;
     
    36353655    if (!m_backdropLayerClones && m_backdropLayer)
    36363656        m_backdropLayerClones = std::make_unique<LayerMap>();
    3637    
     3657
     3658    if (!m_backdropClippingLayerClones && m_backdropClippingLayer)
     3659        m_backdropClippingLayerClones = std::make_unique<LayerMap>();
     3660
    36383661    primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
    36393662    structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
     
    36433666    shapeMaskLayer = findOrMakeClone(cloneID, m_shapeMaskLayer.get(), m_shapeMaskLayerClones.get(), cloneLevel);
    36443667    backdropLayer = findOrMakeClone(cloneID, m_backdropLayer.get(), m_backdropLayerClones.get(), cloneLevel);
     3668    backdropClippingLayer = findOrMakeClone(cloneID, m_backdropClippingLayer.get(), m_backdropClippingLayerClones.get(), cloneLevel);
    36453669}
    36463670
     
    36653689    clearClones(m_shapeMaskLayerClones);
    36663690    clearClones(m_backdropLayerClones);
     3691    clearClones(m_backdropClippingLayerClones);
    36673692}
    36683693
     
    36993724    RefPtr<PlatformCALayer> shapeMaskLayer;
    37003725    RefPtr<PlatformCALayer> backdropLayer;
    3701     ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, contentsClippingLayer, contentsShapeMaskLayer, shapeMaskLayer, backdropLayer, cloneLevel);
     3726    RefPtr<PlatformCALayer> backdropClippingLayer;
     3727    ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, contentsClippingLayer, contentsShapeMaskLayer, shapeMaskLayer, backdropLayer, backdropClippingLayer, cloneLevel);
    37023728
    37033729    if (m_maskLayer) {
     
    37463772    if (replicaLayer || structuralLayer || contentsLayer || contentsClippingLayer || childLayers.size() > 0) {
    37473773        if (structuralLayer) {
    3748             if (backdropLayer)
     3774            if (backdropLayer) {
    37493775                clonalSublayers.append(backdropLayer);
     3776                backdropLayer->setMask(backdropClippingLayer.get());
     3777            }
    37503778           
    37513779            // Replicas render behind the actual layer content.
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

    r201759 r201785  
    105105
    106106    WEBCORE_EXPORT bool setBackdropFilters(const FilterOperations&) override;
    107     WEBCORE_EXPORT void setBackdropFiltersRect(const FloatRect&) override;
     107    WEBCORE_EXPORT void setBackdropFiltersRect(const FloatRoundedRect&) override;
    108108
    109109#if ENABLE(CSS_COMPOSITING)
     
    376376
    377377    void ensureCloneLayers(CloneID, RefPtr<PlatformCALayer>& primaryLayer, RefPtr<PlatformCALayer>& structuralLayer,
    378         RefPtr<PlatformCALayer>& contentsLayer, RefPtr<PlatformCALayer>& contentsClippingLayer, RefPtr<PlatformCALayer>& contentsShapeMaskLayer, RefPtr<PlatformCALayer>& shapeMaskLayer, RefPtr<PlatformCALayer>& backdropLayer, CloneLevel);
     378        RefPtr<PlatformCALayer>& contentsLayer, RefPtr<PlatformCALayer>& contentsClippingLayer, RefPtr<PlatformCALayer>& contentsShapeMaskLayer,
     379        RefPtr<PlatformCALayer>& shapeMaskLayer, RefPtr<PlatformCALayer>& backdropLayer, RefPtr<PlatformCALayer>& backdropClippingLayer,
     380        CloneLevel);
    379381
    380382    static void clearClones(std::unique_ptr<LayerMap>&);
     
    509511    RefPtr<PlatformCALayer> m_contentsClippingLayer; // A layer used to clip inner content
    510512    RefPtr<PlatformCALayer> m_shapeMaskLayer; // Used to clip with non-trivial corner radii.
     513    RefPtr<PlatformCALayer> m_backdropClippingLayer; // Used to clip the backdrop layer with corner radii.
    511514    RefPtr<PlatformCALayer> m_contentsLayer; // A layer used for inner content, like image and video
    512515    RefPtr<PlatformCALayer> m_contentsShapeMaskLayer; // Used to clip the content layer with non-trivial corner radii.
     
    521524    std::unique_ptr<LayerMap> m_shapeMaskLayerClones;
    522525    std::unique_ptr<LayerMap> m_backdropLayerClones;
     526    std::unique_ptr<LayerMap> m_backdropClippingLayerClones;
    523527
    524528#ifdef VISIBLE_TILE_WASH
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r201040 r201785  
    426426
    427427    RenderBox& renderer = downcast<RenderBox>(this->renderer());
    428     LayoutRect backdropFiltersRect = renderer.borderBoxRect();
     428    LayoutRect boxRect = renderer.borderBoxRect();
    429429    if (renderer.hasClip())
    430         backdropFiltersRect.intersect(renderer.clipRect(LayoutPoint(), nullptr));
    431 
    432     backdropFiltersRect.move(contentOffsetInCompostingLayer());
    433     m_graphicsLayer->setBackdropFiltersRect(snapRectToDevicePixels(backdropFiltersRect, deviceScaleFactor()));
     430        boxRect.intersect(renderer.clipRect(LayoutPoint(), nullptr));
     431    boxRect.move(contentOffsetInCompostingLayer());
     432
     433    FloatRoundedRect backdropFiltersRect;
     434    if (renderer.style().hasBorderRadius() && !renderer.hasClip())
     435        backdropFiltersRect = renderer.style().getRoundedInnerBorderFor(boxRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor());
     436    else
     437        backdropFiltersRect = FloatRoundedRect(snapRectToDevicePixels(boxRect, deviceScaleFactor()));
     438
     439    m_graphicsLayer->setBackdropFiltersRect(backdropFiltersRect);
    434440}
    435441#endif
Note: See TracChangeset for help on using the changeset viewer.