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 id14589
push usercjones@mozilla.com
push dateFri, 23 Jul 2010 17:12:29 +0000
treeherdermozilla-central@49185ce20807 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvlad
bugs570294
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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