Backed out changeset a89f08f4fd3e (bug 959089)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 29 Apr 2014 12:21:52 +0200
changeset 181092 553c79e46788f94da19d0a560139773a2c69f86c
parent 181091 633ff919c7f7140b689afd12e76c78ba370db363
child 181093 dd434e37123903399b6c45febac237718f182f0e
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
bugs959089
milestone32.0a1
backs outa89f08f4fd3e16cc982435f65ea52f1808298328
Backed out changeset a89f08f4fd3e (bug 959089)
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
gfx/layers/GrallocImages.h
gfx/layers/ipc/CompositableTransactionParent.cpp
gfx/layers/ipc/ISurfaceAllocator.cpp
gfx/layers/ipc/ISurfaceAllocator.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionChild.cpp
gfx/layers/ipc/LayerTransactionChild.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/LayersSurfaces.ipdlh
gfx/layers/ipc/PCompositor.ipdl
gfx/layers/ipc/PGrallocBuffer.ipdl
gfx/layers/ipc/PImageBridge.ipdl
gfx/layers/ipc/PLayerTransaction.ipdl
gfx/layers/ipc/PTexture.ipdl
gfx/layers/ipc/ShadowLayerUtils.h
gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
gfx/layers/ipc/ShadowLayerUtilsGralloc.h
gfx/layers/ipc/ShadowLayers.h
gfx/layers/moz.build
gfx/layers/opengl/GrallocTextureClient.cpp
gfx/layers/opengl/GrallocTextureClient.h
gfx/layers/opengl/GrallocTextureHost.cpp
gfx/layers/opengl/GrallocTextureHost.h
gfx/thebes/gfxPlatform.cpp
hal/sandbox/PHal.ipdl
ipc/chromium/src/chrome/common/file_descriptor_set_posix.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -24,17 +24,16 @@
 #include "mozilla/dom/PCrashReporterChild.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/ImageBridgeChild.h"
-#include "mozilla/layers/SharedBufferManagerChild.h"
 #include "mozilla/layers/PCompositorChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/Preferences.h"
 
 #if defined(MOZ_CONTENT_SANDBOX)
 #if defined(XP_WIN)
 #define TARGET_SANDBOX_EXPORTS
 #include "mozilla/sandboxTarget.h"
@@ -684,23 +683,16 @@ ContentChild::RecvDumpGCAndCCLogsToFile(
 
 PCompositorChild*
 ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
                                     base::ProcessId aOtherProcess)
 {
     return CompositorChild::Create(aTransport, aOtherProcess);
 }
 
-PSharedBufferManagerChild*
-ContentChild::AllocPSharedBufferManagerChild(mozilla::ipc::Transport* aTransport,
-                                              base::ProcessId aOtherProcess)
-{
-    return SharedBufferManagerChild::StartUpInChildProcess(aTransport, aOtherProcess);
-}
-
 PImageBridgeChild*
 ContentChild::AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
                                      base::ProcessId aOtherProcess)
 {
     return ImageBridgeChild::StartUpInChildProcess(aTransport, aOtherProcess);
 }
 
 PBackgroundChild*
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -84,21 +84,16 @@ public:
     void SetProcessName(const nsAString& aName, bool aDontOverride = false);
     void GetProcessName(nsAString& aName);
     void GetProcessName(nsACString& aName);
     static void AppendProcessId(nsACString& aName);
 
     PCompositorChild*
     AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
                           base::ProcessId aOtherProcess) MOZ_OVERRIDE;
-
-    PSharedBufferManagerChild*
-    AllocPSharedBufferManagerChild(mozilla::ipc::Transport* aTransport,
-                                    base::ProcessId aOtherProcess) MOZ_OVERRIDE;
-
     PImageBridgeChild*
     AllocPImageBridgeChild(mozilla::ipc::Transport* aTransport,
                            base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual bool RecvSetProcessSandbox() MOZ_OVERRIDE;
 
     PBackgroundChild*
     AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -49,17 +49,16 @@
 #include "SmsParent.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/ImageBridgeParent.h"
-#include "mozilla/layers/SharedBufferManagerParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "nsAppRunner.h"
 #include "nsAutoPtr.h"
 #include "nsCDefaultURIFixup.h"
@@ -1591,20 +1590,16 @@ ContentParent::InitInternal(ProcessPrior
             MOZ_ASSERT(opened);
 
             if (gfxPrefs::AsyncVideoEnabled()) {
                 opened = PImageBridge::Open(this);
                 MOZ_ASSERT(opened);
             }
         }
     }
-#ifdef MOZ_WIDGET_GONK
-    DebugOnly<bool> opened = PSharedBufferManager::Open(this);
-    MOZ_ASSERT(opened);
-#endif
 
     if (aSendRegisteredChrome) {
         nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
         nsChromeRegistryChrome* chromeRegistry =
             static_cast<nsChromeRegistryChrome*>(registrySvc.get());
         chromeRegistry->SendRegisteredChrome(this);
     }
 
@@ -2192,23 +2187,16 @@ ContentParent::AllocPImageBridgeParent(m
 
 PBackgroundParent*
 ContentParent::AllocPBackgroundParent(Transport* aTransport,
                                       ProcessId aOtherProcess)
 {
     return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
 }
 
-PSharedBufferManagerParent*
-ContentParent::AllocPSharedBufferManagerParent(mozilla::ipc::Transport* aTransport,
-                                                base::ProcessId aOtherProcess)
-{
-    return SharedBufferManagerParent::Create(aTransport, aOtherProcess);
-}
-
 bool
 ContentParent::RecvGetProcessAttributes(uint64_t* aId,
                                         bool* aIsForApp, bool* aIsForBrowser)
 {
     *aId = mChildID;
     *aIsForApp = IsForApp();
     *aIsForBrowser = mIsForBrowser;
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -42,17 +42,16 @@ class TestShellParent;
 
 namespace jsipc {
 class JavaScriptParent;
 class PJavaScriptParent;
 }
 
 namespace layers {
 class PCompositorParent;
-class PSharedBufferManagerParent;
 } // namespace layers
 
 namespace dom {
 
 class Element;
 class TabParent;
 class PStorageParent;
 class ClonedMessageData;
@@ -323,19 +322,16 @@ private:
 
     PCompositorParent*
     AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
                            base::ProcessId aOtherProcess) MOZ_OVERRIDE;
     PImageBridgeParent*
     AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
                             base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
-    PSharedBufferManagerParent*
-    AllocPSharedBufferManagerParent(mozilla::ipc::Transport* aTranport,
-                                     base::ProcessId aOtherProcess) MOZ_OVERRIDE;
     PBackgroundParent*
     AllocPBackgroundParent(Transport* aTransport, ProcessId aOtherProcess)
                            MOZ_OVERRIDE;
 
     virtual bool RecvGetProcessAttributes(uint64_t* aId,
                                           bool* aIsForApp,
                                           bool* aIsForBrowser) MOZ_OVERRIDE;
     virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline) MOZ_OVERRIDE;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -16,17 +16,16 @@ include protocol PDeviceStorageRequest;
 include protocol PFileDescriptorSet;
 include protocol PFMRadio;
 include protocol PFileSystemRequest;
 include protocol PHal;
 include protocol PImageBridge;
 include protocol PIndexedDB;
 include protocol PMemoryReportRequest;
 include protocol PNecko;
-include protocol PSharedBufferManager;
 include protocol PSms;
 include protocol PSpeechSynthesis;
 include protocol PStorage;
 include protocol PTelephony;
 include protocol PTestShell;
 include protocol PJavaScript;
 include DOMTypes;
 include JavaScriptTypes;
@@ -259,17 +258,16 @@ struct PrefSetting {
   nsCString name;
   MaybePrefValue defaultValue;
   MaybePrefValue userValue;
 };
 
 intr protocol PContent
 {
     parent opens PCompositor;
-    parent opens PSharedBufferManager;
     parent opens PImageBridge;
     child opens PBackground;
 
     manages PAsmJSCacheEntry;
     manages PBlob;
     manages PBluetooth;
     manages PBrowser;
     manages PCrashReporter;
--- a/gfx/layers/GrallocImages.h
+++ b/gfx/layers/GrallocImages.h
@@ -76,20 +76,16 @@ public:
     HAL_PIXEL_FORMAT_YCbCr_422_P            = 0x102,
     HAL_PIXEL_FORMAT_YCbCr_420_P            = 0x103,
     HAL_PIXEL_FORMAT_YCbCr_420_SP           = 0x109,
     HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO    = 0x10A,
     HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED     = 0x7FA30C03,
     HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS     = 0x7FA30C04,
   };
 
-  enum {
-    GRALLOC_SW_UAGE = android::GraphicBuffer::USAGE_SOFTWARE_MASK,
-  };
-
   virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
 
   android::sp<android::GraphicBuffer> GetGraphicBuffer() const;
 
   void* GetNativeBuffer();
 
   virtual bool IsValid() { return !!mTextureClient; }
 
@@ -97,21 +93,16 @@ public:
 
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) MOZ_OVERRIDE;
 
   virtual uint8_t* GetBuffer()
   {
     return static_cast<uint8_t*>(GetNativeBuffer());
   }
 
