Bug 1146214 - Implement fence delivery. Combine ipc messages and remove reply fence delivery message. r=nical
authorEthan Lin <etlin@mozilla.com>
Fri, 10 Apr 2015 02:19:00 +0200
changeset 239700 7ff2d1f3a2c27336ef78c79f129ea340be0b89a3
parent 239699 0af24986e84357eda91521228114c6d77a83564e
child 239701 ef36caa16cf31bc12898ad20cd164bc6cb0265b4
push id28606
push userryanvm@gmail.com
push dateFri, 17 Apr 2015 19:45:37 +0000
treeherdermozilla-central@a55f9bdb2bf4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1146214
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1146214 - Implement fence delivery. Combine ipc messages and remove reply fence delivery message. r=nical
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/ipc/CompositableTransactionParent.cpp
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/LayerTransactionChild.cpp
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/opengl/GrallocTextureHost.cpp
gfx/layers/opengl/GrallocTextureHost.h
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -144,28 +144,16 @@ PTextureParent*
 TextureHost::GetIPDLActor()
 {
   return mActor;
 }
 
 FenceHandle
 TextureHost::GetAndResetReleaseFenceHandle()
 {
-#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
-  TextureHostOGL* hostOGL = this->AsHostOGL();
-  if (!hostOGL) {
-    return FenceHandle();
-  }
-
-  android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
-  if (fence.get() && fence->isValid()) {
-    FenceHandle handle = FenceHandle(fence);
-    return handle;
-  }
-#endif
   return FenceHandle();
 }
 
 // implemented in TextureHostOGL.cpp
 TemporaryRef<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
                                                ISurfaceAllocator* aDeallocator,
                                                TextureFlags aFlags);
 
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -468,17 +468,17 @@ public:
   /**
    * Return a pointer to the IPDLActor.
    *
    * This is to be used with IPDL messages only. Do not store the returned
    * pointer.
    */
   PTextureParent* GetIPDLActor();
 
-  FenceHandle GetAndResetReleaseFenceHandle();
+  virtual FenceHandle GetAndResetReleaseFenceHandle();
 
   /**
    * Specific to B2G's Composer2D
    * XXX - more doc here
    */
   virtual LayerRenderState GetRenderState()
   {
     // By default we return an empty render state, this should be overridden
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -151,37 +151,48 @@ CompositableParentManager::ReceiveCompos
                              op.transactionId(),
                              op.textureParent(),
                              compositable);
 
         // If the message is recievied via PLayerTransaction,
         // Send message back via PImageBridge.
         ImageBridgeParent::ReplyRemoveTexture(
                              GetChildProcessId(),
-                             OpReplyRemoveTexture(true, // isMain
-                                                  op.holderId(),
+                             OpReplyRemoveTexture(op.holderId(),
                                                   op.transactionId()));
       } else {
         // send FenceHandle if present.
         SendFenceHandleIfPresent(op.textureParent(), compositable);
 
-        ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain
-                                                op.holderId(),
+        ReplyRemoveTexture(OpReplyRemoveTexture(op.holderId(),
                                                 op.transactionId()));
       }
       break;
     }
     case CompositableOperation::TOpUseTexture: {
       const OpUseTexture& op = aEdit.get_OpUseTexture();
       CompositableHost* compositable = AsCompositable(op);
       RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
 
       MOZ_ASSERT(tex.get());
       compositable->UseTextureHost(tex);
 
+      MaybeFence maybeFence = op.fence();
+      if (maybeFence.type() == MaybeFence::TFenceHandle) {
+        FenceHandle fence = maybeFence.get_FenceHandle();
+        if (fence.IsValid() && tex) {
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
+          TextureHostOGL* hostOGL = tex->AsHostOGL();
+          if (hostOGL) {
+            hostOGL->SetAcquireFence(fence.mFence);
+          }
+#endif
+        }
+      }
+
       if (IsAsync() && compositable->GetLayer()) {
         ScheduleComposition(op);
         // Async layer updates don't trigger invalidation, manually tell the layer
         // that its content have changed.
         compositable->GetLayer()->SetInvalidRectToVisibleRegion();
       }
       break;
     }
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -108,25 +108,21 @@ struct AutoEndTransaction {
 void
 ImageBridgeChild::UseTexture(CompositableClient* aCompositable,
                              TextureClient* aTexture)
 {
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aTexture);
   MOZ_ASSERT(aCompositable->GetIPDLActor());
   MOZ_ASSERT(aTexture->GetIPDLActor());
-#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
-  FenceHandle handle = aTexture->GetAcquireFenceHandle();
-  if (handle.IsValid()) {
-    RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle);
-    SendFenceHandle(tracker, aTexture->GetIPDLActor(), handle);
-  }
-#endif
+
+  FenceHandle fence = aTexture->GetAcquireFenceHandle();
   mTxn->AddNoSwapEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
