⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 287079 in webkit


Ignore:
Timestamp:
Dec 15, 2021, 9:46:07 AM (5 years ago)
Author:
Simon Fraser
Message:

Twitter scroll stutter: ensure that CA backing store is always deallocated on the main thread
https://bugs.webkit.org/show_bug.cgi?id=234328
<rdar://85892959>

Reviewed by Tim Horton.

When scrolling pages like Twitter and Facebook we observed CoreAnimation commits on the
scrolling thread taking longer than they should because CABackingStore objects were being
released in those transactions.

Work around this issue by extending the lifetime of CABackingStore objects if we detect that
they might be entrained into a scrolling tree commit, by virtue of having overlapping main
thread and scrolling thread commits.

The logic is contained in PlatformCALayerContentsDelayedReleaser, which puts layer contents
into a retaining vector when they are being cleared on the layer. They are released at the
end of a main thread commit; if we detected overlapping commits, then we release on a
dispatch to extend the lifetime slightly.

The remaining changes are plumbing to get commit willBegin/didEnd messages to PlatformCALayerContentsDelayedReleaser
for main and scrolling threads.

  • SourcesCocoa.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • page/scrolling/ScrollingTree.h:
  • page/scrolling/ThreadedScrollingTree.h:
  • page/scrolling/mac/ScrollingCoordinatorMac.h:
  • page/scrolling/mac/ScrollingCoordinatorMac.mm:

(WebCore::ScrollingCoordinatorMac::willStartPlatformRenderingUpdate):
(WebCore::ScrollingCoordinatorMac::didCompletePlatformRenderingUpdate):

  • page/scrolling/mac/ScrollingTreeMac.h:
  • page/scrolling/mac/ScrollingTreeMac.mm:

(ScrollingTreeMac::applyLayerPositionsInternal):
(ScrollingTreeMac::registerForPlatformRenderingUpdateCallback):

  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::GraphicsLayerCA::updateContentsVisibility):
(WebCore::GraphicsLayerCA::updateDrawsContent):

  • platform/graphics/ca/PlatformCALayer.cpp:

(WebCore::PlatformCALayer::clearContents):

  • platform/graphics/ca/PlatformCALayer.h:
  • platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
  • platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:

(WebCore::PlatformCALayerCocoa::setBackingStoreAttached):
(WebCore::PlatformCALayerCocoa::clearContents):

  • platform/graphics/ca/cocoa/PlatformCALayerContentsDelayedReleaser.h: Added.

(WebCore::PlatformCALayerContentsDelayedReleaser::WTF_GUARDED_BY_LOCK):

  • platform/graphics/ca/cocoa/PlatformCALayerContentsDelayedReleaser.mm: Added.

(WebCore::PlatformCALayerContentsDelayedReleaser::singleton):
(WebCore::PlatformCALayerContentsDelayedReleaser::takeLayerContents):
(WebCore::PlatformCALayerContentsDelayedReleaser::mainThreadCommitWillStart):
(WebCore::PlatformCALayerContentsDelayedReleaser::mainThreadCommitDidEnd):
(WebCore::PlatformCALayerContentsDelayedReleaser::scrollingThreadCommitWillStart):
(WebCore::PlatformCALayerContentsDelayedReleaser::scrollingThreadCommitDidEnd):
(WebCore::PlatformCALayerContentsDelayedReleaser::updateSawOverlappingCommit):
(WebCore::PlatformCALayerContentsDelayedReleaser::clearRetainedContents):

