Title: [166545] trunk/Source/WebKit2
Revision
166545
Author
[email protected]
Date
2014-03-31 16:30:43 -0700 (Mon, 31 Mar 2014)

Log Message

[iOS WebKit2] Flush all surfaces after painting into all of them, instead of after painting into each one
https://bugs.webkit.org/show_bug.cgi?id=130768
<rdar://problem/16421471>

Reviewed by Benjamin Poulain.

* Shared/mac/RemoteLayerBackingStore.h:
Make RemoteLayerBackingStore noncopyable.
Add flush(), which synchronously flushes painting operations on the underlying backing store.
Add storage for the CGContext that needs to be flushed, and ensure that it is flushed before we paint again.

* Shared/mac/RemoteLayerBackingStore.mm:
(RemoteLayerBackingStore::display):

(RemoteLayerBackingStore::drawInContext):
Don't flush the context immediately after painting.

(RemoteLayerBackingStore::flush):
Flush the current front surface/buffer's context.
Clear the new pending-flush members.

* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::flushBackingStoreChangesInTransaction):
(WebKit::RemoteLayerTreeDrawingArea::flushLayers):
Crawl through all of the valid changed backing stores in the transaction and flush them.
Reset changed properties after encoding the commit.

* Shared/mac/RemoteLayerTreeTransaction.h:
(WebKit::RemoteLayerTreeTransaction::LayerProperties::resetChangedProperties):
(WebKit::RemoteLayerTreeTransaction::changedLayers):
(WebKit::RemoteLayerTreeTransaction::changedLayerProperties):
* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
(WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
(WebKit::RemoteLayerTreeTransaction::encode):
(WebKit::RemoteLayerTreeTransaction::decode):
(WebKit::RemoteLayerTreeTransaction::layerPropertiesChanged):
(WebKit::dumpChangedLayers):
Instead of storing a copy of the LayerProperties struct for each changed layer
while building the transaction in the Web process, store a list of changed layers,
and directly encode the commit from those layers' LayerProperties. This provides a few benefits:
        - We avoid copying LayerProperties for every changed layer, every commit
        - We can make RemoteLayerBackingStore noncopyable
        - We can walk the changed layers after building the transaction
        in order to flush backing store, and actually affect the layers'
        own RemoteLayerBackingStore instead of a copy.
The UI process will still generate a LayerPropertiesMap at decode time.

* UIProcess/mac/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::updateLayerTree):
Don't copy the LayerProperties struct for the debug overlay. Instead,
adjust the properties which the debug overlay whacks directly on the layer,
after applying the normal LayerProperties.

* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(PlatformCALayerRemote::recursiveBuildTransaction):
Don't reset changed layer properties in the middle of building a transaction. Instead,
RemoteLayerTreeDrawingArea::flushLayers() will reset all the flags on all changed layers
after the commit is encoded.

* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
(WebKit::PlatformCALayerRemote::properties):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (166544 => 166545)


