Make it possible to detach GraphicsLayerCA backing store
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Apr 2015 04:36:12 +0000 (04:36 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Apr 2015 04:36:12 +0000 (04:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144140

Reviewed by Tim Horton.
Source/WebCore:

This changes makes it possible to denote a GraphicsLayerCA's backing store
as "attached" or not. When not attached, the backing store is made volatile
and can be purged. This will be used in a future patch.

* platform/graphics/ca/GraphicsLayerCA.h: Add updateBackingStoreAttachment().
* platform/graphics/ca/PlatformCALayer.h:
* platform/graphics/ca/mac/PlatformCALayerMac.h:
* platform/graphics/ca/mac/PlatformCALayerMac.mm: Stubs. In future, we could
remove backing store on Mac and iOS WK1 too.
(PlatformCALayerMac::setBackingStoreAttached):
(PlatformCALayerMac::backingStoreAttached):

Source/WebKit2:

This changes makes it possible to denote a GraphicsLayerCA's backing store
as "attached" or not. When not attached, the backing store is made volatile
and can be purged. This will be used in a future patch.

* Shared/mac/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::~RemoteLayerBackingStore): Whitespace.
(WebKit::RemoteLayerBackingStore::display): If backingStoreWillBeDisplayed()
returns true, this indicates that the backing store was brought out of the
"unreachable" list, so return true even if the backing store doesn't require
painting.
* Shared/mac/RemoteLayerBackingStoreCollection.h: C++11 initializer, and comments.
* Shared/mac/RemoteLayerBackingStoreCollection.mm:
(WebKit::RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection):
(WebKit::RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed): Return true
if the caller will need to submit the backing store in the current transaction.
(WebKit::RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable): This
explicit dirtying is no longer necessary given the backingStoreWillBeDisplayed() change.
* Shared/mac/RemoteLayerTreePropertyApplier.mm:
(WebKit::applyPropertiesToLayer): Only set the layer's backing if we both have backing
store, and it's attached.
* Shared/mac/RemoteLayerTreeTransaction.h: New bit, and data member.
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
(WebKit::RemoteLayerTreeTransaction::LayerProperties::encode):
(WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
(WebKit::dumpChangedLayers):
* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(WebKit::PlatformCALayerRemote::recursiveBuildTransaction): Only call display()
on the backing store if it's attached.
(WebKit::PlatformCALayerRemote::setBackingStoreAttached):
(WebKit::PlatformCALayerRemote::backingStoreAttached):
* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
* WebProcess/WebPage/mac/RemoteLayerTreeContext.h:
* WebProcess/WebPage/mac/RemoteLayerTreeContext.mm:
(WebKit::RemoteLayerTreeContext::backingStoreWillBeDisplayed):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183242 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
Source/WebCore/platform/graphics/ca/PlatformCALayer.h
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm
Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.h
Source/WebKit2/Shared/mac/RemoteLayerBackingStoreCollection.mm
Source/WebKit2/Shared/mac/RemoteLayerTreePropertyApplier.mm
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h
Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.h
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeContext.mm

index d3dd5a8..0a1b047 100644 (file)
@@ -1,5 +1,24 @@
 2015-04-23  Simon Fraser  <simon.fraser@apple.com>
 
+        Make it possible to detach GraphicsLayerCA backing store
+        https://bugs.webkit.org/show_bug.cgi?id=144140
+
+        Reviewed by Tim Horton.
+
+        This changes makes it possible to denote a GraphicsLayerCA's backing store
+        as "attached" or not. When not attached, the backing store is made volatile
+        and can be purged. This will be used in a future patch.
+
+        * platform/graphics/ca/GraphicsLayerCA.h: Add updateBackingStoreAttachment().
+        * platform/graphics/ca/PlatformCALayer.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.h:
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm: Stubs. In future, we could
+        remove backing store on Mac and iOS WK1 too.
+        (PlatformCALayerMac::setBackingStoreAttached):
+        (PlatformCALayerMac::backingStoreAttached):
+
+2015-04-23  Simon Fraser  <simon.fraser@apple.com>
+
         Remove "layer" from GraphicsLayerCA member function names
         https://bugs.webkit.org/show_bug.cgi?id=144139
 
index 40f6c97..04b2ff3 100644 (file)
@@ -363,6 +363,7 @@ private:
     void updateBackfaceVisibility();
     void updateStructuralLayer();
     void updateDrawsContent();
+    void updateBackingStoreAttachment();
     void updateBackgroundColor();
 
     void updateContentsImage();
index 007704d..6d9e47d 100644 (file)
@@ -176,6 +176,9 @@ public:
 
     virtual void setContentsRect(const FloatRect&) = 0;
 
+    virtual void setBackingStoreAttached(bool) = 0;
+    virtual bool backingStoreAttached() const = 0;
+
     virtual void setMinificationFilter(FilterType) = 0;
     virtual void setMagnificationFilter(FilterType) = 0;
 
index 0b53514..2e0d555 100644 (file)
@@ -89,6 +89,9 @@ public:
 
     virtual void setHidden(bool) override;
 
+    virtual void setBackingStoreAttached(bool) override;
+    virtual bool backingStoreAttached() const override;
+
     WEBCORE_EXPORT virtual void setGeometryFlipped(bool) override;
 
     virtual bool isDoubleSided() const override;
index eb7929c..7e0f357 100644 (file)
@@ -594,6 +594,16 @@ void PlatformCALayerMac::setHidden(bool value)
     END_BLOCK_OBJC_EXCEPTIONS
 }
 
+void PlatformCALayerMac::setBackingStoreAttached(bool)
+{
+    // We could throw away backing store here with setContents:nil.
+}
+
+bool PlatformCALayerMac::backingStoreAttached() const
+{
+    return true;
+}
+
 void PlatformCALayerMac::setGeometryFlipped(bool value)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
index 0af44cd..6365ab8 100644 (file)
@@ -1,3 +1,46 @@
+2015-04-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Make it possible to detach GraphicsLayerCA backing store
+        https://bugs.webkit.org/show_bug.cgi?id=144140
+
+        Reviewed by Tim Horton.
+        
+        This changes makes it possible to denote a GraphicsLayerCA's backing store
+        as "attached" or not. When not attached, the backing store is made volatile
+        and can be purged. This will be used in a future patch.
+
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        (WebKit::RemoteLayerBackingStore::~RemoteLayerBackingStore): Whitespace.
+        (WebKit::RemoteLayerBackingStore::display): If backingStoreWillBeDisplayed()
+        returns true, this indicates that the backing store was brought out of the
+        "unreachable" list, so return true even if the backing store doesn't require
+        painting.
+        * Shared/mac/RemoteLayerBackingStoreCollection.h: C++11 initializer, and comments.
+        * Shared/mac/RemoteLayerBackingStoreCollection.mm:
+        (WebKit::RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection):
+        (WebKit::RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed): Return true
+        if the caller will need to submit the backing store in the current transaction.
+        (WebKit::RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable): This
+        explicit dirtying is no longer necessary given the backingStoreWillBeDisplayed() change.
+        * Shared/mac/RemoteLayerTreePropertyApplier.mm:
+        (WebKit::applyPropertiesToLayer): Only set the layer's backing if we both have backing
+        store, and it's attached.
+        * Shared/mac/RemoteLayerTreeTransaction.h: New bit, and data member.
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::encode):
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
+        (WebKit::dumpChangedLayers):
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (WebKit::PlatformCALayerRemote::recursiveBuildTransaction): Only call display()
+        on the backing store if it's attached.
+        (WebKit::PlatformCALayerRemote::setBackingStoreAttached):
+        (WebKit::PlatformCALayerRemote::backingStoreAttached):
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeContext.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeContext.mm:
+        (WebKit::RemoteLayerTreeContext::backingStoreWillBeDisplayed):
+
 2015-04-23  Tim Horton  <timothy_horton@apple.com>
 
         Quick Look preview popover is not dismissed on scroll in Mail
