Changeset 235165 in webkit


Ignore:
Timestamp:
Aug 22, 2018 5:14:14 AM (6 years ago)
Author:
zandobersek@gmail.com
Message:

[CoordGraphics] Switch to Nicosia::CompositionLayer state tracking
https://bugs.webkit.org/show_bug.cgi?id=188693

Reviewed by Carlos Garcia Campos.

.:

  • Source/cmake/OptionsGTK.cmake: Enable USE_NICOSIA alongside

USE_COORDINATED_GRAPHICS and USE_COORDINATED_GRAPHICS_THREADED.

  • Source/cmake/OptionsWPE.cmake: Ditto.

Source/WebCore:

Populate Nicosia::CompositionLayer with additional LayerState member
objects. For now we're using pending, staging and committed states,
though it might be possible to narrow down these to just two.

Pending state contains state that will be moved to staging during the
final steps of the next layer flush. flushState() method accumulates all
state changes in the staging state, and also allows the caller to
additionally perform flushing operations that are specific to backing
store, image backing or content layer containers.

commitState() method moves staging state over into the committed state,
again allowing user to pass a functor that receives the just-committed
state and apply it to their composition engine.

Changes in state objects are done under a thread-safe lock. This might
not be completely necessary at this point, but will be useful when
additonal layer state updates will be coming from e.g. the scrolling
thread. It might also make sense to tie in this lock use with the
Nicosia::Scene lock in the future.

Nicosia::ContentLayerTextureMapperImpl is modified slightly to allow
determining during flushes whether an update is pending. This is
necessary for a special case in ThreadedCompositor where content (i.e.
platform) layers like WebGL or video require an additional level of
scene update coordination. This complete special case has to go through
another review to see whether it's still necessary. Ideally we would be
able to remove it.