-  int GetUsage()
-  {
-    return (static_cast<ANativeWindowBuffer*>(GetNativeBuffer()))->usage;
-  }
-
 private:
   RefPtr<GrallocTextureClientOGL> mTextureClient;
 };
 
 } // namespace layers
 } // namespace mozilla
 #endif
 
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -11,17 +11,16 @@
 #include "GLContext.h"                  // for GLContext
 #include "Layers.h"                     // for Layer
 #include "RenderTrace.h"                // for RenderTraceInvalidateEnd, etc
 #include "TiledLayerBuffer.h"           // for TiledLayerComposer
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/ContentHost.h"  // for ContentHostBase
-#include "mozilla/layers/SharedBufferManagerParent.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
 #include "mozilla/layers/TextureHost.h"  // for TextureHost
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
 #include "mozilla/layers/ThebesLayerComposite.h"
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
--- a/gfx/layers/ipc/ISurfaceAllocator.cpp
+++ b/gfx/layers/ipc/ISurfaceAllocator.cpp
@@ -9,17 +9,16 @@
 #include <sys/types.h>                  // for int32_t
 #include "gfx2DGlue.h"                  // for IntSize
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
 #include "gfxSharedImageSurface.h"      // for gfxSharedImageSurface
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Atomics.h"            // for PrimitiveIntrinsics
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
-#include "mozilla/layers/SharedBufferManagerChild.h"
 #include "ShadowLayerUtils.h"
 #include "mozilla/mozalloc.h"           // for operator delete[], etc
 #include "nsAutoPtr.h"                  // for nsRefPtr, getter_AddRefs, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "mozilla/ipc/Shmem.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #ifdef DEBUG
@@ -304,25 +303,10 @@ ISurfaceAllocator::ShrinkShmemSectionHea
       mUsedShmems[i] = mUsedShmems[mUsedShmems.size() - 1];
       mUsedShmems.pop_back();
       i--;
       break;
     }
   }
 }
 
-bool
-ISurfaceAllocator::AllocGrallocBuffer(const gfx::IntSize& aSize,
-                                      uint32_t aFormat,
-                                      uint32_t aUsage,
-                                      MaybeMagicGrallocBufferHandle* aHandle)
-{
-  return SharedBufferManagerChild::GetSingleton()->AllocGrallocBuffer(aSize, aFormat, aUsage, aHandle);
-}
-
-void
-ISurfaceAllocator::DeallocGrallocBuffer(MaybeMagicGrallocBufferHandle* aHandle)
-{
-  SharedBufferManagerChild::GetSingleton()->DeallocGrallocBuffer(*aHandle);
-}
-
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/ISurfaceAllocator.h
+++ b/gfx/layers/ipc/ISurfaceAllocator.h
@@ -41,16 +41,17 @@ namespace ipc {
 class Shmem;
 }
 namespace gfx {
 class DataSourceSurface;
 }
 
 namespace layers {
 
+class PGrallocBufferChild;
 class MaybeMagicGrallocBufferHandle;
 class MemoryTextureClient;
 class MemoryTextureHost;
 
 enum BufferCapabilities {
   DEFAULT_BUFFER_CAPS = 0,
   /**
    * The allocated buffer must be efficiently mappable as a
@@ -149,22 +150,28 @@ public:
   /**
    * Returns the maximum texture size supported by the compositor.
    */
   virtual int32_t GetMaxTextureSize() const { return INT32_MAX; }
 
   virtual void DestroySharedSurface(SurfaceDescriptor* aSurface);
 
   // method that does the actual allocation work
-  bool AllocGrallocBuffer(const gfx::IntSize& aSize,
-                          uint32_t aFormat,
-                          uint32_t aUsage,
-                          MaybeMagicGrallocBufferHandle* aHandle);
+  virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize,
+                                                  uint32_t aFormat,
+                                                  uint32_t aUsage,
+                                                  MaybeMagicGrallocBufferHandle* aHandle)
+  {
+    return nullptr;
+  }
 
-  void DeallocGrallocBuffer(MaybeMagicGrallocBufferHandle* aHandle);
+  virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild)
+  {
+    NS_RUNTIMEABORT("should not be called");
+  }
 
   virtual bool IPCOpen() const { return true; }
   virtual bool IsSameProcess() const = 0;
 
   // Returns true if aSurface wraps a Shmem.
   static bool IsShmem(SurfaceDescriptor* aSurface);
 
 protected:
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -47,16 +47,17 @@ using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace ipc {
 class Shmem;
 }
 
 namespace layers {
 
+class PGrallocBufferChild;
 typedef std::vector<CompositableOperation> OpVector;
 
 struct CompositableTransaction
 {
   CompositableTransaction()
   : mSwapRequired(false)
   , mFinished(true)
   {}
@@ -198,16 +199,54 @@ static void CreateImageClientSync(RefPtr
                                   bool *aDone)
 {
   ReentrantMonitorAutoEnter autoMon(*barrier);
   *result = sImageBridgeChildSingleton->CreateImageClientNow(aType);
   *aDone = true;
   barrier->NotifyAll();
 }
 
+
+struct GrallocParam {
+  IntSize size;
+  uint32_t format;
+  uint32_t usage;
+  MaybeMagicGrallocBufferHandle* handle;
+  PGrallocBufferChild** child;
+
+  GrallocParam(const IntSize& aSize,
+               const uint32_t& aFormat,
+               const uint32_t& aUsage,
+               MaybeMagicGrallocBufferHandle* aHandle,
+               PGrallocBufferChild** aChild)
+    : size(aSize)
+    , format(aFormat)
+    , usage(aUsage)
+    , handle(aHandle)
+    , child(aChild)
+  {}
+};
+
+// dispatched function
+static void AllocGrallocBufferSync(const GrallocParam& aParam,
+                                   Monitor* aBarrier,
+                                   bool* aDone)
+{
+  MonitorAutoLock autoMon(*aBarrier);
+
+  sImageBridgeChildSingleton->AllocGrallocBufferNow(aParam.size,
+                                                    aParam.format,
+                                                    aParam.usage,
+                                                    aParam.handle,
+                                                    aParam.child);
+  *aDone = true;
+  aBarrier->NotifyAll();
+}
+
+// dispatched function
 static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * parent)
 {
   MessageLoop *parentMsgLoop = parent->GetMessageLoop();
   ipc::MessageChannel *parentChannel = parent->GetIPCChannel();
   child->Open(parentChannel, parentMsgLoop, mozilla::ipc::ChildSide);
 }
 
 ImageBridgeChild::ImageBridgeChild()
@@ -611,16 +650,40 @@ ImageBridgeChild::CreateImageClientNow(C
     = ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS);
   MOZ_ASSERT(client, "failed to create ImageClient");
   if (client) {
     client->Connect();
   }
   return client.forget();
 }
 
+PGrallocBufferChild*
+ImageBridgeChild::AllocPGrallocBufferChild(const IntSize&, const uint32_t&, const uint32_t&,
+                                           MaybeMagicGrallocBufferHandle*)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  return GrallocBufferActor::Create();
+#else
+  NS_RUNTIMEABORT("No gralloc buffers for you");
+  return nullptr;
+#endif
+}
+
+bool
+ImageBridgeChild::DeallocPGrallocBufferChild(PGrallocBufferChild* actor)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  delete actor;
+  return true;
+#else
+  NS_RUNTIMEABORT("Um, how did we get here?");
+  return false;
+#endif
+}
+
 bool
 ImageBridgeChild::AllocUnsafeShmem(size_t aSize,
                                    ipc::SharedMemory::SharedMemoryType aType,
                                    ipc::Shmem* aShmem)
 {
   if (InImageBridgeChildThread()) {
     return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
   } else {
@@ -732,16 +795,109 @@ ImageBridgeChild::DeallocShmem(ipc::Shme
                                                    &barrier,
                                                    &done));
     while (!done) {
       barrier.Wait();
     }
   }
 }
 
+PGrallocBufferChild*
+ImageBridgeChild::AllocGrallocBuffer(const IntSize& aSize,
+                                     uint32_t aFormat,
+                                     uint32_t aUsage,
+                                     MaybeMagicGrallocBufferHandle* aHandle)
+{
+  if (InImageBridgeChildThread()) {
+    PGrallocBufferChild* child = nullptr;
+    ImageBridgeChild::AllocGrallocBufferNow(aSize, aFormat, aUsage, aHandle, &child);
+    return child;
+  }
+
+  Monitor barrier("AllocGrallocBuffer Lock");
+  MonitorAutoLock autoMon(barrier);
+  bool done = false;
+  PGrallocBufferChild* child = nullptr;
+
+  GetMessageLoop()->PostTask(
+    FROM_HERE,
+    NewRunnableFunction(&AllocGrallocBufferSync,
+                        GrallocParam(aSize, aFormat, aUsage, aHandle, &child), &barrier, &done));
+
+  while (!done) {
+    barrier.Wait();
+  }
+
+  return child;
+}
+
+void
+ImageBridgeChild::AllocGrallocBufferNow(const gfx::IntSize& aSize,
+                                        uint32_t aFormat, uint32_t aUsage,
+                                        MaybeMagicGrallocBufferHandle* aHandle,
+                                        PGrallocBufferChild** aChild)
+{
+#ifdef MOZ_WIDGET_GONK
+  *aChild = SendPGrallocBufferConstructor(aSize,
+                                          aFormat,
+                                          aUsage,
+                                          aHandle);
+#else
+  NS_RUNTIMEABORT("not implemented");
+  aChild = nullptr;
+#endif
+}
+
+static void ProxyDeallocGrallocBufferNow(ISurfaceAllocator* aAllocator,
+                                         PGrallocBufferChild* aChild,
+                                         ReentrantMonitor* aBarrier,
+                                         bool* aDone)
+{
+  MOZ_ASSERT(aChild);
+  MOZ_ASSERT(aDone);
+  MOZ_ASSERT(aBarrier);
+
+#ifdef MOZ_WIDGET_GONK
+  PGrallocBufferChild::Send__delete__(aChild);
+#else
+  NS_RUNTIMEABORT("not implemented");
+#endif
+
+  ReentrantMonitorAutoEnter autoMon(*aBarrier);
+  *aDone = true;
+  aBarrier->NotifyAll();
+}
+
+void
+ImageBridgeChild::DeallocGrallocBuffer(PGrallocBufferChild* aChild)
+{
+  MOZ_ASSERT(aChild);
+  if (InImageBridgeChildThread()) {
+#ifdef MOZ_WIDGET_GONK
+    PGrallocBufferChild::Send__delete__(aChild);
+#else
+    NS_RUNTIMEABORT("not implemented");
+#endif
+  } else {
+    ReentrantMonitor barrier("AllocatorProxy Dealloc");
+    ReentrantMonitorAutoEnter autoMon(barrier);
+
+    bool done = false;
+    GetMessageLoop()->PostTask(FROM_HERE,
+                               NewRunnableFunction(&ProxyDeallocGrallocBufferNow,
+                                                   this,
+                                                   aChild,
+                                                   &barrier,
+                                                   &done));
+    while (!done) {
+      barrier.Wait();
+    }
+  }
+}
+
 PTextureChild*
 ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
                                      const TextureFlags&)
 {
   return TextureClient::CreateIPDLActor();
 }
 
 bool
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -8,16 +8,17 @@
 
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint32_t, uint64_t
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE
 #include "mozilla/RefPtr.h"             // for TemporaryRef
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/CompositorTypes.h"  // for TextureIdentifier, etc
+#include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferChild
 #include "mozilla/layers/PImageBridgeChild.h"
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsRegion.h"                   // for nsIntRegion
 class MessageLoop;
 struct nsIntPoint;
 struct nsIntRect;
 
 namespace base {
@@ -181,16 +182,23 @@ public:
   bool DeallocPCompositableChild(PCompositableChild* aActor) MOZ_OVERRIDE;
 
   /**
    * This must be called by the static function DeleteImageBridgeSync defined
    * in ImageBridgeChild.cpp ONLY.
    */
   ~ImageBridgeChild();
 
+  virtual PGrallocBufferChild*
+  AllocPGrallocBufferChild(const gfx::IntSize&, const uint32_t&, const uint32_t&,
+                           MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
+
+  virtual bool
+  DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
+
   virtual PTextureChild*
   AllocPTextureChild(const SurfaceDescriptor& aSharedData, const TextureFlags& aFlags) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE;
 
   TemporaryRef<ImageClient> CreateImageClient(CompositableType aType);
   TemporaryRef<ImageClient> CreateImageClientNow(CompositableType aType);
@@ -297,22 +305,33 @@ public:
    */
   virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem);
 
   virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
                                        TextureFlags aFlags) MOZ_OVERRIDE;
 
   virtual bool IsSameProcess() const MOZ_OVERRIDE;
 
