Bug 570294, part f: Implement the "manager" side of IPC layers. r=vlad
authorChris Jones <jones.chris.g@gmail.com>
Wed, 21 Jul 2010 16:17:33 -0500
changeset 48139 f008f1965cc9bb8cd0b5bc2ac0c636615e1c1c00
parent 48138 8912027ef25c8e3eae8dff8a359bd44c02e8eed5
child 48140 4515c729fe32b9aee03531341c9b80b029050b7b
push idunknown
push userunknown
push dateunknown
reviewersvlad
bugs570294
milestone2.0b3pre
Bug 570294, part f: Implement the "manager" side of IPC layers. r=vlad
gfx/layers/Makefile.in
gfx/layers/ipc/ShadowLayerChild.h
gfx/layers/ipc/ShadowLayerParent.cpp
gfx/layers/ipc/ShadowLayerParent.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayersChild.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/ipc/ShadowLayersParent.h
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -95,16 +95,18 @@ CPPSRCS += \
         CanvasLayerD3D9.cpp \
         $(NULL)
 endif
 endif
 
 ifdef MOZ_IPC #{
 CPPSRCS += \
         ShadowLayers.cpp \
+        ShadowLayerParent.cpp \
+        ShadowLayersParent.cpp \
         $(NULL)
 endif #}
 
 # Enable GLES2.0 under maemo
 ifdef MOZ_X11
 ifdef MOZ_PLATFORM_MAEMO
 DEFINES += -DUSE_GLES2
 endif
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayerChild.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_layers_ShadowLayerChild_h
+#define mozilla_layers_ShadowLayerChild_h
+
+#include "mozilla/layers/PLayerChild.h"
+
+namespace mozilla {
+namespace layers {
+
+class ShadowableLayer;
+
+class ShadowLayerChild : public PLayerChild
+{
+public:
+  ShadowLayerChild(ShadowableLayer* aLayer) : mLayer(aLayer)
+  { }
+
+  virtual ~ShadowLayerChild()
+  { }
+
+  ShadowableLayer* layer() const { return mLayer; }
+
+private:
+  ShadowableLayer* mLayer;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // ifndef mozilla_layers_ShadowLayerChild_h
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayerParent.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ShadowLayersParent.h"
+#include "ShadowLayerParent.h"
+#include "ShadowLayers.h"
+
+#include "BasicLayers.h"
+
+namespace mozilla {
+namespace layers {
+
+ShadowLayerParent::ShadowLayerParent() : mLayer(NULL)
+{
+}
+
+ShadowLayerParent::~ShadowLayerParent()
+{
+}
+
+void
+ShadowLayerParent::Bind(Layer* layer)
+{
+  mLayer = layer;
+}
+
+ContainerLayer*
+ShadowLayerParent::AsContainer() const
+{
+  return static_cast<ContainerLayer*>(AsLayer());
+}
+
+bool
+ShadowLayerParent::Recv__delete__()
+{
+  mLayer = NULL;
+  return true;
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayerParent.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_layers_ShadowLayerParent_h
+#define mozilla_layers_ShadowLayerParent_h
+
+#include "mozilla/layers/PLayerParent.h"
+
+namespace mozilla {
+namespace layers {
+
+class ContainerLayer;
+class Layer;
+class LayerManager;
+class ShadowLayersParent;
+
+class ShadowLayerParent : public PLayerParent
+{
+public:
+  ShadowLayerParent();
+
+  virtual ~ShadowLayerParent();
+
+  void Bind(Layer* layer);
+
+  Layer* AsLayer() const { return mLayer; }
+  ContainerLayer* AsContainer() const;
+
+private:
+  NS_OVERRIDE virtual bool Recv__delete__();
+
+  nsRefPtr<Layer> mLayer;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // ifndef mozilla_layers_ShadowLayerParent_h
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -41,16 +41,17 @@
 #include <set>
 #include <vector>
 
 #include "gfxSharedImageSurface.h"
 
 #include "mozilla/layers/PLayerChild.h"
 #include "mozilla/layers/PLayersChild.h"
 #include "ShadowLayers.h"
+#include "ShadowLayerChild.h"
 
 namespace mozilla {
 namespace layers {
 
 typedef std::vector<Edit> EditVector;
 typedef std::set<ShadowableLayer*> ShadowableLayerSet;
 
 class Transaction
@@ -288,10 +289,17 @@ ShadowLayerForwarder::EndTransaction(nsT
     MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
     return PR_FALSE;
   }
 
   MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
   return PR_TRUE;
 }
 
+PLayerChild*
+ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer)
+{
+  NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
+  return mShadowManager->SendPLayerConstructor(new ShadowLayerChild(aLayer));
+}
+
 } // namespace layers
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayersChild.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_layers_ShadowLayersChild_h
+#define mozilla_layers_ShadowLayersChild_h
+
+#include "mozilla/layers/PLayersChild.h"
+#include "mozilla/layers/ShadowLayerChild.h"
+
+namespace mozilla {
+namespace layers {
+
+class ShadowLayersChild : public PLayersChild
+{
+public:
+  ShadowLayersChild() { }
+  ~ShadowLayersChild() { }
+
+protected:
+  NS_OVERRIDE virtual PLayerChild* AllocPLayer() {
+    // we always use the "power-user" ctor
+    NS_RUNTIMEABORT("not reached");
+    return NULL;
+  }
+
+  NS_OVERRIDE virtual bool DeallocPLayer(PLayerChild* actor) {
+    delete actor;
+    return true;
+  }
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // ifndef mozilla_layers_ShadowLayersChild_h
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -0,0 +1,376 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <vector>
+
+#include "ShadowLayersParent.h"
+#include "ShadowLayerParent.h"
+#include "ShadowLayers.h"
+
+#include "mozilla/unused.h"
+
+#include "gfxSharedImageSurface.h"
+
+#include "ImageLayers.h"
+
+typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
+
+namespace mozilla {
+namespace layers {
+
+//--------------------------------------------------
+// Convenience accessors
+static ShadowLayerParent*
+cast(const PLayerParent* in)
+{ 
+  return const_cast<ShadowLayerParent*>(
+    static_cast<const ShadowLayerParent*>(in));
+}
+
+template<class OpCreateT>
+static ShadowLayerParent*
+AsShadowLayer(const OpCreateT& op)
+{
+  return cast(op.layerParent());
+}
+
+static ShadowLayerParent*
+AsShadowLayer(const OpSetRoot& op)
+{
+  return cast(op.rootParent());
+}
+
+static ShadowLayerParent*
+ShadowContainer(const OpInsertAfter& op)
+{
+  return cast(op.containerParent());
+}
+static ShadowLayerParent*
+ShadowChild(const OpInsertAfter& op)
+{
+  return cast(op.childLayerParent());
+}
+static ShadowLayerParent*
+ShadowAfter(const OpInsertAfter& op)
+{
+  return cast(op.afterParent());
+}
+
+static ShadowLayerParent*
+ShadowContainer(const OpAppendChild& op)
+{
+  return cast(op.containerParent());
+}
+static ShadowLayerParent*
+ShadowChild(const OpAppendChild& op)
+{
+  return cast(op.childLayerParent());
+}
+
+static ShadowLayerParent*
+ShadowContainer(const OpRemoveChild& op)
+{
+  return cast(op.containerParent());
+}
+static ShadowLayerParent*
+ShadowChild(const OpRemoveChild& op)
+{
+  return cast(op.childLayerParent());
+}
+
+//--------------------------------------------------
+// ShadowLayersParent
+ShadowLayersParent::ShadowLayersParent(ShadowLayerManager* aManager)
+{
+  MOZ_COUNT_CTOR(ShadowLayersParent);
+  mLayerManager = aManager;
+}
+
+ShadowLayersParent::~ShadowLayersParent()
+{
+  MOZ_COUNT_DTOR(ShadowLayersParent);
+}
+
+bool
+ShadowLayersParent::RecvUpdate(const nsTArray<Edit>& cset,
+                               nsTArray<EditReply>* reply)
+{
+  MOZ_LAYERS_LOG(("[ParentSide] recieved txn with %d edits", cset.Length()));
+
+  EditReplyVector replyv;
+
+  layer_manager()->BeginTransactionWithTarget(NULL);
+
+  for (EditArray::index_type i = 0; i < cset.Length(); ++i) {
+    const Edit& edit = cset[i];
+
+    switch (edit.type()) {
+      // Create* ops
+    case Edit::TOpCreateThebesLayer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateThebesLayer"));
+
+      nsRefPtr<ThebesLayer> layer = layer_manager()->CreateShadowThebesLayer();
+      AsShadowLayer(edit.get_OpCreateThebesLayer())->Bind(layer);
+      break;
+    }
+    case Edit::TOpCreateContainerLayer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateContainerLayer"));
+
+      nsRefPtr<ContainerLayer> layer = layer_manager()->CreateContainerLayer();
+      AsShadowLayer(edit.get_OpCreateContainerLayer())->Bind(layer);
+      break;
+    }
+    case Edit::TOpCreateImageLayer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateImageLayer"));
+
+      AsShadowLayer(edit.get_OpCreateImageLayer())->Bind(
+        layer_manager()->CreateShadowImageLayer().get());
+      break;
+    }
+    case Edit::TOpCreateColorLayer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateColorLayer"));
+
+      nsRefPtr<ColorLayer> layer = layer_manager()->CreateColorLayer();
+      AsShadowLayer(edit.get_OpCreateColorLayer())->Bind(layer);
+      break;
+    }
+    case Edit::TOpCreateCanvasLayer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasLayer"));
+
+      nsRefPtr<CanvasLayer> layer = layer_manager()->CreateShadowCanvasLayer();
+      AsShadowLayer(edit.get_OpCreateCanvasLayer())->Bind(layer);
+      break;
+    }
+    case Edit::TOpCreateThebesBuffer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateThebesBuffer"));
+
+      const OpCreateThebesBuffer& otb = edit.get_OpCreateThebesBuffer();
+      ShadowThebesLayer* thebes = static_cast<ShadowThebesLayer*>(
+        AsShadowLayer(otb)->AsLayer());
+
+      unused << thebes->Swap(new gfxSharedImageSurface(otb.initialFront()),
+                             otb.bufferRect(),
+                             nsIntPoint(0, 0));
+
+      break;
+    }
+    case Edit::TOpCreateCanvasBuffer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasBuffer"));
+
+      const OpCreateCanvasBuffer& ocb = edit.get_OpCreateCanvasBuffer();
+      ShadowCanvasLayer* canvas = static_cast<ShadowCanvasLayer*>(
+        AsShadowLayer(ocb)->AsLayer());
+      nsRefPtr<gfxSharedImageSurface> front =
+        new gfxSharedImageSurface(ocb.initialFront());
+      CanvasLayer::Data data;
+      data.mSurface = front;
+      data.mSize = ocb.size();
+
+      canvas->Initialize(data);
+
+      break;
+    }
+    case Edit::TOpCreateImageBuffer: {
+      MOZ_LAYERS_LOG(("[ParentSide] CreateImageBuffer"));
+
+      const OpCreateImageBuffer ocb = edit.get_OpCreateImageBuffer();
+      ShadowImageLayer* image = static_cast<ShadowImageLayer*>(
+        AsShadowLayer(ocb)->AsLayer());
+
+      image->Init(new gfxSharedImageSurface(ocb.initialFront()), ocb.size());
+
+      break;
+    }
+
+      // Attributes
+    case Edit::TOpSetLayerAttributes: {
+      MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes"));
+
+      const OpSetLayerAttributes& osla = edit.get_OpSetLayerAttributes();
+      Layer* layer = AsShadowLayer(osla)->AsLayer();
+      const LayerAttributes& attrs = osla.attrs();
+
+      const CommonLayerAttributes& common = attrs.common();
+      layer->SetVisibleRegion(common.visibleRegion());
+      layer->SetIsOpaqueContent(common.isOpaqueContent());
+      layer->SetOpacity(common.opacity());
+      layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
+      layer->SetTransform(common.transform());
+
+      typedef SpecificLayerAttributes Specific;
+      const SpecificLayerAttributes& specific = attrs.specific();
+      switch (specific.type()) {
+      case Specific::Tnull_t:
+        break;
+
+      case Specific::TThebesLayerAttributes:
+        MOZ_LAYERS_LOG(("[ParentSide]   thebes layer"));
+
+        static_cast<ShadowThebesLayer*>(layer)->SetValidRegion(
+          specific.get_ThebesLayerAttributes().validRegion());
+        break;
+
+      case Specific::TColorLayerAttributes:
+        MOZ_LAYERS_LOG(("[ParentSide]   color layer"));
+
+        static_cast<ColorLayer*>(layer)->SetColor(
+          specific.get_ColorLayerAttributes().color());
+        break;
+
+      case Specific::TCanvasLayerAttributes:
+        MOZ_LAYERS_LOG(("[ParentSide]   canvas layer"));
+
+        static_cast<CanvasLayer*>(layer)->SetFilter(
+          specific.get_CanvasLayerAttributes().filter());
+        break;
+
+      case Specific::TImageLayerAttributes:
+        MOZ_LAYERS_LOG(("[ParentSide]   image layer"));
+
+        static_cast<ImageLayer*>(layer)->SetFilter(
+          specific.get_ImageLayerAttributes().filter());
+        break;
+
+      default:
+        NS_RUNTIMEABORT("not reached");
+      }
+      break;
+    }
+
+      // Tree ops
+    case Edit::TOpSetRoot: {
+      MOZ_LAYERS_LOG(("[ParentSide] SetRoot"));
+
+      layer_manager()->SetRoot(AsShadowLayer(edit.get_OpSetRoot())->AsLayer());
+      break;
+    }
+    case Edit::TOpInsertAfter: {
+      MOZ_LAYERS_LOG(("[ParentSide] InsertAfter"));
+
+      const OpInsertAfter& oia = edit.get_OpInsertAfter();
+      ShadowContainer(oia)->AsContainer()->InsertAfter(
+        ShadowChild(oia)->AsLayer(), ShadowAfter(oia)->AsLayer());
+      break;
+    }
+    case Edit::TOpAppendChild: {
+      MOZ_LAYERS_LOG(("[ParentSide] AppendChild"));
+
+      const OpAppendChild& oac = edit.get_OpAppendChild();
+      ShadowContainer(oac)->AsContainer()->InsertAfter(
+        ShadowChild(oac)->AsLayer(), NULL);
+      break;
+    }
+    case Edit::TOpRemoveChild: {
+      MOZ_LAYERS_LOG(("[ParentSide] RemoveChild"));
+
+      const OpRemoveChild& orc = edit.get_OpRemoveChild();
+      Layer* childLayer = ShadowChild(orc)->AsLayer();
+      ShadowContainer(orc)->AsContainer()->RemoveChild(childLayer);
+      break;
+    }
+
+    case Edit::TOpPaintThebesBuffer: {
+      MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));
+
+      const OpPaintThebesBuffer& op = edit.get_OpPaintThebesBuffer();
+      ShadowLayerParent* shadow = AsShadowLayer(op);
+      ShadowThebesLayer* thebes =
+        static_cast<ShadowThebesLayer*>(shadow->AsLayer());
+      const ThebesBuffer& newFront = op.newFrontBuffer();
+
+      nsRefPtr<gfxSharedImageSurface> newBack =
+        thebes->Swap(new gfxSharedImageSurface(newFront.buffer()),
+                     newFront.rect(),
+                     newFront.rotation());
+
+      // XXX figure me out
+      replyv.push_back(OpBufferSwap(shadow, NULL,
+                                    newBack->GetShmem()));
+      break;
+    }
+    case Edit::TOpPaintCanvas: {
+      MOZ_LAYERS_LOG(("[ParentSide] Paint CanvasLayer"));
+
+      const OpPaintCanvas& op = edit.get_OpPaintCanvas();
+      ShadowLayerParent* shadow = AsShadowLayer(op);
+      ShadowCanvasLayer* canvas =
+        static_cast<ShadowCanvasLayer*>(shadow->AsLayer());
+
+      nsRefPtr<gfxSharedImageSurface> newBack =
+        canvas->Swap(new gfxSharedImageSurface(op.newFrontBuffer()));
+      canvas->Updated(op.updated());
+
+      replyv.push_back(OpBufferSwap(shadow, NULL,
+                                    newBack->GetShmem()));
+
+      break;
+    }
+    case Edit::TOpPaintImage: {
+      MOZ_LAYERS_LOG(("[ParentSide] Paint ImageLayer"));
+
+      const OpPaintImage& op = edit.get_OpPaintImage();
+      ShadowLayerParent* shadow = AsShadowLayer(op);
+      ShadowImageLayer* image =
+        static_cast<ShadowImageLayer*>(shadow->AsLayer());
+
+      nsRefPtr<gfxSharedImageSurface> newBack =
+        image->Swap(new gfxSharedImageSurface(op.newFrontBuffer()));
+
+      replyv.push_back(OpBufferSwap(shadow, NULL,
+                                    newBack->GetShmem()));
+
+      break;
+    }
+
+    default:
+      NS_RUNTIMEABORT("not reached");
+    }
+  }
+
+  layer_manager()->EndTransaction(NULL, NULL);
+
+  reply->SetCapacity(replyv.size());
+  reply->AppendElements(replyv.data(), replyv.size());
+
+  return true;
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayersParent.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_layers_ShadowLayersParent_h
+#define mozilla_layers_ShadowLayersParent_h
+
+#include "mozilla/layers/PLayersParent.h"
+#include "ShadowLayerParent.h"
+
+namespace mozilla {
+namespace layers {
+
+class ShadowLayerManager;
+
+class ShadowLayersParent : public PLayersParent
+{
+  typedef nsTArray<Edit> EditArray;
+  typedef nsTArray<EditReply> EditReplyArray;
+
+public:
+  ShadowLayersParent(ShadowLayerManager* aManager);
+  ~ShadowLayersParent();
+
+  ShadowLayerManager* layer_manager() const { return mLayerManager; }
+
+protected:
+  NS_OVERRIDE virtual bool RecvUpdate(const EditArray& cset,
+                                      EditReplyArray* reply);
+
+  NS_OVERRIDE virtual PLayerParent* AllocPLayer() {
+    return new ShadowLayerParent();
+  }
+
+  NS_OVERRIDE virtual bool DeallocPLayer(PLayerParent* actor) {
+    delete actor;
+    return true;
+  }
+
+private:
+  nsRefPtr<ShadowLayerManager> mLayerManager;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // ifndef mozilla_layers_ShadowLayersParent_h