Changeset 218735 in webkit


Ignore:
Timestamp:
Jun 22, 2017 9:34:14 PM (7 years ago)
Author:
Antti Koivisto
Message:

REGRESSION(r217695): Offscreen/overflowed items not being rendered while translating in-frame
https://bugs.webkit.org/show_bug.cgi?id=173732

Reviewed by Simon Fraser.

Source/WebCore:

If an accelerated animation starts completely outside the view we fail to create backing for it
when it moves into view.

Fix by computing the full extent rect of the animation when it starts and doing the viewport overlap
testing with that.

Test: compositing/backing/transform-transition-from-outside-view.html

  • platform/graphics/GraphicsLayer.h:

(WebCore::GraphicsLayer::animationExtent):
(WebCore::GraphicsLayer::setAnimationExtent):

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::computeVisibleAndCoverageRect):

Return the current animation transformation matrix so we can use it elsewhere without recomputing.

(WebCore::GraphicsLayerCA::setVisibleAndCoverageRects):

If we have animation extent use it instead of bounds for visibility testing.

(WebCore::GraphicsLayerCA::recursiveCommitChanges):

Track if theres is a visible ancestor layer with a transition animation.

(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
(WebCore::GraphicsLayerCA::updateCoverage):

For simplicity create backing for all sublayers of a visible transform animated layer.

  • platform/graphics/ca/GraphicsLayerCA.h:

(WebCore::GraphicsLayerCA::VisibleAndCoverageRects::VisibleAndCoverageRects): Deleted.

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateGeometry):

Pass the animation extent (including descendants) to GraphicsLayer.

