Back out ef1cd14c8cac (bug 1067455) for Windows assertion failures
authorPhil Ringnalda <philringnalda@gmail.com>
Sun, 05 Oct 2014 19:16:56 -0700
changeset 232121 51509077b97ccd5b193f0d0504d64d10e22b9702
parent 232120 2b73787681bddb7b30b4b6c4c484278f10f582ab
child 232122 e8cd71a4dc0c50c2bc8aaca82f8a43ca64585ea9
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1067455
milestone35.0a1
backs outef1cd14c8cac8a4bf009bfcda46d1628cc637aa1
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
Back out ef1cd14c8cac (bug 1067455) for Windows assertion failures CLOSED TREE
gfx/layers/Compositor.h
gfx/layers/client/TextureClient.h
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/ipc/CompositableTransactionParent.cpp
gfx/layers/ipc/CompositableTransactionParent.h
gfx/layers/ipc/FenceUtils.h
gfx/layers/ipc/FenceUtilsGonk.cpp
gfx/layers/ipc/FenceUtilsGonk.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/CompositorOGL.h
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -8,17 +8,16 @@
 
 #include "Units.h"                      // for ScreenPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for TemporaryRef, RefCounted
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
 #include "mozilla/gfx/Types.h"          // for Float
 #include "mozilla/layers/CompositorTypes.h"  // for DiagnosticTypes, etc
-#include "mozilla/layers/FenceUtils.h"  // for FenceHandle
 #include "mozilla/layers/LayersTypes.h"  // for LayersBackend
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsRegion.h"
 #include <vector>
 #include "mozilla/WidgetUtils.h"
 
 /**
  * Different elements of a web pages are rendered into separate "layers" before
@@ -349,21 +348,16 @@ public:
 
   /**
    * Flush the current frame to the screen and tidy up.
    */
   virtual void EndFrame() = 0;
 
   virtual void SetFBAcquireFence(Layer* aLayer) {}
 
-  virtual FenceHandle GetReleaseFence()
-  {
-    return FenceHandle();
-  }
-
   /**
    * Post-rendering stuff if the rendering is done outside of this Compositor
    * e.g., by Composer2D.
    * aTransform is the transform from user space to window space.
    */
   virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) = 0;
 
   /**
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -353,17 +353,17 @@ public:
    * If the texture flags contain TextureFlags::DEALLOCATE_CLIENT, the destruction
    * will be synchronously coordinated with the compositor side, otherwise it
    * will be done asynchronously.
    */
   void ForceRemove();
 
   virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
   {
-    mReleaseFenceHandle.Merge(aReleaseFenceHandle);
+    mReleaseFenceHandle = aReleaseFenceHandle;
   }
 
   const FenceHandle& GetReleaseFenceHandle() const
   {
     return mReleaseFenceHandle;
   }
 
   virtual void SetAcquireFenceHandle(FenceHandle aAcquireFenceHandle)
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -75,16 +75,18 @@ public:
 
   ~TextureParent();
 
   bool Init(const SurfaceDescriptor& aSharedData,
             const TextureFlags& aFlags);
 
   void CompositorRecycle();
 
+  void SendFenceHandleIfPresent();
+
   virtual bool RecvClientRecycle() MOZ_OVERRIDE;
 
   virtual bool RecvClearTextureHostSync() MOZ_OVERRIDE;
 
   virtual bool RecvRemoveTexture() MOZ_OVERRIDE;
 
   TextureHost* GetTextureHost() { return mTextureHost; }
 
@@ -140,16 +142,24 @@ TextureHost::AsTextureHost(PTextureParen
 }
 
 PTextureParent*
 TextureHost::GetIPDLActor()
 {
   return mActor;
 }
 
