Bug 785333 - Synchronise layer InsertAfter/RemoveChild methods. r=bas
authorChris Lord <chrislord.net@gmail.com>
Wed, 29 Aug 2012 11:52:44 +0100
changeset 105787 c06b09e067d7e50f36ac41905b3fa52d2c8915c2
parent 105786 91d39d72ac86b08a20e8039fd90841be17a2adf5
child 105788 a9023cfa7721525a4646eab737d228dbafdf527c
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersbas
bugs785333
milestone18.0a1
Bug 785333 - Synchronise layer InsertAfter/RemoveChild methods. r=bas InsertAfter/RemoveChild in the Direct3D and OpenGL Layer backends have fallen behind the implementation in BasicContainerLayer. Synchronise them.
gfx/layers/d3d10/ContainerLayerD3D10.cpp
gfx/layers/d3d9/ContainerLayerD3D9.cpp
gfx/layers/opengl/ContainerLayerOGL.cpp
--- a/gfx/layers/d3d10/ContainerLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ContainerLayerD3D10.cpp
@@ -27,89 +27,81 @@ ContainerLayerD3D10::~ContainerLayerD3D1
   while (mFirstChild) {
     RemoveChild(mFirstChild);
   }
 }
 template<class Container>
 static void
 ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter)
 {
-    aChild->SetParent(aContainer);
-    if (!aAfter) {
-        Layer *oldFirstChild = aContainer->GetFirstChild();
-        aContainer->mFirstChild = aChild;
-        aChild->SetNextSibling(oldFirstChild);
-        aChild->SetPrevSibling(nullptr);
-        if (oldFirstChild) {
-            oldFirstChild->SetPrevSibling(aChild);
-        } else {
-            aContainer->mLastChild = aChild;
-        }
-        NS_ADDREF(aChild);
-        aContainer->DidInsertChild(aChild);
-        return;
+  NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
+               "Child has wrong manager");
+  NS_ASSERTION(!aChild->GetParent(),
+               "aChild already in the tree");
+  NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
+               "aChild already has siblings?");
+  NS_ASSERTION(!aAfter ||
+               (aAfter->Manager() == aContainer->Manager() &&
+                aAfter->GetParent() == aContainer),
+               "aAfter is not our child");
+
+  aChild->SetParent(aContainer);
+  if (aAfter == aContainer->mLastChild) {
+    aContainer->mLastChild = aChild;
+  }
+  if (!aAfter) {
+    aChild->SetNextSibling(aContainer->mFirstChild);
+    if (aContainer->mFirstChild) {
+      aContainer->mFirstChild->SetPrevSibling(aChild);
     }
-    for (Layer *child = aContainer->GetFirstChild(); 
-        child; child = child->GetNextSibling()) {
-            if (aAfter == child) {
-                Layer *oldNextSibling = child->GetNextSibling();
-                child->SetNextSibling(aChild);
-                aChild->SetNextSibling(oldNextSibling);
-                if (oldNextSibling) {
-                    oldNextSibling->SetPrevSibling(aChild);
-                } else {
-                    aContainer->mLastChild = aChild;
-                }
-                aChild->SetPrevSibling(child);
-                NS_ADDREF(aChild);
-                aContainer->DidInsertChild(aChild);
-                return;
-            }
-    }
-    NS_WARNING("Failed to find aAfter layer!");
+    aContainer->mFirstChild = aChild;
+    NS_ADDREF(aChild);
+    aContainer->DidInsertChild(aChild);
+    return;
+  }
+
+  Layer* next = aAfter->GetNextSibling();
+  aChild->SetNextSibling(next);
+  aChild->SetPrevSibling(aAfter);
+  if (next) {
+    next->SetPrevSibling(aChild);
+  }
+  aAfter->SetNextSibling(aChild);
+  NS_ADDREF(aChild);
+  aContainer->DidInsertChild(aChild);
 }
 
 template<class Container>
 static void
 ContainerRemoveChild(Container* aContainer, Layer* aChild)
 {
-    if (aContainer->GetFirstChild() == aChild) {
-        aContainer->mFirstChild = aContainer->GetFirstChild()->GetNextSibling();
-        if (aContainer->mFirstChild) {
-            aContainer->mFirstChild->SetPrevSibling(nullptr);
-        } else {
-            aContainer->mLastChild = nullptr;
-        }
-        aChild->SetNextSibling(nullptr);
-        aChild->SetPrevSibling(nullptr);
-        aChild->SetParent(nullptr);
-        aContainer->DidRemoveChild(aChild);
-        NS_RELEASE(aChild);
-        return;
-    }
-    Layer *lastChild = nullptr;
-    for (Layer *child = aContainer->GetFirstChild(); child; 
-        child = child->GetNextSibling()) {
-            if (child == aChild) {
-                // We're sure this is not our first child. So lastChild != NULL.
-                lastChild->SetNextSibling(child->GetNextSibling());
-                if (child->GetNextSibling()) {
-                    child->GetNextSibling()->SetPrevSibling(lastChild);
-                } else {
-                    aContainer->mLastChild = lastChild;
-                }
-                child->SetNextSibling(nullptr);
-                child->SetPrevSibling(nullptr);
-                child->SetParent(nullptr);
-                aContainer->DidRemoveChild(aChild);
-                NS_RELEASE(aChild);
-                return;
-            }
-            lastChild = child;
-    }
+  NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
+               "Child has wrong manager");
+  NS_ASSERTION(aChild->GetParent() == aContainer,
+               "aChild not our child");
+
+  Layer* prev = aChild->GetPrevSibling();
+  Layer* next = aChild->GetNextSibling();
+  if (prev) {
+    prev->SetNextSibling(next);
+  } else {
+    aContainer->mFirstChild = next;
+  }
+  if (next) {
+    next->SetPrevSibling(prev);
+  } else {
+    aContainer->mLastChild = prev;
+  }
+
+  aChild->SetNextSibling(nullptr);
+  aChild->SetPrevSibling(nullptr);
+  aChild->SetParent(nullptr);
+
+  aContainer->DidRemoveChild(aChild);
+  NS_RELEASE(aChild);
 }
 
 void
 ContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter)
 {
   ContainerInsertAfter(this, aChild, aAfter);
 }
 
--- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp
@@ -11,89 +11,81 @@
 
 namespace mozilla {
 namespace layers {
 
 template<class Container>
 static void
 ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter)
 {
+  NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
+               "Child has wrong manager");
+  NS_ASSERTION(!aChild->GetParent(),
+               "aChild already in the tree");
+  NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
+               "aChild already has siblings?");
+  NS_ASSERTION(!aAfter ||
+               (aAfter->Manager() == aContainer->Manager() &&
+                aAfter->GetParent() == aContainer),
+               "aAfter is not our child");
+
   aChild->SetParent(aContainer);
+  if (aAfter == aContainer->mLastChild) {
+    aContainer->mLastChild = aChild;
+  }
   if (!aAfter) {
-    Layer *oldFirstChild = aContainer->GetFirstChild();
+    aChild->SetNextSibling(aContainer->mFirstChild);
+    if (aContainer->mFirstChild) {
+      aContainer->mFirstChild->SetPrevSibling(aChild);
+    }
     aContainer->mFirstChild = aChild;
-    aChild->SetNextSibling(oldFirstChild);
-    aChild->SetPrevSibling(nullptr);
-    if (oldFirstChild) {
-      oldFirstChild->SetPrevSibling(aChild);
-    } else {
-      aContainer->mLastChild = aChild;
-    }
     NS_ADDREF(aChild);
     aContainer->DidInsertChild(aChild);
     return;
   }