+  void AllocGrallocBufferNow(const gfx::IntSize& aSize,
+                             uint32_t aFormat, uint32_t aUsage,
+                             MaybeMagicGrallocBufferHandle* aHandle,
+                             PGrallocBufferChild** aChild);
 protected:
   ImageBridgeChild();
   bool DispatchAllocShmemInternal(size_t aSize,
                                   SharedMemory::SharedMemoryType aType,
                                   Shmem* aShmem,
                                   bool aUnsafe);
 
   CompositableTransaction* mTxn;
+
+  // ISurfaceAllocator
+  virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize,
+                                                  uint32_t aFormat, uint32_t aUsage,
+                                                  MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
+
+  virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE;
 };
 
 } // layers
 } // mozilla
 
 #endif
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -7,17 +7,17 @@
 #include "ImageBridgeParent.h"
 #include <stdint.h>                     // for uint64_t, uint32_t
 #include "CompositableHost.h"           // for CompositableParent, Create
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessHandle
 #include "base/process_util.h"          // for OpenProcessHandle
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "base/tracked.h"               // for FROM_HERE
-#include "mozilla/gfx/Point.h"                   // for IntSize
+#include "mozilla/gfx/Point.h"          // for IntSize
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/layers/CompositableTransactionParent.h"
 #include "mozilla/layers/CompositorParent.h"  // for CompositorParent
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply
 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferParent
@@ -35,16 +35,18 @@
 #include "nsThreadUtils.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
+class PGrallocBufferParent;
+
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport)
   : mMessageLoop(aLoop)
   , mTransport(aTransport)
 {
   // creates the map only if it has not been created already, so it is safe
   // with several bridges
   CompositableMap::Create();
 }
@@ -154,16 +156,42 @@ bool ImageBridgeParent::RecvStop()
 
 static  uint64_t GenImageContainerID() {
   static uint64_t sNextImageID = 1;
 
   ++sNextImageID;
   return sNextImageID;
 }
 
+PGrallocBufferParent*
+ImageBridgeParent::AllocPGrallocBufferParent(const IntSize& aSize,
+                                             const uint32_t& aFormat,
+                                             const uint32_t& aUsage,
+                                             MaybeMagicGrallocBufferHandle* aOutHandle)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  return GrallocBufferActor::Create(aSize, aFormat, aUsage, aOutHandle);
+#else
+  NS_RUNTIMEABORT("No gralloc buffers for you");
+  return nullptr;
+#endif
+}
+
+bool
+ImageBridgeParent::DeallocPGrallocBufferParent(PGrallocBufferParent* actor)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  delete actor;
+  return true;
+#else
+  NS_RUNTIMEABORT("Um, how did we get here?");
+  return false;
+#endif
+}
+
 PCompositableParent*
 ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
                                             uint64_t* aID)
 {
   uint64_t id = GenImageContainerID();
   *aID = id;
   return CompositableHost::CreateIPDLActor(this, aInfo, id);
 }
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -15,20 +15,16 @@
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
 #include "mozilla/layers/PImageBridgeParent.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsISupportsImpl.h"
 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
 
 class MessageLoop;
 