+// static
+void
+TextureHost::SendFenceHandleIfPresent(PTextureParent* actor)
+{
+  TextureParent* parent = static_cast<TextureParent*>(actor);
+  parent->SendFenceHandleIfPresent();
+}
+
 FenceHandle
 TextureHost::GetAndResetReleaseFenceHandle()
 {
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   TextureHostOGL* hostOGL = this->AsHostOGL();
   if (!hostOGL) {
     return FenceHandle();
   }
@@ -699,25 +709,48 @@ static void RecycleCallback(TextureHost*
   TextureParent* tp = reinterpret_cast<TextureParent*>(aClosure);
   tp->CompositorRecycle();
 }
 
 void
 TextureParent::CompositorRecycle()
 {
   mTextureHost->ClearRecycleCallback();
+  SendFenceHandleIfPresent();
 
   if (mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
     mozilla::unused << SendCompositorRecycle();
     // Don't forget to prepare for the next reycle
     // if TextureClient request it.
     mWaitForClientRecycle = mTextureHost;
   }
 }
 
+void
+TextureParent::SendFenceHandleIfPresent()
+{
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
+  if (mTextureHost) {
+    TextureHostOGL* hostOGL = mTextureHost->AsHostOGL();
+    if (!hostOGL) {
+      return;
+    }
+    android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
+    if (fence.get() && fence->isValid()) {
+      // HWC might not provide Fence.
+      // In this case, HWC implicitly handles buffer's fence.
+
+      FenceHandle handle = FenceHandle(fence);
+      RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle);
+      mCompositableManager->SendFenceHandle(tracker, this, handle);
+    }
+  }
+#endif
+}
+
 bool
 TextureParent::RecvClientRecycle()
 {
   // This will allow the RecycleCallback to be called once the compositor
   // releases any external references to TextureHost.
   mTextureHost->SetRecycleCallback(RecycleCallback, this);
   if (!mWaitForClientRecycle) {
     RECYCLE_LOG("Not a recycable tile");
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -416,16 +416,18 @@ public:
   /**
    * Return a pointer to the IPDLActor.
    *
    * This is to be used with IPDL messages only. Do not store the returned
    * pointer.
    */
   PTextureParent* GetIPDLActor();
 
+  static void SendFenceHandleIfPresent(PTextureParent* actor);
+
   FenceHandle GetAndResetReleaseFenceHandle();
 
   /**
    * Specific to B2G's Composer2D
    * XXX - more doc here
    */
   virtual LayerRenderState GetRenderState()
   {
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -157,46 +157,45 @@ CompositableParentManager::ReceiveCompos
     case CompositableOperation::TOpRemoveTexture: {
       const OpRemoveTexture& op = aEdit.get_OpRemoveTexture();
       CompositableHost* compositable = AsCompositable(op);
       RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
 
       MOZ_ASSERT(tex.get());
       compositable->RemoveTextureHost(tex);
       // send FenceHandle if present.
-      SendFenceHandleIfPresent(op.textureParent(), compositable);
+      TextureHost::SendFenceHandleIfPresent(op.textureParent());
       break;
     }
     case CompositableOperation::TOpRemoveTextureAsync: {
       const OpRemoveTextureAsync& op = aEdit.get_OpRemoveTextureAsync();
       CompositableHost* compositable = AsCompositable(op);
       RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
 
       MOZ_ASSERT(tex.get());
       compositable->RemoveTextureHost(tex);
 
       if (!IsAsync() && GetChildProcessId()) {
         // send FenceHandle if present via ImageBridge.
         ImageBridgeParent::SendFenceHandleToTrackerIfPresent(
                              GetChildProcessId(),
                              op.holderId(),
                              op.transactionId(),
-                             op.textureParent(),
-                             compositable);
+                             op.textureParent());
 
         // If the message is recievied via PLayerTransaction,
         // Send message back via PImageBridge.
         ImageBridgeParent::ReplyRemoveTexture(
                              GetChildProcessId(),
                              OpReplyRemoveTexture(true, // isMain
                                                   op.holderId(),
                                                   op.transactionId()));
       } else {
         // send FenceHandle if present.
-        SendFenceHandleIfPresent(op.textureParent(), compositable);
+        TextureHost::SendFenceHandleIfPresent(op.textureParent());
 
         ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain
                                                 op.holderId(),
                                                 op.transactionId()));
       }
       break;
     }
     case CompositableOperation::TOpUseTexture: {
@@ -254,47 +253,11 @@ CompositableParentManager::ReceiveCompos
     default: {
       MOZ_ASSERT(false, "bad type");
     }
   }
 
   return true;
 }
 