-  for (Layer *child = aContainer->GetFirstChild(); 
-       child; child = child->GetNextSibling()) {
-    if (aAfter == child) {
-      Layer *oldNextSibling = child->GetNextSibling();
-      child->SetNextSibling(aChild);
-      aChild->SetNextSibling(oldNextSibling);
-      if (oldNextSibling) {
-        oldNextSibling->SetPrevSibling(aChild);
-      } else {
-        aContainer->mLastChild = aChild;
-      }
-      aChild->SetPrevSibling(child);
-      NS_ADDREF(aChild);
-      aContainer->DidInsertChild(aChild);
-      return;
-    }
+
+  Layer* next = aAfter->GetNextSibling();
+  aChild->SetNextSibling(next);
+  aChild->SetPrevSibling(aAfter);
+  if (next) {
+    next->SetPrevSibling(aChild);
   }
-  NS_WARNING("Failed to find aAfter layer!");
+  aAfter->SetNextSibling(aChild);
+  NS_ADDREF(aChild);
+  aContainer->DidInsertChild(aChild);
 }
 
 template<class Container>
 static void
 ContainerRemoveChild(Container* aContainer, Layer* aChild)
 {
-  if (aContainer->GetFirstChild() == aChild) {
-    aContainer->mFirstChild = aContainer->GetFirstChild()->GetNextSibling();
-    if (aContainer->mFirstChild) {
-      aContainer->mFirstChild->SetPrevSibling(nullptr);
-    } else {
-      aContainer->mLastChild = nullptr;
-    }
-    aChild->SetNextSibling(nullptr);
-    aChild->SetPrevSibling(nullptr);
-    aChild->SetParent(nullptr);
-    aContainer->DidRemoveChild(aChild);
-    NS_RELEASE(aChild);
-    return;
+  NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
+               "Child has wrong manager");
+  NS_ASSERTION(aChild->GetParent() == aContainer,
+               "aChild not our child");
+
+  Layer* prev = aChild->GetPrevSibling();
+  Layer* next = aChild->GetNextSibling();
+  if (prev) {
+    prev->SetNextSibling(next);
+  } else {
+    aContainer->mFirstChild = next;
   }
-  Layer *lastChild = nullptr;
-  for (Layer *child = aContainer->GetFirstChild(); child; 
-       child = child->GetNextSibling()) {
-    if (child == aChild) {
-      // We're sure this is not our first child. So lastChild != NULL.
-      lastChild->SetNextSibling(child->GetNextSibling());
-      if (child->GetNextSibling()) {
-        child->GetNextSibling()->SetPrevSibling(lastChild);
-      } else {
-        aContainer->mLastChild = lastChild;
-      }
-      child->SetNextSibling(nullptr);
-      child->SetPrevSibling(nullptr);
-      child->SetParent(nullptr);
-      aContainer->DidRemoveChild(aChild);
-      NS_RELEASE(aChild);
-      return;
-    }
-    lastChild = child;
+  if (next) {
+    next->SetPrevSibling(prev);
+  } else {
+    aContainer->mLastChild = prev;
   }
+
+  aChild->SetNextSibling(nullptr);
+  aChild->SetPrevSibling(nullptr);
+  aChild->SetParent(nullptr);
+
+  aContainer->DidRemoveChild(aChild);
+  NS_RELEASE(aChild);
 }
 
 static inline LayerD3D9*
 GetNextSibling(LayerD3D9* aLayer)
 {
    Layer* layer = aLayer->GetLayer()->GetNextSibling();
    return layer ? static_cast<LayerD3D9*>(layer->
                                          ImplData())
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -8,89 +8,81 @@
 
 namespace mozilla {
 namespace layers {
 
 template<class Container>
 static void
 ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter)
 {
+  NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
+               "Child has wrong manager");
+  NS_ASSERTION(!aChild->GetParent(),
+               "aChild already in the tree");
+  NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
+               "aChild already has siblings?");
+  NS_ASSERTION(!aAfter ||
+               (aAfter->Manager() == aContainer->Manager() &&
+                aAfter->GetParent() == aContainer),
+               "aAfter is not our child");
+
   aChild->SetParent(aContainer);
+  if (aAfter == aContainer->mLastChild) {
+    aContainer->mLastChild = aChild;
+  }
   if (!aAfter) {
-    Layer *oldFirstChild = aContainer->GetFirstChild();
+    aChild->SetNextSibling(aContainer->mFirstChild);
+    if (aContainer->mFirstChild) {
+      aContainer->mFirstChild->SetPrevSibling(aChild);
+    }
     aContainer->mFirstChild = aChild;
-    aChild->SetNextSibling(oldFirstChild);
-    aChild->SetPrevSibling(nullptr);
-    if (oldFirstChild) {
-      oldFirstChild->SetPrevSibling(aChild);
-    } else {
-      aContainer->mLastChild = aChild;
-    }
     NS_ADDREF(aChild);
     aContainer->DidInsertChild(aChild);
     return;
   }
-  for (Layer *child = aContainer->GetFirstChild(); 
-       child; child = child->GetNextSibling()) {
-    if (aAfter == child) {
-      Layer *oldNextSibling = child->GetNextSibling();
-      child->SetNextSibling(aChild);
-      aChild->SetNextSibling(oldNextSibling);
-      if (oldNextSibling) {
-        oldNextSibling->SetPrevSibling(aChild);
-      } else {
-        aContainer->mLastChild = aChild;
-      }
-      aChild->SetPrevSibling(child);
-      NS_ADDREF(aChild);
-      aContainer->DidInsertChild(aChild);
-      return;
-    }
+
+  Layer* next = aAfter->GetNextSibling();
+  aChild->SetNextSibling(next);
+  aChild->SetPrevSibling(aAfter);
+  if (next) {
+    next->SetPrevSibling(aChild);
   }
-  NS_WARNING("Failed to find aAfter layer!");
+  aAfter->SetNextSibling(aChild);
+  NS_ADDREF(aChild);
+  aContainer->DidInsertChild(aChild);
 }
 
 template<class Container>
 static void
 ContainerRemoveChild(Container* aContainer, Layer* aChild)
 {
-  if (aContainer->GetFirstChild() == aChild) {
-    aContainer->mFirstChild = aContainer->GetFirstChild()->GetNextSibling();
-    if (aContainer->mFirstChild) {
-      aContainer->mFirstChild->SetPrevSibling(nullptr);
-    } else {
-      aContainer->mLastChild = nullptr;
-    }
-    aChild->SetNextSibling(nullptr);
-    aChild->SetPrevSibling(nullptr);
-    aChild->SetParent(nullptr);
-    aContainer->DidRemoveChild(aChild);
-    NS_RELEASE(aChild);
-    return;
+  NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
+               "Child has wrong manager");
+  NS_ASSERTION(aChild->GetParent() == aContainer,
+               "aChild not our child");
+
+  Layer* prev = aChild->GetPrevSibling();
+  Layer* next = aChild->GetNextSibling();
+  if (prev) {
+    prev->SetNextSibling(next);
+  } else {
+    aContainer->mFirstChild = next;
   }
-  Layer *lastChild = nullptr;
-  for (Layer *child = aContainer->GetFirstChild(); child; 
-       child = child->GetNextSibling()) {
-    if (child == aChild) {
-      // We're sure this is not our first child. So lastChild != NULL.
-      lastChild->SetNextSibling(child->GetNextSibling());
-      if (child->GetNextSibling()) {
-        child->GetNextSibling()->SetPrevSibling(lastChild);
-      } else {
-        aContainer->mLastChild = lastChild;
-      }
-      child->SetNextSibling(nullptr);
-      child->SetPrevSibling(nullptr);
-      child->SetParent(nullptr);
-      aContainer->DidRemoveChild(aChild);
-      NS_RELEASE(aChild);
-      return;
-    }
-    lastChild = child;
+  if (next) {
+    next->SetPrevSibling(prev);
+  } else {
+    aContainer->mLastChild = prev;
   }
+
+  aChild->SetNextSibling(nullptr);
+  aChild->SetPrevSibling(nullptr);
+  aChild->SetParent(nullptr);
+
+  aContainer->DidRemoveChild(aChild);
+  NS_RELEASE(aChild);
 }
 
 template<class Container>
 static void
 ContainerDestroy(Container* aContainer)
  {
   if (!aContainer->mDestroyed) {
     while (aContainer->mFirstChild) {