--- trunk/Source/WebKit2/ChangeLog	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/ChangeLog	2014-03-31 23:30:43 UTC (rev 166545)
@@ -1,3 +1,68 @@
+2014-03-31  Tim Horton  <[email protected]>
+
+        [iOS WebKit2] Flush all surfaces after painting into all of them, instead of after painting into each one
+        https://bugs.webkit.org/show_bug.cgi?id=130768
+        <rdar://problem/16421471>
+
+        Reviewed by Benjamin Poulain.
+
+        * Shared/mac/RemoteLayerBackingStore.h:
+        Make RemoteLayerBackingStore noncopyable.
+        Add flush(), which synchronously flushes painting operations on the underlying backing store.
+        Add storage for the CGContext that needs to be flushed, and ensure that it is flushed before we paint again.
+
+        * Shared/mac/RemoteLayerBackingStore.mm:
+        (RemoteLayerBackingStore::display):
+
+        (RemoteLayerBackingStore::drawInContext):
+        Don't flush the context immediately after painting.
+
+        (RemoteLayerBackingStore::flush):
+        Flush the current front surface/buffer's context.
+        Clear the new pending-flush members.
+
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::flushBackingStoreChangesInTransaction):
+        (WebKit::RemoteLayerTreeDrawingArea::flushLayers):
+        Crawl through all of the valid changed backing stores in the transaction and flush them.
+        Reset changed properties after encoding the commit.
+
+        * Shared/mac/RemoteLayerTreeTransaction.h:
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::resetChangedProperties):
+        (WebKit::RemoteLayerTreeTransaction::changedLayers):
+        (WebKit::RemoteLayerTreeTransaction::changedLayerProperties):
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::LayerProperties):
+        (WebKit::RemoteLayerTreeTransaction::LayerProperties::decode):
+        (WebKit::RemoteLayerTreeTransaction::encode):
+        (WebKit::RemoteLayerTreeTransaction::decode):
+        (WebKit::RemoteLayerTreeTransaction::layerPropertiesChanged):
+        (WebKit::dumpChangedLayers):
+        Instead of storing a copy of the LayerProperties struct for each changed layer
+        while building the transaction in the Web process, store a list of changed layers,
+        and directly encode the commit from those layers' LayerProperties. This provides a few benefits:
+                - We avoid copying LayerProperties for every changed layer, every commit
+                - We can make RemoteLayerBackingStore noncopyable
+                - We can walk the changed layers after building the transaction
+                in order to flush backing store, and actually affect the layers'
+                own RemoteLayerBackingStore instead of a copy.
+        The UI process will still generate a LayerPropertiesMap at decode time.
+        
+        * UIProcess/mac/RemoteLayerTreeHost.mm:
+        (WebKit::RemoteLayerTreeHost::updateLayerTree):
+        Don't copy the LayerProperties struct for the debug overlay. Instead,
+        adjust the properties which the debug overlay whacks directly on the layer,
+        after applying the normal LayerProperties.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (PlatformCALayerRemote::recursiveBuildTransaction):
+        Don't reset changed layer properties in the middle of building a transaction. Instead,
+        RemoteLayerTreeDrawingArea::flushLayers() will reset all the flags on all changed layers
+        after the commit is encoded.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        (WebKit::PlatformCALayerRemote::properties):
+
 2014-03-31  Simon Fraser  <[email protected]>
 
         [UI-side compositing] Proxy animations to the UI process

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h (166544 => 166545)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.h	2014-03-31 23:30:43 UTC (rev 166545)
@@ -43,6 +43,8 @@
 class PlatformCALayerRemote;
 
 class RemoteLayerBackingStore {
+    WTF_MAKE_NONCOPYABLE(RemoteLayerBackingStore);
+    WTF_MAKE_FAST_ALLOCATED;
 public:
     RemoteLayerBackingStore();
 
@@ -76,6 +78,8 @@
         return !!m_frontBuffer;
     }
 
+    void flush();
+
 private:
     void drawInContext(WebCore::GraphicsContext&, CGImageRef backImage);
     void clearBackingStore();
@@ -95,6 +99,8 @@
     RefPtr<WebCore::IOSurface> m_backSurface;
 #endif
 
+    RetainPtr<CGContextRef> m_frontContextPendingFlush;
+
     bool m_acceleratesDrawing;
 
     WebCore::RepaintRectList m_paintingRects;

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm (166544 => 166545)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm	2014-03-31 23:30:43 UTC (rev 166545)
@@ -151,6 +151,8 @@
 
 bool RemoteLayerBackingStore::display()
 {
+    ASSERT(!m_frontContextPendingFlush);
+
     if (!m_layer)
         return false;
 
@@ -202,10 +204,10 @@
 
         return true;
     }
-#else
-    ASSERT(!m_acceleratesDrawing);
 #endif
 
+    ASSERT(!m_acceleratesDrawing);
+
     std::swap(m_frontBuffer, m_backBuffer);
     if (!m_frontBuffer)
         m_frontBuffer = ShareableBitmap::createShareable(expandedScaledSize, m_isOpaque ? ShareableBitmap::NoFlags : ShareableBitmap::SupportsAlpha);
@@ -294,7 +296,7 @@
     m_dirtyRegion = Region();
     m_paintingRects.clear();
 