-void
-CompositableParentManager::SendPendingAsyncMessges()
-{
-  if (mPendingAsyncMessage.empty()) {
-    return;
-  }
-
-  // Some type of AsyncParentMessageData message could have
-  // one file descriptor (e.g. OpDeliverFence).
-  // A number of file descriptors per gecko ipc message have a limitation
-  // on OS_POSIX (MACOSX or LINUX).
-#if defined(OS_POSIX)
-  static const uint32_t kMaxMessageNumber = FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE;
-#else
-  // default number that works everywhere else
-  static const uint32_t kMaxMessageNumber = 250;
-#endif
-
-  InfallibleTArray<AsyncParentMessageData> messages;
-  messages.SetCapacity(mPendingAsyncMessage.size());
-  for (size_t i = 0; i < mPendingAsyncMessage.size(); i++) {
-    messages.AppendElement(mPendingAsyncMessage[i]);
-    // Limit maximum number of messages.
-    if (messages.Length() >= kMaxMessageNumber) {
-      SendAsyncMessage(messages);
-      // Initialize Messages.
-      messages.Clear();
-    }
-  }
-
-  if (messages.Length() > 0) {
-    SendAsyncMessage(messages);
-  }
-  mPendingAsyncMessage.clear();
-}
-
 } // namespace
 } // namespace
 
--- a/gfx/layers/ipc/CompositableTransactionParent.h
+++ b/gfx/layers/ipc/CompositableTransactionParent.h
@@ -25,27 +25,22 @@ typedef std::vector<mozilla::layers::Edi
 // Since PCompositble has two potential manager protocols, we can't just call
 // the Manager() method usually generated when there's one manager protocol,
 // so both manager protocols implement this and we keep a reference to them
 // through this interface.
 class CompositableParentManager : public ISurfaceAllocator
                                 , public AsyncTransactionTrackersHolder
 {
 public:
-  virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
-                                        CompositableHost* aCompositableHost) = 0;
-
   virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
                                PTextureParent* aTexture,
                                const FenceHandle& aFence) = 0;
 
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) = 0;
 
-  void SendPendingAsyncMessges();
-
   /**
    * Get child side's process Id.
    */
   virtual base::ProcessId GetChildProcessId() = 0;
 
 protected:
   /**
    * Handle the IPDL messages that affect PCompositable actors.
@@ -57,15 +52,14 @@ protected:
   /**
    * Return true if this protocol is asynchronous with respect to the content
    * thread (ImageBridge for instance).
    */
   virtual bool IsAsync() const { return false; }
 
   virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) {}
 
-  std::vector<AsyncParentMessageData> mPendingAsyncMessage;
 };
 
 } // namespace
 } // namespace
 
 #endif