CoordinatedGraphicsLayer is finally switched over to using
Nicosia layer objects for state updates of any kind. This patch only
adds all the necessary bits, but doesn't yet remove any of the existing
code (but rather disables it temporarily, before it's removed).

Updating of simple state values is already in place. For backing stores,
the flushCompositingStateForThisLayerOnly() method now takes care of
preparing the backing store object if necessary as per layer state,
while the updateContentBuffers() method is switched to operate with
TiledBackingStore objects now kept on the BackingStoreTextureMapperImpl
instance associated with that backing store. Helper methods like
adjustContentsScale() and createBackingStore(), only called from the
updateContentBuffers() method, are removed and the code there inlined.

For image-backed layers, the update is now done directly in
the flushCompositingStateForThisLayerOnly() method, if necessary. The
helper syncImageBacking() method is commented out in order to prevent
double-painting of image buffers for now, but all this (along with the
CoordinatedImageBacking logic in CompositingCoordinator) will be removed
later.

For layers backed by platform layer objects, integration is relatively
simple. setContentsToPlatformLayer() is changed to properly handle any
passed-in platform layer object, and updatePlatformLayer() invokes the
swapBuffersIfNeeded() method on the ContentLayerTextureMapperImpl object
during each flush, if necessary.

In order to ensure any Nicosia-specific state update properly triggers
a composition update, m_nicosia.performLayerUpdate is added and flipped
to true during the flush in case of any state change. This then triggers
a layer sync in the CompositingCoordinator object when the
syncPendingStateChangesIncludingSubLayers() method is called. While no
old-style layer state update is provided, it causes the necessary
synchronization step that properly picks up the Nicosia-provided state
changes. Once the old-style layer state tracking is removed, this method
of update triggering will have to be updated as well.

  • platform/graphics/nicosia/NicosiaPlatformLayer.h:

(Nicosia::CompositionLayer::flushState):
(Nicosia::CompositionLayer::commitState):
(Nicosia::CompositionLayer::accessCommitted):

  • platform/graphics/nicosia/NicosiaScene.h:
  • platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp:

(Nicosia::ContentLayerTextureMapperImpl::flushUpdate):

  • platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.h:
  • platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:

(WebCore::CoordinatedGraphicsLayer::~CoordinatedGraphicsLayer):
(WebCore::CoordinatedGraphicsLayer::setContentsNeedsDisplay):
(WebCore::CoordinatedGraphicsLayer::setContentsToPlatformLayer):
(WebCore::CoordinatedGraphicsLayer::updatePlatformLayer):
(WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
(WebCore::CoordinatedGraphicsLayer::syncPendingStateChangesIncludingSubLayers):
(WebCore::CoordinatedGraphicsLayer::updateContentBuffers):
(WebCore::CoordinatedGraphicsLayer::purgeBackingStores):
(WebCore::CoordinatedGraphicsLayer::adjustContentsScale): Deleted.
(WebCore::CoordinatedGraphicsLayer::createBackingStore): Deleted.

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

Source/WebKit:

Switch CoordinatedGraphicsScene to utilizing Nicosia::CompositionLayer
objects for state updates of the TextureMapper layer tree.

CoordinatedGraphicsScene::paintToCurrentGLContext() now calls
updateSceneState() at the beginning. This is a new method that manages
all updates for a given Nicosia::Scene instance. Any removed layers
have their composition-side state cleaned up, and the current set of
layers is then iterated to ensure and update the corresponding
TextureMapperLayer objects.

Layers with any backing (painted backing store, platform-layer or image
content) are temporarly stored for updating outside of mutex-controlled
scene update. Performing all other state updates outside of this mutex
area will be investigated at a later point.

We then iterate over vectors for each layer backing, gathering any
affected CoordinatedBackingStore or TextureMapperPlatformLayerProxy
objects that we have to update.

This drops a bunch of member variables and helper methods off the
CoordinatedGraphicsScene class. The applyStateChanges() method will be
further simplified in the future. coordinateUpdateCompletionWithClient
logic in ThreadedCompositor should be checked to see whether it still
addresses any real-life problem, because at the moment it imposes a few
additional operations in terms of scene updates that we could really do
without. This will be checked later and removed if possible.

  • Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp:

(WebKit::CoordinatedGraphicsScene::applyStateChanges):
(WebKit::CoordinatedGraphicsScene::paintToCurrentGLContext):
(WebKit::compositionLayerImpl):
(WebKit::contentLayerImpl):
(WebKit::backingStoreImpl):
(WebKit::imageBackingImpl):
(WebKit::texmapLayer):
(WebKit::updateBackingStore):
(WebKit::updateImageBacking):
(WebKit::removeLayer):
(WebKit::CoordinatedGraphicsScene::commitSceneState):
(WebKit::CoordinatedGraphicsScene::updateSceneState):
(WebKit::CoordinatedGraphicsScene::purgeGLResources):
(WebKit::CoordinatedGraphicsScene::syncPlatformLayerIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::setLayerChildrenIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::setLayerFiltersIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::setLayerState): Deleted.
(WebKit::CoordinatedGraphicsScene::getLayerByIDIfExists): Deleted.
(WebKit::CoordinatedGraphicsScene::createLayers): Deleted.
(WebKit::CoordinatedGraphicsScene::createLayer): Deleted.
(WebKit::CoordinatedGraphicsScene::deleteLayers): Deleted.
(WebKit::CoordinatedGraphicsScene::deleteLayer): Deleted.
(WebKit::CoordinatedGraphicsScene::setRootLayerID): Deleted.
(WebKit::CoordinatedGraphicsScene::prepareContentBackingStore): Deleted.
(WebKit::CoordinatedGraphicsScene::createBackingStoreIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::removeBackingStoreIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize): Deleted.
(WebKit::CoordinatedGraphicsScene::createTilesIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::removeTilesIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::updateTilesIfNeeded): Deleted.
(WebKit::CoordinatedGraphicsScene::syncImageBackings): Deleted.
(WebKit::CoordinatedGraphicsScene::createImageBacking): Deleted.
(WebKit::CoordinatedGraphicsScene::updateImageBacking): Deleted.
(WebKit::CoordinatedGraphicsScene::clearImageBackingContents): Deleted.
(WebKit::CoordinatedGraphicsScene::removeImageBacking): Deleted.
(WebKit::CoordinatedGraphicsScene::assignImageBackingToLayer): Deleted.
(WebKit::CoordinatedGraphicsScene::setLayerAnimationsIfNeeded): Deleted.

  • Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h:

(WebKit::CoordinatedGraphicsScene::layerByID): Deleted.

  • Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:

(WebKit::ThreadedCompositor::renderLayerTree):

  • WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp:

(WebKit::CompositingCoordinator::flushPendingLayerChanges):

Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r235118 r235165  
     12018-08-22  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [CoordGraphics] Switch to Nicosia::CompositionLayer state tracking
     4        https://bugs.webkit.org/show_bug.cgi?id=188693
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        * Source/cmake/OptionsGTK.cmake: Enable USE_NICOSIA alongside
     9        USE_COORDINATED_GRAPHICS and USE_COORDINATED_GRAPHICS_THREADED.
     10        * Source/cmake/OptionsWPE.cmake: Ditto.
     11
    1122018-08-21  Adrian Perez de Castro  <aperez@igalia.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r235164 r235165  
     12018-08-22  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [CoordGraphics] Switch to Nicosia::CompositionLayer state tracking
     4        https://bugs.webkit.org/show_bug.cgi?id=188693
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Populate Nicosia::CompositionLayer with additional LayerState member
     9        objects. For now we're using pending, staging and committed states,
     10        though it might be possible to narrow down these to just two.
     11
     12        Pending state contains state that will be moved to staging during the
     13        final steps of the next layer flush. flushState() method accumulates all
     14        state changes in the staging state, and also allows the caller to
     15        additionally perform flushing operations that are specific to backing
     16        store, image backing or content layer containers.
     17
     18        commitState() method moves staging state over into the committed state,
     19        again allowing user to pass a functor that receives the just-committed
     20        state and apply it to their composition engine.
     21
     22        Changes in state objects are done under a thread-safe lock. This might
     23        not be completely necessary at this point, but will be useful when
     24        additonal layer state updates will be coming from e.g. the scrolling
     25        thread. It might also make sense to tie in this lock use with the
     26        Nicosia::Scene lock in the future.
     27
     28        Nicosia::ContentLayerTextureMapperImpl is modified slightly to allow
     29        determining during flushes whether an update is pending. This is
     30        necessary for a special case in ThreadedCompositor where content (i.e.
     31        platform) layers like WebGL or video require an additional level of
     32        scene update coordination. This complete special case has to go through
     33        another review to see whether it's still necessary. Ideally we would be
     34        able to remove it.
     35
     36        CoordinatedGraphicsLayer is finally switched over to using
     37        Nicosia layer objects for state updates of any kind. This patch only
     38        adds all the necessary bits, but doesn't yet remove any of the existing
     39        code (but rather disables it temporarily, before it's removed).
     40
     41        Updating of simple state values is already in place. For backing stores,
     42        the flushCompositingStateForThisLayerOnly() method now takes care of
     43        preparing the backing store object if necessary as per layer state,
     44        while the updateContentBuffers() method is switched to operate with
     45        TiledBackingStore objects now kept on the BackingStoreTextureMapperImpl
     46        instance associated with that backing store. Helper methods like
     47        adjustContentsScale() and createBackingStore(), only called from the
     48        updateContentBuffers() method, are removed and the code there inlined.
     49
     50        For image-backed layers, the update is now done directly in
     51        the flushCompositingStateForThisLayerOnly() method, if necessary. The
     52        helper syncImageBacking() method is commented out in order to prevent
     53        double-painting of image buffers for now, but all this (along with the
     54        CoordinatedImageBacking logic in CompositingCoordinator) will be removed
     55        later.
     56
     57        For layers backed by platform layer objects, integration is relatively
     58        simple. setContentsToPlatformLayer() is changed to properly handle any
     59        passed-in platform layer object, and updatePlatformLayer() invokes the
     60        swapBuffersIfNeeded() method on the ContentLayerTextureMapperImpl object
     61        during each flush, if necessary.
     62
     63        In order to ensure any Nicosia-specific state update properly triggers
     64        a composition update, m_nicosia.performLayerUpdate is added and flipped
     65        to true during the flush in case of any state change. This then triggers
     66        a layer sync in the CompositingCoordinator object when the
     67        syncPendingStateChangesIncludingSubLayers() method is called. While no
     68        old-style layer state update is provided, it causes the necessary
     69        synchronization step that properly picks up the Nicosia-provided state
     70        changes. Once the old-style layer state tracking is removed, this method
     71        of update triggering will have to be updated as well.
     72
     73        * platform/graphics/nicosia/NicosiaPlatformLayer.h:
     74        (Nicosia::CompositionLayer::flushState):
     75        (Nicosia::CompositionLayer::commitState):
     76        (Nicosia::CompositionLayer::accessCommitted):
     77        * platform/graphics/nicosia/NicosiaScene.h:
     78        * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp:
     79        (Nicosia::ContentLayerTextureMapperImpl::flushUpdate):
     80        * platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.h:
     81        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
     82        (WebCore::CoordinatedGraphicsLayer::~CoordinatedGraphicsLayer):
     83        (WebCore::CoordinatedGraphicsLayer::setContentsNeedsDisplay):
     84        (WebCore::CoordinatedGraphicsLayer::setContentsToPlatformLayer):
     85        (WebCore::CoordinatedGraphicsLayer::updatePlatformLayer):
     86        (WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
     87        (WebCore::CoordinatedGraphicsLayer::syncPendingStateChangesIncludingSubLayers):
     88        (WebCore::CoordinatedGraphicsLayer::updateContentBuffers):
     89        (WebCore::CoordinatedGraphicsLayer::purgeBackingStores):
     90        (WebCore::CoordinatedGraphicsLayer::adjustContentsScale): Deleted.
     91        (WebCore::CoordinatedGraphicsLayer::createBackingStore): Deleted.
     92        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:
     93
    1942018-08-22  David Kilzer  <ddkilzer@apple.com>
    295
  • trunk/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h

    r234594 r235165  
    181181    }
    182182
     183    template<typename T>
     184    void flushState(const T& functor)
     185    {
     186        LockHolder locker(PlatformLayer::m_state.lock);
     187        auto& pending = m_state.pending;
     188        auto& staging = m_state.staging;
     189
     190        staging.delta.value |= pending.delta.value;
     191
     192        if (pending.delta.positionChanged)
     193            staging.position = pending.position;
     194        if (pending.delta.anchorPointChanged)
     195            staging.anchorPoint = pending.anchorPoint;
     196        if (pending.delta.sizeChanged)
     197            staging.size = pending.size;
     198
     199        if (pending.delta.transformChanged)
     200            staging.transform = pending.transform;
     201        if (pending.delta.childrenTransformChanged)
     202            staging.childrenTransform = pending.childrenTransform;
     203
     204        if (pending.delta.contentsRectChanged)
     205            staging.contentsRect = pending.contentsRect;
     206        if (pending.delta.contentsTilingChanged) {
     207            staging.contentsTilePhase = pending.contentsTilePhase;
     208            staging.contentsTileSize = pending.contentsTileSize;
     209        }
     210
     211        if (pending.delta.opacityChanged)
     212            staging.opacity = pending.opacity;
     213        if (pending.delta.solidColorChanged)
     214            staging.solidColor = pending.solidColor;
     215
     216        if (pending.delta.filtersChanged)
     217            staging.filters = pending.filters;
     218        if (pending.delta.animationsChanged)
     219            staging.animations = pending.animations;
     220
     221        if (pending.delta.childrenChanged)
     222            staging.children = pending.children;
     223        if (pending.delta.maskChanged)
     224            staging.mask = pending.mask;
     225        if (pending.delta.replicaChanged)
     226            staging.replica = pending.replica;
     227
     228        if (pending.delta.flagsChanged)
     229            staging.flags.value = pending.flags.value;
     230
     231        if (pending.delta.repaintCounterChanged)
     232            staging.repaintCounter = pending.repaintCounter;
     233        if (pending.delta.debugBorderChanged)
     234            staging.debugBorder = pending.debugBorder;
     235
     236        if (pending.delta.backingStoreChanged)
     237            staging.backingStore = pending.backingStore;
     238        if (pending.delta.contentLayerChanged)
     239            staging.contentLayer = pending.contentLayer;
     240        if (pending.delta.imageBackingChanged)
     241            staging.imageBacking = pending.imageBacking;
     242
     243        pending.delta = { };
     244
     245        functor(staging);
     246    }
     247
     248    template<typename T>
     249    void commitState(const T& functor)
     250    {
     251        LockHolder locker(PlatformLayer::m_state.lock);
     252        m_state.committed = m_state.staging;
     253        m_state.staging.delta = { };
     254
     255        functor(m_state.committed);
     256    }
     257
     258    template<typename T>
     259    void accessCommitted(const T& functor)
     260    {
     261        LockHolder locker(PlatformLayer::m_state.lock);
     262        functor(m_state.committed);
     263    }
     264
    183265private:
    184266    CompositionLayer(uint64_t, const Impl::Factory&);
     
    188270    struct {
    189271        LayerState pending;
     272        LayerState staging;
     273        LayerState committed;
    190274    } m_state;
    191275};
  • trunk/Source/WebCore/platform/graphics/nicosia/NicosiaScene.h

    r234593 r235165  
    5252
    5353        uint32_t id { 0 };
     54        // FIXME: This is needed for a ThreadedCompositor oddity that might not even be
     55        // necessary anymore. It that has to be checked and ideally removed.
     56        // https://bugs.webkit.org/show_bug.cgi?id=188839
     57        bool platformLayerUpdated { false };
    5458        HashSet<RefPtr<Nicosia::CompositionLayer>> layers;
    5559        RefPtr<Nicosia::CompositionLayer> rootLayer;
  • trunk/Source/WebCore/platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.cpp

    r234643 r235165  
    6464}
    6565
     66bool ContentLayerTextureMapperImpl::flushUpdate()
     67{
     68    LockHolder locker(m_client.lock);
     69    return std::exchange(m_client.pendingUpdate, false);
     70}
     71
    6672void ContentLayerTextureMapperImpl::swapBuffersIfNeeded()
    6773{
  • trunk/Source/WebCore/platform/graphics/nicosia/texmap/NicosiaContentLayerTextureMapperImpl.h

    r234643 r235165  
    5757    void invalidateClient();
    5858
     59    bool flushUpdate();
     60
    5961    WebCore::TextureMapperPlatformLayerProxy& proxy() const { return m_proxy; }
    6062    void swapBuffersIfNeeded();
     
    6567        Lock lock;
    6668        Client* client { nullptr };
     69        bool pendingUpdate { true }; // Starts off with a pending update.
    6770    } m_client;
    6871};
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp

    r234688 r235165  
    3131#include "GraphicsLayer.h"
    3232#include "GraphicsLayerFactory.h"
     33#include "NicosiaBackingStoreTextureMapperImpl.h"
    3334#include "NicosiaCompositionLayerTextureMapperImpl.h"
     35#include "NicosiaContentLayerTextureMapperImpl.h"
     36#include "NicosiaImageBackingTextureMapperImpl.h"
     37#include "NicosiaPaintingContext.h"
    3438#include "NicosiaPaintingEngine.h"
    3539#include "ScrollableArea.h"
     
    161165    ASSERT(!m_coordinatedImageBacking);
    162166    ASSERT(!m_mainBackingStore);
     167    ASSERT(!m_nicosia.imageBacking);
     168    ASSERT(!m_nicosia.backingStore);
    163169    willBeDestroyed();
    164170}
     
    422428{
    423429#if USE(COORDINATED_GRAPHICS_THREADED)
     430#if USE(NICOSIA)
     431    if (m_nicosia.contentLayer)
     432        m_shouldUpdatePlatformLayer = true;
     433#else
    424434    if (m_platformLayer)
    425435        m_shouldUpdatePlatformLayer = true;
    426436#endif
     437#endif
    427438
    428439    notifyFlushRequired();
     
    434445#if USE(COORDINATED_GRAPHICS_THREADED)
    435446#if USE(NICOSIA)
     447    auto* contentLayer = downcast<Nicosia::ContentLayer>(platformLayer);
     448    if (m_nicosia.contentLayer != contentLayer) {
     449        m_shouldSyncPlatformLayer = true;
     450        m_nicosia.contentLayer = contentLayer;
     451        m_nicosia.delta.contentLayerChanged = true;
     452    }
    436453#else
    437454    if (m_platformLayer != platformLayer)
     
    768785#if USE(COORDINATED_GRAPHICS_THREADED)
    769786#if USE(NICOSIA)
     787    if (m_nicosia.contentLayer)
     788        downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosia.contentLayer->impl()).swapBuffersIfNeeded();
    770789#else
    771790    m_layerState.platformLayerUpdated = true;
     
    786805    computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset);
    787806
    788     syncImageBacking();
     807    // FIXME: this is commented out to immediately disable any old-way image updates.
     808    // It will soon be removed in a larger cleanup.
     809    // syncImageBacking();
     810
    789811    syncLayerState();
    790812    syncAnimations();
     
    798820    if (!hasActiveTransformAnimation)
    799821        m_movingVisibleRect = false;
     822
     823    // Determine the backing store presence. Content is painted later, in the updateContentBuffers() traversal.
     824    if (shouldHaveBackingStore()) {
     825        if (!m_nicosia.backingStore) {
     826            m_nicosia.backingStore = Nicosia::BackingStore::create(Nicosia::BackingStoreTextureMapperImpl::createFactory());
     827            m_nicosia.delta.backingStoreChanged = true;
     828        }
     829    } else if (m_nicosia.backingStore) {
     830        auto& layerState = downcast<Nicosia::BackingStoreTextureMapperImpl>(m_nicosia.backingStore->impl()).layerState();
     831        layerState.isPurging = true;
     832        layerState.mainBackingStore = nullptr;
     833        layerState.previousBackingStore = nullptr;
     834
     835        m_nicosia.backingStore = nullptr;
     836        m_nicosia.delta.backingStoreChanged = true;
     837    }
     838
     839    // Determine image backing presence according to the composited image source.
     840    if (m_compositedNativeImagePtr) {
     841        ASSERT(m_compositedImage);
     842        auto& image = *m_compositedImage;
     843        uintptr_t imageID = reinterpret_cast<uintptr_t>(&image);
     844        uintptr_t nativeImageID = reinterpret_cast<uintptr_t>(m_compositedNativeImagePtr.get());
     845
     846        // Respawn the ImageBacking object if the underlying image changed.
     847        if (m_nicosia.imageBacking) {
     848            auto& impl = downcast<Nicosia::ImageBackingTextureMapperImpl>(m_nicosia.imageBacking->impl());
     849            if (impl.layerState().imageID != imageID) {
     850                impl.layerState().update = Nicosia::ImageBackingTextureMapperImpl::Update { };
     851                m_nicosia.imageBacking = nullptr;
     852            }
     853        }
     854        if (!m_nicosia.imageBacking) {
     855            m_nicosia.imageBacking = Nicosia::ImageBacking::create(Nicosia::ImageBackingTextureMapperImpl::createFactory());
     856            m_nicosia.delta.imageBackingChanged = true;
     857        }
     858
     859        // Update the image contents only when the image layer is visible and the native image changed.
     860        auto& impl = downcast<Nicosia::ImageBackingTextureMapperImpl>(m_nicosia.imageBacking->impl());
     861        auto& layerState = impl.layerState();
     862        layerState.imageID = imageID;
     863        layerState.update.isVisible = transformedVisibleRect().intersects(IntRect(contentsRect()));
     864        if (layerState.update.isVisible && layerState.nativeImageID != nativeImageID) {
     865            auto buffer = Nicosia::Buffer::create(IntSize(image.size()),
     866                !image.currentFrameKnownToBeOpaque() ? Nicosia::Buffer::SupportsAlpha : Nicosia::Buffer::NoFlags);
     867            Nicosia::PaintingContext::paint(buffer,
     868                [&image](GraphicsContext& context)
     869                {
     870                    IntRect rect { { }, IntSize { image.size() } };
     871                    context.drawImage(image, rect, rect, ImagePaintingOptions(CompositeCopy));
     872                });
     873            layerState.nativeImageID = nativeImageID;
     874            layerState.update.buffer = WTFMove(buffer);
     875            m_nicosia.delta.imageBackingChanged = true;
     876        }
     877    } else if (m_nicosia.imageBacking) {
     878        auto& layerState = downcast<Nicosia::ImageBackingTextureMapperImpl>(m_nicosia.imageBacking->impl()).layerState();
     879        layerState.update = Nicosia::ImageBackingTextureMapperImpl::Update { };
     880        m_nicosia.imageBacking = nullptr;
     881        m_nicosia.delta.imageBackingChanged = true;
     882    }
    800883
    801884    {
     
    868951                if (localDelta.debugBorderChanged)
    869952                    state.debugBorder = m_nicosia.debugBorder;
     953
     954                if (localDelta.backingStoreChanged)
     955                    state.backingStore = m_nicosia.backingStore;
     956                if (localDelta.contentLayerChanged)
     957                    state.contentLayer = m_nicosia.contentLayer;
     958                if (localDelta.imageBackingChanged)
     959                    state.imageBacking = m_nicosia.imageBacking;
    870960            });
     961        m_nicosia.performLayerSync = !!m_nicosia.delta.value;
    871962        m_nicosia.delta = { };
    872963    }
     
    875966void CoordinatedGraphicsLayer::syncPendingStateChangesIncludingSubLayers()
    876967{
    877     if (m_layerState.hasPendingChanges()) {
     968    // FIXME: For now the best way for layer state changes to trigger an update is to use
     969    // the CoordinatedGraphicsLayerClient::syncLayerState() method. This should be simplified
     970    // once the m_layerState member object is removed.
     971    if (m_nicosia.performLayerSync || m_layerState.hasPendingChanges()) {
    878972        m_coordinator->syncLayerState(m_id, m_layerState);
    879973        resetLayerState();
    880974    }
     975    m_nicosia.performLayerSync = false;
    881976
    882977    if (maskLayer())
     
    9221017{
    9231018    return selfOrAncestorHaveNonAffineTransforms() ? 1 : deviceScaleFactor() * pageScaleFactor();
    924 }
    925 
    926 void CoordinatedGraphicsLayer::adjustContentsScale()
    927 {
    928     ASSERT(shouldHaveBackingStore());
    929     if (!m_mainBackingStore || m_mainBackingStore->contentsScale() == effectiveContentsScale())
    930         return;
    931 
    932     // Between creating the new backing store and painting the content,
    933     // we do not want to drop the previous one as that might result in
    934     // briefly seeing flickering as the old tiles may be dropped before
    935     // something replaces them.
    936     m_previousBackingStore = WTFMove(m_mainBackingStore);
    937 
    938     // No reason to save the previous backing store for non-visible areas.
    939     m_previousBackingStore->removeAllNonVisibleTiles(transformedVisibleRect(), IntRect(0, 0, size().width(), size().height()));
    940 }
    941 
    942 void CoordinatedGraphicsLayer::createBackingStore()
    943 {
    944     m_mainBackingStore = std::make_unique<TiledBackingStore>(*this, effectiveContentsScale());
    9451019}
    9461020
     
    10251099void CoordinatedGraphicsLayer::updateContentBuffers()
    10261100{
    1027     if (!shouldHaveBackingStore()) {
    1028         m_mainBackingStore = nullptr;
    1029         m_previousBackingStore = nullptr;
    1030         return;
    1031     }
    1032 
     1101    if (!m_nicosia.backingStore)
     1102        return;
     1103
     1104    // Prepare for painting on the impl-contained backing store. isFlushing is used there
     1105    // for internal sanity checks.
     1106    auto& impl = downcast<Nicosia::BackingStoreTextureMapperImpl>(m_nicosia.backingStore->impl());
     1107    auto& layerState = impl.layerState();
     1108    layerState.isFlushing = true;
     1109
     1110    // Helper lambda that finished the flush update and determines layer sync necessity.
     1111    auto finishUpdate =
     1112        [this, &layerState] {
     1113            auto& update = layerState.update;
     1114            m_nicosia.performLayerSync = !update.tilesToCreate.isEmpty()
     1115                || !update.tilesToRemove.isEmpty() || !update.tilesToUpdate.isEmpty();
     1116            layerState.isFlushing = false;
     1117        };
     1118
     1119    // Address the content scale adjustment.
     1120    // FIXME: the previousBackingStore logic is likely possible to remove.
     1121    // https://bugs.webkit.org/show_bug.cgi?id=188693
    10331122    if (m_pendingContentsScaleAdjustment) {
    1034         adjustContentsScale();
     1123        if (layerState.mainBackingStore && layerState.mainBackingStore->contentsScale() != effectiveContentsScale()) {
     1124            // Between creating the new backing store and painting the content, we do not
     1125            // want to drop the previous one as that might result in briefly seeing flickering
     1126            // as the old tiles may be dropped before something replaces them.
     1127            layerState.previousBackingStore = WTFMove(layerState.mainBackingStore);
     1128
     1129            // No reason to save the previous backing store for non-visible areas.
     1130            layerState.previousBackingStore->removeAllNonVisibleTiles(transformedVisibleRect(), IntRect(0, 0, size().width(), size().height()));
     1131        }
    10351132        m_pendingContentsScaleAdjustment = false;
    10361133    }
    10371134
    1038     // This is the only place we (re)create the main tiled backing store, once we
    1039     // have a remote client and we are ready to send our data to the UI process.
    1040     if (!m_mainBackingStore) {
    1041         createBackingStore();
     1135    // Ensure the TiledBackingStore object, and enforce a complete repaint if it's not been present yet.
     1136    if (!layerState.mainBackingStore) {
     1137        layerState.mainBackingStore = std::make_unique<TiledBackingStore>(impl, effectiveContentsScale());
    10421138        m_pendingVisibleRectAdjustment = true;
    10431139    }
    10441140
    1045     if (!m_pendingVisibleRectAdjustment && !m_needsDisplay.completeLayer && m_needsDisplay.rects.isEmpty())
    1046         return;
     1141    // Bail if there's no painting recorded or enforced.
     1142    if (!m_pendingVisibleRectAdjustment && !m_needsDisplay.completeLayer && m_needsDisplay.rects.isEmpty()) {
     1143        finishUpdate();
     1144        return;
     1145    }
    10471146
    10481147    if (!m_needsDisplay.completeLayer) {
    10491148        for (auto& rect : m_needsDisplay.rects)
    1050             m_mainBackingStore->invalidate(IntRect { rect });
     1149            layerState.mainBackingStore->invalidate(IntRect { rect });
    10511150    } else
    1052         m_mainBackingStore->invalidate({ { }, IntSize { m_size } });
     1151        layerState.mainBackingStore->invalidate({ { }, IntSize { m_size } });
    10531152
    10541153    m_needsDisplay.completeLayer = false;
     
    10571156    if (m_pendingVisibleRectAdjustment) {
    10581157        m_pendingVisibleRectAdjustment = false;
    1059         m_mainBackingStore->createTilesIfNeeded(transformedVisibleRect(), IntRect(0, 0, size().width(), size().height()));
     1158        layerState.mainBackingStore->createTilesIfNeeded(transformedVisibleRect(), IntRect(0, 0, m_size.width(), m_size.height()));
    10601159    }
    10611160
    10621161    ASSERT(m_coordinator && m_coordinator->isFlushingLayerChanges());
    10631162
    1064     auto dirtyTiles = m_mainBackingStore->dirtyTiles();
     1163    // With all the affected tiles created and/or invalidated, we can finally paint them.
     1164    auto dirtyTiles = layerState.mainBackingStore->dirtyTiles();
    10651165    if (!dirtyTiles.isEmpty()) {
    10661166        bool didUpdateTiles = false;
     
    10801180
    10811181            if (!m_coordinator->paintingEngine().paint(*this, WTFMove(coordinatedBuffer),
    1082                 dirtyRect, m_mainBackingStore->mapToContents(dirtyRect),
    1083                 IntRect { { 0, 0 }, dirtyRect.size() }, m_mainBackingStore->contentsScale()))
     1182                dirtyRect, layerState.mainBackingStore->mapToContents(dirtyRect),
     1183                IntRect { { 0, 0 }, dirtyRect.size() }, layerState.mainBackingStore->contentsScale()))
    10841184                continue;
    10851185
    1086             updateTile(tile.tileID(), updateInfo, tileRect);
     1186            impl.updateTile(tile.tileID(), updateInfo, tileRect);
    10871187
    10881188            tile.markClean();
     
    10971197    // removing the existing tiles and painting the new ones. The first time
    10981198    // the visibleRect is full painted we remove the previous backing store.
    1099     if (m_previousBackingStore && m_mainBackingStore->visibleAreaIsCovered())
    1100         m_previousBackingStore = nullptr;
     1199    if (layerState.previousBackingStore && layerState.mainBackingStore->visibleAreaIsCovered())
     1200        layerState.previousBackingStore = nullptr;
     1201
     1202    // Request a second update immediately if some tiles are still pending creation.
     1203    if (layerState.hasPendingTileCreation) {
     1204        setNeedsVisibleRectAdjustment();
     1205        notifyFlushRequired();
     1206    }
     1207
     1208    finishUpdate();
    11011209}
    11021210
     
    11081216    m_mainBackingStore = nullptr;
    11091217    m_previousBackingStore = nullptr;
     1218    if (m_nicosia.backingStore) {
     1219        auto& layerState = downcast<Nicosia::BackingStoreTextureMapperImpl>(m_nicosia.backingStore->impl()).layerState();
     1220        layerState.isPurging = true;
     1221        layerState.mainBackingStore = nullptr;
     1222        layerState.previousBackingStore = nullptr;
     1223
     1224        m_nicosia.backingStore = nullptr;
     1225    }
    11101226
    11111227    releaseImageBackingIfNeeded();
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h

    r233910 r235165  
    111111    void suspendAnimations(MonotonicTime) override;
    112112    void resumeAnimations() override;
    113     bool usesContentsLayer() const override { return m_platformLayer || m_compositedImage; }
     113    bool usesContentsLayer() const override { return m_platformLayer || m_nicosia.contentLayer || m_compositedImage; }
    114114
    115115    void syncPendingStateChangesIncludingSubLayers();
     
    162162    void updateContentBuffers();
    163163
    164     void createBackingStore();
    165164    void releaseImageBackingIfNeeded();
    166165
     
    172171    bool selfOrAncestorHasActiveTransformAnimation() const;
    173172    bool selfOrAncestorHaveNonAffineTransforms();
    174     void adjustContentsScale();
    175173
    176174    void setShouldUpdateVisibleRect();
     
    232230        Nicosia::CompositionLayer::LayerState::RepaintCounter repaintCounter;
    233231        Nicosia::CompositionLayer::LayerState::DebugBorder debugBorder;
     232        bool performLayerSync { false };
     233
     234        RefPtr<Nicosia::BackingStore> backingStore;
     235        RefPtr<Nicosia::ContentLayer> contentLayer;
     236        RefPtr<Nicosia::ImageBacking> imageBacking;
    234237    } m_nicosia;
    235238};
  • trunk/Source/WebKit/ChangeLog

    r235158 r235165  
     12018-08-22  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [CoordGraphics] Switch to Nicosia::CompositionLayer state tracking
     4        https://bugs.webkit.org/show_bug.cgi?id=188693
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Switch CoordinatedGraphicsScene to utilizing Nicosia::CompositionLayer
     9        objects for state updates of the TextureMapper layer tree.
     10
     11        CoordinatedGraphicsScene::paintToCurrentGLContext() now calls
     12        updateSceneState() at the beginning. This is a new method that manages
     13        all updates for a given Nicosia::Scene instance. Any removed layers
     14        have their composition-side state cleaned up, and the current set of
     15        layers is then iterated to ensure and update the corresponding
     16        TextureMapperLayer objects.
     17
     18        Layers with any backing (painted backing store, platform-layer or image
     19        content) are temporarly stored for updating outside of mutex-controlled
     20        scene update. Performing all other state updates outside of this mutex
     21        area will be investigated at a later point.
     22
     23        We then iterate over vectors for each layer backing, gathering any
     24        affected CoordinatedBackingStore or TextureMapperPlatformLayerProxy
     25        objects that we have to update.
     26
     27        This drops a bunch of member variables and helper methods off the
     28        CoordinatedGraphicsScene class. The applyStateChanges() method will be
     29        further simplified in the future. coordinateUpdateCompletionWithClient
     30        logic in ThreadedCompositor should be checked to see whether it still
     31        addresses any real-life problem, because at the moment it imposes a few
     32        additional operations in terms of scene updates that we could really do
     33        without. This will be checked later and removed if possible.
     34
     35        * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp:
     36        (WebKit::CoordinatedGraphicsScene::applyStateChanges):
     37        (WebKit::CoordinatedGraphicsScene::paintToCurrentGLContext):
     38        (WebKit::compositionLayerImpl):
     39        (WebKit::contentLayerImpl):
     40        (WebKit::backingStoreImpl):
     41        (WebKit::imageBackingImpl):
     42        (WebKit::texmapLayer):
     43        (WebKit::updateBackingStore):
     44        (WebKit::updateImageBacking):
     45        (WebKit::removeLayer):
     46        (WebKit::CoordinatedGraphicsScene::commitSceneState):
     47        (WebKit::CoordinatedGraphicsScene::updateSceneState):
     48        (WebKit::CoordinatedGraphicsScene::purgeGLResources):
     49        (WebKit::CoordinatedGraphicsScene::syncPlatformLayerIfNeeded): Deleted.
     50        (WebKit::CoordinatedGraphicsScene::setLayerChildrenIfNeeded): Deleted.
     51        (WebKit::CoordinatedGraphicsScene::setLayerFiltersIfNeeded): Deleted.
     52        (WebKit::CoordinatedGraphicsScene::setLayerState): Deleted.
     53        (WebKit::CoordinatedGraphicsScene::getLayerByIDIfExists): Deleted.
     54        (WebKit::CoordinatedGraphicsScene::createLayers): Deleted.
     55        (WebKit::CoordinatedGraphicsScene::createLayer): Deleted.
     56        (WebKit::CoordinatedGraphicsScene::deleteLayers): Deleted.
     57        (WebKit::CoordinatedGraphicsScene::deleteLayer): Deleted.
     58        (WebKit::CoordinatedGraphicsScene::setRootLayerID): Deleted.
     59        (WebKit::CoordinatedGraphicsScene::prepareContentBackingStore): Deleted.
     60        (WebKit::CoordinatedGraphicsScene::createBackingStoreIfNeeded): Deleted.
     61        (WebKit::CoordinatedGraphicsScene::removeBackingStoreIfNeeded): Deleted.
     62        (WebKit::CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize): Deleted.
     63        (WebKit::CoordinatedGraphicsScene::createTilesIfNeeded): Deleted.
     64        (WebKit::CoordinatedGraphicsScene::removeTilesIfNeeded): Deleted.
     65        (WebKit::CoordinatedGraphicsScene::updateTilesIfNeeded): Deleted.
     66        (WebKit::CoordinatedGraphicsScene::syncImageBackings): Deleted.
     67        (WebKit::CoordinatedGraphicsScene::createImageBacking): Deleted.
     68        (WebKit::CoordinatedGraphicsScene::updateImageBacking): Deleted.
     69        (WebKit::CoordinatedGraphicsScene::clearImageBackingContents): Deleted.
     70        (WebKit::CoordinatedGraphicsScene::removeImageBacking): Deleted.
     71        (WebKit::CoordinatedGraphicsScene::assignImageBackingToLayer): Deleted.
     72        (WebKit::CoordinatedGraphicsScene::setLayerAnimationsIfNeeded): Deleted.
     73        * Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h:
     74        (WebKit::CoordinatedGraphicsScene::layerByID): Deleted.
     75        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
     76        (WebKit::ThreadedCompositor::renderLayerTree):
     77        * WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp:
     78        (WebKit::CompositingCoordinator::flushPendingLayerChanges):
     79
    1802018-08-21  Ryosuke Niwa  <rniwa@webkit.org>
    281
  • trunk/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp

    r234455 r235165  
    2626
    2727#include <WebCore/CoordinatedBackingStore.h>
     28#include <WebCore/NicosiaBackingStoreTextureMapperImpl.h>
    2829#include <WebCore/NicosiaBuffer.h>
     30#include <WebCore/NicosiaCompositionLayerTextureMapperImpl.h>
     31#include <WebCore/NicosiaContentLayerTextureMapperImpl.h>
     32#include <WebCore/NicosiaImageBackingTextureMapperImpl.h>
     33#include <WebCore/NicosiaScene.h>
    2934#include <WebCore/TextureMapper.h>
    3035#include <WebCore/TextureMapperBackingStore.h>
     
    5863
    5964    for (auto& state : states)
    60         commitSceneState(state);
     65        commitSceneState(state.nicosia);
    6166}
    6267
    6368void CoordinatedGraphicsScene::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect, const Color& backgroundColor, bool drawsBackground, TextureMapper::PaintFlags PaintFlags)
    6469{
     70    updateSceneState();
     71
    6572    TextureMapperLayer* currentRootLayer = rootLayer();
    6673    if (!currentRootLayer)
    6774        return;
    68 
    69 #if USE(COORDINATED_GRAPHICS_THREADED)
    70     for (auto& proxy : m_platformLayerProxies.values())
    71         proxy->swapBuffer();
    72 #endif
    7375
    7476    currentRootLayer->setTextureMapper(m_textureMapper.get());
     
    105107}
    106108
    107 void CoordinatedGraphicsScene::syncPlatformLayerIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
    108 {
    109 #if USE(COORDINATED_GRAPHICS_THREADED)
    110     if (!state.platformLayerChanged)
    111         return;
    112 
    113     if (state.platformLayerProxy) {
    114         m_platformLayerProxies.set(layer, state.platformLayerProxy);
    115         state.platformLayerProxy->activateOnCompositingThread(this, layer);
    116     } else
    117         m_platformLayerProxies.remove(layer);
    118 #else
    119     UNUSED_PARAM(layer);
    120     UNUSED_PARAM(state);
    121 #endif
    122 }
    123 
    124109#if USE(COORDINATED_GRAPHICS_THREADED)
    125110void CoordinatedGraphicsScene::onNewBufferAvailable()
     
    129114#endif
    130115
    131 void CoordinatedGraphicsScene::setLayerChildrenIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
    132 {
    133     if (!state.childrenChanged)
    134         return;
    135 
    136     Vector<TextureMapperLayer*> children;
    137     children.reserveCapacity(state.children.size());
    138     for (auto& child : state.children)
    139         children.append(layerByID(child));
    140 
    141     layer->setChildren(children);
    142 }
    143 
    144 void CoordinatedGraphicsScene::setLayerFiltersIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
    145 {
    146     if (!state.filtersChanged)
    147         return;
    148 
    149     layer->setFilters(state.filters);
    150 }
    151 
    152 void CoordinatedGraphicsScene::setLayerState(CoordinatedLayerID id, const CoordinatedGraphicsLayerState& layerState, CommitScope& commitScope)
    153 {
    154     ASSERT(m_rootLayerID != InvalidCoordinatedLayerID);
    155     TextureMapperLayer* layer = layerByID(id);
    156 
    157     if (layerState.positionChanged)
    158         layer->setPosition(layerState.pos);
    159 
    160     if (layerState.anchorPointChanged)
    161         layer->setAnchorPoint(layerState.anchorPoint);
    162 
    163     if (layerState.sizeChanged)
    164         layer->setSize(layerState.size);
    165 
    166     if (layerState.transformChanged)
    167         layer->setTransform(layerState.transform);
    168 
    169     if (layerState.childrenTransformChanged)
    170         layer->setChildrenTransform(layerState.childrenTransform);
    171 
    172     if (layerState.contentsRectChanged)
    173         layer->setContentsRect(layerState.contentsRect);
    174 
    175     if (layerState.contentsTilingChanged) {
    176         layer->setContentsTilePhase(layerState.contentsTilePhase);
    177         layer->setContentsTileSize(layerState.contentsTileSize);
    178     }
    179 
    180     if (layerState.opacityChanged)
    181         layer->setOpacity(layerState.opacity);
    182 
    183     if (layerState.solidColorChanged)
    184         layer->setSolidColor(layerState.solidColor);
    185 
    186     if (layerState.debugVisualsChanged)
    187         layer->setDebugVisuals(layerState.debugVisuals.showDebugBorders, layerState.debugVisuals.debugBorderColor, layerState.debugVisuals.debugBorderWidth);
    188     if (layerState.repaintCountChanged)
    189         layer->setRepaintCounter(layerState.repaintCount.showRepaintCounter, layerState.repaintCount.count);
    190 
    191     if (layerState.replicaChanged)
    192         layer->setReplicaLayer(getLayerByIDIfExists(layerState.replica));
    193 
    194     if (layerState.maskChanged)
    195         layer->setMaskLayer(getLayerByIDIfExists(layerState.mask));
    196 
    197     if (layerState.imageChanged)
    198         assignImageBackingToLayer(layer, layerState.imageID);
    199 
    200     if (layerState.flagsChanged) {
    201         layer->setContentsOpaque(layerState.contentsOpaque);
    202         layer->setDrawsContent(layerState.drawsContent);
    203         layer->setContentsVisible(layerState.contentsVisible);
    204         layer->setBackfaceVisibility(layerState.backfaceVisible);
    205 
    206         // Never clip the root layer.
    207         layer->setMasksToBounds(id == m_rootLayerID ? false : layerState.masksToBounds);
    208         layer->setPreserves3D(layerState.preserves3D);
    209     }
    210 
    211     // Apply Operations.
    212     setLayerChildrenIfNeeded(layer, layerState);
    213     setLayerFiltersIfNeeded(layer, layerState);
    214     setLayerAnimationsIfNeeded(layer, layerState);
    215     prepareContentBackingStore(layer, commitScope);
    216     createTilesIfNeeded(layer, layerState);
    217     removeTilesIfNeeded(layer, layerState, commitScope);
    218     updateTilesIfNeeded(layer, layerState, commitScope);
    219     syncPlatformLayerIfNeeded(layer, layerState);
    220 }
    221 
    222 TextureMapperLayer* CoordinatedGraphicsScene::getLayerByIDIfExists(CoordinatedLayerID id)
    223 {
    224     return (id != InvalidCoordinatedLayerID) ? layerByID(id) : 0;
    225 }
    226 
    227 void CoordinatedGraphicsScene::createLayers(const Vector<CoordinatedLayerID>& layerIDs)
    228 {
    229     for (auto& layerID : layerIDs)
    230         createLayer(layerID);
    231 }
    232 
    233 void CoordinatedGraphicsScene::createLayer(CoordinatedLayerID id)
    234 {
    235     std::unique_ptr<TextureMapperLayer> newLayer = std::make_unique<TextureMapperLayer>();
    236     newLayer->setID(id);
    237     m_layers.add(id, WTFMove(newLayer));
    238 }
    239 
    240 void CoordinatedGraphicsScene::deleteLayers(const Vector<CoordinatedLayerID>& layerIDs)
    241 {
    242     for (auto& layerID : layerIDs)
    243         deleteLayer(layerID);
    244 }
    245 
    246 void CoordinatedGraphicsScene::deleteLayer(CoordinatedLayerID layerID)
    247 {
    248     std::unique_ptr<TextureMapperLayer> layer = m_layers.take(layerID);
    249     ASSERT(layer);
    250 
    251     m_backingStores.remove(layer.get());
    252 #if USE(COORDINATED_GRAPHICS_THREADED)
    253     if (auto platformLayerProxy = m_platformLayerProxies.take(layer.get()))
    254         platformLayerProxy->invalidate();
    255 #endif
    256 }
    257 
    258 void CoordinatedGraphicsScene::setRootLayerID(CoordinatedLayerID layerID)
    259 {
    260     ASSERT(layerID != InvalidCoordinatedLayerID);
    261     ASSERT(m_rootLayerID == InvalidCoordinatedLayerID);
    262 
    263     m_rootLayerID = layerID;
    264 
    265     TextureMapperLayer* layer = layerByID(layerID);
    266     ASSERT(m_rootLayer->children().isEmpty());
    267     m_rootLayer->addChild(layer);
    268 }
    269 
    270 void CoordinatedGraphicsScene::prepareContentBackingStore(TextureMapperLayer* layer, CommitScope& commitScope)
    271 {
    272     if (!layerShouldHaveBackingStore(layer)) {
    273         removeBackingStoreIfNeeded(layer);
    274         return;
    275     }
    276 
    277     createBackingStoreIfNeeded(layer);
    278     resetBackingStoreSizeToLayerSize(layer, commitScope);
    279 }
    280 
    281 void CoordinatedGraphicsScene::createBackingStoreIfNeeded(TextureMapperLayer* layer)
    282 {
    283     if (m_backingStores.contains(layer))
    284         return;
    285 
    286     auto backingStore = CoordinatedBackingStore::create();
    287     m_backingStores.add(layer, backingStore.copyRef());
    288     layer->setBackingStore(backingStore.ptr());
    289 }
    290 
    291 void CoordinatedGraphicsScene::removeBackingStoreIfNeeded(TextureMapperLayer* layer)
    292 {
    293     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.take(layer);
    294     if (!backingStore)
    295         return;
    296 
    297     layer->setBackingStore(nullptr);
    298 }
    299 
    300 void CoordinatedGraphicsScene::resetBackingStoreSizeToLayerSize(TextureMapperLayer* layer, CommitScope& commitScope)
    301 {
    302     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
    303     ASSERT(backingStore);
    304     backingStore->setSize(layer->size());
    305     commitScope.backingStoresWithPendingBuffers.add(backingStore);
    306 }
    307 
    308 void CoordinatedGraphicsScene::createTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
    309 {
    310     if (state.tilesToCreate.isEmpty())
    311         return;
    312 
    313     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
    314     ASSERT(backingStore || !layerShouldHaveBackingStore(layer));
    315     if (!backingStore)
    316         return;
    317 
    318     for (auto& tile : state.tilesToCreate)
    319         backingStore->createTile(tile.tileID, tile.scale);
    320 }
    321 
    322 void CoordinatedGraphicsScene::removeTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state, CommitScope& commitScope)
    323 {
    324     if (state.tilesToRemove.isEmpty())
    325         return;
    326 
    327     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
    328     if (!backingStore)
    329         return;
    330 
    331     for (auto& tile : state.tilesToRemove)
    332         backingStore->removeTile(tile);
    333 
    334     commitScope.backingStoresWithPendingBuffers.add(backingStore);
    335 }
    336 
    337 void CoordinatedGraphicsScene::updateTilesIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state, CommitScope& commitScope)
    338 {
    339     if (state.tilesToUpdate.isEmpty())
    340         return;
    341 
    342     RefPtr<CoordinatedBackingStore> backingStore = m_backingStores.get(layer);
    343     ASSERT(backingStore || !layerShouldHaveBackingStore(layer));
    344     if (!backingStore)
    345         return;
    346 
    347     for (auto& tile : state.tilesToUpdate) {
    348         const SurfaceUpdateInfo& surfaceUpdateInfo = tile.updateInfo;
    349 
    350         backingStore->updateTile(tile.tileID, surfaceUpdateInfo.updateRect, tile.tileRect, surfaceUpdateInfo.buffer.copyRef(), { 0, 0 });
    351         commitScope.backingStoresWithPendingBuffers.add(backingStore);
    352     }
    353 }
    354 
    355 void CoordinatedGraphicsScene::syncImageBackings(const CoordinatedGraphicsState& state, CommitScope& commitScope)
    356 {
    357     for (auto& image : state.imagesToRemove)
    358         removeImageBacking(image, commitScope);
    359 
    360     for (auto& image : state.imagesToCreate)
    361         createImageBacking(image);
    362 
    363     for (auto& image : state.imagesToUpdate)
    364         updateImageBacking(image.first, image.second.copyRef(), commitScope);
    365 
    366     for (auto& image : state.imagesToClear)
    367         clearImageBackingContents(image, commitScope);
    368 }
    369 
    370 void CoordinatedGraphicsScene::createImageBacking(CoordinatedImageBackingID imageID)
    371 {
    372     ASSERT(!m_imageBackings.contains(imageID));
    373     m_imageBackings.add(imageID, CoordinatedBackingStore::create());
    374 }
    375 
    376 void CoordinatedGraphicsScene::updateImageBacking(CoordinatedImageBackingID imageID, RefPtr<Nicosia::Buffer>&& buffer, CommitScope& commitScope)
    377 {
    378     ASSERT(m_imageBackings.contains(imageID));
    379     auto it = m_imageBackings.find(imageID);
    380     RefPtr<CoordinatedBackingStore> backingStore = it->value;
    381 
    382     // CoordinatedImageBacking is realized to CoordinatedBackingStore with only one tile in UI Process.
    383     backingStore->createTile(1 /* id */, 1 /* scale */);
    384     IntRect rect(IntPoint::zero(), buffer->size());
    385     // See CoordinatedGraphicsLayer::shouldDirectlyCompositeImage()
     116Nicosia::CompositionLayerTextureMapperImpl& compositionLayerImpl(Nicosia::CompositionLayer& compositionLayer)
     117{
     118    return downcast<Nicosia::CompositionLayerTextureMapperImpl>(compositionLayer.impl());
     119}
     120
     121Nicosia::ContentLayerTextureMapperImpl& contentLayerImpl(Nicosia::ContentLayer& contentLayer)
     122{
     123    return downcast<Nicosia::ContentLayerTextureMapperImpl>(contentLayer.impl());
     124}
     125
     126Nicosia::BackingStoreTextureMapperImpl& backingStoreImpl(Nicosia::BackingStore& backingStore)
     127{
     128    return downcast<Nicosia::BackingStoreTextureMapperImpl>(backingStore.impl());
     129}
     130
     131Nicosia::ImageBackingTextureMapperImpl& imageBackingImpl(Nicosia::ImageBacking& imageBacking)
     132{
     133    return downcast<Nicosia::ImageBackingTextureMapperImpl>(imageBacking.impl());
     134}
     135
     136TextureMapperLayer& texmapLayer(Nicosia::CompositionLayer& compositionLayer)
     137{
     138    auto& compositionState = compositionLayerImpl(compositionLayer).compositionState();
     139    if (!compositionState.layer) {
     140        compositionState.layer = std::make_unique<TextureMapperLayer>();
     141        compositionState.layer->setID(compositionLayer.id());
     142    }
     143    return *compositionState.layer;
     144}
     145
     146void updateBackingStore(TextureMapperLayer& layer,
     147    Nicosia::BackingStoreTextureMapperImpl::CompositionState& compositionState,
     148    const Nicosia::BackingStoreTextureMapperImpl::TileUpdate& update)
     149{
     150    if (!layerShouldHaveBackingStore(&layer)) {
     151        layer.setBackingStore(nullptr);
     152        compositionState.backingStore = nullptr;
     153        return;
     154    }
     155
     156    if (!compositionState.backingStore)
     157        compositionState.backingStore = CoordinatedBackingStore::create();
     158    auto& backingStore = *compositionState.backingStore;
     159
     160    layer.setBackingStore(&backingStore);
     161    backingStore.setSize(layer.size());
     162
     163    for (auto& tile : update.tilesToCreate)
     164        backingStore.createTile(tile.tileID, tile.scale);
     165    for (auto& tile : update.tilesToRemove)
     166        backingStore.removeTile(tile.tileID);
     167    for (auto& tile : update.tilesToUpdate) {
     168        backingStore.updateTile(tile.tileID, tile.updateInfo.updateRect,
     169            tile.tileRect, tile.updateInfo.buffer.copyRef(), { 0, 0 });
     170    }
     171}
     172
     173void updateImageBacking(TextureMapperLayer& layer,
     174    Nicosia::ImageBackingTextureMapperImpl::CompositionState& compositionState,
     175    Nicosia::ImageBackingTextureMapperImpl::Update& update)
     176{
     177    if (!update.isVisible) {
     178        layer.setBackingStore(nullptr);
     179        return;
     180    }
     181
     182    if (!compositionState.backingStore)
     183        compositionState.backingStore = CoordinatedBackingStore::create();
     184    auto& backingStore = *compositionState.backingStore;
     185    layer.setContentsLayer(&backingStore);
     186
     187    if (!update.buffer)
     188        return;
     189
     190    backingStore.createTile(1, 1.0);
     191    WebCore::IntRect rect { { }, update.buffer->size() };
    386192    ASSERT(2000 >= std::max(rect.width(), rect.height()));
    387     backingStore->setSize(rect.size());
    388     backingStore->updateTile(1 /* id */, rect, rect, WTFMove(buffer), rect.location());
    389 
    390     commitScope.backingStoresWithPendingBuffers.add(backingStore);
    391 }
    392 
    393 void CoordinatedGraphicsScene::clearImageBackingContents(CoordinatedImageBackingID imageID, CommitScope& commitScope)
    394 {
    395     ASSERT(m_imageBackings.contains(imageID));
    396     auto it = m_imageBackings.find(imageID);
    397     RefPtr<CoordinatedBackingStore> backingStore = it->value;
    398     backingStore->removeAllTiles();
    399     commitScope.backingStoresWithPendingBuffers.add(backingStore);
    400 }
    401 
    402 void CoordinatedGraphicsScene::removeImageBacking(CoordinatedImageBackingID imageID, CommitScope& commitScope)
    403 {
    404     ASSERT(m_imageBackings.contains(imageID));
    405 
    406     // We don't want TextureMapperLayer refers a dangling pointer.
    407     commitScope.releasedImageBackings.append(m_imageBackings.take(imageID));
    408 }
    409 
    410 void CoordinatedGraphicsScene::assignImageBackingToLayer(TextureMapperLayer* layer, CoordinatedImageBackingID imageID)
    411 {
    412     if (imageID == InvalidCoordinatedImageBackingID) {
    413         layer->setContentsLayer(0);
    414         return;
    415     }
    416 
    417     auto it = m_imageBackings.find(imageID);
    418     ASSERT(it != m_imageBackings.end());
    419     layer->setContentsLayer(it->value.get());
    420 }
    421 
    422 void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState& state)
     193    backingStore.setSize(rect.size());
     194    backingStore.updateTile(1, rect, rect, WTFMove(update.buffer), rect.location());
     195}
     196
     197void removeLayer(Nicosia::CompositionLayer& layer)
     198{
     199    layer.accessCommitted(
     200        [](const Nicosia::CompositionLayer::LayerState& committed)
     201        {
     202            if (committed.backingStore) {
     203                auto& compositionState = backingStoreImpl(*committed.backingStore).compositionState();
     204                compositionState.backingStore = nullptr;
     205            }
     206
     207            if (committed.contentLayer)
     208                contentLayerImpl(*committed.contentLayer).proxy().invalidate();
     209
     210            if (committed.imageBacking) {
     211                auto& compositionState = imageBackingImpl(*committed.imageBacking).compositionState();
     212                compositionState.backingStore = nullptr;
     213            }
     214        });
     215
     216    auto& compositionState = compositionLayerImpl(layer).compositionState();
     217    compositionState.layer = nullptr;
     218}
     219
     220void CoordinatedGraphicsScene::commitSceneState(const CoordinatedGraphicsState::NicosiaState& state)
    423221{
    424222    if (!m_client)
    425223        return;
    426224
    427     m_nicosia = state.nicosia;
    428     // FIXME: Start using the Nicosia layer state for updates.
    429 
    430     CommitScope commitScope;
    431 
    432     createLayers(state.layersToCreate);
    433     deleteLayers(state.layersToRemove);
    434 
    435     if (state.rootCompositingLayer != m_rootLayerID)
    436         setRootLayerID(state.rootCompositingLayer);
    437 
    438     syncImageBackings(state, commitScope);
    439 
    440     for (auto& layer : state.layersToUpdate)
    441         setLayerState(layer.first, layer.second, commitScope);
    442 
    443     for (auto& backingStore : commitScope.backingStoresWithPendingBuffers)
     225    m_nicosia.scene = state.scene;
     226}
     227
     228void CoordinatedGraphicsScene::updateSceneState()
     229{
     230    if (!m_nicosia.scene)
     231        return;
     232
     233    // Store layer and impl references along with the corresponding update
     234    // for each type of possible layer backing.
     235    struct {
     236        struct BackingStore {
     237            std::reference_wrapper<TextureMapperLayer> layer;
     238            std::reference_wrapper<Nicosia::BackingStoreTextureMapperImpl> backingStore;
     239            Nicosia::BackingStoreTextureMapperImpl::TileUpdate update;
     240        };
     241        Vector<BackingStore> backingStore;
     242
     243        struct ContentLayer {
     244            std::reference_wrapper<TextureMapperLayer> layer;
     245            std::reference_wrapper<TextureMapperPlatformLayerProxy> proxy;
     246            bool needsActivation { false };
     247        };
     248        Vector<ContentLayer> contentLayer;
     249
     250        struct ImageBacking {
     251            std::reference_wrapper<TextureMapperLayer> layer;
     252            std::reference_wrapper<Nicosia::ImageBackingTextureMapperImpl> imageBacking;
     253            Nicosia::ImageBackingTextureMapperImpl::Update update;
     254        };
     255        Vector<ImageBacking> imageBacking;
     256    } layersByBacking;
     257
     258    // Access the scene state and perform state update for each layer.
     259    m_nicosia.scene->accessState(
     260        [this, &layersByBacking](Nicosia::Scene::State& state)
     261        {
     262            // Bail if the scene didn't change.
     263            if (state.id == m_nicosia.state.id)
     264                return;
     265
     266            // Handle the root layer, adding it to the TextureMapperLayer tree
     267            // on the first update. No such change is expected later.
     268            {
     269                auto& rootLayer = texmapLayer(*state.rootLayer);
     270                if (rootLayer.id() != m_rootLayerID) {
     271                    m_rootLayerID = rootLayer.id();
     272                    RELEASE_ASSERT(m_rootLayer->children().isEmpty());
     273                    m_rootLayer->addChild(&rootLayer);
     274                }
     275            }
     276
     277            // Gather all the to-be-removed layers so that composition-side state
     278            // can be properly purged after the current state's set of layers is adopted.
     279            HashSet<RefPtr<Nicosia::CompositionLayer>> removedLayers;
     280            for (auto& layer : m_nicosia.state.layers) {
     281                if (!state.layers.contains(layer))
     282                    removedLayers.add(layer);
     283            }
     284
     285            m_nicosia.state = state;
     286
     287            for (auto& layer : removedLayers)
     288                removeLayer(*layer);
     289            removedLayers = { };
     290
     291            // Iterate the current state's set of layers, updating state values according to
     292            // the incoming state changes. Layer backings are stored so that the updates
     293            // (possibly time-consuming) can be done outside of this scene update.
     294            for (auto& compositionLayer : m_nicosia.state.layers) {
     295                auto& layer = texmapLayer(*compositionLayer);
     296                compositionLayer->commitState(
     297                    [this, &layer, &compositionLayer, &layersByBacking]
     298                    (const Nicosia::CompositionLayer::LayerState& layerState)
     299                    {
     300                        if (layerState.delta.positionChanged)
     301                            layer.setPosition(layerState.position);
     302                        if (layerState.delta.anchorPointChanged)
     303                            layer.setAnchorPoint(layerState.anchorPoint);
     304                        if (layerState.delta.sizeChanged)
     305                            layer.setSize(layerState.size);
     306
     307                        if (layerState.delta.transformChanged)
     308                            layer.setTransform(layerState.transform);
     309                        if (layerState.delta.childrenTransformChanged)
     310                            layer.setChildrenTransform(layerState.childrenTransform);
     311
     312                        if (layerState.delta.contentsRectChanged)
     313                            layer.setContentsRect(layerState.contentsRect);
     314                        if (layerState.delta.contentsTilingChanged) {
     315                            layer.setContentsTilePhase(layerState.contentsTilePhase);
     316                            layer.setContentsTileSize(layerState.contentsTileSize);
     317                        }
     318
     319                        if (layerState.delta.opacityChanged)
     320                            layer.setOpacity(layerState.opacity);
     321                        if (layerState.delta.solidColorChanged)
     322                            layer.setSolidColor(layerState.solidColor);
     323
     324                        if (layerState.delta.filtersChanged)
     325                            layer.setFilters(layerState.filters);
     326                        if (layerState.delta.animationsChanged)
     327                            layer.setAnimations(layerState.animations);
     328
     329                        if (layerState.delta.childrenChanged) {
     330                            layer.setChildren(WTF::map(layerState.children,
     331                                [](auto& child) { return &texmapLayer(*child); }));
     332                        }
     333
     334                        if (layerState.delta.maskChanged)
     335                            layer.setMaskLayer(layerState.mask ? &texmapLayer(*layerState.mask) : nullptr);
     336                        if (layerState.delta.replicaChanged)
     337                            layer.setReplicaLayer(layerState.replica ? &texmapLayer(*layerState.replica) : nullptr);
     338
     339                        if (layerState.delta.flagsChanged) {
     340                            layer.setContentsOpaque(layerState.flags.contentsOpaque);
     341                            layer.setDrawsContent(layerState.flags.drawsContent);
     342                            layer.setContentsVisible(layerState.flags.contentsVisible);
     343                            layer.setBackfaceVisibility(layerState.flags.backfaceVisible);
     344                            layer.setMasksToBounds(layerState.flags.masksToBounds);
     345                            layer.setPreserves3D(layerState.flags.preserves3D);
     346                        }
     347
     348                        if (layerState.backingStore) {
     349                            auto& impl = backingStoreImpl(*layerState.backingStore);
     350                            layersByBacking.backingStore.append(
     351                                { std::ref(layer), std::ref(impl), impl.takeUpdate() });
     352                        } else
     353                            layer.setBackingStore(nullptr);
     354
     355                        if (layerState.contentLayer) {
     356                            auto& impl = contentLayerImpl(*layerState.contentLayer);
     357                            layersByBacking.contentLayer.append(
     358                                { std::ref(layer), std::ref(impl.proxy()), layerState.delta.contentLayerChanged });
     359                        } else if (layerState.imageBacking) {
     360                            auto& impl = imageBackingImpl(*layerState.imageBacking);
     361                            layersByBacking.imageBacking.append(
     362                                { std::ref(layer), std::ref(impl), impl.takeUpdate() });
     363                        } else
     364                            layer.setContentsLayer(nullptr);
     365                    });
     366            }
     367        });
     368
     369    // Iterate through each backing type of layers and gather backing store
     370    // or proxy objects that need an update.
     371    // FIXME: HashSet<std::reference_wrapper<>> would be ideal, but doesn't work (yet).
     372    HashSet<Ref<WebCore::CoordinatedBackingStore>> backingStoresWithPendingBuffers;
     373    HashSet<Ref<WebCore::TextureMapperPlatformLayerProxy>> proxiesForSwapping;
     374
     375    {
     376        for (auto& entry : layersByBacking.backingStore) {
     377            auto& compositionState = entry.backingStore.get().compositionState();
     378            updateBackingStore(entry.layer.get(), compositionState, entry.update);
     379
     380            if (compositionState.backingStore)
     381                backingStoresWithPendingBuffers.add(makeRef(*compositionState.backingStore));
     382        }
     383
     384        layersByBacking.backingStore = { };
     385    }
     386
     387    {
     388        for (auto& entry : layersByBacking.contentLayer) {
     389            auto& proxy = entry.proxy.get();
     390            if (entry.needsActivation)
     391                proxy.activateOnCompositingThread(this, &entry.layer.get());
     392            proxiesForSwapping.add(makeRef(proxy));
     393        }
     394
     395        layersByBacking.contentLayer = { };
     396    }
     397
     398    {
     399        for (auto& entry : layersByBacking.imageBacking) {
     400            auto& compositionState = entry.imageBacking.get().compositionState();
     401            updateImageBacking(entry.layer.get(), compositionState, entry.update);
     402
     403            if (compositionState.backingStore)
     404                backingStoresWithPendingBuffers.add(makeRef(*compositionState.backingStore));
     405        }
     406
     407        layersByBacking.imageBacking = { };
     408    }
     409
     410    for (auto& backingStore : backingStoresWithPendingBuffers)
    444411        backingStore->commitTileOperations(*m_textureMapper);
     412
     413    for (auto& proxy : proxiesForSwapping)
     414        proxy->swapBuffer();
    445415}
    446416
     
    466436    ASSERT(!m_client);
    467437
    468     m_imageBackings.clear();
    469 #if USE(COORDINATED_GRAPHICS_THREADED)
    470     for (auto& proxy : m_platformLayerProxies.values())
    471         proxy->invalidate();
    472     m_platformLayerProxies.clear();
    473 #endif
     438    if (m_nicosia.scene) {
     439        m_nicosia.scene->accessState(
     440            [this](const Nicosia::Scene::State& state)
     441            {
     442                ASSERT(state.id == m_nicosia.state.id);
     443                for (auto& layer : m_nicosia.state.layers)
     444                    removeLayer(*layer);
     445                m_nicosia.state.layers = { };
     446                m_nicosia.state.rootLayer = nullptr;
     447            });
     448        m_nicosia.scene = nullptr;
     449    }
    474450
    475451    m_rootLayer = nullptr;
    476452    m_rootLayerID = InvalidCoordinatedLayerID;
    477     m_layers.clear();
    478453    m_textureMapper = nullptr;
    479     m_backingStores.clear();
    480 }
    481 
    482 void CoordinatedGraphicsScene::setLayerAnimationsIfNeeded(TextureMapperLayer* layer, const CoordinatedGraphicsLayerState& state)
    483 {
    484     if (!state.animationsChanged)
    485         return;
    486 
    487     layer->setAnimations(state.animations);
    488454}
    489455
  • trunk/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.h

    r234455 r235165  
    8282    void setActive(bool active) { m_isActive = active; }
    8383
    84     void commitSceneState(const WebCore::CoordinatedGraphicsState&);
    85 
    8684    void setViewBackgroundColor(const WebCore::Color& color) { m_viewBackgroundColor = color; }
    8785    WebCore::Color viewBackgroundColor() const { return m_viewBackgroundColor; }
    8886
    8987private:
    90     struct CommitScope {
    91         CommitScope() = default;
    92         CommitScope(CommitScope&) = delete;
    93         CommitScope& operator=(const CommitScope&) = delete;
     88    void commitSceneState(const WebCore::CoordinatedGraphicsState::NicosiaState&);
     89    void updateSceneState();
    9490
    95         Vector<RefPtr<WebCore::CoordinatedBackingStore>> releasedImageBackings;
    96         HashSet<RefPtr<WebCore::CoordinatedBackingStore>> backingStoresWithPendingBuffers;
    97     };
    98 
    99     void setRootLayerID(WebCore::CoordinatedLayerID);
    100     void createLayers(const Vector<WebCore::CoordinatedLayerID>&);
    101     void deleteLayers(const Vector<WebCore::CoordinatedLayerID>&);
    102     void setLayerState(WebCore::CoordinatedLayerID, const WebCore::CoordinatedGraphicsLayerState&, CommitScope&);
    103     void setLayerChildrenIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);
    104     void updateTilesIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&, CommitScope&);
    105     void createTilesIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);
    106     void removeTilesIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&, CommitScope&);
    107     void setLayerFiltersIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);
    108     void setLayerAnimationsIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);
    109     void syncPlatformLayerIfNeeded(WebCore::TextureMapperLayer*, const WebCore::CoordinatedGraphicsLayerState&);
    110 
    111     void syncImageBackings(const WebCore::CoordinatedGraphicsState&, CommitScope&);
    112     void createImageBacking(WebCore::CoordinatedImageBackingID);
    113     void updateImageBacking(WebCore::CoordinatedImageBackingID, RefPtr<Nicosia::Buffer>&&, CommitScope&);
    114     void clearImageBackingContents(WebCore::CoordinatedImageBackingID, CommitScope&);
    115     void removeImageBacking(WebCore::CoordinatedImageBackingID, CommitScope&);
    116 
    117     WebCore::TextureMapperLayer* layerByID(WebCore::CoordinatedLayerID id)
    118     {
    119         ASSERT(m_layers.contains(id));
    120         ASSERT(id != WebCore::InvalidCoordinatedLayerID);
    121         return m_layers.get(id);
    122     }
    123     WebCore::TextureMapperLayer* getLayerByIDIfExists(WebCore::CoordinatedLayerID);
    12491    WebCore::TextureMapperLayer* rootLayer() { return m_rootLayer.get(); }
    12592
    12693    void updateViewport();
    12794
    128     void createLayer(WebCore::CoordinatedLayerID);
    129     void deleteLayer(WebCore::CoordinatedLayerID);
    130 
    131     void assignImageBackingToLayer(WebCore::TextureMapperLayer*, WebCore::CoordinatedImageBackingID);
    13295    void ensureRootLayer();
    133 
    134     void prepareContentBackingStore(WebCore::TextureMapperLayer*, CommitScope&);
    135     void createBackingStoreIfNeeded(WebCore::TextureMapperLayer*);
    136     void removeBackingStoreIfNeeded(WebCore::TextureMapperLayer*);
    137     void resetBackingStoreSizeToLayerSize(WebCore::TextureMapperLayer*, CommitScope&);
    13896
    13997#if USE(COORDINATED_GRAPHICS_THREADED)
     
    14199#endif
    142100
    143     WebCore::CoordinatedGraphicsState::NicosiaState m_nicosia;
     101    struct {
     102        RefPtr<Nicosia::Scene> scene;
     103        Nicosia::Scene::State state;
     104    } m_nicosia;
    144105
    145106    std::unique_ptr<WebCore::TextureMapper> m_textureMapper;
    146 
    147     HashMap<WebCore::CoordinatedImageBackingID, RefPtr<WebCore::CoordinatedBackingStore>> m_imageBackings;
    148     HashMap<WebCore::TextureMapperLayer*, RefPtr<WebCore::CoordinatedBackingStore>> m_backingStores;
    149 
    150 #if USE(COORDINATED_GRAPHICS_THREADED)
    151     HashMap<WebCore::TextureMapperLayer*, RefPtr<WebCore::TextureMapperPlatformLayerProxy>> m_platformLayerProxies;
    152 #endif
    153107
    154108    // Below two members are accessed by only the main thread. The painting thread must lock the main thread to access both members.
     
    158112    std::unique_ptr<WebCore::TextureMapperLayer> m_rootLayer;
    159113
    160     HashMap<WebCore::CoordinatedLayerID, std::unique_ptr<WebCore::TextureMapperLayer>> m_layers;
    161114    WebCore::CoordinatedLayerID m_rootLayerID { WebCore::InvalidCoordinatedLayerID };
    162115    WebCore::Color m_viewBackgroundColor { WebCore::Color::white };
  • trunk/Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp

    r235111 r235165  
    216216            // But do not change coordinateUpdateCompletionWithClient while in force repaint because that
    217217            // demands immediate scene update completion regardless of platform layers.
     218            // FIXME: Check whether we still need all this coordinateUpdateCompletionWithClient logic.
     219            // https://bugs.webkit.org/show_bug.cgi?id=188839
     220            // Relatedly, we should only ever operate with a single Nicosia::Scene object, not with a Vector
     221            // of CoordinatedGraphicsState instances (which at this time will all contain RefPtr to the same
     222            // Nicosia::State object anyway).
    218223            if (!m_inForceRepaint) {
    219224                bool coordinateUpdate = false;
    220                 for (auto& state : states)
    221                     coordinateUpdate |= std::any_of(state.layersToUpdate.begin(), state.layersToUpdate.end(),
    222                         [](auto& it) { return it.second.platformLayerChanged || it.second.platformLayerUpdated; });
     225                for (auto& state : states) {
     226                    state.nicosia.scene->accessState(
     227                        [&coordinateUpdate](Nicosia::Scene::State& state)
     228                        {
     229                            coordinateUpdate |= state.platformLayerUpdated;
     230                            state.platformLayerUpdated = false;
     231                        });
     232                }
    223233                m_attributes.coordinateUpdateCompletionWithClient = coordinateUpdate;
    224234            }
  • trunk/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp

    r234593 r235165  
    3636#include <WebCore/GraphicsContext.h>
    3737#include <WebCore/InspectorController.h>
     38#include <WebCore/NicosiaBackingStoreTextureMapperImpl.h>
     39#include <WebCore/NicosiaContentLayerTextureMapperImpl.h>
     40#include <WebCore/NicosiaImageBackingTextureMapperImpl.h>
    3841#include <WebCore/NicosiaPaintingEngine.h>
    3942#include <WebCore/Page.h>
     
    131134            [this](Nicosia::Scene::State& state)
    132135            {
     136                bool platformLayerUpdated = false;
     137                for (auto& compositionLayer : m_nicosia.state.layers) {
     138                    compositionLayer->flushState(
     139                        [&platformLayerUpdated]
     140                        (const Nicosia::CompositionLayer::LayerState& state)
     141                        {
     142                            if (state.backingStore) {
     143                                auto& impl = downcast<Nicosia::BackingStoreTextureMapperImpl>(state.backingStore->impl());
     144                                impl.flushUpdate();
     145                            }
     146
     147                            if (state.imageBacking) {
     148                                auto& impl = downcast<Nicosia::ImageBackingTextureMapperImpl>(state.imageBacking->impl());
     149                                impl.flushUpdate();
     150                            }
     151
     152                            if (state.contentLayer) {
     153                                auto& impl = downcast<Nicosia::ContentLayerTextureMapperImpl>(state.contentLayer->impl());
     154                                platformLayerUpdated |= impl.flushUpdate();
     155                            }
     156                        });
     157                }
     158
    133159                ++state.id;
     160                state.platformLayerUpdated = platformLayerUpdated;
    134161                state.layers = m_nicosia.state.layers;
    135162                state.rootLayer = m_nicosia.state.rootLayer;
  • trunk/Source/cmake/OptionsGTK.cmake

    r234362 r235165  
    278278    SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS TRUE)
    279279    SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS_THREADED TRUE)
     280    SET_AND_EXPOSE_TO_BUILD(USE_NICOSIA TRUE)
    280281endif ()
    281282
  • trunk/Source/cmake/OptionsWPE.cmake

    r235118 r235165  
    135135SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS TRUE)
    136136SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS_THREADED TRUE)
     137SET_AND_EXPOSE_TO_BUILD(USE_NICOSIA TRUE)
    137138
    138139set(FORWARDING_HEADERS_DIR ${DERIVED_SOURCES_DIR}/ForwardingHeaders)
Note: See TracChangeset for help on using the changeset viewer.