-    CGContextFlush(context.platformContext());
+    m_frontContextPendingFlush = context.platformContext();
 }
 
 void RemoteLayerBackingStore::enumerateRectsBeingDrawn(CGContextRef context, void (^block)(CGRect))
@@ -327,4 +329,12 @@
     layer.contents = (id)m_frontBuffer->makeCGImageCopy().get();
 }
 
+void RemoteLayerBackingStore::flush()
+{
+    if (m_frontContextPendingFlush) {
+        CGContextFlush(m_frontContextPendingFlush.get());
+        m_frontContextPendingFlush = nullptr;
+    }
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h (166544 => 166545)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.h	2014-03-31 23:30:43 UTC (rev 166545)
@@ -108,6 +108,11 @@
             everChangedProperties |= changeFlags;
         }
 
+        void resetChangedProperties()
+        {
+            changedProperties = RemoteLayerTreeTransaction::NoChange;
+        }
+
         LayerChange changedProperties;
         LayerChange everChangedProperties;
 
@@ -163,12 +168,15 @@
 #endif
 
     typedef HashMap<WebCore::GraphicsLayer::PlatformLayerID, std::unique_ptr<LayerProperties>> LayerPropertiesMap;
-    
+
     Vector<LayerCreationProperties> createdLayers() const { return m_createdLayers; }
-    const LayerPropertiesMap& changedLayers() const { return m_changedLayerProperties; }
-    LayerPropertiesMap& changedLayers() { return m_changedLayerProperties; }
     Vector<WebCore::GraphicsLayer::PlatformLayerID> destroyedLayers() const { return m_destroyedLayerIDs; }
 
+    Vector<RefPtr<PlatformCALayerRemote>>& changedLayers() { return m_changedLayers; }
+
+    const LayerPropertiesMap& changedLayerProperties() const { return m_changedLayerProperties; }
+    LayerPropertiesMap& changedLayerProperties() { return m_changedLayerProperties; }
+
     WebCore::IntSize contentsSize() const { return m_contentsSize; }
     void setContentsSize(const WebCore::IntSize& size) { m_contentsSize = size; };
     
@@ -198,7 +206,9 @@
     
 private:
     WebCore::GraphicsLayer::PlatformLayerID m_rootLayerID;
-    LayerPropertiesMap m_changedLayerProperties;
+    Vector<RefPtr<PlatformCALayerRemote>> m_changedLayers; // Only used in the Web process.
+    LayerPropertiesMap m_changedLayerProperties; // Only used in the UI process.
+
     Vector<LayerCreationProperties> m_createdLayers;
     Vector<WebCore::GraphicsLayer::PlatformLayerID> m_destroyedLayerIDs;
     Vector<WebCore::GraphicsLayer::PlatformLayerID> m_videoLayerIDsPendingFullscreen;

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm (166544 => 166545)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm	2014-03-31 23:30:43 UTC (rev 166545)
@@ -128,14 +128,14 @@
     , masksToBounds(other.masksToBounds)
     , opaque(other.opaque)
 {
+    // FIXME: LayerProperties should reference backing store by ID, so that two layers can have the same backing store (for clones).
+    // FIXME: LayerProperties shouldn't be copyable; PlatformCALayerRemote::clone should copy the relevant properties.
+
     if (other.transform)
         transform = std::make_unique<TransformationMatrix>(*other.transform);
 
     if (other.sublayerTransform)
         sublayerTransform = std::make_unique<TransformationMatrix>(*other.sublayerTransform);
-    
-    if (other.backingStore)
-        backingStore = std::make_unique<RemoteLayerBackingStore>(*other.backingStore);
 
     if (other.filters)
         filters = std::make_unique<FilterOperations>(*other.filters);
@@ -382,11 +382,11 @@
         if (!decoder.decode(hasFrontBuffer))
             return false;
         if (hasFrontBuffer) {
-            RemoteLayerBackingStore backingStore;
-            if (!decoder.decode(backingStore))
+            std::unique_ptr<RemoteLayerBackingStore> backingStore = std::make_unique<RemoteLayerBackingStore>();
+            if (!decoder.decode(*backingStore))
                 return false;
             
-            result.backingStore = std::make_unique<RemoteLayerBackingStore>(backingStore);
+            result.backingStore = std::move(backingStore);
         }
     }
 