--- a/gfx/layers/ipc/FenceUtils.h
+++ b/gfx/layers/ipc/FenceUtils.h
@@ -21,17 +21,16 @@ namespace layers {
 
 struct FenceHandleFromChild;
 
 struct FenceHandle {
   FenceHandle() {}
   explicit FenceHandle(const FenceHandleFromChild& aFenceHandle) {}
   bool operator==(const FenceHandle&) const { return false; }
   bool IsValid() const { return false; }
-  void Merge(const FenceHandle& aFenceHandle) {}
 };
 
 struct FenceHandleFromChild {
   FenceHandleFromChild() {}
   explicit FenceHandleFromChild(const FenceHandle& aFence) {}
   bool operator==(const FenceHandle&) const { return false; }
   bool operator==(const FenceHandleFromChild&) const { return false; }
   bool IsValid() const { return false; }
--- a/gfx/layers/ipc/FenceUtilsGonk.cpp
+++ b/gfx/layers/ipc/FenceUtilsGonk.cpp
@@ -44,45 +44,38 @@ ParamTraits<FenceHandle>::Write(Message*
   // 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->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.
     aMsg->WriteFileDescriptor(FileDescriptor(fds[n], false));
   }
 }
 
 bool
 ParamTraits<FenceHandle>::Read(const Message* aMsg,
                                void** aIter, paramType* aResult)
 {
   size_t nbytes;
-  size_t nfds;
   const char* data;
 
   if (!aMsg->ReadSize(aIter, &nbytes) ||
-      !aMsg->ReadSize(aIter, &nfds) ||
       !aMsg->ReadBytes(aIter, &data, nbytes)) {
     return false;
   }
 
-  // Check if nfds is correct.
-  // aMsg->num_fds() could include fds of another ParamTraits<>s.
-  if (nfds > aMsg->num_fds()) {
-    return false;
-  }
+  size_t nfds = aMsg->num_fds();
   int fds[nfds];
 
   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
@@ -140,17 +133,16 @@ ParamTraits<FenceHandleFromChild>::Write
   // 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->WriteSize(nbytes);
-  aMsg->WriteSize(nfds);
   aMsg->WriteBytes(data, nbytes);
   for (size_t n = 0; n < nfds; ++n) {
     // If the Fence 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.
     bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default);
@@ -164,30 +156,24 @@ ParamTraits<FenceHandleFromChild>::Write
   }
 }
 
 bool
 ParamTraits<FenceHandleFromChild>::Read(const Message* aMsg,
                                         void** aIter, paramType* aResult)
 {
   size_t nbytes;
-  size_t nfds;
   const char* data;
 
   if (!aMsg->ReadSize(aIter, &nbytes) ||
-      !aMsg->ReadSize(aIter, &nfds) ||
       !aMsg->ReadBytes(aIter, &data, nbytes)) {
     return false;
   }
 
-  // Check if nfds is correct.
-  // aMsg->num_fds() could include fds of another ParamTraits<>s.
-  if (nfds > aMsg->num_fds()) {
-    return false;
-  }
+  size_t nfds = aMsg->num_fds();
   int fds[nfds];
 
   for (size_t n = 0; n < nfds; ++n) {
     FileDescriptor fd;
     if (!aMsg->ReadFileDescriptor(aIter, &fd)) {
       return false;
     }
     fds[n] = fd.fd;
@@ -220,39 +206,15 @@ FenceHandle::FenceHandle(const sp<Fence>
   : mFence(aFence)
 {
 }
 
 FenceHandle::FenceHandle(const FenceHandleFromChild& aFenceHandle) {
   mFence = aFenceHandle.mFence;
 }
 
-void
-FenceHandle::Merge(const FenceHandle& aFenceHandle)
-{
-  if (!aFenceHandle.IsValid()) {
-    return;
-  }
-
-  if (!IsValid()) {
-    mFence = aFenceHandle.mFence;
-  } else {
-    android::sp<android::Fence> mergedFence = android::Fence::merge(
-                  android::String8::format("FenceHandle"),
-                  mFence, aFenceHandle.mFence);
-    if (!mergedFence.get()) {
-      // synchronization is broken, the best we can do is hope fences
-      // signal in order so the new fence will act like a union.
-      // This error handling is same as android::ConsumerBase does.
-      mFence = aFenceHandle.mFence;
-      return;
-    }
-    mFence = mergedFence;
-  }
-}
-
 FenceHandleFromChild::FenceHandleFromChild(const sp<Fence>& aFence)
   : mFence(aFence)
 {
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/FenceUtilsGonk.h
+++ b/gfx/layers/ipc/FenceUtilsGonk.h
@@ -18,42 +18,40 @@ namespace layers {
 
 struct FenceHandleFromChild;
 
 struct FenceHandle {
   typedef android::Fence Fence;
 
   FenceHandle()
   { }
-  explicit FenceHandle(const android::sp<Fence>& aFence);
+  FenceHandle(const android::sp<Fence>& aFence);
 
-  explicit FenceHandle(const FenceHandleFromChild& aFenceHandle);
+  FenceHandle(const FenceHandleFromChild& aFenceHandle);
 
   bool operator==(const FenceHandle& aOther) const {
     return mFence.get() == aOther.mFence.get();
   }
 
   bool IsValid() const
   {
     return mFence.get() && mFence->isValid();
   }
 
-  void Merge(const FenceHandle& aFenceHandle);
-
   android::sp<Fence> mFence;
 };
 
 struct FenceHandleFromChild {
   typedef android::Fence Fence;
 
   FenceHandleFromChild()
   { }
-  explicit FenceHandleFromChild(const android::sp<Fence>& aFence);
+  FenceHandleFromChild(const android::sp<Fence>& aFence);
 
-  explicit FenceHandleFromChild(const FenceHandle& aFence) {
+  FenceHandleFromChild(const FenceHandle& aFence) {
     mFence = aFence.mFence;
   }
 
   bool operator==(const FenceHandle& aOther) const {
     return mFence.get() == aOther.mFence.get();
   }
 
   bool operator==(const FenceHandleFromChild& aOther) const {
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -91,35 +91,19 @@ ImageBridgeParent::GetCompositorBackendT
 void
 ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
 }
 
-class MOZ_STACK_CLASS AutoImageBridgeParentAsyncMessageSender
-{
-public:
-  explicit AutoImageBridgeParentAsyncMessageSender(ImageBridgeParent* aImageBridge)
-    : mImageBridge(aImageBridge) {}
-
-  ~AutoImageBridgeParentAsyncMessageSender()
-  {
-    mImageBridge->SendPendingAsyncMessges();
-  }
-private:
-  ImageBridgeParent* mImageBridge;
-};
-
 bool
 ImageBridgeParent::RecvUpdate(const EditArray& aEdits, EditReplyArray* aReply)
 {
-  AutoImageBridgeParentAsyncMessageSender autoAsyncMessageSender(this);
-
   // If we don't actually have a compositor, then don't bother
   // creating any textures.
   if (Compositor::GetBackend() == LayersBackend::LAYERS_NONE) {
     return true;
   }
 
   EditReplyVector replyv;
   for (EditArray::index_type i = 0; i < aEdits.Length(); ++i) {
@@ -347,119 +331,66 @@ ImageBridgeParent::CloneToplevel(const I
 bool ImageBridgeParent::IsSameProcess() const
 {
   return OtherProcess() == ipc::kInvalidProcessHandle;
 }
 
 void
 ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
 {
-  mPendingAsyncMessage.push_back(aReply);
+  InfallibleTArray<AsyncParentMessageData> messages;
+  messages.AppendElement(aReply);
+  mozilla::unused << SendParentAsyncMessages(messages);
 }
 
 /*static*/ void
 ImageBridgeParent::ReplyRemoveTexture(base::ProcessId aChildProcessId,
                                       const OpReplyRemoveTexture& aReply)
 {
   ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
   if (!imageBridge) {
     return;
   }
   imageBridge->ReplyRemoveTexture(aReply);
 }
 
-void
-ImageBridgeParent::SendFenceHandleIfPresent(PTextureParent* aTexture,
-                                            CompositableHost* aCompositableHost)
+/*static*/ void
+ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
+                                                     uint64_t aTransactionId,
+                                                     PTextureParent* aTexture)
 {
   RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
   if (!texture) {
     return;
   }
-
-  // Send a ReleaseFence of CompositorOGL.
-  if (aCompositableHost && aCompositableHost->GetCompositor()) {
-    FenceHandle fence = aCompositableHost->GetCompositor()->GetReleaseFence();
-    if (fence.IsValid()) {
-      RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
-      HoldUntilComplete(tracker);
-      mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
-                                                    aTexture, nullptr,
-                                                    fence));
-    }
-  }
-
-  // Send a ReleaseFence that is set by HwcComposer2D.
   FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
-  if (fence.IsValid()) {
-    RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
-    HoldUntilComplete(tracker);
-    mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
-                                                  aTexture, nullptr,
-                                                  fence));
-  }
-}
-
-void
-ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
-                                                     uint64_t aTransactionId,
-                                                     PTextureParent* aTexture,
-                                                     CompositableHost* aCompositableHost)
-{
-  RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
-  if (!texture) {
+  if (!fence.IsValid()) {
     return;
   }
 
-  // Send a ReleaseFence of CompositorOGL.
-  if (aCompositableHost && aCompositableHost->GetCompositor()) {
-    FenceHandle fence = aCompositableHost->GetCompositor()->GetReleaseFence();
-    if (fence.IsValid()) {
-      RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
-      HoldUntilComplete(tracker);
-      mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(tracker->GetId(),
-                                                             aDestHolderId,
-                                                             aTransactionId,
-                                                             fence));
-    }
-  }
-
-  // Send a ReleaseFence that is set by HwcComposer2D.
-  FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
-  if (fence.IsValid()) {
-    RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
-    HoldUntilComplete(tracker);
-    mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(tracker->GetId(),
-                                                           aDestHolderId,
-                                                           aTransactionId,
-                                                           fence));
-  }
+  RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
+  HoldUntilComplete(tracker);
+  InfallibleTArray<AsyncParentMessageData> messages;
+  messages.AppendElement(OpDeliverFenceToTracker(tracker->GetId(),
+                                                 aDestHolderId,
+                                                 aTransactionId,
+                                                 fence));
+  mozilla::unused << SendParentAsyncMessages(messages);
 }
 
 /*static*/ void
 ImageBridgeParent::SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
                                                      uint64_t aDestHolderId,
                                                      uint64_t aTransactionId,
-                                                     PTextureParent* aTexture,
-                                                     CompositableHost* aCompositableHost)
+                                                     PTextureParent* aTexture)
 {
   ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
   if (!imageBridge) {
     return;
   }
   imageBridge->SendFenceHandleToTrackerIfPresent(aDestHolderId,
                                                  aTransactionId,
-                                                 aTexture,
-                                                 aCompositableHost);
+                                                 aTexture);
 }
 
