bool
LayerTransactionChild::RecvParentAsyncMessage(const mozilla::layers::AsyncParentMessageData& aMessage)
{
  switch (aMessage.type()) {
    case AsyncParentMessageData::TOpDeliverFence: {
      const OpDeliverFence& op = aMessage.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;
    }
    default:
      NS_ERROR("unknown AsyncParentMessageData type");
      return false;
  }
  return true;
}
bool
LayerTransactionParent::RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages)
{
  for (AsyncChildMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
    const AsyncChildMessageData& message = aMessages[i];

    switch (message.type()) {
      case AsyncChildMessageData::TOpDeliverFenceFromChild: {
        const OpDeliverFenceFromChild& op = message.get_OpDeliverFenceFromChild();
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
        FenceHandle fence = FenceHandle(op.fence());
        PTextureParent* parent = op.textureParent();

        TextureHostOGL* hostOGL = nullptr;
        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;
}
bool
LayerTransactionChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages)
{
  for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
    const AsyncParentMessageData& message = aMessages[i];

    switch (message.type()) {
      case AsyncParentMessageData::TOpDeliverFence: {
        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;
      }
      default:
        NS_ERROR("unknown AsyncParentMessageData type");
        return false;
    }
  }
  return true;
}