-namespace base {
-class Thread;
-}
-
 namespace mozilla {
 namespace ipc {
 class Shmem;
 }
 
 namespace layers {
 
 /**
@@ -48,16 +44,23 @@ public:
 
   virtual LayersBackend GetCompositorBackendType() const MOZ_OVERRIDE;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   static PImageBridgeParent*
   Create(Transport* aTransport, ProcessId aOtherProcess);
 
+  virtual PGrallocBufferParent*
+  AllocPGrallocBufferParent(const IntSize&, const uint32_t&, const uint32_t&,
+                            MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
+
+  virtual bool
+  DeallocPGrallocBufferParent(PGrallocBufferParent* actor) MOZ_OVERRIDE;
+
   // PImageBridge
   virtual bool RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply) MOZ_OVERRIDE;
   virtual bool RecvUpdateNoSwap(const EditArray& aEdits) MOZ_OVERRIDE;
 
   virtual bool IsAsync() const MOZ_OVERRIDE { return true; }
 
   PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
                                                 uint64_t*) MOZ_OVERRIDE;
--- a/gfx/layers/ipc/LayerTransactionChild.cpp
+++ b/gfx/layers/ipc/LayerTransactionChild.cpp
@@ -2,36 +2,63 @@
  * vim: sw=2 ts=8 et :
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "LayerTransactionChild.h"
 #include "mozilla/layers/CompositableClient.h"  // for CompositableChild
+#include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferChild
 #include "mozilla/layers/PCompositableChild.h"  // for PCompositableChild
 #include "mozilla/layers/PLayerChild.h"  // for PLayerChild
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT, etc
 #include "nsTArray.h"                   // for nsTArray
 #include "mozilla/layers/TextureClient.h"
 
 namespace mozilla {
 namespace layers {
 
+class PGrallocBufferChild;
 
 void
 LayerTransactionChild::Destroy()
 {
   NS_ABORT_IF_FALSE(0 == ManagedPLayerChild().Length(),
                     "layers should have been cleaned up by now");
   PLayerTransactionChild::Send__delete__(this);
   // WARNING: |this| has gone to the great heap in the sky
 }
 
+PGrallocBufferChild*
+LayerTransactionChild::AllocPGrallocBufferChild(const IntSize&,
+                                                const uint32_t&,
+                                                const uint32_t&,
+                                                MaybeMagicGrallocBufferHandle*)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  return GrallocBufferActor::Create();
+#else
+  NS_RUNTIMEABORT("No gralloc buffers for you");
+  return nullptr;
+#endif
+}
+
+bool
+LayerTransactionChild::DeallocPGrallocBufferChild(PGrallocBufferChild* actor)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  delete actor;
+  return true;
+#else
+  NS_RUNTIMEABORT("Um, how did we get here?");
+  return false;
+#endif
+}
 
 PLayerChild*
 LayerTransactionChild::AllocPLayerChild()
 {
   // we always use the "power-user" ctor
   NS_RUNTIMEABORT("not reached");
   return nullptr;
 }
--- a/gfx/layers/ipc/LayerTransactionChild.h
+++ b/gfx/layers/ipc/LayerTransactionChild.h
@@ -38,16 +38,23 @@ public:
   bool IPCOpen() const { return mIPCOpen; }
 
 protected:
   LayerTransactionChild()
     : mIPCOpen(false)
   {}
   ~LayerTransactionChild() { }
 
+  virtual PGrallocBufferChild*
+  AllocPGrallocBufferChild(const IntSize&,
+                           const uint32_t&, const uint32_t&,
+                           MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE;
+  virtual bool
+  DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE;
+
   virtual PLayerChild* AllocPLayerChild() MOZ_OVERRIDE;
   virtual bool DeallocPLayerChild(PLayerChild* actor) MOZ_OVERRIDE;
 
   virtual PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo) MOZ_OVERRIDE;
   virtual bool DeallocPCompositableChild(PCompositableChild* actor) MOZ_OVERRIDE;
 
   virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
                                             const TextureFlags& aFlags) MOZ_OVERRIDE;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -735,16 +735,43 @@ LayerTransactionParent::RecvClearCachedR
 
 bool
 LayerTransactionParent::RecvForceComposite()
 {
   mShadowLayersManager->ForceComposite(this);
   return true;
 }
 
+
+PGrallocBufferParent*
+LayerTransactionParent::AllocPGrallocBufferParent(const IntSize& aSize,
+                                                  const uint32_t& aFormat,
+                                                  const uint32_t& aUsage,
+                                                  MaybeMagicGrallocBufferHandle* aOutHandle)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  return GrallocBufferActor::Create(aSize, aFormat, aUsage, aOutHandle);
+#else
+  NS_RUNTIMEABORT("No gralloc buffers for you");
+  return nullptr;
+#endif
+}
+
+bool
+LayerTransactionParent::DeallocPGrallocBufferParent(PGrallocBufferParent* actor)
+{
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  delete actor;
+  return true;
+#else
+  NS_RUNTIMEABORT("Um, how did we get here?");
+  return false;
+#endif
+}
+
 PLayerParent*
 LayerTransactionParent::AllocPLayerParent()
 {
   return new ShadowLayerParent();
 }
 
 bool
 LayerTransactionParent::DeallocPLayerParent(PLayerParent* actor)
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -98,16 +98,23 @@ protected:
   virtual bool RecvGetOpacity(PLayerParent* aParent,
                               float* aOpacity) MOZ_OVERRIDE;
   virtual bool RecvGetAnimationTransform(PLayerParent* aParent,
                                          MaybeTransform* aTransform)
                                          MOZ_OVERRIDE;
   virtual bool RecvSetAsyncScrollOffset(PLayerParent* aLayer,
                                         const int32_t& aX, const int32_t& aY) MOZ_OVERRIDE;
 
+  virtual PGrallocBufferParent*
+  AllocPGrallocBufferParent(const IntSize& aSize,
+                            const uint32_t& aFormat, const uint32_t& aUsage,
+                            MaybeMagicGrallocBufferHandle* aOutHandle) MOZ_OVERRIDE;
+  virtual bool
+  DeallocPGrallocBufferParent(PGrallocBufferParent* actor) MOZ_OVERRIDE;
+
   virtual PLayerParent* AllocPLayerParent() MOZ_OVERRIDE;
   virtual bool DeallocPLayerParent(PLayerParent* actor) MOZ_OVERRIDE;
 
   virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) MOZ_OVERRIDE;
   virtual bool DeallocPCompositableParent(PCompositableParent* actor) MOZ_OVERRIDE;
 
   virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                               const TextureFlags& aFlags) MOZ_OVERRIDE;
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -3,16 +3,17 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include LayersSurfaces;
 include protocol PCompositable;
 include protocol PCompositor;
+include protocol PGrallocBuffer;
 include protocol PLayer;
 include protocol PRenderFrame;
 include protocol PTexture;
 
 include "gfxipc/ShadowLayerUtils.h";
 include "mozilla/GfxMessageUtils.h";
 include "ImageLayers.h";
 
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -1,34 +1,35 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+include protocol PGrallocBuffer;
+
+
 using struct gfxPoint from "gfxPoint.h";
 using struct nsIntRect from "nsRect.h";
 using nsIntRegion from "nsRegion.h";
 using struct nsIntSize from "nsSize.h";
 using struct mozilla::layers::MagicGrallocBufferHandle from "gfxipc/ShadowLayerUtils.h";
-using struct mozilla::layers::GrallocBufferRef from "gfxipc/ShadowLayerUtils.h";
 using struct mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
 using mozilla::gl::SharedTextureHandle from "GLContextTypes.h";
 using mozilla::gl::SharedTextureShareType from "GLContextTypes.h";
 using mozilla::gfx::SurfaceStreamHandle from "SurfaceTypes.h";
 using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
 using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
 using gfxImageFormat from "gfxTypes.h";
 
 namespace mozilla {
 namespace layers {
 
 union MaybeMagicGrallocBufferHandle {
   MagicGrallocBufferHandle;
-  GrallocBufferRef;
   null_t;
 };
 
 struct SurfaceDescriptorD3D9 {
   // IDirect3DTexture9*
   uintptr_t texture;
 };
 
@@ -52,17 +53,17 @@ struct SurfaceDescriptorMacIOSurface {
 struct SharedTextureDescriptor {
   SharedTextureShareType shareType;
   SharedTextureHandle handle;
   IntSize size;
   bool inverted;
 };
 
 struct NewSurfaceDescriptorGralloc {
-  MaybeMagicGrallocBufferHandle buffer;
+  PGrallocBuffer buffer;
   /**
    * android::GraphicBuffer has a size information. But there are cases
    * that GraphicBuffer's size and actual video's size are different.
    * Extra size member is necessary. See Bug 850566.
    */
   IntSize size;
 };
 
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=8 et :
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include LayersSurfaces;
+include protocol PGrallocBuffer;
 include protocol PLayerTransaction;
 include "mozilla/GfxMessageUtils.h";
 include "nsRegion.h";
 
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
 using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
 using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
new file mode 100644
--- /dev/null
+++ b/gfx/layers/ipc/PGrallocBuffer.ipdl
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PCompositor;
+include protocol PImageBridge;
+include protocol PLayerTransaction;
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * This is a trivial protocol that's used to track gralloc buffers
+ * across thread contexts.  A live PGrallocBuffer actor always
+ * corresponds 1:1 to a pre-shared gralloc buffer (sharing is done by
+ * the PGrallocBuffer constructor).
+ */
+async protocol PGrallocBuffer {
+  manager PImageBridge or PLayerTransaction;
+
+  /** Gralloc buffers can be "owned" by either parent or child. */
+both:
+  async __delete__();
+};
+
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/ipc/PImageBridge.ipdl
+++ b/gfx/layers/ipc/PImageBridge.ipdl
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include LayersSurfaces;
 include LayersMessages;
+include protocol PGrallocBuffer;
 include protocol PCompositable;
-include protocol PLayer;
 include protocol PTexture;
 include ProtocolTypes;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
 
@@ -21,23 +21,32 @@ namespace layers {
 /**
  * The PImageBridge protocol is used to allow isolated threads or processes to push
  * frames directly to the compositor thread/process without relying on the main thread
  * which might be too busy dealing with content script.
  */
 intr protocol PImageBridge
 {
   manages PCompositable;
+  manages PGrallocBuffer;
   manages PTexture;
 
 parent:
 
   sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
   async UpdateNoSwap(CompositableOperation[] ops);
 
+  // Allocates a gralloc buffer that may not suitable to use with
+  // gfxImageSurface but allows hardware decoder to write to the
+  // buffer directly. The format is a enum defined in
+  // system/graphics.h and the usage is the GraphicBuffer usage
+  // flag. See GraphicBuffer.h and gralloc.h.
+  sync PGrallocBuffer(IntSize size, uint32_t format, uint32_t usage)
+    returns (MaybeMagicGrallocBufferHandle handle);
+
   // First step of the destruction sequence. This puts all the ImageContainerParents
   // in a state in which they can't send asynchronous messages to their child
   // counterpart so as to not race with the upcomming __delete__ message.
   // In the child side, the __delete__ messages are not sent right after Stop,
   // they are scheduled in the ImageBridgeChild's message queue in order to ensure
   // that all the messages from the parent side have been received and processed
   // before sending __delete__.
   sync Stop();
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -4,16 +4,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include LayersSurfaces;
 include LayersMessages;
 include protocol PCompositable;
 include protocol PCompositor;
+include protocol PGrallocBuffer;
 include protocol PLayer;
 include protocol PRenderFrame;
 include protocol PTexture;
 
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
@@ -34,19 +35,49 @@ union MaybeTransform {
   gfx3DMatrix;
   void_t;
 };
 
 sync protocol PLayerTransaction {
   manager PRenderFrame or PCompositor;
   manages PLayer;
   manages PCompositable;
+  manages PGrallocBuffer;
   manages PTexture;
 
 parent:
+  /**
+   * Only the parent side has privileges to allocate the buffer.
+   * Allocation may fail (pmem is a scarce resource), and if so null_t
+   * is returned.
+   *
+   * |format| is an Android PixelFormat (see PixelFormat.h)
+   *
+   * commonly used PixelFormats are:
+   *   PIXEL_FORMAT_RGBA_8888
+   *   PIXEL_FORMAT_RGBX_8888
+   *   PIXEL_FORMAT_BGRA_8888
+   *
+   * Note that SurfaceDescriptorGralloc has a "isRBSwapped" boolean
+   * that can treat the R/B bytes as swapped when they are rendered
+   * to the screen, to help with matching the native pixel format
+   * of other rendering engines.
+   *
+   * |usage| is a USAGE_* mask (see GraphicBuffer.h)
+   *
+   * commonly used USAGE flags are:
+   *   USAGE_SW_READ_OFTEN | USAGE_SW_WRITE_OFTEN | USAGE_HW_TEXTURE
+   *     - used for software rendering to a buffer which the compositor
+   *       treats as a texture
+   *   USAGE_HW_RENDER | USAGE_HW_TEXTURE
+   *     - used for GL rendering to a buffer which the compositor
+   *       treats as a texture
+   */
+  sync PGrallocBuffer(IntSize size, uint32_t format, uint32_t usage)
+    returns (MaybeMagicGrallocBufferHandle handle);
   async PLayer();
   async PCompositable(TextureInfo aTextureInfo);
   async PTexture(SurfaceDescriptor aSharedData, TextureFlags aTextureFlags);
 
   // The isFirstPaint flag can be used to indicate that this is the first update
   // for a particular document.
   sync Update(Edit[] cset, TargetConfig targetConfig, bool isFirstPaint, bool scheduleComposite)
     returns (EditReply[] reply);
--- a/gfx/layers/ipc/PTexture.ipdl
+++ b/gfx/layers/ipc/PTexture.ipdl
@@ -3,16 +3,17 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include LayersSurfaces;
 include protocol PLayerTransaction;
 include protocol PImageBridge;
+include protocol PGrallocBuffer;
 include "mozilla/GfxMessageUtils.h";
 
 using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
 using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
 
 namespace mozilla {
 namespace layers {
 
--- a/gfx/layers/ipc/ShadowLayerUtils.h
+++ b/gfx/layers/ipc/ShadowLayerUtils.h
@@ -33,20 +33,16 @@ struct SurfaceDescriptorX11 {
 
 #if defined(MOZ_WIDGET_GONK)
 # include "mozilla/layers/ShadowLayerUtilsGralloc.h"
 #else
 namespace mozilla { namespace layers {
 struct MagicGrallocBufferHandle {
   bool operator==(const MagicGrallocBufferHandle&) const { return false; }
 };
-
-struct GrallocBufferRef {
-  bool operator==(const GrallocBufferRef&) const { return false; }
-};
 } }
 #endif
 
 namespace IPC {
 
 #if !defined(MOZ_HAVE_SURFACEDESCRIPTORX11)
 template <>
 struct ParamTraits<mozilla::layers::SurfaceDescriptorX11> {
@@ -81,23 +77,16 @@ struct ParamTraits<mozilla::gl::SharedTe
 
 #if !defined(MOZ_HAVE_SURFACEDESCRIPTORGRALLOC)
 template <>
 struct ParamTraits<mozilla::layers::MagicGrallocBufferHandle> {
   typedef mozilla::layers::MagicGrallocBufferHandle paramType;
   static void Write(Message*, const paramType&) {}
   static bool Read(const Message*, void**, paramType*) { return false; }
 };
-
-template <>
-struct ParamTraits<mozilla::layers::GrallocBufferRef> {
-  typedef mozilla::layers::GrallocBufferRef paramType;
-  static void Write(Message*, const paramType&) {}
-  static bool Read(const Message*, void**, paramType*) { return false; }
-};
 #endif  // !defined(MOZ_HAVE_XSURFACEDESCRIPTORGRALLOC)
 
 template <>
 struct ParamTraits<mozilla::ScreenRotation>
   : public ContiguousEnumSerializer<
              mozilla::ScreenRotation,
              mozilla::ROTATION_0,
              mozilla::ROTATION_COUNT>
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp
@@ -3,23 +3,23 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/DebugOnly.h"
 
 #include "mozilla/gfx/Point.h"
+#include "mozilla/layers/PGrallocBufferChild.h"
+#include "mozilla/layers/PGrallocBufferParent.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/TextureHost.h"
-#include "mozilla/layers/SharedBufferManagerChild.h"
-#include "mozilla/layers/SharedBufferManagerParent.h"
 #include "mozilla/unused.h"
 #include "nsXULAppAPI.h"
 
 #include "ShadowLayerUtilsGralloc.h"
 
 #include "nsIMemoryReporter.h"
 
 #include "gfxPlatform.h"
@@ -35,38 +35,16 @@
 using namespace android;
 using namespace base;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 
 namespace IPC {
 
 void
-ParamTraits<GrallocBufferRef>::Write(Message* aMsg,
-                                     const paramType& aParam)
-{
-  aMsg->WriteInt(aParam.mOwner);
-  aMsg->WriteInt32(aParam.mKey);
-}
-
-bool
-ParamTraits<GrallocBufferRef>::Read(const Message* aMsg, void** aIter,
-                                    paramType* aParam)
-{
-  int owner;
-  int index;
-  if (!aMsg->ReadInt(aIter, &owner) ||
-      !aMsg->ReadInt32(aIter, &index))
-    return false;
-  aParam->mOwner = owner;
-  aParam->mKey = index;
-  return true;
-}
-
-void
 ParamTraits<MagicGrallocBufferHandle>::Write(Message* aMsg,
                                              const paramType& aParam)
 {
 #if ANDROID_VERSION >= 19
   sp<GraphicBuffer> flattenable = aParam.mGraphicBuffer;
 #else
   Flattenable *flattenable = aParam.mGraphicBuffer.get();
 #endif
@@ -87,18 +65,17 @@ ParamTraits<MagicGrallocBufferHandle>::W
   // to multiple parcelable object consumption. The actual size and fd count
   // which returned by getFlattenedSize() and getFdCount() are not changed.
   // So we change nbytes and nfds back by call corresponding calls.
   nbytes = flattenable->getFlattenedSize();
   nfds = flattenable->getFdCount();
 #else
   flattenable->flatten(data, nbytes, fds, nfds);
 #endif
-  aMsg->WriteInt(aParam.mRef.mOwner);
-  aMsg->WriteInt32(aParam.mRef.mKey);
+
   aMsg->WriteSize(nbytes);
   aMsg->WriteSize(nfds);
 
   aMsg->WriteBytes(data, nbytes);
   for (size_t n = 0; n < nfds; ++n) {
     // These buffers can't die in transit because they're created
     // synchonously and the parent-side buffer can only be dropped if
     // there's a crash.
@@ -108,84 +85,65 @@ ParamTraits<MagicGrallocBufferHandle>::W
 
 bool
 ParamTraits<MagicGrallocBufferHandle>::Read(const Message* aMsg,
                                             void** aIter, paramType* aResult)
 {
   size_t nbytes;
   size_t nfds;
   const char* data;
-  int owner;
-  int index;
 
-  if (!aMsg->ReadInt(aIter, &owner) ||
-      !aMsg->ReadInt32(aIter, &index) ||
-      !aMsg->ReadSize(aIter, &nbytes) ||
+  if (!aMsg->ReadSize(aIter, &nbytes) ||
       !aMsg->ReadSize(aIter, &nfds) ||
       !aMsg->ReadBytes(aIter, &data, nbytes)) {
     return false;
   }
 
   int fds[nfds];
-  bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default);
+
   for (size_t n = 0; n < nfds; ++n) {
     FileDescriptor fd;
     if (!aMsg->ReadFileDescriptor(aIter, &fd)) {
       return false;
     }
     // If the GraphicBuffer was shared cross-process, SCM_RIGHTS does
     // the right thing and dup's the fd.  If it's shared cross-thread,
     // SCM_RIGHTS doesn't dup the fd.  That's surprising, but we just
     // deal with it here.  NB: only the "default" (master) process can
     // alloc gralloc buffers.
-    int dupFd = sameProcess && index < 0 ? dup(fd.fd) : fd.fd;
+    bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default);
+    int dupFd = sameProcess ? dup(fd.fd) : fd.fd;
     fds[n] = dupFd;
   }
 
-  aResult->mRef.mOwner = owner;
-  aResult->mRef.mKey = index;
-  if (sameProcess)
-    aResult->mGraphicBuffer = SharedBufferManagerParent::GetGraphicBuffer(aResult->mRef);
-  else {
-    aResult->mGraphicBuffer = SharedBufferManagerChild::GetSingleton()->GetGraphicBuffer(index);
-    if (index >= 0 && aResult->mGraphicBuffer == nullptr) {
-      //Only newly created GraphicBuffer should deserialize
+  sp<GraphicBuffer> buffer(new GraphicBuffer());
 #if ANDROID_VERSION >= 19
-      sp<GraphicBuffer> flattenable(new GraphicBuffer());
-      const void* datap = (const void*)data;
-      const int* fdsp = &fds[0];
-      if (NO_ERROR == flattenable->unflatten(datap, nbytes, fdsp, nfds)) {
-        aResult->mGraphicBuffer = flattenable;
-      }
+  // Make a copy of "data" and "fds" for unflatten() to avoid casting problem
+  void const *pdata = (void const *)data;
+  int const *pfds = fds;
+
+  if (NO_ERROR == buffer->unflatten(pdata, nbytes, pfds, nfds)) {
 #else
-      sp<GraphicBuffer> buffer(new GraphicBuffer());
-      Flattenable *flattenable = buffer.get();
+  Flattenable *flattenable = buffer.get();
 
-      if (NO_ERROR == flattenable->unflatten(data, nbytes, fds, nfds)) {
-        aResult->mGraphicBuffer = buffer;
-      }
+  if (NO_ERROR == flattenable->unflatten(data, nbytes, fds, nfds)) {
 #endif
-    }
+    aResult->mGraphicBuffer = buffer;
+    return true;
   }
-
-  if (aResult->mGraphicBuffer == nullptr) {
-    return false;
-  }
-
-  return true;
+  return false;
 }
 
 } // namespace IPC
 
 namespace mozilla {
 namespace layers {
 
-MagicGrallocBufferHandle::MagicGrallocBufferHandle(const sp<GraphicBuffer>& aGraphicBuffer, GrallocBufferRef ref)
+MagicGrallocBufferHandle::MagicGrallocBufferHandle(const sp<GraphicBuffer>& aGraphicBuffer)
   : mGraphicBuffer(aGraphicBuffer)
-  , mRef(ref)
 {
 }
 
 //-----------------------------------------------------------------------------
 // Parent process
 
 static gfxImageFormat
 ImageFormatForPixelFormat(android::PixelFormat aFormat)
@@ -250,56 +208,188 @@ PixelFormatForContentType(gfxContentType
 }
 
 static gfxContentType
 ContentTypeFromPixelFormat(android::PixelFormat aFormat)
 {
   return gfxASurface::ContentFromFormat(ImageFormatForPixelFormat(aFormat));
 }
 
+class GrallocReporter MOZ_FINAL : public nsIMemoryReporter
+{
+  friend class GrallocBufferActor;
+
+public:
+  NS_DECL_ISUPPORTS
+
+  GrallocReporter()
+  {
+#ifdef DEBUG
+    // There must be only one instance of this class, due to |sAmount|
+    // being static.  Assert this.
+    static bool hasRun = false;
+    MOZ_ASSERT(!hasRun);
+    hasRun = true;
+#endif
+  }
+
+  NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+                            nsISupports* aData)
+  {
+    return MOZ_COLLECT_REPORT(
+      "gralloc", KIND_OTHER, UNITS_BYTES, sAmount,
+"Special RAM that can be shared between processes and directly accessed by "
+"both the CPU and GPU. Gralloc memory is usually a relatively precious "
+"resource, with much less available than generic RAM. When it's exhausted, "
+"graphics performance can suffer. This value can be incorrect because of race "
+"conditions.");
+  }
+
+private:
+  static int64_t sAmount;
+};
+
+NS_IMPL_ISUPPORTS(GrallocReporter, nsIMemoryReporter)
+
+int64_t GrallocReporter::sAmount = 0;
+
+void InitGralloc() {
+  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
+  RegisterStrongMemoryReporter(new GrallocReporter());
+}
+
+GrallocBufferActor::GrallocBufferActor()
+: mAllocBytes(0)
+, mTextureHost(nullptr)
+{
+}
+
+GrallocBufferActor::~GrallocBufferActor()
+{
+  if (mAllocBytes > 0) {
+    GrallocReporter::sAmount -= mAllocBytes;
+  }
+}
+
+/*static*/ PGrallocBufferParent*
+GrallocBufferActor::Create(const gfx::IntSize& aSize,
+                           const uint32_t& aFormat,
+                           const uint32_t& aUsage,
+                           MaybeMagicGrallocBufferHandle* aOutHandle)
+{
+  PROFILER_LABEL("GrallocBufferActor", "Create");
+  GrallocBufferActor* actor = new GrallocBufferActor();
+  *aOutHandle = null_t();
+  uint32_t format = aFormat;
+  uint32_t usage = aUsage;
+
+  if (format == 0 || usage == 0) {
+    printf_stderr("GrallocBufferActor::Create -- format and usage must be non-zero");
+    return actor;
+  }
+
+  // If the requested size is too big (i.e. exceeds the commonly used max GL texture size)
+  // then we risk OOMing the parent process. It's better to just deny the allocation and
+  // kill the child process, which is what the following code does.
+  // TODO: actually use GL_MAX_TEXTURE_SIZE instead of hardcoding 4096
+  if (aSize.width > 4096 || aSize.height > 4096) {
+    printf_stderr("GrallocBufferActor::Create -- requested gralloc buffer is too big. Killing child instead.");
+    delete actor;
+    return nullptr;
+  }
+
+  sp<GraphicBuffer> buffer(new GraphicBuffer(aSize.width, aSize.height, format, usage));
+  if (buffer->initCheck() != OK)
+    return actor;
+
+  size_t bpp = BytesPerPixelForPixelFormat(format);
+  actor->mAllocBytes = aSize.width * aSize.height * bpp;
+  GrallocReporter::sAmount += actor->mAllocBytes;
+
+  actor->mGraphicBuffer = buffer;
+  *aOutHandle = MagicGrallocBufferHandle(buffer);
+
+  return actor;
+}
+
+void GrallocBufferActor::ActorDestroy(ActorDestroyReason)
+{
+  // Used only for hacky fix for bug 966446.
+  if (mTextureHost) {
+    mTextureHost->ForgetBufferActor();
+    mTextureHost = nullptr;
+  }
+}
+
+void GrallocBufferActor::AddTextureHost(TextureHost* aTextureHost)
+{
+  mTextureHost = aTextureHost;
+}
+
+void GrallocBufferActor::RemoveTextureHost()
+{
+  mTextureHost = nullptr;
+}
+
 /*static*/ bool
 LayerManagerComposite::SupportsDirectTexturing()
 {
   return true;
 }
 
 /*static*/ void
 LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
 {
   // Nothing to be done for gralloc.
 }
 
 //-----------------------------------------------------------------------------
+// Child process
+
+/*static*/ PGrallocBufferChild*
+GrallocBufferActor::Create()
+{
+  return new GrallocBufferActor();
+}
+
+void
+GrallocBufferActor::InitFromHandle(const MagicGrallocBufferHandle& aHandle)
+{
+  MOZ_ASSERT(!mGraphicBuffer.get());
+  MOZ_ASSERT(aHandle.mGraphicBuffer.get());
+
+  mGraphicBuffer = aHandle.mGraphicBuffer;
+}
+
+PGrallocBufferChild*
+ShadowLayerForwarder::AllocGrallocBuffer(const gfx::IntSize& aSize,
+                                         uint32_t aFormat,
+                                         uint32_t aUsage,
+                                         MaybeMagicGrallocBufferHandle* aHandle)
+{
+  if (!mShadowManager->IPCOpen()) {
+    return nullptr;
+  }
+  return mShadowManager->SendPGrallocBufferConstructor(aSize, aFormat, aUsage, aHandle);
+}
+
+void
+ShadowLayerForwarder::DeallocGrallocBuffer(PGrallocBufferChild* aChild)
+{
+  MOZ_ASSERT(aChild);
+  PGrallocBufferChild::Send__delete__(aChild);
+}
+
+//-----------------------------------------------------------------------------
 // Both processes
 
-/*static*/ sp<GraphicBuffer>
-GetGraphicBufferFrom(MaybeMagicGrallocBufferHandle aHandle)
+android::GraphicBuffer*
+GrallocBufferActor::GetGraphicBuffer()
 {
-  if (aHandle.type() != MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle) {
-    if (aHandle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
-      if (XRE_GetProcessType() == GeckoProcessType_Default) {
-        return SharedBufferManagerParent::GetGraphicBuffer(aHandle.get_GrallocBufferRef());
-      }
-      return SharedBufferManagerChild::GetSingleton()->GetGraphicBuffer(aHandle.get_GrallocBufferRef().mKey);
-    }
-  } else {
-    MagicGrallocBufferHandle realHandle = aHandle.get_MagicGrallocBufferHandle();
-    return realHandle.mGraphicBuffer;
-  }
-  return nullptr;
-}
-
-android::sp<android::GraphicBuffer>
-GetGraphicBufferFromDesc(SurfaceDescriptor aDesc)
-{
-  MaybeMagicGrallocBufferHandle handle;
-  if (aDesc.type() == SurfaceDescriptor::TNewSurfaceDescriptorGralloc) {
-    handle = aDesc.get_NewSurfaceDescriptorGralloc().buffer();
-  }
-  return GetGraphicBufferFrom(handle);
+  return mGraphicBuffer.get();
 }
 
 /*static*/ void
 ShadowLayerForwarder::PlatformSyncBeforeUpdate()
 {
   // Nothing to be done for gralloc.
 }
 
--- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.h
+++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.h
@@ -6,91 +6,113 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_ShadowLayerUtilsGralloc_h
 #define mozilla_layers_ShadowLayerUtilsGralloc_h
 
 #include <unistd.h>
 #include <ui/GraphicBuffer.h>
 
-#include "base/process.h"
 #include "ipc/IPCMessageUtils.h"
+#include "mozilla/layers/PGrallocBufferChild.h"
+#include "mozilla/layers/PGrallocBufferParent.h"
 
 #define MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
 #define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
 
 namespace mozilla {
 namespace layers {
 
 class MaybeMagicGrallocBufferHandle;
-class SurfaceDescriptor;
 class TextureHost;
 
-struct GrallocBufferRef {
-  base::ProcessId mOwner;
-  int mKey;
-
-  GrallocBufferRef()
-    : mOwner(0)
-    , mKey(-1)
-  {
-
-  }
-
-  bool operator== (const GrallocBufferRef rhs) const{
-    return mOwner == rhs.mOwner && mKey == rhs.mKey;
-  }
-};
 /**
  * This class exists to share the underlying GraphicBuffer resources
  * from one thread context to another.  This requires going through
  * slow paths in the kernel so can be somewhat expensive.
  *
  * This is not just platform-specific, but also
  * gralloc-implementation-specific.
  */
 struct MagicGrallocBufferHandle {
   typedef android::GraphicBuffer GraphicBuffer;
-  MagicGrallocBufferHandle() {}
 
-  MagicGrallocBufferHandle(const android::sp<GraphicBuffer>& aGraphicBuffer, GrallocBufferRef ref);
+  MagicGrallocBufferHandle()
+  { }
+
+  MagicGrallocBufferHandle(const android::sp<GraphicBuffer>& aGraphicBuffer);
 
   // Default copy ctor and operator= are OK
 
   bool operator==(const MagicGrallocBufferHandle& aOther) const {
     return mGraphicBuffer == aOther.mGraphicBuffer;
   }
 
   android::sp<GraphicBuffer> mGraphicBuffer;
-  GrallocBufferRef mRef;
 };
 
 /**
- * Util function to find GraphicBuffer from SurfaceDescriptor, caller of this function should check origin
- * to make sure not corrupt others buffer
+ * GrallocBufferActor is an "IPC wrapper" for an underlying
+ * GraphicBuffer (pmem region).  It allows us to cheaply and
+ * conveniently share gralloc handles between processes.
  */
-android::sp<android::GraphicBuffer> GetGraphicBufferFrom(MaybeMagicGrallocBufferHandle aHandle);
-android::sp<android::GraphicBuffer> GetGraphicBufferFromDesc(SurfaceDescriptor aDesc);
+class GrallocBufferActor : public PGrallocBufferChild
+                         , public PGrallocBufferParent
+{
+  friend class ShadowLayerForwarder;
+  friend class LayerManagerComposite;
+  friend class ImageBridgeChild;
+  typedef android::GraphicBuffer GraphicBuffer;
+
+public:
+  virtual ~GrallocBufferActor();
+
+  static PGrallocBufferParent*
+  Create(const gfx::IntSize& aSize,
+         const uint32_t& aFormat,
+         const uint32_t& aUsage,
+         MaybeMagicGrallocBufferHandle* aOutHandle);
+
+  static PGrallocBufferChild*
+  Create();
+
+  // used only for hacky fix in gecko 23 for bug 862324
+  // see bug 865908 about fixing this.
+  void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
+
+  void AddTextureHost(TextureHost* aTextureHost);
+  void RemoveTextureHost();
+
+  android::GraphicBuffer* GetGraphicBuffer();
+
+  void InitFromHandle(const MagicGrallocBufferHandle& aHandle);
+
+private:
+  GrallocBufferActor();
+
+  android::sp<GraphicBuffer> mGraphicBuffer;
+
+  // This value stores the number of bytes allocated in this
+  // BufferActor. This will be used for the memory reporter.
+  size_t mAllocBytes;
+
+  // Used only for hacky fix for bug 966446.
+  TextureHost* mTextureHost;
+
+  friend class ISurfaceAllocator;
+};
 
 } // namespace layers
 } // namespace mozilla
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::layers::MagicGrallocBufferHandle> {
   typedef mozilla::layers::MagicGrallocBufferHandle paramType;
 
   static void Write(Message* aMsg, const paramType& aParam);
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
 };
 
-template<>
-struct ParamTraits<mozilla::layers::GrallocBufferRef> {
-  typedef mozilla::layers::GrallocBufferRef paramType;
-  static void Write(Message* aMsg, const paramType& aParam);
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
-};
-
-
 } // namespace IPC
 
 #endif  // mozilla_layers_ShadowLayerUtilsGralloc_h
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -371,16 +371,26 @@ protected:
 #ifdef DEBUG
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
 #else
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {}
 #endif
 
   RefPtr<LayerTransactionChild> mShadowManager;
 
+#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
+  // from ISurfaceAllocator
+  virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize,
+                                                  uint32_t aFormat,
+                                                  uint32_t aUsage,
+                                                  MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE;
+
+  virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE;
+#endif
+
 private:
 
   Transaction* mTxn;
   DiagnosticTypes mDiagnosticTypes;
   bool mIsFirstPaint;
   bool mWindowOverlayChanged;
 };
 
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -142,18 +142,16 @@ EXPORTS.mozilla.layers += [
     'ipc/FenceUtils.h',
     'ipc/ImageBridgeChild.h',
     'ipc/ImageBridgeParent.h',
     'ipc/ISurfaceAllocator.h',
     'ipc/LayerTransactionChild.h',
     'ipc/LayerTransactionParent.h',
     'ipc/ShadowLayers.h',
     'ipc/ShadowLayersManager.h',
-    'ipc/SharedBufferManagerChild.h',
-    'ipc/SharedBufferManagerParent.h',
     'ipc/SharedPlanarYCbCrImage.h',
     'ipc/SharedRGBImage.h',
     'LayersTypes.h',
     'opengl/CompositingRenderTargetOGL.h',
     'opengl/CompositorOGL.h',
     'opengl/GrallocTextureClient.h',
     'opengl/GrallocTextureHost.h',
     'opengl/MacIOSurfaceTextureClientOGL.h',
@@ -279,18 +277,16 @@ UNIFIED_SOURCES += [
     'ipc/ImageBridgeChild.cpp',
     'ipc/ImageBridgeParent.cpp',
     'ipc/ISurfaceAllocator.cpp',
     'ipc/LayerTransactionChild.cpp',
     'ipc/LayerTransactionParent.cpp',
     'ipc/ShadowLayerChild.cpp',
     'ipc/ShadowLayerParent.cpp',
     'ipc/ShadowLayers.cpp',
-    'ipc/SharedBufferManagerChild.cpp',
-    'ipc/SharedBufferManagerParent.cpp',
     'ipc/SharedPlanarYCbCrImage.cpp',
     'ipc/SharedRGBImage.cpp',
     'LayerScope.cpp',
     'LayersLogging.cpp',
     'LayerSorter.cpp',
     'LayerUtils.cpp',
     'opengl/CompositingRenderTargetOGL.cpp',
     'opengl/CompositorOGL.cpp',
@@ -326,20 +322,20 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
         'opengl/MacIOSurfaceTextureHostOGL.cpp',
     ]
 
 IPDL_SOURCES = [
     'ipc/LayersMessages.ipdlh',
     'ipc/LayersSurfaces.ipdlh',
     'ipc/PCompositable.ipdl',
     'ipc/PCompositor.ipdl',
+    'ipc/PGrallocBuffer.ipdl',
     'ipc/PImageBridge.ipdl',
     'ipc/PLayer.ipdl',
     'ipc/PLayerTransaction.ipdl',
-    'ipc/PSharedBufferManager.ipdl',
     'ipc/PTexture.ipdl',
 ]
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
--- a/gfx/layers/opengl/GrallocTextureClient.cpp
+++ b/gfx/layers/opengl/GrallocTextureClient.cpp
@@ -15,53 +15,56 @@
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace android;
 
 class GrallocTextureClientData : public TextureClientData {
 public:
-  GrallocTextureClientData(MaybeMagicGrallocBufferHandle aDesc)
-    : mGrallocHandle(aDesc)
+  GrallocTextureClientData(GrallocBufferActor* aActor)
+    : mGrallocActor(aActor)
   {
     MOZ_COUNT_CTOR(GrallocTextureClientData);
   }
 
   ~GrallocTextureClientData()
   {
     MOZ_COUNT_DTOR(GrallocTextureClientData);
+    MOZ_ASSERT(!mGrallocActor);
   }
 
   virtual void DeallocateSharedData(ISurfaceAllocator* allocator) MOZ_OVERRIDE
   {
-    allocator->DeallocGrallocBuffer(&mGrallocHandle);
+    allocator->DeallocGrallocBuffer(mGrallocActor);
+    mGrallocActor = nullptr;
   }
 
 private:
-  MaybeMagicGrallocBufferHandle mGrallocHandle;
+  GrallocBufferActor* mGrallocActor;
 };
 
 TextureClientData*
 GrallocTextureClientOGL::DropTextureData()
 {
-  TextureClientData* result = new GrallocTextureClientData(mGrallocHandle);
+  TextureClientData* result = new GrallocTextureClientData(mGrallocActor);
+  mGrallocActor = nullptr;
+  mGraphicBuffer = nullptr;
   return result;
 }
 
-GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer,
+GrallocTextureClientOGL::GrallocTextureClientOGL(GrallocBufferActor* aActor,
                                                  gfx::IntSize aSize,
                                                  gfx::BackendType aMoz2dBackend,
                                                  TextureFlags aFlags)
 : BufferTextureClient(nullptr, gfx::SurfaceFormat::UNKNOWN, aMoz2dBackend, aFlags)
-, mGrallocHandle(buffer)
 , mMappedBuffer(nullptr)
 , mMediaBuffer(nullptr)
 {
-  InitWith(buffer, aSize);
+  InitWith(aActor, aSize);
   MOZ_COUNT_CTOR(GrallocTextureClientOGL);
 }
 
 GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
                                                  gfx::SurfaceFormat aFormat,
                                                  gfx::BackendType aMoz2dBackend,
                                                  TextureFlags aFlags)
 : BufferTextureClient(aAllocator, aFormat, aMoz2dBackend, aFlags)
@@ -71,39 +74,40 @@ GrallocTextureClientOGL::GrallocTextureC
   MOZ_COUNT_CTOR(GrallocTextureClientOGL);
 }
 
 GrallocTextureClientOGL::~GrallocTextureClientOGL()
 {
   MOZ_COUNT_DTOR(GrallocTextureClientOGL);
     if (ShouldDeallocateInDestructor()) {
     ISurfaceAllocator* allocator = GetAllocator();
-    allocator->DeallocGrallocBuffer(&mGrallocHandle);
+    allocator->DeallocGrallocBuffer(mGrallocActor);
   }
 }
 
 void
-GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle, gfx::IntSize aSize)
+GrallocTextureClientOGL::InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize)
 {
+  MOZ_ASSERT(aActor);
   MOZ_ASSERT(!IsAllocated());
   MOZ_ASSERT(IsValid());
-  mGrallocHandle = aHandle;
-  mGraphicBuffer = GetGraphicBufferFrom(aHandle);
+  mGrallocActor = aActor;
+  mGraphicBuffer = aActor->GetGraphicBuffer();
   mSize = aSize;
 }
 
 bool
 GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
   MOZ_ASSERT(IsValid());
   if (!IsAllocated()) {
     return false;
   }
 
-  aOutDescriptor = NewSurfaceDescriptorGralloc(mGrallocHandle, mSize);
+  aOutDescriptor = NewSurfaceDescriptorGralloc(nullptr, mGrallocActor, mSize);
   return true;
 }
 
 void
 GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
 {
   mReleaseFenceHandle = aReleaseFenceHandle;
 }
@@ -296,35 +300,37 @@ bool
 GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
                                          uint32_t aAndroidFormat,
                                          uint32_t aUsage)
 {
   MOZ_ASSERT(IsValid());
   ISurfaceAllocator* allocator = GetAllocator();
 
   MaybeMagicGrallocBufferHandle handle;
-  bool allocateResult =
+  PGrallocBufferChild* actor =
     allocator->AllocGrallocBuffer(aSize,
                                   aAndroidFormat,
                                   aUsage,
                                   &handle);
-  if (!allocateResult) {
+  if (!actor) {
     return false;
   }
+  GrallocBufferActor* gba = static_cast<GrallocBufferActor*>(actor);
+  gba->InitFromHandle(handle.get_MagicGrallocBufferHandle());
 
-  sp<GraphicBuffer> graphicBuffer = GetGraphicBufferFrom(handle);
+  sp<GraphicBuffer> graphicBuffer = gba->GetGraphicBuffer();
   if (!graphicBuffer.get()) {
     return false;
   }
 
   if (graphicBuffer->initCheck() != NO_ERROR) {
     return false;
   }
 
-  mGrallocHandle = handle;
+  mGrallocActor = gba;
   mGraphicBuffer = graphicBuffer;
   mSize = aSize;
   return true;
 }
 
 bool
 GrallocTextureClientOGL::IsAllocated() const
 {
--- a/gfx/layers/opengl/GrallocTextureClient.h
+++ b/gfx/layers/opengl/GrallocTextureClient.h
@@ -32,17 +32,17 @@ namespace layers {
  *
  * More info about Gralloc here: https://wiki.mozilla.org/Platform/GFX/Gralloc
  *
  * This is only used in Firefox OS
  */
 class GrallocTextureClientOGL : public BufferTextureClient
 {
 public:
-  GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer,
+  GrallocTextureClientOGL(GrallocBufferActor* aActor,
                           gfx::IntSize aSize,
                           gfx::BackendType aMoz2dBackend,
                           TextureFlags aFlags = TextureFlags::DEFAULT);
   GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
                           gfx::SurfaceFormat aFormat,
                           gfx::BackendType aMoz2dBackend,
                           TextureFlags aFlags = TextureFlags::DEFAULT);
 
@@ -61,17 +61,17 @@ public:
   virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
 
   virtual TextureClientData* DropTextureData() MOZ_OVERRIDE;
 
   virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) MOZ_OVERRIDE;
 
   virtual void WaitReleaseFence() MOZ_OVERRIDE;
 
-  void InitWith(MaybeMagicGrallocBufferHandle aDesc, gfx::IntSize aSize);
+  void InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize);
 
   void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
 
   gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   android::sp<android::GraphicBuffer> GetGraphicBuffer()
   {
     return mGraphicBuffer;
@@ -115,17 +115,17 @@ public:
   {
     return mMediaBuffer;
   }
 
 protected:
   /**
    * Unfortunately, until bug 879681 is fixed we need to use a GrallocBufferActor.
    */
-  MaybeMagicGrallocBufferHandle mGrallocHandle;
+  GrallocBufferActor* mGrallocActor;
 
   android::sp<android::GraphicBuffer> mGraphicBuffer;
 
   /**
    * Points to a mapped gralloc buffer between calls to lock and unlock.
    * Should be null outside of the lock-unlock pair.
    */
   uint8_t* mMappedBuffer;
--- a/gfx/layers/opengl/GrallocTextureHost.cpp
+++ b/gfx/layers/opengl/GrallocTextureHost.cpp
@@ -1,21 +1,19 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 //  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "base/process.h"
 #include "GLContext.h"
 #include "gfx2DGlue.h"
 #include <ui/GraphicBuffer.h>
 #include "GrallocImages.h"  // for GrallocImage
 #include "mozilla/layers/GrallocTextureHost.h"
 #include "mozilla/layers/CompositorOGL.h"
-#include "mozilla/layers/SharedBufferManagerParent.h"
 #include "EGLImageHelpers.h"
 #include "GLReadTexImageHelper.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace android;
 
@@ -273,36 +271,45 @@ GrallocTextureSourceOGL::DeallocateDevic
     mEGLImage = EGL_NO_IMAGE;
   }
 }
 
 GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
                                              const NewSurfaceDescriptorGralloc& aDescriptor)
   : TextureHost(aFlags)
 {
-  mGrallocHandle = aDescriptor;
+  android::GraphicBuffer* graphicBuffer = nullptr;
+  gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
 
-  android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
-  if (!graphicBuffer) {
-	  NS_RUNTIMEABORT("Invalid SurfaceDescriptor passed in");
+  mSize = aDescriptor.size();
+  mGrallocActor =
+    static_cast<GrallocBufferActor*>(aDescriptor.bufferParent());
+
+  if (mGrallocActor) {
+    mGrallocActor->AddTextureHost(this);
+    graphicBuffer = mGrallocActor->GetGraphicBuffer();
   }
 
-  mSize = aDescriptor.size();
-  gfx::SurfaceFormat format =
-    SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
-                                       aFlags & TextureFlags::RB_SWAPPED);
-
+  if (graphicBuffer) {
+    format =
+      SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
+                                         aFlags);
+  }
   mTextureSource = new GrallocTextureSourceOGL(nullptr,
                                                graphicBuffer,
                                                format);
 }
 
 GrallocTextureHostOGL::~GrallocTextureHostOGL()
 {
   mTextureSource = nullptr;
+  if (mGrallocActor) {
+    mGrallocActor->RemoveTextureHost();
+    mGrallocActor = nullptr;
+  }
 }
 
 void
 GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
 {
   mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor));
 }
 
@@ -335,27 +342,18 @@ GrallocTextureHostOGL::GetFormat() const
 }
 
 void
 GrallocTextureHostOGL::DeallocateSharedData()
 {
   if (mTextureSource) {
     mTextureSource->ForgetBuffer();
   }
-  if (mGrallocHandle.buffer().type() != SurfaceDescriptor::Tnull_t) {
-    MaybeMagicGrallocBufferHandle handle = mGrallocHandle.buffer();
-    base::ProcessId owner;
-    if (handle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
-      owner = handle.get_GrallocBufferRef().mOwner;
-    }
-    else {
-      owner = handle.get_MagicGrallocBufferHandle().mRef.mOwner;
-    }
-
-    SharedBufferManagerParent::GetInstance(owner)->DropGrallocBuffer(mGrallocHandle);
+  if (mGrallocActor) {
+    PGrallocBufferParent::Send__delete__(mGrallocActor);
   }
 }
 
 void
 GrallocTextureHostOGL::ForgetSharedData()
 {
   if (mTextureSource) {
     mTextureSource->ForgetBuffer();
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -120,18 +120,24 @@ public:
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
   virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
 
   bool IsValid() const;
 
   virtual const char* Name() MOZ_OVERRIDE { return "GrallocTextureHostOGL"; }
 
+  // Forget buffer actor. Used only for hacky fix for bug 966446. 
+  virtual void ForgetBufferActor()
+  {
+    mGrallocActor = nullptr;
+  }
+
 private:
-  NewSurfaceDescriptorGralloc mGrallocHandle;
+  GrallocBufferActor* mGrallocActor;
   RefPtr<GrallocTextureSourceOGL> mTextureSource;
   gfx::IntSize mSize; // See comment in textureClientOGL.h
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -5,17 +5,16 @@
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif
 
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/ImageBridgeChild.h"
-#include "mozilla/layers/SharedBufferManagerChild.h"
 #include "mozilla/layers/ISurfaceAllocator.h"     // for GfxMemoryImageReporter
 
 #include "prlog.h"
 
 #include "gfxPlatform.h"
 #include "gfxPrefs.h"
 
 #ifdef XP_WIN
@@ -371,19 +370,16 @@ gfxPlatform::Init()
       useOffMainThreadCompositing &= GetPlatform()->SupportsOffMainThreadCompositing();
     }
 
     if (useOffMainThreadCompositing && (XRE_GetProcessType() == GeckoProcessType_Default)) {
         CompositorParent::StartUp();
         if (gfxPrefs::AsyncVideoEnabled()) {
             ImageBridgeChild::StartUp();
         }
-#ifdef MOZ_WIDGET_GONK
-        SharedBufferManagerChild::StartUp();
-#endif
     }
 
     nsresult rv;
 
 #if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID) // temporary, until this is implemented on others
     rv = gfxPlatformFontList::Init();
     if (NS_FAILED(rv)) {
         NS_RUNTIMEABORT("Could not initialize gfxPlatformFontList");
@@ -495,19 +491,17 @@ gfxPlatform::Shutdown()
     // could go away. Unfortunately, we currently support WGL (the default) for
     // WebGL on Optimus.
     mozilla::gl::GLContextProviderEGL::Shutdown();
 #endif
 
     // This will block this thread untill the ImageBridge protocol is completely
     // deleted.
     ImageBridgeChild::ShutDown();
-#ifdef MOZ_WIDGET_GONK
-    SharedBufferManagerChild::ShutDown();
-#endif
+
     CompositorParent::ShutDown();
 
     delete gGfxPlatformPrefsLock;
 
     gfxPrefs::DestroySingleton();
     gfxFont::DestroySingletons();
 
     delete gPlatform;
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -2,18 +2,16 @@
 /* vim: set sw=2 ts=8 et ft=cpp : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PContent;
 include protocol PBrowser;
 
-include "mozilla/GfxMessageUtils.h";
-
 using mozilla::dom::ScreenOrientation from "mozilla/dom/ScreenOrientation.h";
 using mozilla::hal::FlashMode from "mozilla/HalTypes.h";
 using mozilla::hal::LightType from "mozilla/HalTypes.h";
 using mozilla::hal::LightMode from "mozilla/HalTypes.h";
 using mozilla::hal::SensorType from "mozilla/HalSensor.h";
 using mozilla::hal::SensorAccuracyType from "mozilla/HalSensor.h";
 using mozilla::hal::WakeLockControl from "mozilla/HalTypes.h";
 using mozilla::hal::SwitchState from "mozilla/HalTypes.h";
--- a/ipc/chromium/src/chrome/common/file_descriptor_set_posix.h
+++ b/ipc/chromium/src/chrome/common/file_descriptor_set_posix.h
@@ -25,17 +25,17 @@ class FileDescriptorSet : public base::R
   // because the control message kernel interface has to be given a buffer which
   // is large enough to store all the descriptor numbers. Otherwise the kernel
   // tells us that it truncated the control data and the extra descriptors are
   // lost.
   //
   // In debugging mode, it's a fatal error to try and add more than this number
   // of descriptors to a FileDescriptorSet.
   enum {
-    MAX_DESCRIPTORS_PER_MESSAGE = 7
+    MAX_DESCRIPTORS_PER_MESSAGE = 4
   };
 
   // ---------------------------------------------------------------------------
   // Interfaces for building during message serialisation...
 
   // Add a descriptor to the end of the set. Returns false iff the set is full.
   bool Add(int fd);
   // Add a descriptor to the end of the set and automatically close it after