-/*static*/ void
-ImageBridgeParent::SendPendingAsyncMessges(base::ProcessId aChildProcessId)
-{
-  ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId);
-  if (!imageBridge) {
-    return;
-  }
-  imageBridge->SendPendingAsyncMessges();
-}
 
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -51,19 +51,16 @@ public:
   virtual LayersBackend GetCompositorBackendType() const MOZ_OVERRIDE;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   static PImageBridgeParent*
   Create(Transport* aTransport, ProcessId aChildProcessId);
 
   // CompositableParentManager
-  virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
-                                        CompositableHost* aCompositableHost) MOZ_OVERRIDE;
-
   virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
                                PTextureParent* aTexture,
                                const FenceHandle& aFence) MOZ_OVERRIDE;
 
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) MOZ_OVERRIDE;
 
   virtual base::ProcessId GetChildProcessId() MOZ_OVERRIDE
   {
@@ -120,27 +117,22 @@ public:
 
   virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) MOZ_OVERRIDE;
 
   static void ReplyRemoveTexture(base::ProcessId aChildProcessId,
                                  const OpReplyRemoveTexture& aReply);
 
   void SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
                                          uint64_t aTransactionId,
-                                         PTextureParent* aTexture,
-                                         CompositableHost* aCompositableHost);
+                                         PTextureParent* aTexture);
 
   static void SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
                                                 uint64_t aDestHolderId,
                                                 uint64_t aTransactionId,