-                                   nullptr, aTexture->GetIPDLActor()));
+                                   nullptr, aTexture->GetIPDLActor(),
+                                   fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t())));
 }
 
 void
 ImageBridgeChild::UseComponentAlphaTextures(CompositableClient* aCompositable,
                                             TextureClient* aTextureOnBlack,
                                             TextureClient* aTextureOnWhite)
 {
   MOZ_ASSERT(aCompositable);
@@ -151,20 +147,18 @@ ImageBridgeChild::UseOverlaySource(Compo
 }
 #endif
 
 void
 ImageBridgeChild::SendFenceHandle(AsyncTransactionTracker* aTracker,
                                   PTextureChild* aTexture,
                                   const FenceHandle& aFence)
 {
-  HoldUntilComplete(aTracker);
   InfallibleTArray<AsyncChildMessageData> messages;
-  messages.AppendElement(OpDeliverFenceFromChild(aTracker->GetId(),
-                                                 nullptr, aTexture,
+  messages.AppendElement(OpDeliverFenceFromChild(nullptr, aTexture,
                                                  aFence));
   SendChildAsyncMessages(messages);
 }
 
 void
 ImageBridgeChild::UpdatePictureRect(CompositableClient* aCompositable,
                                     const nsIntRect& aRect)
 {
@@ -830,35 +824,25 @@ ImageBridgeChild::RecvParentAsyncMessage
         const OpDeliverFence& op = message.get_OpDeliverFence();
         FenceHandle fence = op.fence();
         PTextureChild* child = op.textureChild();
 
         RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
         if (texture) {
           texture->SetReleaseFenceHandle(fence);
         }
-        HoldTransactionsToRespond(op.transactionId());
         break;
       }
       case AsyncParentMessageData::TOpDeliverFenceToTracker: {
         const OpDeliverFenceToTracker& op = message.get_OpDeliverFenceToTracker();
         FenceHandle fence = op.fence();
 
         AsyncTransactionTrackersHolder::SetReleaseFenceHandle(fence,
                                                               op.destHolderId(),
                                                               op.destTransactionId());
-        // Send back a response.
-        InfallibleTArray<AsyncChildMessageData> replies;
-        replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
-        SendChildAsyncMessages(replies);
-        break;
-      }
-      case AsyncParentMessageData::TOpReplyDeliverFence: {
-        const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
-        TransactionCompleteted(op.transactionId());
         break;
       }
       case AsyncParentMessageData::TOpReplyRemoveTexture: {
         const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
 
         AsyncTransactionTrackersHolder::TransactionCompleteted(op.holderId(),
                                                                op.transactionId());
         break;
@@ -943,24 +927,12 @@ void ImageBridgeChild::RemoveTexture(Tex
 
 bool ImageBridgeChild::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
 }
 
 void ImageBridgeChild::SendPendingAsyncMessges()
 {
-  if (!IsCreated() ||
-      mTransactionsToRespond.empty()) {
-    return;
-  }
-  // Send OpReplyDeliverFence messages
-  InfallibleTArray<AsyncChildMessageData> replies;
-  replies.SetCapacity(mTransactionsToRespond.size());
-  for (size_t i = 0; i < mTransactionsToRespond.size(); i++) {
-    replies.AppendElement(OpReplyDeliverFence(mTransactionsToRespond[i]));
-  }
-  mTransactionsToRespond.clear();
-  SendChildAsyncMessages(replies);
 }
 
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -242,20 +242,18 @@ ImageBridgeParent::DeallocPTextureParent
   return TextureHost::DestroyIPDLActor(actor);
 }
 
 void
 ImageBridgeParent::SendFenceHandle(AsyncTransactionTracker* aTracker,
                                    PTextureParent* aTexture,
                                    const FenceHandle& aFence)
 {
-  HoldUntilComplete(aTracker);
   InfallibleTArray<AsyncParentMessageData> messages;
-  messages.AppendElement(OpDeliverFence(aTracker->GetId(),
-                                        aTexture, nullptr,
+  messages.AppendElement(OpDeliverFence(aTexture, nullptr,
                                         aFence));
   mozilla::unused << SendParentAsyncMessages(messages);
 }
 
 void
 ImageBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
 {
   mozilla::unused << SendParentAsyncMessages(aMessage);
@@ -278,25 +276,16 @@ ImageBridgeParent::RecvChildAsyncMessage
         RefPtr<TextureHost> texture = TextureHost::AsTextureHost(parent);
         if (texture) {
           hostOGL = texture->AsHostOGL();
         }
         if (hostOGL) {
           hostOGL->SetAcquireFence(fence.mFence);
         }
 #endif
-        // Send back a response.
-        InfallibleTArray<AsyncParentMessageData> replies;
-        replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
-        mozilla::unused << SendParentAsyncMessages(replies);
-        break;
-      }
-      case AsyncChildMessageData::TOpReplyDeliverFence: {
-        const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
-        TransactionCompleteted(op.transactionId());
         break;
       }
       default:
         NS_ERROR("unknown AsyncChildMessageData type");
         return false;
     }
   }
   return true;
@@ -368,31 +357,25 @@ ImageBridgeParent::SendFenceHandleIfPres
   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,
+      mPendingAsyncMessage.push_back(OpDeliverFence(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,
+    mPendingAsyncMessage.push_back(OpDeliverFence(aTexture, nullptr,
                                                   fence));
   }
 }
 
 void
 ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
                                                      uint64_t aTransactionId,
                                                      PTextureParent* aTexture,
@@ -402,32 +385,26 @@ ImageBridgeParent::SendFenceHandleToTrac
   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(OpDeliverFenceToTracker(tracker->GetId(),
-                                                             aDestHolderId,
+      mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(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,
+    mPendingAsyncMessage.push_back(OpDeliverFenceToTracker(aDestHolderId,
                                                            aTransactionId,
                                                            fence));
   }
 }
 
 /*static*/ void
 ImageBridgeParent::SendFenceHandleToTrackerIfPresent(base::ProcessId aChildProcessId,
                                                      uint64_t aDestHolderId,
--- a/gfx/layers/ipc/LayerTransactionChild.cpp
+++ b/gfx/layers/ipc/LayerTransactionChild.cpp
@@ -85,29 +85,16 @@ LayerTransactionChild::RecvParentAsyncMe
         const OpDeliverFence& op = message.get_OpDeliverFence();
         FenceHandle fence = op.fence();
         PTextureChild* child = op.textureChild();
 
         RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
         if (texture) {
           texture->SetReleaseFenceHandle(fence);
         }
-        if (mForwarder) {
-          mForwarder->HoldTransactionsToRespond(op.transactionId());
-        } else {
-          // Send back a response.
-          InfallibleTArray<AsyncChildMessageData> replies;
-          replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
-          SendChildAsyncMessages(replies);
-        }
-        break;
-      }
-      case AsyncParentMessageData::TOpReplyDeliverFence: {
-        const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
-        TransactionCompleteted(op.transactionId());
         break;
       }
       case AsyncParentMessageData::TOpReplyRemoveTexture: {
         const OpReplyRemoveTexture& op = message.get_OpReplyRemoveTexture();
 
         AsyncTransactionTrackersHolder::TransactionCompleteted(op.holderId(),
                                                                op.transactionId());
         break;
@@ -120,20 +107,18 @@ LayerTransactionChild::RecvParentAsyncMe
   return true;
 }
 
 void
 LayerTransactionChild::SendFenceHandle(AsyncTransactionTracker* aTracker,
                                        PTextureChild* aTexture,
                                        const FenceHandle& aFence)
 {
-  HoldUntilComplete(aTracker);
   InfallibleTArray<AsyncChildMessageData> messages;
-  messages.AppendElement(OpDeliverFenceFromChild(aTracker->GetId(),
-                                                 nullptr, aTexture,
+  messages.AppendElement(OpDeliverFenceFromChild(nullptr, aTexture,
                                                  aFence));
   SendChildAsyncMessages(messages);
 }
 
 void
 LayerTransactionChild::ActorDestroy(ActorDestroyReason why)
 {
   mDestroyed = true;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -924,25 +924,16 @@ LayerTransactionParent::RecvChildAsyncMe
         RefPtr<TextureHost> texture = TextureHost::AsTextureHost(parent);
         if (texture) {
           hostOGL = texture->AsHostOGL();
         }
         if (hostOGL) {
           hostOGL->SetAcquireFence(fence.mFence);
         }
 #endif
-        // Send back a response.
-        InfallibleTArray<AsyncParentMessageData> replies;
-        replies.AppendElement(OpReplyDeliverFence(op.transactionId()));
-        mozilla::unused << SendParentAsyncMessages(replies);
-        break;
-      }
-      case AsyncChildMessageData::TOpReplyDeliverFence: {
-        const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence();
-        TransactionCompleteted(op.transactionId());
         break;
       }
       case AsyncChildMessageData::TOpRemoveTextureAsync: {
         const OpRemoveTextureAsync& op = message.get_OpRemoveTextureAsync();
         CompositableHost* compositable = CompositableHost::FromIPDLActor(op.compositableParent());
         RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
 
         MOZ_ASSERT(tex.get());
@@ -955,19 +946,18 @@ LayerTransactionParent::RecvChildAsyncMe
             GetChildProcessId(),
             op.holderId(),
             op.transactionId(),
             op.textureParent(),
             compositable);
           // Send message back via PImageBridge.
           ImageBridgeParent::ReplyRemoveTexture(
             GetChildProcessId(),
-            OpReplyRemoveTexture(true, // isMain
-            op.holderId(),
-            op.transactionId()));
+            OpReplyRemoveTexture(op.holderId(),
+                                 op.transactionId()));
         } else {
           NS_ERROR("ImageBridgeParent should exist");
         }
         break;
       }
       default:
         NS_ERROR("unknown AsyncChildMessageData type");
         return false;
@@ -995,44 +985,36 @@ LayerTransactionParent::SendFenceHandleI
   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,
+      mPendingAsyncMessage.push_back(OpDeliverFence(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,
+    mPendingAsyncMessage.push_back(OpDeliverFence(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,
+  messages.AppendElement(OpDeliverFence(aTexture, nullptr,
                                         aFence));
   mozilla::unused << SendParentAsyncMessages(messages);
 }
 
 void
 LayerTransactionParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
 {
   mozilla::unused << SendParentAsyncMessages(aMessage);
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -362,64 +362,62 @@ struct OpRemoveTexture {
 struct OpRemoveTextureAsync {
   uint64_t holderId;
   uint64_t transactionId;
   PCompositable compositable;
   PTexture texture;
 };
 
 struct OpReplyRemoveTexture {
-  bool isMain;
   uint64_t holderId;
   uint64_t transactionId;
 };
 
+union MaybeFence {
+  FenceHandle;
+  null_t;
+};
+
 /**
  * Tells the compositor-side which texture to use (for example, as front buffer
  * if there is several textures for double buffering)
  */
 struct OpUseTexture {
   PCompositable compositable;
   PTexture texture;
+  MaybeFence fence;
 };
 
 struct OpUseComponentAlphaTextures {
   PCompositable compositable;
   PTexture textureOnBlack;
   PTexture textureOnWhite;
 };
 
 union MaybeRegion {
   nsIntRegion;
   null_t;
 };
 
 struct OpDeliverFence {
-  uint64_t transactionId;
   PTexture texture;
   FenceHandle fence;
 };
 
 struct OpDeliverFenceToTracker {
-  uint64_t transactionId;
   uint64_t destHolderId;
   uint64_t destTransactionId;
   FenceHandle fence;
 };
 
 struct OpDeliverFenceFromChild {
-  uint64_t transactionId;
   PTexture texture;
   FenceHandle fence;
 };
 
-struct OpReplyDeliverFence {
-  uint64_t transactionId;
-};
-
 union CompositableOperation {
   OpUpdatePictureRect;
 
   OpPaintTextureRegion;
 
   OpUseTiledLayerBuffer;
 
   OpRemoveTexture;
@@ -475,20 +473,18 @@ union EditReply {
   OpContentBufferSwap;
 
   ReturnReleaseFence;
 };
 
 union AsyncParentMessageData {
   OpDeliverFence;
   OpDeliverFenceToTracker;
-  OpReplyDeliverFence;
   OpReplyRemoveTexture;
 };
 
 union AsyncChildMessageData {
   OpDeliverFenceFromChild;
-  OpReplyDeliverFence;
   OpRemoveTextureAsync;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -364,25 +364,21 @@ ShadowLayerForwarder::UpdatePictureRect(
 void
 ShadowLayerForwarder::UseTexture(CompositableClient* aCompositable,
                                  TextureClient* aTexture)
 {
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aTexture);
   MOZ_ASSERT(aCompositable->GetIPDLActor());
   MOZ_ASSERT(aTexture->GetIPDLActor());
-#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
-  FenceHandle handle = aTexture->GetAcquireFenceHandle();
-  if (handle.IsValid()) {
-    RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle);
-    SendFenceHandle(tracker, aTexture->GetIPDLActor(), handle);
-  }
-#endif
+
+  FenceHandle fence = aTexture->GetAcquireFenceHandle();
   mTxn->AddEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
-                             nullptr, aTexture->GetIPDLActor()));
+                             nullptr, aTexture->GetIPDLActor(),
+                             fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t())));
   if (aTexture->GetFlags() & TextureFlags::IMMEDIATE_UPLOAD
       && aTexture->HasInternalBuffer()) {
     // We use IMMEDIATE_UPLOAD when we want to be sure that the upload cannot
     // race with updates on the main thread. In this case we want the transaction
     // to be synchronous.
     mTxn->MarkSyncTransaction();
   }
 }
@@ -850,32 +846,25 @@ void ShadowLayerForwarder::Composite()
   }
   mShadowManager->SendForceComposite();
 }
 
 void ShadowLayerForwarder::SendPendingAsyncMessges()
 {
   if (!HasShadowManager() ||
       !mShadowManager->IPCOpen()) {
-    mTransactionsToRespond.clear();
     mPendingAsyncMessages.clear();
     return;
   }
 
-  if (mTransactionsToRespond.empty() && mPendingAsyncMessages.empty()) {
+  if (mPendingAsyncMessages.empty()) {
     return;
   }
 
   InfallibleTArray<AsyncChildMessageData> replies;
-  replies.SetCapacity(mTransactionsToRespond.size());
-  // Prepare OpReplyDeliverFence messages.
-  for (size_t i = 0; i < mTransactionsToRespond.size(); i++) {
-    replies.AppendElement(OpReplyDeliverFence(mTransactionsToRespond[i]));
-  }
-  mTransactionsToRespond.clear();
   // Prepare pending messages.
   for (size_t i = 0; i < mPendingAsyncMessages.size(); i++) {
     replies.AppendElement(mPendingAsyncMessages[i]);
   }
   mPendingAsyncMessages.clear();
   mShadowManager->SendChildAsyncMessages(replies);
 }
 
--- a/gfx/layers/opengl/GrallocTextureHost.cpp
+++ b/gfx/layers/opengl/GrallocTextureHost.cpp
@@ -255,16 +255,29 @@ GrallocTextureHostOGL::UnbindTextureSour
   // detached, Although decreasing the refcount of the TextureSource may lead
   // to the gl handle being destroyed, which would unlock the gralloc buffer.
   // That said, this method is called before another TextureHost attaches to the
   // TextureSource, which has the effect of unlocking the gralloc buffer. So when
   // this is called we know we are going to be unlocked soon.
   mGLTextureSource = nullptr;
 }
 
+FenceHandle
+GrallocTextureHostOGL::GetAndResetReleaseFenceHandle()
+{
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
+  android::sp<android::Fence> fence = GetAndResetReleaseFence();
+  if (fence.get() && fence->isValid()) {
+    FenceHandle handle = FenceHandle(fence);
+    return handle;
+  }
+#endif
+  return FenceHandle();
+}
+
 GLenum GetTextureTarget(gl::GLContext* aGL, android::PixelFormat aFormat) {
   MOZ_ASSERT(aGL);
   if (aGL->Renderer() == gl::GLRenderer::SGX530 ||
       aGL->Renderer() == gl::GLRenderer::SGX540) {
     // SGX has a quirk that only TEXTURE_EXTERNAL works and any other value will
     // result in black pixels when trying to draw from bound textures.
     // Unfortunately, using TEXTURE_EXTERNAL on Adreno has a terrible effect on
     // performance.
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -48,16 +48,18 @@ public:
   virtual LayerRenderState GetRenderState() override;
 
   virtual void PrepareTextureSource(CompositableTextureSourceRef& aTextureSource) override;
 
   virtual bool BindTextureSource(CompositableTextureSourceRef& aTextureSource) override;
 
   virtual void UnbindTextureSource() override;
 
+  virtual FenceHandle GetAndResetReleaseFenceHandle() override;
+
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   virtual TextureHostOGL* AsHostOGL() override
   {
     return this;
   }
 #endif
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() override;