LayoutTests:

  • compositing/backing/transform-transition-from-outside-view-expected.txt: Added.
  • compositing/backing/transform-transition-from-outside-view.html: Added.
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r218733 r218735  
     12017-06-22  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION(r217695): Offscreen/overflowed items not being rendered while translating in-frame
     4        https://bugs.webkit.org/show_bug.cgi?id=173732
     5
     6        Reviewed by Simon Fraser.
     7
     8        * compositing/backing/transform-transition-from-outside-view-expected.txt: Added.
     9        * compositing/backing/transform-transition-from-outside-view.html: Added.
     10
    1112017-06-22  Myles C. Maxfield  <mmaxfield@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r218734 r218735  
     12017-06-22  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION(r217695): Offscreen/overflowed items not being rendered while translating in-frame
     4        https://bugs.webkit.org/show_bug.cgi?id=173732
     5
     6        Reviewed by Simon Fraser.
     7
     8        If an accelerated animation starts completely outside the view we fail to create backing for it
     9        when it moves into view.
     10
     11        Fix by computing the full extent rect of the animation when it starts and doing the viewport overlap
     12        testing with that.
     13
     14        Test: compositing/backing/transform-transition-from-outside-view.html
     15
     16        * platform/graphics/GraphicsLayer.h:
     17        (WebCore::GraphicsLayer::animationExtent):
     18        (WebCore::GraphicsLayer::setAnimationExtent):
     19        * platform/graphics/ca/GraphicsLayerCA.cpp:
     20        (WebCore::GraphicsLayerCA::computeVisibleAndCoverageRect):
     21
     22            Return the current animation transformation matrix so we can use it elsewhere without recomputing.
     23
     24        (WebCore::GraphicsLayerCA::setVisibleAndCoverageRects):
     25
     26            If we have animation extent use it instead of bounds for visibility testing.
     27
     28        (WebCore::GraphicsLayerCA::recursiveCommitChanges):
     29
     30            Track if theres is a visible ancestor layer with a transition animation.
     31
     32        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
     33        (WebCore::GraphicsLayerCA::updateCoverage):
     34
     35            For simplicity create backing for all sublayers of a visible transform animated layer.
     36
     37        * platform/graphics/ca/GraphicsLayerCA.h:
     38        (WebCore::GraphicsLayerCA::VisibleAndCoverageRects::VisibleAndCoverageRects): Deleted.
     39        * rendering/RenderLayerBacking.cpp:
     40        (WebCore::RenderLayerBacking::updateGeometry):
     41
     42            Pass the animation extent (including descendants) to GraphicsLayer.
     43
    1442017-06-22  Chris Dumez  <cdumez@apple.com>
    245
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.h

    r218615 r218735  
    572572    virtual bool isCoordinatedGraphicsLayer() const { return false; }
    573573
     574    const std::optional<FloatRect>& animationExtent() const { return m_animationExtent; }
     575    void setAnimationExtent(std::optional<FloatRect> animationExtent) { m_animationExtent = animationExtent; }
     576
    574577    static void traverse(GraphicsLayer&, const WTF::Function<void (GraphicsLayer&)>&);
    575578
     
    677680    FloatSize m_contentsTileSize;
    678681    FloatRoundedRect m_backdropFiltersRect;
     682    std::optional<FloatRect> m_animationExtent;
    679683
    680684    int m_repaintCount;
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r217737 r218735  
    13441344    if (!applyWasClamped && !mapWasClamped)
    13451345        clipRectForSelf.intersect(clipRectForChildren);
    1346    
     1346
    13471347    if (masksToBounds()) {
    13481348        ASSERT(accumulation == TransformState::FlattenTransform);
     
    13611361        coverageRect = (*quad).boundingBox();
    13621362
    1363     return VisibleAndCoverageRects(clipRectForSelf, coverageRect);
     1363    return { clipRectForSelf, coverageRect, currentTransform };
    13641364}
    13651365
     
    13931393    bool visibleRectChanged = rects.visibleRect != m_visibleRect;
    13941394    bool coverageRectChanged = rects.coverageRect != m_coverageRect;
    1395     if (!visibleRectChanged && !coverageRectChanged)
    1396         return;
     1395    if (!visibleRectChanged && !coverageRectChanged && !animationExtent())
     1396        return;
     1397
     1398    auto bounds = FloatRect(m_boundsOrigin, size());
     1399    if (auto extent = animationExtent()) {
     1400        // Adjust the animation extent to match the current animation position.
     1401        bounds = rects.animatingTransform.inverse().value_or(TransformationMatrix()).mapRect(*extent);
     1402    }
    13971403
    13981404    // FIXME: we need to take reflections into account when determining whether this layer intersects the coverage rect.
    1399     bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(FloatRect(m_boundsOrigin, size()));
     1405    bool intersectsCoverageRect = isViewportConstrained || rects.coverageRect.intersects(bounds);
    14001406    if (intersectsCoverageRect != m_intersectsCoverageRect) {
    14011407        addUncommittedChanges(CoverageRectChanged);
     
    14911497    if (affectedByPageScale)
    14921498        baseRelativePosition += m_position;
    1493    
     1499
    14941500    commitLayerChangesBeforeSublayers(childCommitState, pageScaleFactor, baseRelativePosition);
    14951501
    14961502    if (isRunningTransformAnimation()) {
    14971503        childCommitState.ancestorHasTransformAnimation = true;
     1504        if (m_intersectsCoverageRect)
     1505            childCommitState.ancestorWithTransformAnimationIntersectsCoverageRect = true;
    14981506        affectedByTransformAnimation = true;
    14991507    }
     
    17451753
    17461754    if (m_uncommittedChanges & CoverageRectChanged)
    1747         updateCoverage();
     1755        updateCoverage(commitState);
    17481756
    17491757    if (m_uncommittedChanges & TilingAreaChanged) // Needs to happen after CoverageRectChanged, ContentsScaleChanged
     
    22832291}
    22842292
    2285 void GraphicsLayerCA::updateCoverage()
     2293void GraphicsLayerCA::updateCoverage(const CommitState& commitState)
    22862294{
    22872295    // FIXME: Need to set coverage on clone layers too.
     
    22922300
    22932301    if (canDetachBackingStore()) {
    2294         m_layer->setBackingStoreAttached(m_intersectsCoverageRect);
     2302        bool requiresBacking = m_intersectsCoverageRect
     2303            || commitState.ancestorWithTransformAnimationIntersectsCoverageRect // FIXME: Compute backing exactly for descendants of animating layers.
     2304            || (isRunningTransformAnimation() && !animationExtent()); // Create backing if we don't know the animation extent.
     2305
     2306        m_layer->setBackingStoreAttached(requiresBacking);
    22952307        if (m_layerClones) {
    22962308            for (auto& it : *m_layerClones)
    2297                 it.value->setBackingStoreAttached(m_intersectsCoverageRect);
     2309                it.value->setBackingStoreAttached(requiresBacking);
    22982310        }
    22992311    }
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

    r217737 r218735  
    158158        bool ancestorHadChanges { false };
    159159        bool ancestorHasTransformAnimation { false };
     160        bool ancestorWithTransformAnimationIntersectsCoverageRect { false };
    160161        bool ancestorIsViewportConstrained { false };
    161162    };
     
    300301        FloatRect visibleRect;
    301302        FloatRect coverageRect;
    302        
    303         VisibleAndCoverageRects(const FloatRect& visRect, const FloatRect& covRect)
    304             : visibleRect(visRect)
    305             , coverageRect(covRect)
    306         {
    307         }
     303        TransformationMatrix animatingTransform;
    308304    };
    309305   
     
    401397    void updateStructuralLayer();
    402398    void updateDrawsContent();
    403     void updateCoverage();
     399    void updateCoverage(const CommitState&);
    404400    void updateBackgroundColor();
    405401    void updateUserInteractionEnabled();
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r218615 r218735  
    946946
    947947    const RenderStyle& style = renderer().style();
     948
     949    bool isRunningAcceleratedTransformAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused);
     950    bool isRunningAcceleratedOpacityAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused);
     951
    948952    // Set transform property, if it is not animating. We have to do this here because the transform
    949953    // is affected by the layer dimensions.
    950     if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused))
     954    if (!isRunningAcceleratedTransformAnimation)
    951955        updateTransform(style);
    952956
    953957    // Set opacity, if it is not animating.
    954     if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused))
     958    if (!isRunningAcceleratedOpacityAnimation)
    955959        updateOpacity(style);
    956960
     
    978982    m_graphicsLayer->setPosition(primaryGraphicsLayerRect.location());
    979983    m_graphicsLayer->setSize(primaryGraphicsLayerRect.size());
     984
     985    auto computeAnimationExtent = [&] () -> std::optional<FloatRect> {
     986        LayoutRect animatedBounds;
     987        if (isRunningAcceleratedTransformAnimation && m_owningLayer.getOverlapBoundsIncludingChildrenAccountingForTransformAnimations(animatedBounds))
     988            return FloatRect(animatedBounds);
     989        return { };
     990    };
     991    m_graphicsLayer->setAnimationExtent(computeAnimationExtent());
    980992
    981993    ComputedOffsets rendererOffset(m_owningLayer, LayoutRect(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
Note: See TracChangeset for help on using the changeset viewer.