-                                                PTextureParent* aTexture,
-                                                CompositableHost* aCompositableHost);
-
-  using CompositableParentManager::SendPendingAsyncMessges;
-  static void SendPendingAsyncMessges(base::ProcessId aChildProcessId);
+                                                PTextureParent* aTexture);
 
   static ImageBridgeParent* GetInstance(ProcessId aId);
 
   // Overriden from IToplevelProtocol
   IToplevelProtocol*
   CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
                 base::ProcessHandle aPeerProcess,
                 mozilla::ipc::ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -13,17 +13,16 @@
 #include "ShadowLayerParent.h"          // for ShadowLayerParent
 #include "CompositableTransactionParent.h"  // for EditReplyVector
 #include "ShadowLayersManager.h"        // for ShadowLayersManager
 #include "mozilla/gfx/BasePoint3D.h"    // for BasePoint3D
 #include "mozilla/layers/CanvasLayerComposite.h"
 #include "mozilla/layers/ColorLayerComposite.h"
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/ContainerLayerComposite.h"
-#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
 #include "mozilla/layers/ImageLayerComposite.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferParent
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
 #include "mozilla/layers/PCompositableParent.h"
 #include "mozilla/layers/PLayerParent.h"  // for PLayerParent
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
@@ -188,31 +187,16 @@ LayerTransactionParent::RecvUpdateNoSwap
                                          const bool& isRepeatTransaction,
                                          const mozilla::TimeStamp& aTransactionStart)
 {
   return RecvUpdate(cset, aTransactionId, targetConfig, isFirstPaint,
       scheduleComposite, paintSequenceNumber, isRepeatTransaction,
       aTransactionStart, nullptr);
 }
 
