Remote Layer Tree: Implement superlayer, removeFromSuperlayer, replaceSublayer, and...
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Oct 2013 08:24:50 +0000 (08:24 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Oct 2013 08:24:50 +0000 (08:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123130

Reviewed by Anders Carlsson.

Implement the remaining layer-hierarchy-manipulation methods.

* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(PlatformCALayerRemote::PlatformCALayerRemote):
(PlatformCALayerRemote::~PlatformCALayerRemote):
Null out the superlayer back-pointer on our sublayers.

(PlatformCALayerRemote::recursiveBuildTransaction):
Ensure that our children all have us as their superlayer.

(PlatformCALayerRemote::superlayer):
Return the stored superlayer pointer.

(PlatformCALayerRemote::removeFromSuperlayer):
Call removeSublayer on our superlayer, if we have one.

(PlatformCALayerRemote::removeSublayer):
Remove the given layer if it's in our list of sublayers, clear its
reference to us, and note that we'll need to commit hierarchy changes.

(PlatformCALayerRemote::setSublayers):
removeAllSublayers() before setting the new list, to clear superlayer
back-pointers. Children will be protected by the PlatformCALayerList.
Update the new layers' superlayers.

(PlatformCALayerRemote::removeAllSublayers):
Remove each sublayer from its superlayer, then clear our list of children.

(PlatformCALayerRemote::appendSublayer):
(PlatformCALayerRemote::insertSublayer):
Protect the layer from deletion, so that we can remove it from its prior
superlayer before appending or inserting it.

(PlatformCALayerRemote::replaceSublayer):
Find the reference sublayer, if it exists, and replace it with the new one.

(PlatformCALayerRemote::adoptSublayers):
adoptSublayers is really just "set sublayers to this other layer's sublayers".
Since setSublayers already removes layers from the existing superlayer,
we can just go ahead and call it.

(PlatformCALayerRemote::addAnimationForKey):
(PlatformCALayerRemote::removeAnimationForKey):
(PlatformCALayerRemote::animationForKey):
Add some ASSERT_NOT_REACHEDs in animation code.
We ought not get here because we've disabled hardware animations
in GraphicsLayerCARemote.

* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
Add m_superlayer and removeSublayer().

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

Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp
Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h

index c69e46c..6dc0b60 100644 (file)
@@ -1,3 +1,61 @@
+2013-10-23  Tim Horton  <timothy_horton@apple.com>
+
+        Remote Layer Tree: Implement superlayer, removeFromSuperlayer, replaceSublayer, and adoptSublayers
+        https://bugs.webkit.org/show_bug.cgi?id=123130
+
+        Reviewed by Anders Carlsson.
+
+        Implement the remaining layer-hierarchy-manipulation methods.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (PlatformCALayerRemote::PlatformCALayerRemote):
+        (PlatformCALayerRemote::~PlatformCALayerRemote):
+        Null out the superlayer back-pointer on our sublayers.
+
+        (PlatformCALayerRemote::recursiveBuildTransaction):
+        Ensure that our children all have us as their superlayer.
+
+        (PlatformCALayerRemote::superlayer):
+        Return the stored superlayer pointer.
+
+        (PlatformCALayerRemote::removeFromSuperlayer):
+        Call removeSublayer on our superlayer, if we have one.
+
+        (PlatformCALayerRemote::removeSublayer):
+        Remove the given layer if it's in our list of sublayers, clear its
+        reference to us, and note that we'll need to commit hierarchy changes.
+
+        (PlatformCALayerRemote::setSublayers):
+        removeAllSublayers() before setting the new list, to clear superlayer
+        back-pointers. Children will be protected by the PlatformCALayerList.
+        Update the new layers' superlayers.
+
+        (PlatformCALayerRemote::removeAllSublayers):
+        Remove each sublayer from its superlayer, then clear our list of children.
+
+        (PlatformCALayerRemote::appendSublayer):
+        (PlatformCALayerRemote::insertSublayer):
+        Protect the layer from deletion, so that we can remove it from its prior
+        superlayer before appending or inserting it.
+
+        (PlatformCALayerRemote::replaceSublayer):
+        Find the reference sublayer, if it exists, and replace it with the new one.
+
+        (PlatformCALayerRemote::adoptSublayers):
+        adoptSublayers is really just "set sublayers to this other layer's sublayers".
+        Since setSublayers already removes layers from the existing superlayer,
+        we can just go ahead and call it.
+
+        (PlatformCALayerRemote::addAnimationForKey):
+        (PlatformCALayerRemote::removeAnimationForKey):
+        (PlatformCALayerRemote::animationForKey):
+        Add some ASSERT_NOT_REACHEDs in animation code.
+        We ought not get here because we've disabled hardware animations
+        in GraphicsLayerCARemote.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        Add m_superlayer and removeSublayer().
+
 2013-10-22  Ryuan Choi  <ryuan.choi@samsung.com>
 
         Unreviewed build fix attempt on Soup based port after r157842.
index 1e7daf9..00871fa 100644 (file)
@@ -50,6 +50,12 @@ static RemoteLayerTreeTransaction::LayerID generateLayerID()
     return ++layerID;
 }
 
+static PlatformCALayerRemote* toPlatformCALayerRemote(PlatformCALayer* layer)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!layer || layer->isRemote());
+    return static_cast<PlatformCALayerRemote*>(layer);
+}
+
 PassRefPtr<PlatformCALayer> PlatformCALayerRemote::create(LayerType layerType, PlatformCALayerClient* owner, RemoteLayerTreeContext* context)
 {
     return adoptRef(new PlatformCALayerRemote(layerType, owner, context));
@@ -58,6 +64,7 @@ PassRefPtr<PlatformCALayer> PlatformCALayerRemote::create(LayerType layerType, P
 PlatformCALayerRemote::PlatformCALayerRemote(LayerType layerType, PlatformCALayerClient* owner, RemoteLayerTreeContext* context)
     : PlatformCALayer(layerType, owner)
     , m_layerID(generateLayerID())
+    , m_superlayer(nullptr)
     , m_context(context)
 {
     m_context->layerWasCreated(this, layerType);
@@ -70,6 +77,8 @@ PassRefPtr<PlatformCALayer> PlatformCALayerRemote::clone(PlatformCALayerClient*
 
 PlatformCALayerRemote::~PlatformCALayerRemote()
 {
+    for (const auto& layer : m_children)
+        toPlatformCALayerRemote(layer.get())->m_superlayer = nullptr;
     m_context->layerWillBeDestroyed(this);
 }
 
@@ -82,7 +91,7 @@ void PlatformCALayerRemote::recursiveBuildTransaction(RemoteLayerTreeTransaction
         if (m_properties.changedProperties & RemoteLayerTreeTransaction::ChildrenChanged) {
             m_properties.children.clear();
             for (auto layer : m_children)
-                m_properties.children.append(static_cast<PlatformCALayerRemote*>(layer.get())->layerID());
+                m_properties.children.append(toPlatformCALayerRemote(layer.get())->layerID());
         }
 
         transaction.layerPropertiesChanged(this, m_properties);
@@ -90,7 +99,8 @@ void PlatformCALayerRemote::recursiveBuildTransaction(RemoteLayerTreeTransaction
     }
 
     for (size_t i = 0; i < m_children.size(); ++i) {
-        PlatformCALayerRemote* child = static_cast<PlatformCALayerRemote*>(m_children[i].get());
+        PlatformCALayerRemote* child = toPlatformCALayerRemote(m_children[i].get());
+        ASSERT(child->superlayer() == this);
         child->recursiveBuildTransaction(transaction);
     }
 }
@@ -128,76 +138,106 @@ void PlatformCALayerRemote::setContentsChanged()
 
 PlatformCALayer* PlatformCALayerRemote::superlayer() const
 {
-    return nullptr;
+    return m_superlayer;
 }
 
 void PlatformCALayerRemote::removeFromSuperlayer()
 {
-    ASSERT_NOT_REACHED();
+    if (!m_superlayer)
+        return;
+
+    m_superlayer->removeSublayer(this);
 }
 
-void PlatformCALayerRemote::setSublayers(const PlatformCALayerList& list)
+void PlatformCALayerRemote::removeSublayer(PlatformCALayerRemote* layer)
 {
-#ifndef ASSERT_DISABLED
-    for (const auto& layer : list) {
-        ASSERT_WITH_SECURITY_IMPLICATION(layer->isRemote());
-    }
-#endif
+    size_t childIndex = m_children.find(layer);
+    if (childIndex != notFound)
+        m_children.remove(childIndex);
+    layer->m_superlayer = nullptr;
+    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ChildrenChanged);
+}
 
+void PlatformCALayerRemote::setSublayers(const PlatformCALayerList& list)
+{
+    removeAllSublayers();
     m_children = list;
+
+    for (const auto& layer : list)
+        toPlatformCALayerRemote(layer.get())->m_superlayer = this;
+
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ChildrenChanged);
 }
 
 void PlatformCALayerRemote::removeAllSublayers()
 {
+    for (const auto& layer : m_children)
+        layer->removeFromSuperlayer();
     m_children.clear();
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ChildrenChanged);
 }
 
 void PlatformCALayerRemote::appendSublayer(PlatformCALayer* layer)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(layer->isRemote());
+    RefPtr<PlatformCALayer> layerProtector(layer);
 
+    layer->removeFromSuperlayer();
     m_children.append(layer);
+    toPlatformCALayerRemote(layer)->m_superlayer = this;
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ChildrenChanged);
 }
 
 void PlatformCALayerRemote::insertSublayer(PlatformCALayer* layer, size_t index)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(layer->isRemote());
