Changeset 246963 in webkit


Ignore:
Timestamp:
Jul 1, 2019 1:01:19 AM (5 years ago)
Author:
magomez@igalia.com
Message:

[WPE][GTK] Content disappearing when using CSS transforms
https://bugs.webkit.org/show_bug.cgi?id=181757

Reviewed by Žan Doberšek.

Source/WebCore:

During each layer flush, create an AnimatedBackingStoreClient instance for each layer that
has a backingStore and is to be animated, and send that client to the appropriate
TextureMapperLayer on the compositor thread. During each frame rendering, the client will
use the future layer position (currently 50ms in the future) to check whether new tiles are
required to keep the animation ongoing, and notify the appropriate CoordinatedGraphicsLayer so
it can perform a layer flush and provide new tiles.

  • platform/TextureMapper.cmake:
  • platform/graphics/nicosia/NicosiaAnimatedBackingStoreClient.h: Added.
  • platform/graphics/nicosia/NicosiaPlatformLayer.h:

(Nicosia::CompositionLayer::flushState):

  • platform/graphics/texmap/TextureMapperAnimation.cpp:

(WebCore::TextureMapperAnimation::applyKeepingInternalState):
(WebCore::TextureMapperAnimations::applyKeepingInternalState):

  • platform/graphics/texmap/TextureMapperAnimation.h:
  • platform/graphics/texmap/TextureMapperLayer.cpp:

(WebCore::TextureMapperLayer::computeTransformsRecursive):
(WebCore::TextureMapperLayer::setAnimatedBackingStoreClient):
(WebCore::TextureMapperLayer::syncAnimations):

  • platform/graphics/texmap/TextureMapperLayer.h:
  • platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:

(WebCore::CoordinatedGraphicsLayer::~CoordinatedGraphicsLayer):
(WebCore::clampToContentsRectIfRectIsInfinite):
(WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
(WebCore::CoordinatedGraphicsLayer::requestBackingStoreUpdate):
(WebCore::CoordinatedGraphicsLayer::updateContentBuffers):

  • platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:

Source/WebKit:

Set the appropriate AnimatedBackingStoreClient to the TextureMapperLayers when required.

  • Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp:

(WebKit::CoordinatedGraphicsScene::updateSceneState):

Location:
trunk/Source
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246962 r246963  
     12019-07-01  Miguel Gomez  <magomez@igalia.com>
     2
     3        [WPE][GTK] Content disappearing when using CSS transforms
     4        https://bugs.webkit.org/show_bug.cgi?id=181757
     5
     6        Reviewed by Žan Doberšek.
     7
     8        During each layer flush, create an AnimatedBackingStoreClient instance for each layer that
     9        has a backingStore and is to be animated, and send that client to the appropriate
     10        TextureMapperLayer on the compositor thread. During each frame rendering, the client will
     11        use the future layer position (currently 50ms in the future) to check whether new tiles are
     12        required to keep the animation ongoing, and notify the appropriate CoordinatedGraphicsLayer so
     13        it can perform a layer flush and provide new tiles.
     14
     15        * platform/TextureMapper.cmake:
     16        * platform/graphics/nicosia/NicosiaAnimatedBackingStoreClient.h: Added.
     17        * platform/graphics/nicosia/NicosiaPlatformLayer.h:
     18        (Nicosia::CompositionLayer::flushState):
     19        * platform/graphics/texmap/TextureMapperAnimation.cpp:
     20        (WebCore::TextureMapperAnimation::applyKeepingInternalState):
     21        (WebCore::TextureMapperAnimations::applyKeepingInternalState):
     22        * platform/graphics/texmap/TextureMapperAnimation.h:
     23        * platform/graphics/texmap/TextureMapperLayer.cpp:
     24        (WebCore::TextureMapperLayer::computeTransformsRecursive):
     25        (WebCore::TextureMapperLayer::setAnimatedBackingStoreClient):
     26        (WebCore::TextureMapperLayer::syncAnimations):
     27        * platform/graphics/texmap/TextureMapperLayer.h:
     28        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
     29        (WebCore::CoordinatedGraphicsLayer::~CoordinatedGraphicsLayer):
     30        (WebCore::clampToContentsRectIfRectIsInfinite):
     31        (WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
     32        (WebCore::CoordinatedGraphicsLayer::requestBackingStoreUpdate):
     33        (WebCore::CoordinatedGraphicsLayer::updateContentBuffers):
     34        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:
     35
    1362019-06-30  Antti Koivisto  <antti@apple.com>
    237
  • trunk/Source/WebCore/platform/TextureMapper.cmake

    r246400 r246963  
    9898        page/scrolling/nicosia/ScrollingTreeStickyNode.h
    9999
     100        platform/graphics/nicosia/NicosiaAnimatedBackingStoreClient.h
    100101        platform/graphics/nicosia/NicosiaBuffer.h
    101102        platform/graphics/nicosia/NicosiaPaintingEngine.h
  • trunk/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h

    r246400 r246963  
    3535#include "FloatRect.h"
    3636#include "FloatSize.h"
     37#include "NicosiaAnimatedBackingStoreClient.h"
    3738#include "NicosiaSceneIntegration.h"
    3839#include "TextureMapperAnimation.h"
     
    127128                    bool backingStoreChanged : 1;
    128129                    bool imageBackingChanged : 1;
     130                    bool animatedBackingStoreClientChanged : 1;
    129131                    bool repaintCounterChanged : 1;
    130132                    bool debugBorderChanged : 1;
     
    179181        RefPtr<BackingStore> backingStore;
    180182        RefPtr<ImageBacking> imageBacking;
     183        RefPtr<AnimatedBackingStoreClient> animatedBackingStoreClient;
    181184
    182185        struct RepaintCounter {
     
    257260        if (pending.delta.imageBackingChanged)
    258261            staging.imageBacking = pending.imageBacking;
     262        if (pending.delta.animatedBackingStoreClientChanged)
     263            staging.animatedBackingStoreClient = pending.animatedBackingStoreClient;
    259264
    260265        pending.delta = { };
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp

    r239535 r246963  
    240240}
    241241
     242void TextureMapperAnimation::applyKeepingInternalState(ApplicationResult& applicationResults, MonotonicTime time)
     243{
     244    MonotonicTime oldLastRefreshedTime = m_lastRefreshedTime;
     245    Seconds oldTotalRunningTime = m_totalRunningTime;
     246    AnimationState oldState = m_state;
     247
     248    apply(applicationResults, time);
     249
     250    m_lastRefreshedTime = oldLastRefreshedTime;
     251    m_totalRunningTime = oldTotalRunningTime;
     252    m_state = oldState;
     253}
     254
    242255void TextureMapperAnimation::pause(Seconds time)
    243256{
     
    339352}
    340353
     354void TextureMapperAnimations::applyKeepingInternalState(TextureMapperAnimation::ApplicationResult& applicationResults, MonotonicTime time)
     355{
     356    for (auto& animation : m_animations)
     357        animation.applyKeepingInternalState(applicationResults, time);
     358}
     359
    341360bool TextureMapperAnimations::hasActiveAnimationsOfType(AnimatedPropertyID type) const
    342361{
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.h

    r239427 r246963  
    4545
    4646    void apply(ApplicationResult&, MonotonicTime);
     47    void applyKeepingInternalState(ApplicationResult&, MonotonicTime);
    4748    void pause(Seconds);
    4849    void resume();
     
    8283
    8384    void apply(TextureMapperAnimation::ApplicationResult&, MonotonicTime);
     85    void applyKeepingInternalState(TextureMapperAnimation::ApplicationResult&, MonotonicTime);
    8486
    8587    bool isEmpty() const { return m_animations.isEmpty(); }
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp

    r242995 r246963  
    7979        m_layerTransforms.combinedForChildren.multiply(m_state.childrenTransform);
    8080        m_layerTransforms.combinedForChildren.translate3d(-originX, -originY, -m_state.anchorPoint.z());
     81
     82#if USE(COORDINATED_GRAPHICS)
     83        // Compute transforms for the future as well.
     84        TransformationMatrix futureParentTransform;
     85        if (m_parent)
     86            futureParentTransform = m_parent->m_layerTransforms.futureCombinedForChildren;
     87        else if (m_effectTarget)
     88            futureParentTransform = m_effectTarget->m_layerTransforms.futureCombined;
     89
     90        m_layerTransforms.futureCombined = futureParentTransform;
     91        m_layerTransforms.futureCombined
     92            .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
     93            .multiply(m_layerTransforms.futureLocalTransform);
     94
     95        m_layerTransforms.futureCombinedForChildren = m_layerTransforms.futureCombined;
     96        m_layerTransforms.futureCombined.translate3d(-originX, -originY, -m_state.anchorPoint.z());
     97
     98        if (!m_state.preserves3D)
     99            m_layerTransforms.futureCombinedForChildren = m_layerTransforms.futureCombinedForChildren.to2dTransform();
     100        m_layerTransforms.futureCombinedForChildren.multiply(m_state.childrenTransform);
     101        m_layerTransforms.futureCombinedForChildren.translate3d(-originX, -originY, -m_state.anchorPoint.z());
     102#endif
    81103    }
    82104
     
    98120    if (m_state.preserves3D)
    99121        sortByZOrder(m_children);
     122
     123#if USE(COORDINATED_GRAPHICS)
     124    if (m_backingStore && m_animatedBackingStoreClient)
     125        m_animatedBackingStoreClient->requestBackingStoreUpdateIfNeeded(m_layerTransforms.futureCombined);
     126#endif
    100127}
    101128
     
    624651}
    625652
     653#if USE(COORDINATED_GRAPHICS)
     654void TextureMapperLayer::setAnimatedBackingStoreClient(Nicosia::AnimatedBackingStoreClient* client)
     655{
     656    m_animatedBackingStoreClient = client;
     657}
     658#endif
     659
    626660bool TextureMapperLayer::descendantsOrSelfHaveRunningAnimations() const
    627661{
     
    652686    m_currentFilters = applicationResults.filters.valueOr(m_state.filters);
    653687
     688#if USE(COORDINATED_GRAPHICS)
     689    // Calculate localTransform 50ms in the future.
     690    TextureMapperAnimation::ApplicationResult futureApplicationResults;
     691    m_animations.applyKeepingInternalState(futureApplicationResults, time + 50_ms);
     692    m_layerTransforms.futureLocalTransform = futureApplicationResults.transform.valueOr(m_layerTransforms.localTransform);
     693#endif
     694
    654695    return applicationResults.hasRunningAnimations;
    655696}
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h

    r234139 r246963  
    2727#include "TextureMapperBackingStore.h"
    2828#include <wtf/WeakPtr.h>
     29
     30#if USE(COORDINATED_GRAPHICS)
     31#include "NicosiaAnimatedBackingStoreClient.h"
     32#endif
    2933
    3034namespace WebCore {
     
    8993    void setAnimations(const TextureMapperAnimations&);
    9094    void setBackingStore(TextureMapperBackingStore*);
     95#if USE(COORDINATED_GRAPHICS)
     96    void setAnimatedBackingStoreClient(Nicosia::AnimatedBackingStoreClient*);
     97#endif
    9198
    9299    bool applyAnimationsRecursively(MonotonicTime);
     
    198205    TextureMapperAnimations m_animations;
    199206    uint32_t m_id { 0 };
     207#if USE(COORDINATED_GRAPHICS)
     208    RefPtr<Nicosia::AnimatedBackingStoreClient> m_animatedBackingStoreClient;
     209#endif
    200210
    201211    struct {
    202212        TransformationMatrix localTransform;
    203 
    204213        TransformationMatrix combined;
    205214        TransformationMatrix combinedForChildren;
     215#if USE(COORDINATED_GRAPHICS)
     216        TransformationMatrix futureLocalTransform;
     217        TransformationMatrix futureCombined;
     218        TransformationMatrix futureCombinedForChildren;
     219#endif
    206220    } m_layerTransforms;
    207221};
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp

    r243866 r246963  
    150150    ASSERT(!m_nicosia.imageBacking);
    151151    ASSERT(!m_nicosia.backingStore);
     152    if (m_animatedBackingStoreHost)
     153        m_animatedBackingStoreHost->layerWillBeDestroyed();
    152154    willBeDestroyed();
    153155}
     
    631633#endif
    632634}
     635
     636static void clampToContentsRectIfRectIsInfinite(FloatRect& rect, const FloatSize& contentsSize)
     637{
     638    if (rect.width() >= LayoutUnit::nearlyMax() || rect.width() <= LayoutUnit::nearlyMin()) {
     639        rect.setX(0);
     640        rect.setWidth(contentsSize.width());
     641    }
     642
     643    if (rect.height() >= LayoutUnit::nearlyMax() || rect.height() <= LayoutUnit::nearlyMin()) {
     644        rect.setY(0);
     645        rect.setHeight(contentsSize.height());
     646    }
     647}
     648
     649class CoordinatedAnimatedBackingStoreClient final : public Nicosia::AnimatedBackingStoreClient {
     650public:
     651    static Ref<CoordinatedAnimatedBackingStoreClient> create(RefPtr<CoordinatedGraphicsLayer::AnimatedBackingStoreHost>&& host, const FloatRect& visibleRect, const FloatRect& coverRect, const FloatSize& size, float contentsScale)
     652    {
     653        return adoptRef(*new CoordinatedAnimatedBackingStoreClient(WTFMove(host), visibleRect, coverRect, size, contentsScale));
     654    }
     655
     656    ~CoordinatedAnimatedBackingStoreClient() = default;
     657
     658    void setCoverRect(const IntRect& rect) { m_coverRect = rect; }
     659    void requestBackingStoreUpdateIfNeeded(const TransformationMatrix& transform) final
     660    {
     661        ASSERT(!isMainThread());
     662
     663        // Calculate the contents rectangle of the layer in backingStore coordinates.
     664        FloatRect contentsRect = { { 0, 0 }, m_size };
     665        contentsRect.scale(m_contentsScale);
     666
     667        // If the area covered by tiles (the coverRect, already in backingStore coordinates) covers the whole
     668        // layer contents then we don't need to do anything.
     669        if (m_coverRect.contains(contentsRect))
     670            return;
     671
     672        // Non-invertible layers are not visible.
     673        if (!transform.isInvertible())
     674            return;
     675
     676        // Calculate the inverse of the layer transformation. The inverse transform will have the inverse of the
     677        // scaleFactor applied, so we need to scale it back.
     678        TransformationMatrix inverse = transform.inverse().valueOr(TransformationMatrix()).scale(m_contentsScale);
     679
     680        // Apply the inverse transform to the visible rectangle, so we have the visible rectangle in layer coordinates.
     681        FloatRect rect = inverse.clampedBoundsOfProjectedQuad(FloatQuad(m_visibleRect));
     682        clampToContentsRectIfRectIsInfinite(rect, m_size);
     683        FloatRect transformedVisibleRect = enclosingIntRect(rect);
     684
     685        // Convert the calculated visible rectangle to backingStore coordinates.
     686        transformedVisibleRect.scale(m_contentsScale);
     687
     688        // Restrict the calculated visible rect to the contents rectangle of the layer.
     689        transformedVisibleRect.intersect(contentsRect);
     690
     691        // If the coverRect doesn't contain the calculated visible rectangle we need to request a backingStore
     692        // update to render more tiles.
     693        if (!m_coverRect.contains(transformedVisibleRect)) {
     694            callOnMainThread([protectedHost = m_host.copyRef()]() {
     695                protectedHost->requestBackingStoreUpdate();
     696            });
     697        }
     698    }
     699
     700private:
     701    CoordinatedAnimatedBackingStoreClient(RefPtr<CoordinatedGraphicsLayer::AnimatedBackingStoreHost>&& host, const FloatRect& visibleRect, const FloatRect& coverRect, const FloatSize& size, float contentsScale)
     702        : m_host(WTFMove(host))
     703        , m_visibleRect(visibleRect)
     704        , m_coverRect(coverRect)
     705        , m_size(size)
     706        , m_contentsScale(contentsScale)
     707    { }
     708
     709    RefPtr<CoordinatedGraphicsLayer::AnimatedBackingStoreHost> m_host;
     710    FloatRect m_visibleRect;
     711    FloatRect m_coverRect;
     712    FloatSize m_size;
     713    float m_contentsScale;
     714};
    633715
    634716void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
     
    666748        m_nicosia.delta.backingStoreChanged = true;
    667749    }
     750
     751    if (hasActiveTransformAnimation && m_nicosia.backingStore) {
     752        // The layer has a backingStore and a transformation animation. This means that we need to add an
     753        // AnimatedBackingStoreClient to check whether we need to update the backingStore due to the animation.
     754        // At this point we don't know the area covered by tiles available, so we just pass an empty rectangle
     755        // for that. The call to updateContentBuffers will calculate the tile coverage and set the appropriate
     756        // rectangle to the client.
     757        if (!m_animatedBackingStoreHost)
     758            m_animatedBackingStoreHost = AnimatedBackingStoreHost::create(*this);
     759        m_nicosia.animatedBackingStoreClient = CoordinatedAnimatedBackingStoreClient::create(m_animatedBackingStoreHost.copyRef(), m_coordinator->visibleContentsRect(), { }, m_size, effectiveContentsScale());
     760    }
     761    // Each layer flush changes the AnimatedBackingStoreClient, being it null or a real one.
     762    m_nicosia.delta.animatedBackingStoreClientChanged = true;
    668763
    669764    // Determine image backing presence according to the composited image source.
     
    788883                if (localDelta.imageBackingChanged)
    789884                    state.imageBacking = m_nicosia.imageBacking;
     885                if (localDelta.animatedBackingStoreClientChanged)
     886                    state.animatedBackingStoreClient = m_nicosia.animatedBackingStoreClient;
    790887            });
    791888        m_nicosia.performLayerSync = !!m_nicosia.delta.value;
     
    816913{
    817914    return selfOrAncestorHaveNonAffineTransforms() ? 1 : deviceScaleFactor() * pageScaleFactor();
    818 }
    819 
    820 static void clampToContentsRectIfRectIsInfinite(FloatRect& rect, const FloatSize& contentsSize)
    821 {
    822     if (rect.width() >= LayoutUnit::nearlyMax() || rect.width() <= LayoutUnit::nearlyMin()) {
    823         rect.setX(0);
    824         rect.setWidth(contentsSize.width());
    825     }
    826 
    827     if (rect.height() >= LayoutUnit::nearlyMax() || rect.height() <= LayoutUnit::nearlyMin()) {
    828         rect.setY(0);
    829         rect.setHeight(contentsSize.height());
    830     }
    831915}
    832916
     
    844928    clampToContentsRectIfRectIsInfinite(rect, size());
    845929    return enclosingIntRect(rect);
     930}
     931
     932void CoordinatedGraphicsLayer::requestBackingStoreUpdate()
     933{
     934    setNeedsVisibleRectAdjustment();
     935    notifyFlushRequired();
    846936}
    847937
     
    9131003        m_pendingVisibleRectAdjustment = false;
    9141004        layerState.mainBackingStore->createTilesIfNeeded(transformedVisibleRect(), IntRect(0, 0, m_size.width(), m_size.height()));
     1005    }
     1006
     1007    if (m_nicosia.animatedBackingStoreClient) {
     1008        // Determine the coverRect and set it to the client.
     1009        downcast<CoordinatedAnimatedBackingStoreClient>(m_nicosia.animatedBackingStoreClient.get())->setCoverRect(layerState.mainBackingStore->coverRect());
    9151010    }
    9161011
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h

    r243866 r246963  
    3030#include "Image.h"
    3131#include "IntSize.h"
     32#include "NicosiaAnimatedBackingStoreClient.h"
    3233#include "NicosiaBuffer.h"
    3334#include "NicosiaPlatformLayer.h"
     
    125126    const RefPtr<Nicosia::CompositionLayer>& compositionLayer() const;
    126127
     128    class AnimatedBackingStoreHost : public ThreadSafeRefCounted<AnimatedBackingStoreHost> {
     129    public:
     130        static Ref<AnimatedBackingStoreHost> create(CoordinatedGraphicsLayer& layer)
     131        {
     132            return adoptRef(*new AnimatedBackingStoreHost(layer));
     133        }
     134
     135        void requestBackingStoreUpdate()
     136        {
     137            if (m_layer)
     138                m_layer->requestBackingStoreUpdate();
     139        }
     140
     141        void layerWillBeDestroyed() { m_layer = nullptr; }
     142    private:
     143        explicit AnimatedBackingStoreHost(CoordinatedGraphicsLayer& layer)
     144            : m_layer(&layer)
     145        { }
     146
     147        CoordinatedGraphicsLayer* m_layer;
     148    };
     149
     150    void requestBackingStoreUpdate();
     151
    127152private:
    128153    bool isCoordinatedGraphicsLayer() const override;
     
    199224        RefPtr<Nicosia::ContentLayer> contentLayer;
    200225        RefPtr<Nicosia::ImageBacking> imageBacking;
     226        RefPtr<Nicosia::AnimatedBackingStoreClient> animatedBackingStoreClient;
    201227    } m_nicosia;
     228
     229    RefPtr<AnimatedBackingStoreHost> m_animatedBackingStoreHost;
    202230};
    203231
  • trunk/Source/WebKit/ChangeLog

    r246962 r246963  
     12019-07-01  Miguel Gomez  <magomez@igalia.com>
     2
     3        [WPE][GTK] Content disappearing when using CSS transforms
     4        https://bugs.webkit.org/show_bug.cgi?id=181757
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Set the appropriate AnimatedBackingStoreClient to the TextureMapperLayers when required.
     9
     10        * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp:
     11        (WebKit::CoordinatedGraphicsScene::updateSceneState):
     12
    1132019-06-30  Antti Koivisto  <antti@apple.com>
    214
  • trunk/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp

    r243475 r246963  
    357357                        } else
    358358                            layer.setContentsLayer(nullptr);
     359
     360                        if (layerState.animatedBackingStoreClient)
     361                            layer.setAnimatedBackingStoreClient(layerState.animatedBackingStoreClient.get());
     362                        else
     363                            layer.setAnimatedBackingStoreClient(nullptr);
    359364                    });
    360365            }
Note: See TracChangeset for help on using the changeset viewer.