-class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender
-{
-public:
-  explicit AutoLayerTransactionParentAsyncMessageSender(LayerTransactionParent* aLayerTransaction)
-    : mLayerTransaction(aLayerTransaction) {}
-
-  ~AutoLayerTransactionParentAsyncMessageSender()
-  {
-    mLayerTransaction->SendPendingAsyncMessges();
-    ImageBridgeParent::SendPendingAsyncMessges(mLayerTransaction->GetChildProcessId());
-  }
-private:
-  LayerTransactionParent* mLayerTransaction;
-};
-
 bool
 LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
                                    const uint64_t& aTransactionId,
                                    const TargetConfig& targetConfig,
                                    const bool& isFirstPaint,
                                    const bool& scheduleComposite,
                                    const uint32_t& paintSequenceNumber,
                                    const bool& isRepeatTransaction,
@@ -234,17 +218,16 @@ LayerTransactionParent::RecvUpdate(const
   }
 
   if (mLayerManager && mLayerManager->GetCompositor() &&
       !targetConfig.naturalBounds().IsEmpty()) {
     mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
   }
 
   EditReplyVector replyv;
-  AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this);
 
   {
     AutoResolveRefLayers resolve(mShadowLayersManager->GetCompositionManager(this));
     layer_manager()->BeginTransaction();
   }
 
   for (EditArray::index_type i = 0; i < cset.Length(); ++i) {
     const Edit& edit = cset[i];
@@ -902,48 +885,16 @@ LayerTransactionParent::ActorDestroy(Act
 }
 
 bool LayerTransactionParent::IsSameProcess() const
 {
   return OtherProcess() == ipc::kInvalidProcessHandle;
 }
 
 void
-LayerTransactionParent::SendFenceHandleIfPresent(PTextureParent* aTexture,
-                                                 CompositableHost* aCompositableHost)
-{
-  RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
-  if (!texture) {
-    return;
-  }
-
-  // Send a ReleaseFence of CompositorOGL.
-  if (aCompositableHost && aCompositableHost->GetCompositor()) {
-    FenceHandle fence = aCompositableHost->GetCompositor()->GetReleaseFence();
-    if (fence.IsValid()) {
-      RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
-      HoldUntilComplete(tracker);
-      mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
-                                                    aTexture, nullptr,
-                                                    fence));
-    }
-  }
-
-  // Send a ReleaseFence that is set by HwcComposer2D.
-  FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
-  if (fence.IsValid()) {
-    RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
-    HoldUntilComplete(tracker);
-    mPendingAsyncMessage.push_back(OpDeliverFence(tracker->GetId(),
-                                                  aTexture, nullptr,
-                                                  fence));
-  }
-}
-
-void
 LayerTransactionParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
                                         PTextureParent* aTexture,
                                         const FenceHandle& aFence)
 {
   HoldUntilComplete(aTracker);
   InfallibleTArray<AsyncParentMessageData> messages;
   messages.AppendElement(OpDeliverFence(aTracker->GetId(),
                                         aTexture, nullptr,
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -81,19 +81,16 @@ public:
   virtual LayersBackend GetCompositorBackendType() const MOZ_OVERRIDE;
 
   virtual bool IsSameProcess() const MOZ_OVERRIDE;
 
   const uint64_t& GetPendingTransactionId() { return mPendingTransaction; }
   void SetPendingTransactionId(uint64_t aId) { mPendingTransaction = aId; }
 
   // CompositableParentManager
-  virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,
-                                        CompositableHost* aCompositableHost) MOZ_OVERRIDE;
-
   virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
                                PTextureParent* aTexture,
                                const FenceHandle& aFence) MOZ_OVERRIDE;
 
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) MOZ_OVERRIDE;
 
   virtual base::ProcessId GetChildProcessId() MOZ_OVERRIDE
   {
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -1393,43 +1393,59 @@ CompositorOGL::SetFBAcquireFence(Layer* 
   // FBAcquireFence is FramebufferSurface's AcquireFence.
   // AcquireFence will be signaled when a buffer's content is available.
   // See Bug 974152.
 
   if (!aLayer) {
     return;
   }
 
-  android::sp<android::Fence> fence = new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd());
-  if (fence.get() && fence->isValid()) {
-    FenceHandle handle = FenceHandle(fence);
-    mReleaseFenceHandle.Merge(handle);
+  const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
+  if (visibleRegion.IsEmpty()) {
+      return;
   }
-}
+
+  // Set FBAcquireFence on ContainerLayer's childs
+  ContainerLayer* container = aLayer->AsContainerLayer();
+  if (container) {
+    for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
+      SetFBAcquireFence(child);
+    }
+    return;
+  }
 