+    RefPtr<PlatformCALayer> layerProtector(layer);
 
+    layer->removeFromSuperlayer();
     m_children.insert(index, layer);
+    toPlatformCALayerRemote(layer)->m_superlayer = this;
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ChildrenChanged);
 }
 
 void PlatformCALayerRemote::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* layer)
 {
-    ASSERT_NOT_REACHED();
+    ASSERT(reference->superlayer() == this);
+    RefPtr<PlatformCALayer> layerProtector(layer);
+
+    layer->removeFromSuperlayer();
+    size_t referenceIndex = m_children.find(reference);
+    if (referenceIndex != notFound) {
+        m_children[referenceIndex]->removeFromSuperlayer();
+        m_children.remove(referenceIndex);
+        m_children.insert(referenceIndex, layer);
+    }
+
+    m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::ChildrenChanged);
 }
 
 void PlatformCALayerRemote::adoptSublayers(PlatformCALayer* source)
 {
-    ASSERT_NOT_REACHED();
+    setSublayers(toPlatformCALayerRemote(source)->m_children);
 }
 
 void PlatformCALayerRemote::addAnimationForKey(const String& key, PlatformCAAnimation* animation)
 {
+    ASSERT_NOT_REACHED();
 }
 
 void PlatformCALayerRemote::removeAnimationForKey(const String& key)
 {
+    ASSERT_NOT_REACHED();
 }
 
 PassRefPtr<PlatformCAAnimation> PlatformCALayerRemote::animationForKey(const String& key)
 {
+    ASSERT_NOT_REACHED();
+
     return nullptr;
 }
 
 void PlatformCALayerRemote::setMask(PlatformCALayer* layer)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(layer->isRemote());
-
-    m_properties.maskLayer = static_cast<PlatformCALayerRemote*>(layer)->layerID();
+    m_properties.maskLayer = toPlatformCALayerRemote(layer)->layerID();
     m_properties.notePropertiesChanged(RemoteLayerTreeTransaction::MaskLayerChanged);
 }
 
index fa7f1bf..ef18ae8 100644 (file)
@@ -149,10 +149,12 @@ private:
     virtual AVPlayerLayer *playerLayer() const OVERRIDE;
 
     void ensureBackingStore();
+    void removeSublayer(PlatformCALayerRemote*);
 
     RemoteLayerTreeTransaction::LayerID m_layerID;
     RemoteLayerTreeTransaction::LayerProperties m_properties;
     WebCore::PlatformCALayerList m_children;
+    PlatformCALayerRemote* m_superlayer;
 
     RemoteLayerTreeContext* m_context;
 };