@@ -428,11 +428,11 @@
     encoder << m_rootLayerID;
     encoder << m_createdLayers;
 
-    encoder << m_changedLayerProperties.size();
+    encoder << static_cast<uint64_t>(m_changedLayers.size());
 
-    for (const auto& layerProperties : m_changedLayerProperties) {
-        encoder << layerProperties.key;
-        encoder << *layerProperties.value;
+    for (RefPtr<PlatformCALayerRemote> layer : m_changedLayers) {
+        encoder << layer->layerID();
+        encoder << layer->properties();
     }
     
     encoder << m_destroyedLayerIDs;
@@ -461,11 +461,11 @@
     if (!decoder.decode(result.m_createdLayers))
         return false;
 
-    int numChangedLayerProperties;
+    uint64_t numChangedLayerProperties;
     if (!decoder.decode(numChangedLayerProperties))
         return false;
 
-    for (int i = 0; i < numChangedLayerProperties; ++i) {
+    for (uint64_t i = 0; i < numChangedLayerProperties; ++i) {
         GraphicsLayer::PlatformLayerID layerID;
         if (!decoder.decode(layerID))
             return false;
@@ -474,7 +474,7 @@
         if (!decoder.decode(*layerProperties))
             return false;
 
-        result.changedLayers().set(layerID, std::move(layerProperties));
+        result.changedLayerProperties().set(layerID, std::move(layerProperties));
     }
 
     if (!decoder.decode(result.m_destroyedLayerIDs))
@@ -527,7 +527,7 @@
 
 void RemoteLayerTreeTransaction::layerPropertiesChanged(PlatformCALayerRemote* remoteLayer, RemoteLayerTreeTransaction::LayerProperties& properties)
 {
-    m_changedLayerProperties.set(remoteLayer->layerID(), std::make_unique<RemoteLayerTreeTransaction::LayerProperties>(properties));
+    m_changedLayers.append(remoteLayer);
 }
 
 void RemoteLayerTreeTransaction::setCreatedLayers(Vector<LayerCreationProperties> createdLayers)
@@ -818,7 +818,7 @@
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
             if (const RemoteLayerBackingStore* backingStore = layerProperties.backingStore.get())
-                dumpProperty<RemoteLayerBackingStore>(ts, "backingStore", *backingStore);
+                dumpProperty<const RemoteLayerBackingStore&>(ts, "backingStore", *backingStore);
             else
                 dumpProperty<String>(ts, "backingStore", "removed");
         }

Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm (166544 => 166545)


--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm	2014-03-31 23:30:43 UTC (rev 166545)
@@ -56,7 +56,7 @@
 bool RemoteLayerTreeHost::updateLayerTree(const RemoteLayerTreeTransaction& transaction, float indicatorScaleFactor)
 {
     for (const auto& createdLayer : transaction.createdLayers()) {
-        const RemoteLayerTreeTransaction::LayerProperties* properties = transaction.changedLayers().get(createdLayer.layerID);
+        const RemoteLayerTreeTransaction::LayerProperties* properties = transaction.changedLayerProperties().get(createdLayer.layerID);
         createLayer(createdLayer, properties);
     }
 
@@ -67,7 +67,7 @@
         rootLayerChanged = true;
     }
 
-    for (auto& changedLayer : transaction.changedLayers()) {
+    for (auto& changedLayer : transaction.changedLayerProperties()) {
         auto layerID = changedLayer.key;
         const RemoteLayerTreeTransaction::LayerProperties& properties = *changedLayer.value;
 
@@ -84,13 +84,13 @@
             relatedLayers.set(properties.maskLayerID, getLayer(properties.maskLayerID));
 
         if (m_isDebugLayerTreeHost) {
-            RemoteLayerTreeTransaction::LayerProperties propertiesCopy(properties);
-            propertiesCopy.masksToBounds = false;
-            if (propertiesCopy.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged)
-                propertiesCopy.borderWidth *= 1 / indicatorScaleFactor;
-            
-            RemoteLayerTreePropertyApplier::applyProperties(layer, this, propertiesCopy, relatedLayers);
-        } else
+            RemoteLayerTreePropertyApplier::applyProperties(layer, properties, relatedLayers);
+
+            if (properties.changedProperties & RemoteLayerTreeTransaction::BorderWidthChanged)
+                asLayer(layer).borderWidth = properties.borderWidth / indicatorScaleFactor;
+            asLayer(layer).masksToBounds = false;
+          } else
+        else
             RemoteLayerTreePropertyApplier::applyProperties(layer, this, properties, relatedLayers);
     }
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp (166544 => 166545)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp	2014-03-31 23:30:43 UTC (rev 166545)
@@ -72,7 +72,7 @@
 {
     RefPtr<PlatformCALayerRemote> layer = adoptRef(new PlatformCALayerRemote(other, owner, context));
 
-    context->layerWasCreated(layer.get(), LayerTypeCustom);
+    context->layerWasCreated(layer.get(), other.layerType());
 
     return layer.release();
 }
@@ -126,12 +126,11 @@
 
         if (m_layerType == LayerTypeCustom) {
             RemoteLayerTreePropertyApplier::applyProperties(platformLayer(), nullptr, m_properties, RemoteLayerTreePropertyApplier::RelatedLayerMap());
-            m_properties.changedProperties = RemoteLayerTreeTransaction::NoChange;
+            m_properties.resetChangedProperties();
             return;
         }
 
         transaction.layerPropertiesChanged(this, m_properties);
-        m_properties.changedProperties = RemoteLayerTreeTransaction::NoChange;
     }
 
     for (size_t i = 0; i < m_children.size(); ++i) {

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h (166544 => 166545)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h	2014-03-31 23:30:43 UTC (rev 166545)
@@ -151,6 +151,8 @@
 
     virtual uint32_t hostingContextID();
 
+    RemoteLayerTreeTransaction::LayerProperties& properties() { return m_properties; }
+
 protected:
     PlatformCALayerRemote(WebCore::PlatformCALayer::LayerType, WebCore::PlatformCALayerClient* owner, RemoteLayerTreeContext* context);
     PlatformCALayerRemote(const PlatformCALayerRemote&, WebCore::PlatformCALayerClient*, RemoteLayerTreeContext*);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (166544 => 166545)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-03-31 23:27:29 UTC (rev 166544)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-03-31 23:30:43 UTC (rev 166545)
@@ -28,6 +28,7 @@
 
 #import "DrawingAreaProxyMessages.h"
 #import "GraphicsLayerCARemote.h"
+#import "PlatformCALayerRemote.h"
 #import "RemoteLayerTreeContext.h"
 #import "RemoteLayerTreeDrawingAreaProxyMessages.h"
 #import "RemoteScrollingCoordinator.h"
@@ -309,6 +310,17 @@
     flushLayers();
 }
 
+static void flushBackingStoreChangesInTransaction(RemoteLayerTreeTransaction& transaction)
+{
+    for (RefPtr<PlatformCALayerRemote> layer : transaction.changedLayers()) {
+        if (!layer->properties().changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged)
+            return;
+
+        if (RemoteLayerBackingStore* backingStore = layer->properties().backingStore.get())
+            backingStore->flush();
+    }
+}
+
 void RemoteLayerTreeDrawingArea::flushLayers()
 {
     if (!m_rootLayer)
@@ -340,8 +352,14 @@
         toRemoteScrollingCoordinator(m_webPage->scrollingCoordinator())->buildTransaction(scrollingTransaction);
 #endif
 
+    // FIXME: Move flushing backing store and sending CommitLayerTree onto a background thread.
+    flushBackingStoreChangesInTransaction(layerTransaction);
+
     m_waitingForBackingStoreSwap = true;
     m_webPage->send(Messages::RemoteLayerTreeDrawingAreaProxy::CommitLayerTree(layerTransaction, scrollingTransaction));
+
+    for (auto& layer : layerTransaction.changedLayers())
+        layer->properties().resetChangedProperties();
 }
 
 void RemoteLayerTreeDrawingArea::didUpdate()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to