index 1ef8e76..2ccbac7 100644 (file)
@@ -66,6 +66,7 @@ RemoteLayerBackingStore::~RemoteLayerBackingStore()
 
     if (!m_layer)
         return;
+
     if (RemoteLayerTreeContext* context = m_layer->context())
         context->backingStoreWillBeDestroyed(*this);
 }
@@ -206,8 +207,9 @@ bool RemoteLayerBackingStore::display()
 
     m_lastDisplayTime = std::chrono::steady_clock::now();
 
+    bool needToEncodeBackingStore = false;
     if (RemoteLayerTreeContext* context = m_layer->context())
-        context->backingStoreWillBeDisplayed(*this);
+        needToEncodeBackingStore = context->backingStoreWillBeDisplayed(*this);
 
     // Make the previous front buffer non-volatile early, so that we can dirty the whole layer if it comes back empty.
     setBufferVolatility(BufferType::Front, false);
@@ -215,7 +217,7 @@ bool RemoteLayerBackingStore::display()
     IntSize expandedScaledSize = backingStoreSize();
 
     if (m_dirtyRegion.isEmpty() || expandedScaledSize.isEmpty())
-        return false;
+        return needToEncodeBackingStore;
 
     IntRect layerBounds(IntPoint(), expandedIntSize(m_size));
     if (!hasFrontBuffer())