Location:
trunk/Source/WebCore
Files:
2 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r287077 r287079  
     12021-12-15  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Twitter scroll stutter: ensure that CA backing store is always deallocated on the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=234328
     5        <rdar://85892959>
     6
     7        Reviewed by Tim Horton.
     8
     9        When scrolling pages like Twitter and Facebook we observed CoreAnimation commits on the
     10        scrolling thread taking longer than they should because CABackingStore objects were being
     11        released in those transactions.
     12
     13        Work around this issue by extending the lifetime of CABackingStore objects if we detect that
     14        they might be entrained into a scrolling tree commit, by virtue of having overlapping main
     15        thread and scrolling thread commits.
     16
     17        The logic is contained in PlatformCALayerContentsDelayedReleaser, which puts layer contents
     18        into a retaining vector when they are being cleared on the layer. They are released at the
     19        end of a main thread commit; if we detected overlapping commits, then we release on a
     20        dispatch to extend the lifetime slightly.
     21
     22        The remaining changes are plumbing to get commit willBegin/didEnd messages to PlatformCALayerContentsDelayedReleaser
     23        for main and scrolling threads.
     24
     25        * SourcesCocoa.txt:
     26        * WebCore.xcodeproj/project.pbxproj:
     27        * page/scrolling/ScrollingTree.h:
     28        * page/scrolling/ThreadedScrollingTree.h:
     29        * page/scrolling/mac/ScrollingCoordinatorMac.h:
     30        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
     31        (WebCore::ScrollingCoordinatorMac::willStartPlatformRenderingUpdate):
     32        (WebCore::ScrollingCoordinatorMac::didCompletePlatformRenderingUpdate):
     33        * page/scrolling/mac/ScrollingTreeMac.h:
     34        * page/scrolling/mac/ScrollingTreeMac.mm:
     35        (ScrollingTreeMac::applyLayerPositionsInternal):
     36        (ScrollingTreeMac::registerForPlatformRenderingUpdateCallback):
     37        * platform/graphics/ca/GraphicsLayerCA.cpp:
     38        (WebCore::GraphicsLayerCA::updateContentsVisibility):
     39        (WebCore::GraphicsLayerCA::updateDrawsContent):
     40        * platform/graphics/ca/PlatformCALayer.cpp:
     41        (WebCore::PlatformCALayer::clearContents):
     42        * platform/graphics/ca/PlatformCALayer.h:
     43        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.h:
     44        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
     45        (WebCore::PlatformCALayerCocoa::setBackingStoreAttached):
     46        (WebCore::PlatformCALayerCocoa::clearContents):
     47        * platform/graphics/ca/cocoa/PlatformCALayerContentsDelayedReleaser.h: Added.
     48        (WebCore::PlatformCALayerContentsDelayedReleaser::WTF_GUARDED_BY_LOCK):
     49        * platform/graphics/ca/cocoa/PlatformCALayerContentsDelayedReleaser.mm: Added.
     50        (WebCore::PlatformCALayerContentsDelayedReleaser::singleton):
     51        (WebCore::PlatformCALayerContentsDelayedReleaser::takeLayerContents):
     52        (WebCore::PlatformCALayerContentsDelayedReleaser::mainThreadCommitWillStart):
     53        (WebCore::PlatformCALayerContentsDelayedReleaser::mainThreadCommitDidEnd):
     54        (WebCore::PlatformCALayerContentsDelayedReleaser::scrollingThreadCommitWillStart):
     55        (WebCore::PlatformCALayerContentsDelayedReleaser::scrollingThreadCommitDidEnd):
     56        (WebCore::PlatformCALayerContentsDelayedReleaser::updateSawOverlappingCommit):
     57        (WebCore::PlatformCALayerContentsDelayedReleaser::clearRetainedContents):
     58
    1592021-12-15  Chris Dumez  <cdumez@apple.com>
    260
  • trunk/Source/WebCore/SourcesCocoa.txt

    r287015 r287079  
    338338platform/graphics/ca/cocoa/PlatformCAFiltersCocoa.mm
    339339platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm
     340platform/graphics/ca/cocoa/PlatformCALayerContentsDelayedReleaser.mm
    340341platform/graphics/ca/cocoa/WebSystemBackdropLayer.mm
    341342platform/graphics/ca/cocoa/WebTiledBackingLayer.mm
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r287015 r287079  
    63956395                0FA24D77162DF91900A3F4C0 /* GraphicsLayerUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsLayerUpdater.cpp; sourceTree = "<group>"; };
    63966396                0FA24D78162DF91900A3F4C0 /* GraphicsLayerUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsLayerUpdater.h; sourceTree = "<group>"; };
     6397                0FA2B233276817540020C7C1 /* PlatformCALayerContentsDelayedReleaser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformCALayerContentsDelayedReleaser.h; sourceTree = "<group>"; };
     6398                0FA2B235276817550020C7C1 /* PlatformCALayerContentsDelayedReleaser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformCALayerContentsDelayedReleaser.mm; sourceTree = "<group>"; };
    63976399                0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimation.h; sourceTree = "<group>"; };
    63986400                0FB0689425243B90001E8E75 /* DisplayTextBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayTextBox.cpp; sourceTree = "<group>"; };
     
    2167221674                                2D70BA1218074DDF0001908A /* PlatformCALayerCocoa.h */,
    2167321675                                4958782012A57DDF007238AC /* PlatformCALayerCocoa.mm */,
     21676                                0FA2B233276817540020C7C1 /* PlatformCALayerContentsDelayedReleaser.h */,
     21677                                0FA2B235276817550020C7C1 /* PlatformCALayerContentsDelayedReleaser.mm */,
    2167421678                                31DEA4541B39F4D900F77178 /* WebSystemBackdropLayer.h */,
    2167521679                                31DEA4531B39F4D900F77178 /* WebSystemBackdropLayer.mm */,
     
    3312233126                        buildActionMask = 2147483647;
    3312333127                        files = (
    33124                                 7B582DD82716F55B004B92D0 /* (null) in Headers */,
    3312533128                                7CD0E2B81F80A4820016A4CE /* AbortController.h in Headers */,
    3312633129                                7CD0E2BF1F80A56E0016A4CE /* AbortSignal.h in Headers */,
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r286351 r287079  
    246246    std::optional<FramesPerSecond> nominalFramesPerSecond();
    247247
    248     void applyLayerPositionsInternal() WTF_REQUIRES_LOCK(m_treeLock);
     248    WEBCORE_EXPORT virtual void applyLayerPositionsInternal() WTF_REQUIRES_LOCK(m_treeLock);
    249249    void removeAllNodes() WTF_REQUIRES_LOCK(m_treeLock);
    250250   
  • trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h

    r286932 r287079  
    109109   
    110110    void storeScrollPositionsAtLastDisplayRefresh() WTF_REQUIRES_LOCK(m_treeLock);
    111    
     111
    112112    void serviceScrollAnimations(MonotonicTime) WTF_REQUIRES_LOCK(m_treeLock);
    113113
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h

    r286905 r287079  
    5454    void didCompleteRenderingUpdate() final;
    5555
     56    void willStartPlatformRenderingUpdate() final;
    5657    void didCompletePlatformRenderingUpdate() final;
    5758
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm

    r286905 r287079  
    3434#import "Logging.h"
    3535#import "Page.h"
     36#import "PlatformCALayerContentsDelayedReleaser.h"
    3637#import "PlatformWheelEvent.h"
    3738#import "Region.h"
     
    143144}
    144145
     146void ScrollingCoordinatorMac::willStartPlatformRenderingUpdate()
     147{
     148    PlatformCALayerContentsDelayedReleaser::singleton().mainThreadCommitWillStart();
     149}
     150
    145151void ScrollingCoordinatorMac::didCompletePlatformRenderingUpdate()
    146152{
    147153    downcast<ThreadedScrollingTree>(scrollingTree())->didCompletePlatformRenderingUpdate();
     154    PlatformCALayerContentsDelayedReleaser::singleton().mainThreadCommitDidEnd();
    148155}
    149156
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.h

    r277943 r287079  
    5656    void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) final;
    5757
     58    void registerForPlatformRenderingUpdateCallback();
     59    void applyLayerPositionsInternal() final WTF_REQUIRES_LOCK(m_treeLock);
     60
    5861    void lockLayersForHitTesting() final WTF_ACQUIRES_LOCK(m_layerHitTestMutex);
    5962    void unlockLayersForHitTesting() final WTF_RELEASES_LOCK(m_layerHitTestMutex);
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm

    r284920 r287079  
    2929#import "Logging.h"
    3030#import "PlatformCALayer.h"
     31#import "PlatformCALayerContentsDelayedReleaser.h"
    3132#import "ScrollingTreeFixedNode.h"
    3233#import "ScrollingTreeFrameHostingNode.h"
     
    3940#import "WebLayer.h"
    4041#import "WheelEventTestMonitor.h"
     42#import <pal/spi/cocoa/QuartzCoreSPI.h>
    4143#import <wtf/text/TextStream.h>
    4244
     
    241243}
    242244
     245void ScrollingTreeMac::applyLayerPositionsInternal()
     246{
     247    if (ScrollingThread::isCurrentThread())
     248        registerForPlatformRenderingUpdateCallback();
     249
     250    ThreadedScrollingTree::applyLayerPositionsInternal();
     251}
     252
     253void ScrollingTreeMac::registerForPlatformRenderingUpdateCallback()
     254{
     255    [CATransaction addCommitHandler:[] {
     256        PlatformCALayerContentsDelayedReleaser::singleton().scrollingThreadCommitWillStart();
     257    } forPhase:kCATransactionPhasePreLayout];
     258
     259    [CATransaction addCommitHandler:[] {
     260        PlatformCALayerContentsDelayedReleaser::singleton().scrollingThreadCommitDidEnd();
     261    } forPhase:kCATransactionPhasePostCommit];
     262}
     263
    243264void ScrollingTreeMac::setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&& monitor)
    244265{
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r286943 r287079  
    23522352            m_backdropLayer->setHidden(false);
    23532353    } else {
    2354         m_layer->setContents(nullptr);
     2354        m_layer->clearContents();
    23552355
    23562356        if (m_layerClones) {
     
    26752675        m_hasEverPainted = false;
    26762676    } else {
    2677         m_layer->setContents(nullptr);
     2677        m_layer->clearContents();
    26782678        if (m_layerClones) {
    26792679            for (auto& layer : m_layerClones->primaryLayerClones.values())
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.cpp

    r284453 r287079  
    200200}
    201201
     202void PlatformCALayer::clearContents()
     203{
     204    setContents(nullptr);
     205}
     206
    202207void PlatformCALayer::dumpAdditionalProperties(TextStream&, OptionSet<PlatformLayerTreeAsTextFlags>)
    203208{
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h

    r286943 r287079  
    200200    virtual CFTypeRef contents() const = 0;
    201201    virtual void setContents(CFTypeRef) = 0;
     202    virtual void clearContents();
    202203
    203204#if HAVE(IOSURFACE)
  • trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.h

    r286943 r287079  
    121121    CFTypeRef contents() const override;
    122122    void setContents(CFTypeRef) override;
     123    void clearContents() override;
    123124#if HAVE(IOSURFACE)
    124125    void setContents(const WebCore::IOSurface&) override;
  • trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm

    r286943 r287079  
    3636#import "PlatformCAAnimationCocoa.h"
    3737#import "PlatformCAFilters.h"
     38#import "PlatformCALayerContentsDelayedReleaser.h"
    3839#import "ScrollbarThemeMac.h"
    3940#import "TileController.h"
     
    679680        setNeedsDisplay();
    680681    else
    681         setContents(nullptr);
     682        clearContents();
    682683}
    683684
     
    783784{
    784785    return (__bridge CFTypeRef)[m_layer contents];
     786}
     787
     788void PlatformCALayerCocoa::clearContents()
     789{
     790#if PLATFORM(MAC)
     791    PlatformCALayerContentsDelayedReleaser::singleton().takeLayerContents(*this);
     792#else
     793    setContents(nullptr);
     794#endif
    785795}
    786796
Note: See TracChangeset for help on using the changeset viewer.