Bug 570294, part e: Implement the "forwarder" side of IPC layers. r=jrmuizel
authorChris Jones <jones.chris.g@gmail.com>
Wed, 21 Jul 2010 16:17:33 -0500
changeset 48138 8912027ef25c8e3eae8dff8a359bd44c02e8eed5
parent 48137 e6299aaa482e4231d8c6ce214efe04b8cdff2440
child 48139 f008f1965cc9bb8cd0b5bc2ac0c636615e1c1c00
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)
reviewersjrmuizel
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 e: Implement the "forwarder" side of IPC layers. r=jrmuizel
gfx/layers/Makefile.in
gfx/layers/ipc/ShadowLayers.cpp
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -92,16 +92,22 @@ CPPSRCS += \
         ContainerLayerD3D9.cpp \
         ImageLayerD3D9.cpp \
         ColorLayerD3D9.cpp \
         CanvasLayerD3D9.cpp \
         $(NULL)
 endif
 endif
 
+ifdef MOZ_IPC #{
+CPPSRCS += \
+        ShadowLayers.cpp \
+        $(NULL)
+endif #}
+
 # Enable GLES2.0 under maemo
 ifdef MOZ_X11
 ifdef MOZ_PLATFORM_MAEMO
 DEFINES += -DUSE_GLES2
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -0,0 +1,297 @@
+/* -*- 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 <set>
+#include <vector>
+
+#include "gfxSharedImageSurface.h"
+
+#include "mozilla/layers/PLayerChild.h"
+#include "mozilla/layers/PLayersChild.h"
+#include "ShadowLayers.h"
+
+namespace mozilla {
+namespace layers {
+
+typedef std::vector<Edit> EditVector;
+typedef std::set<ShadowableLayer*> ShadowableLayerSet;
+
+class Transaction
+{
+public:
+  Transaction() : mOpen(PR_FALSE) {}
+
+  void Begin() { mOpen = PR_TRUE; }
+
+  void AddEdit(const Edit& aEdit)
+  {
+    NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?");
+    mCset.push_back(aEdit);
+  }
+  void AddMutant(ShadowableLayer* aLayer)
+  {
+    NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?");
+    mMutants.insert(aLayer);
+  }
+
+  void End()
+  {
+    mCset.clear();
+    mMutants.clear();
+    mOpen = PR_FALSE;
+  }
+
+  PRBool Empty() const { return mCset.empty() && mMutants.empty(); }
+  PRBool Finished() const { return !mOpen && Empty(); }
+
+  EditVector mCset;
+  ShadowableLayerSet mMutants;
+
+private:
+  PRBool mOpen;
+
+  // disabled
+  Transaction(const Transaction&);
+  Transaction& operator=(const Transaction&);
+};
+struct AutoTxnEnd {
+  AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {}
+  ~AutoTxnEnd() { mTxn->End(); }
+  Transaction* mTxn;
+};
+
+ShadowLayerForwarder::ShadowLayerForwarder() : mShadowManager(NULL)
+{
+  mTxn = new Transaction();
+}
+
+ShadowLayerForwarder::~ShadowLayerForwarder()
+{
+  NS_ABORT_IF_FALSE(mTxn->Finished(), "unfinished transaction?");
+  delete mTxn;
+}
+
+void
+ShadowLayerForwarder::BeginTransaction()
+{
+  NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
+  NS_ABORT_IF_FALSE(mTxn->Finished(), "uncommitted txn?");
+  mTxn->Begin();
+}
+
+static PLayerChild*
+Shadow(ShadowableLayer* aLayer)
+{
+  return aLayer->GetShadow();
+}
+
+template<typename OpCreateT>
+static void
+CreatedLayer(Transaction* aTxn, ShadowableLayer* aLayer)
+{
+  aTxn->AddEdit(OpCreateT(NULL, Shadow(aLayer)));
+}
+
+void
+ShadowLayerForwarder::CreatedThebesLayer(ShadowableLayer* aThebes)
+{
+  CreatedLayer<OpCreateThebesLayer>(mTxn, aThebes);
+}
+void
+ShadowLayerForwarder::CreatedContainerLayer(ShadowableLayer* aContainer)
+{
+  CreatedLayer<OpCreateContainerLayer>(mTxn, aContainer);
+}
+void
+ShadowLayerForwarder::CreatedImageLayer(ShadowableLayer* aImage)
+{
+  CreatedLayer<OpCreateImageLayer>(mTxn, aImage);
+}
+void
+ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor)
+{
+  CreatedLayer<OpCreateColorLayer>(mTxn, aColor);
+}
+void
+ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas)
+{
+  CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas);
+}
+
+void
+ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes,
+                                          nsIntRect aBufferRect,
+                                          gfxSharedImageSurface* aTempFrontBuffer)
+{
+  mTxn->AddEdit(OpCreateThebesBuffer(NULL, Shadow(aThebes),
+                                     aBufferRect,
+                                     aTempFrontBuffer->GetShmem()));
+}
+
+void
+ShadowLayerForwarder::CreatedImageBuffer(ShadowableLayer* aImage,
+                                         nsIntSize aSize,
+                                         gfxSharedImageSurface* aTempFrontSurface)
+{
+  mTxn->AddEdit(OpCreateImageBuffer(NULL, Shadow(aImage),
+                                    aSize,
+                                    aTempFrontSurface->GetShmem()));
+}
+
+void
+ShadowLayerForwarder::CreatedCanvasBuffer(ShadowableLayer* aCanvas,
+                                          nsIntSize aSize,
+                                          gfxSharedImageSurface* aTempFrontSurface)
+{
+  mTxn->AddEdit(OpCreateCanvasBuffer(NULL, Shadow(aCanvas),
+                                     aSize,
+                                     aTempFrontSurface->GetShmem()));
+}
+
+void
+ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant)
+{
+  mTxn->AddMutant(aMutant);
+}
+
+void
+ShadowLayerForwarder::SetRoot(ShadowableLayer* aRoot)
+{
+  mTxn->AddEdit(OpSetRoot(NULL, Shadow(aRoot)));
+}
+void
+ShadowLayerForwarder::InsertAfter(ShadowableLayer* aContainer,
+                                  ShadowableLayer* aChild,
+                                  ShadowableLayer* aAfter)
+{
+  if (aAfter)
+    mTxn->AddEdit(OpInsertAfter(NULL, Shadow(aContainer),
+                                NULL, Shadow(aChild),
+                                NULL, Shadow(aAfter)));
+  else
+    mTxn->AddEdit(OpAppendChild(NULL, Shadow(aContainer),
+                                NULL, Shadow(aChild)));
+}
+void
+ShadowLayerForwarder::RemoveChild(ShadowableLayer* aContainer,
+                                  ShadowableLayer* aChild)
+{
+  mTxn->AddEdit(OpRemoveChild(NULL, Shadow(aContainer),
+                              NULL, Shadow(aChild)));
+}
+
+void
+ShadowLayerForwarder::PaintedThebesBuffer(ShadowableLayer* aThebes,
+                                          nsIntRect aBufferRect,
+                                          nsIntPoint aBufferRotation,
+                                          gfxSharedImageSurface* aNewFrontBuffer)
+{
+  mTxn->AddEdit(OpPaintThebesBuffer(NULL, Shadow(aThebes),
+                                    ThebesBuffer(aNewFrontBuffer->GetShmem(),
+                                                 aBufferRect,
+                                                 aBufferRotation)));
+}
+void
+ShadowLayerForwarder::PaintedImage(ShadowableLayer* aImage,
+                                   gfxSharedImageSurface* aNewFrontSurface)
+{
+  mTxn->AddEdit(OpPaintImage(NULL, Shadow(aImage),
+                             aNewFrontSurface->GetShmem()));
+}
+void
+ShadowLayerForwarder::PaintedCanvas(ShadowableLayer* aCanvas,
+                                    gfxSharedImageSurface* aNewFrontSurface)
+{
+  mTxn->AddEdit(OpPaintCanvas(NULL, Shadow(aCanvas),
+                              nsIntRect(),
+                              aNewFrontSurface->GetShmem()));
+}
+
+PRBool
+ShadowLayerForwarder::EndTransaction(nsTArray<EditReply>* aReplies)
+{
+  NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
+  NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?");
+
+  AutoTxnEnd _(mTxn);
+
+  if (mTxn->Empty()) {
+    MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?), skipping Update()"));
+    return PR_TRUE;
+  }
+
+  MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
+
+  for (ShadowableLayerSet::const_iterator it = mTxn->mMutants.begin();
+       it != mTxn->mMutants.end(); ++it) {
+    ShadowableLayer* shadow = *it;
+    Layer* mutant = shadow->AsLayer();
+    NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?");
+
+    LayerAttributes attrs;
+    CommonLayerAttributes& common = attrs.common();
+    common.visibleRegion() = mutant->GetVisibleRegion();
+    common.transform() = mutant->GetTransform();
+    common.isOpaqueContent() = mutant->IsOpaqueContent();
+    common.opacity() = mutant->GetOpacity();
+    common.useClipRect() = !!mutant->GetClipRect();
+    common.clipRect() = (common.useClipRect() ?
+                         *mutant->GetClipRect() : nsIntRect());
+    attrs.specific() = null_t();
+    mutant->FillSpecificAttributes(attrs.specific());
+
+    mTxn->AddEdit(OpSetLayerAttributes(NULL, Shadow(shadow), attrs));
+  }
+
+  nsAutoTArray<Edit, 10> cset;
+  cset.SetCapacity(mTxn->mCset.size());
+  cset.AppendElements(mTxn->mCset.data(), mTxn->mCset.size());
+
+  if (!mShadowManager->SendUpdate(cset, aReplies)) {
+    MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
+    return PR_FALSE;
+  }
+
+  MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
+  return PR_TRUE;
+}
+
+} // namespace layers
+} // namespace mozilla