index a82942d..fe4971e 100644 (file)
@@ -45,7 +45,8 @@ public:
     void backingStoreWasCreated(RemoteLayerBackingStore&);
     void backingStoreWillBeDestroyed(RemoteLayerBackingStore&);
 
-    void backingStoreWillBeDisplayed(RemoteLayerBackingStore&);
+    // Return value indicates whether the backing store needs to be included in the transaction.
+    bool backingStoreWillBeDisplayed(RemoteLayerBackingStore&);
     void backingStoreBecameUnreachable(RemoteLayerBackingStore&);
 
     void willFlushLayers();
@@ -67,11 +68,13 @@ private:
 
     HashSet<RemoteLayerBackingStore*> m_liveBackingStore;
     HashSet<RemoteLayerBackingStore*> m_unparentedBackingStore;
+
+    // Only used during a single flush.
     HashSet<RemoteLayerBackingStore*> m_reachableBackingStoreInLatestFlush;
 
     WebCore::Timer m_volatilityTimer;
 
-    bool m_inLayerFlush;
+    bool m_inLayerFlush { false };
 };
 
 } // namespace WebKit
index fdcc330..4959a8b 100644 (file)
@@ -38,7 +38,6 @@ namespace WebKit {
 
 RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection()
     : m_volatilityTimer(*this, &RemoteLayerBackingStoreCollection::volatilityTimerFired)
-    , m_inLayerFlush(false)
 {
 }
 
@@ -88,16 +87,18 @@ void RemoteLayerBackingStoreCollection::backingStoreWillBeDestroyed(RemoteLayerB
     m_unparentedBackingStore.remove(&backingStore);
 }
 
-void RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed(RemoteLayerBackingStore& backingStore)
+bool RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed(RemoteLayerBackingStore& backingStore)
 {
     ASSERT(m_inLayerFlush);
     m_reachableBackingStoreInLatestFlush.add(&backingStore);
 
     auto backingStoreIter = m_unparentedBackingStore.find(&backingStore);
     if (backingStoreIter == m_unparentedBackingStore.end())
-        return;
+        return false;
+
     m_liveBackingStore.add(&backingStore);
     m_unparentedBackingStore.remove(backingStoreIter);
+    return true;
 }
 
 bool RemoteLayerBackingStoreCollection::markBackingStoreVolatileImmediately(RemoteLayerBackingStore& backingStore, VolatilityMarkingFlags volatilityMarkingFlags)
@@ -141,10 +142,6 @@ void RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable(RemoteLaye
     m_unparentedBackingStore.add(&backingStore);
     m_liveBackingStore.remove(backingStoreIter);
 
-    // If a layer with backing store is removed from the tree, mark it as having changed backing store, so that
-    // on the commit which returns it to the tree, we serialize the backing store (despite possibly not painting).
-    backingStore.layer()->properties().notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreChanged);
-
     // This will not succeed in marking all buffers as volatile, because the commit unparenting the layer hasn't
     // made it to the UI process yet. The volatility timer will finish marking the remaining buffers later.
     markBackingStoreVolatileImmediately(backingStore);
index d18bcc0..2def5ea 100644 (file)
@@ -233,8 +233,11 @@ static void applyPropertiesToLayer(CALayer *layer, RemoteLayerTreeHost* layerTre
     if (properties.changedProperties & RemoteLayerTreeTransaction::TimeOffsetChanged)
         layer.timeOffset = properties.timeOffset;
 
-    if (properties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
-        if (RemoteLayerBackingStore* backingStore = properties.backingStore.get())
+    if (properties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged
+        || properties.changedProperties & RemoteLayerTreeTransaction::BackingStoreAttachmentChanged)
+    {
+        RemoteLayerBackingStore* backingStore = properties.backingStore.get();
+        if (backingStore && properties.backingStoreAttached)
             backingStore->applyBackingStoreToLayer(layer);
         else {
             layer.contents = nil;
index 4d02a57..ab86315 100644 (file)
@@ -81,10 +81,11 @@ public:
         SpeedChanged                    = 1LLU << 28,
         TimeOffsetChanged               = 1LLU << 29,
         BackingStoreChanged             = 1LLU << 30,
-        FiltersChanged                  = 1LLU << 31,
-        AnimationsChanged               = 1LLU << 32,
-        EdgeAntialiasingMaskChanged     = 1LLU << 33,
-        CustomAppearanceChanged         = 1LLU << 34
+        BackingStoreAttachmentChanged   = 1LLU << 31,
+        FiltersChanged                  = 1LLU << 32,
+        AnimationsChanged               = 1LLU << 33,
+        EdgeAntialiasingMaskChanged     = 1LLU << 34,
+        CustomAppearanceChanged         = 1LLU << 35,
     };
     typedef uint64_t LayerChange;
 
@@ -156,6 +157,7 @@ public:
         WebCore::BlendMode blendMode;
         WebCore::WindRule windRule;
         bool hidden;
+        bool backingStoreAttached;
         bool geometryFlipped;
         bool doubleSided;
         bool masksToBounds;
index 1b73aae..3aa7b26 100644 (file)
@@ -98,6 +98,7 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties()
     , blendMode(BlendModeNormal)
     , windRule(RULE_NONZERO)
     , hidden(false)
+    , backingStoreAttached(true)
     , geometryFlipped(false)
     , doubleSided(true)
     , masksToBounds(false)
@@ -134,6 +135,7 @@ RemoteLayerTreeTransaction::LayerProperties::LayerProperties(const LayerProperti
     , blendMode(other.blendMode)
     , windRule(other.windRule)
     , hidden(other.hidden)
+    , backingStoreAttached(other.backingStoreAttached)
     , geometryFlipped(other.geometryFlipped)
     , doubleSided(other.doubleSided)
     , masksToBounds(other.masksToBounds)
@@ -255,6 +257,9 @@ void RemoteLayerTreeTransaction::LayerProperties::encode(IPC::ArgumentEncoder& e
             encoder << *backingStore;
     }
 
+    if (changedProperties & BackingStoreAttachmentChanged)
+        encoder << backingStoreAttached;
+
     if (changedProperties & FiltersChanged)
         encoder << *filters;
 
@@ -454,6 +459,11 @@ bool RemoteLayerTreeTransaction::LayerProperties::decode(IPC::ArgumentDecoder& d
             result.backingStore = nullptr;
     }
 
+    if (result.changedProperties & BackingStoreAttachmentChanged) {
+        if (!decoder.decode(result.backingStoreAttached))
+            return false;
+    }
+
     if (result.changedProperties & FiltersChanged) {
         std::unique_ptr<FilterOperations> filters = std::make_unique<FilterOperations>();
         if (!decoder.decode(*filters))
@@ -1181,6 +1191,9 @@ static void dumpChangedLayers(RemoteLayerTreeTextStream& ts, const RemoteLayerTr
                 dumpProperty(ts, "backingStore", "removed");
         }
 
+        if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackingStoreAttachmentChanged)
+            dumpProperty(ts, "backingStoreAttached", layerProperties.backingStoreAttached);
+
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)
             dumpProperty(ts, "filters", layerProperties.filters ? *layerProperties.filters : FilterOperations());
 
index c68cbc3..d0834bc 100644 (file)
@@ -153,7 +153,7 @@ void PlatformCALayerRemote::recursiveBuildTransaction(RemoteLayerTreeContext& co
         m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreChanged);
     }
 
-    if (m_properties.backingStore && m_properties.backingStore->display())
+    if (m_properties.backingStore && m_properties.backingStoreAttached && m_properties.backingStore->display())
         m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreChanged);
 
     if (m_properties.changedProperties != RemoteLayerTreeTransaction::NoChange) {
@@ -502,6 +502,20 @@ void PlatformCALayerRemote::setHidden(bool value)
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::HiddenChanged);
 }
 
+void PlatformCALayerRemote::setBackingStoreAttached(bool value)
+{
+    if (m_properties.backingStoreAttached == value)
+        return;
+
+    m_properties.backingStoreAttached = value;
+    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreAttachmentChanged);
+}
+
+bool PlatformCALayerRemote::backingStoreAttached() const
+{
+    return m_properties.backingStoreAttached;
+}
+
 void PlatformCALayerRemote::setGeometryFlipped(bool value)
 {
     m_properties.geometryFlipped = value;
index 2febf2e..296b818 100644 (file)
@@ -94,6 +94,9 @@ public:
 
     virtual void setHidden(bool) override;
 
+    virtual void setBackingStoreAttached(bool) override;
+    virtual bool backingStoreAttached() const override;
+
     virtual void setGeometryFlipped(bool) override;
 
     virtual bool isDoubleSided() const override;
index 1db48d0..f7d2527 100644 (file)
@@ -51,7 +51,7 @@ public:
 
     void backingStoreWasCreated(RemoteLayerBackingStore&);
     void backingStoreWillBeDestroyed(RemoteLayerBackingStore&);
-    void backingStoreWillBeDisplayed(RemoteLayerBackingStore&);
+    bool backingStoreWillBeDisplayed(RemoteLayerBackingStore&);
 
     WebCore::LayerPool& layerPool() { return m_layerPool; }
 
index 4992b31..cea452b 100644 (file)
@@ -94,9 +94,9 @@ void RemoteLayerTreeContext::backingStoreWillBeDestroyed(RemoteLayerBackingStore
     m_backingStoreCollection.backingStoreWillBeDestroyed(backingStore);
 }
 
-void RemoteLayerTreeContext::backingStoreWillBeDisplayed(RemoteLayerBackingStore& backingStore)
+bool RemoteLayerTreeContext::backingStoreWillBeDisplayed(RemoteLayerBackingStore& backingStore)
 {
-    m_backingStoreCollection.backingStoreWillBeDisplayed(backingStore);
+    return m_backingStoreCollection.backingStoreWillBeDisplayed(backingStore);
 }
 
 std::unique_ptr<GraphicsLayer> RemoteLayerTreeContext::createGraphicsLayer(WebCore::GraphicsLayer::Type layerType, GraphicsLayerClient& client)