-FenceHandle
-CompositorOGL::GetReleaseFence()
-{
-  if (!mReleaseFenceHandle.IsValid()) {
-    return FenceHandle();
+  // Set FBAcquireFence as tiles' ReleaseFence on TiledLayerComposer.
+  TiledLayerComposer* composer = nullptr;
+  LayerComposite* shadow = aLayer->AsLayerComposite();
+  // Only ask for the composer if we have a compositable host. Timing
+  // may make it so that we don't - see bug 1000634.
+  if (shadow && shadow->GetCompositableHost()) {
+    composer = shadow->GetTiledLayerComposer();
+    if (composer) {
+      composer->SetReleaseFence(new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd()));
+      return;
+    }
   }
-  return FenceHandle(new android::Fence(mReleaseFenceHandle.mFence->dup()));
+
+  // Set FBAcquireFence as layer buffer's ReleaseFence
+  LayerRenderState state = aLayer->GetRenderState();
+  if (!state.mTexture) {
+    return;
+  }
+  TextureHostOGL* texture = state.mTexture->AsHostOGL();
+  if (!texture) {
+    return;
+  }
+  texture->SetReleaseFence(new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd()));
 }
-
 #else
 void
 CompositorOGL::SetFBAcquireFence(Layer* aLayer)
 {
 }
-
-FenceHandle
-CompositorOGL::GetReleaseFence()
-{
-  return FenceHandle();
-}
 #endif
 
 void
 CompositorOGL::EndFrameForExternalComposition(const gfx::Matrix& aTransform)
 {
   // This lets us reftest and screenshot content rendered externally
   if (mTarget) {
     MakeCurrent();
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -204,17 +204,16 @@ public:
   virtual void DrawQuad(const gfx::Rect& aRect,
                         const gfx::Rect& aClipRect,
                         const EffectChain &aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE;
 
   virtual void EndFrame() MOZ_OVERRIDE;
   virtual void SetFBAcquireFence(Layer* aLayer) MOZ_OVERRIDE;
-  virtual FenceHandle GetReleaseFence() MOZ_OVERRIDE;
   virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) MOZ_OVERRIDE;
   virtual void AbortFrame() MOZ_OVERRIDE;
 
   virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE;
 
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) MOZ_OVERRIDE
   {
     if (!mGLContext)
@@ -389,16 +388,14 @@ private:
 
   bool mDestroyed;
 
   /**
    * Height of the OpenGL context's primary framebuffer in pixels. Used by
    * FlipY for the y-flipping calculation.
    */
   GLint mHeight;
-
-  FenceHandle mReleaseFenceHandle;
 };
 
 }
 }
 
 #endif /* MOZILLA_GFX_COMPOSITOROGL_H */