예제 #1
0
void
ParamTraits<FenceHandle>::Write(Message* aMsg,
                                const paramType& aParam)
{
  FenceHandle handle = aParam;

  MOZ_ASSERT(handle.IsValid());

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
  RefPtr<FenceHandle::FdObj> fence = handle.GetAndResetFdObj();
  aMsg->WriteFileDescriptor(base::FileDescriptor(fence->GetAndResetFd(), true));
#endif
}
예제 #2
0
bool
TextureHost::SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle)
{
  if (!aReleaseFenceHandle.IsValid()) {
    // HWC might not provide Fence.
    // In this case, HWC implicitly handles buffer's fence.
    return false;
  }

  mReleaseFenceHandle.Merge(aReleaseFenceHandle);

  return true;
}
예제 #3
0
bool
HwcComposer2D::Commit(nsScreenGonk* aScreen)
{
    for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) {
        mList->hwLayers[j].acquireFenceFd = -1;
        if (mHwcLayerMap.IsEmpty() ||
            (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER)) {
            continue;
        }
        LayerRenderState state = mHwcLayerMap[j]->GetLayer()->GetRenderState();
        if (!state.mTexture) {
            continue;
        }
        FenceHandle fence = state.mTexture->GetAndResetAcquireFenceHandle();
        if (fence.IsValid()) {
            RefPtr<FenceHandle::FdObj> fdObj = fence.GetAndResetFdObj();
            mList->hwLayers[j].acquireFenceFd = fdObj->GetAndResetFd();
        }
    }

    int err = mHal->Set(mList, aScreen->GetDisplayType());

    mPrevRetireFence.TransferToAnotherFenceHandle(mPrevDisplayFence);

    for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) {
        if (mList->hwLayers[j].releaseFenceFd >= 0) {
            int fd = mList->hwLayers[j].releaseFenceFd;
            mList->hwLayers[j].releaseFenceFd = -1;
            RefPtr<FenceHandle::FdObj> fdObj = new FenceHandle::FdObj(fd);
            FenceHandle fence(fdObj);

            LayerRenderState state = mHwcLayerMap[j]->GetLayer()->GetRenderState();
            if (!state.mTexture) {
                continue;
            }
            state.mTexture->SetReleaseFenceHandle(fence);
        }
    }

    if (mList->retireFenceFd >= 0) {
        mPrevRetireFence = FenceHandle(new FenceHandle::FdObj(mList->retireFenceFd));
    }

    // Set DisplaySurface layer fence
    DisplaySurface* displaySurface = aScreen->GetDisplaySurface();
    displaySurface->setReleaseFenceFd(mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd);
    mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd = -1;

    mPrepared = false;
    return !err;
}
예제 #4
0
void
FenceHandle::Merge(const FenceHandle& aFenceHandle)
{
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
  if (!aFenceHandle.IsValid()) {
    return;
  }

  if (!IsValid()) {
    mFence = aFenceHandle.mFence;
  } else {
    int result = sync_merge("FenceHandle", mFence->mFd, aFenceHandle.mFence->mFd);
    if (result == -1) {
      mFence = aFenceHandle.mFence;
    } else {
      mFence = new FdObj(result);
    }
  }
#endif
}
예제 #5
0
/*static*/ void
ImageBridgeParent::SendFenceHandleToTrackerIfPresent(uint64_t aDestHolderId,
                                                     uint64_t aTransactionId,
                                                     PTextureParent* aTexture)
{
  RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
  if (!texture) {
    return;
  }
  FenceHandle fence = texture->GetAndResetReleaseFenceHandle();
  if (!fence.IsValid()) {
    return;
  }

  RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(fence);
  HoldUntilComplete(tracker);
  InfallibleTArray<AsyncParentMessageData> messages;
  messages.AppendElement(OpDeliverFenceToTracker(tracker->GetId(),
                                                 aDestHolderId,
                                                 aTransactionId,
                                                 fence));
  mozilla::unused << SendParentAsyncMessages(messages);
}
예제 #6
0
void
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
{
    if (mForwarder->GetSyncObject()) {
        mForwarder->GetSyncObject()->FinalizeFrame();
    }

    mPhase = PHASE_FORWARD;

    mLatestTransactionId = mTransactionIdAllocator->GetTransactionId();
    TimeStamp transactionStart;
    if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) {
        transactionStart = mTransactionIdAllocator->GetTransactionStart();
    } else {
        transactionStart = mTransactionStart;
    }

    // forward this transaction's changeset to our LayerManagerComposite
    bool sent;
    AutoInfallibleTArray<EditReply, 10> replies;
    if (mForwarder->EndTransaction(&replies, mRegionToClear,
                                   mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber,
                                   mIsRepeatTransaction, transactionStart, &sent)) {
        for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
            const EditReply& reply = replies[i];

            switch (reply.type()) {
            case EditReply::TOpContentBufferSwap: {
                MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));

                const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();

                CompositableClient* compositable =
                    CompositableClient::FromIPDLActor(obs.compositableChild());
                ContentClientRemote* contentClient =
                    static_cast<ContentClientRemote*>(compositable);
                MOZ_ASSERT(contentClient);

                contentClient->SwapBuffers(obs.frontUpdatedRegion());

                break;
            }
            case EditReply::TReturnReleaseFence: {
                const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence();
                FenceHandle fence = rep.fence();
                PTextureChild* child = rep.textureChild();

                if (!fence.IsValid() || !child) {
                    break;
                }
                RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
                if (texture) {
                    texture->SetReleaseFenceHandle(fence);
                }
                break;
            }

            default:
                NS_RUNTIMEABORT("not reached");
            }
        }

        if (sent) {
            mNeedsComposite = false;
        }
    } else if (HasShadowManager()) {
        NS_WARNING("failed to forward Layers transaction");
    }

    if (!sent) {
        // Clear the transaction id so that it doesn't get returned
        // unless we forwarded to somewhere that doesn't actually
        // have a compositor.
        mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
    }

    mForwarder->RemoveTexturesIfNecessary();
    mForwarder->SendPendingAsyncMessges();
    mPhase = PHASE_NONE;

    // this may result in Layers being deleted, which results in
    // PLayer::Send__delete__() and DeallocShmem()
    mKeepAlive.Clear();
}
bool
CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
                                                     EditReplyVector& replyv)
{
  switch (aEdit.type()) {
    case CompositableOperation::TOpPaintTextureRegion: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint PaintedLayer"));

      const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion();
      CompositableHost* compositable = AsCompositable(op);
      Layer* layer = compositable->GetLayer();
      if (!layer || layer->GetType() != Layer::TYPE_PAINTED) {
        return false;
      }
      PaintedLayerComposite* thebes = static_cast<PaintedLayerComposite*>(layer);

      const ThebesBufferData& bufferData = op.bufferData();

      RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds());

      nsIntRegion frontUpdatedRegion;
      if (!compositable->UpdateThebes(bufferData,
                                      op.updatedRegion(),
                                      thebes->GetValidRegion(),
                                      &frontUpdatedRegion))
      {
        return false;
      }
      replyv.push_back(
        OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion));

      RenderTraceInvalidateEnd(thebes, "FF00FF");
      break;
    }
    case CompositableOperation::TOpUseTiledLayerBuffer: {
      MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
      const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer();
      TiledContentHost* compositable = AsCompositable(op)->AsTiledContentHost();

      NS_ASSERTION(compositable, "The compositable is not tiled");

      const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
      bool success = compositable->UseTiledLayerBuffer(this, tileDesc);
      if (!success) {
        return false;
      }
      break;
    }
    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);
      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() && ImageBridgeParent::GetInstance(GetChildProcessId())) {
        // send FenceHandle if present via ImageBridge.
        ImageBridgeParent::AppendDeliverFenceMessage(
                             GetChildProcessId(),
                             op.holderId(),
                             op.transactionId(),
                             op.textureParent(),
                             compositable);

        // If the message is recievied via PLayerTransaction,
        // Send message back via PImageBridge.
        ImageBridgeParent::ReplyRemoveTexture(
                             GetChildProcessId(),
                             OpReplyRemoveTexture(op.holderId(),
                                                  op.transactionId()));
      } else {
        // send FenceHandle if present.
        SendFenceHandleIfPresent(op.textureParent(), compositable);

        ReplyRemoveTexture(OpReplyRemoveTexture(op.holderId(),
                                                op.transactionId()));
      }
      break;
    }
    case CompositableOperation::TOpUseTexture: {
      const OpUseTexture& op = aEdit.get_OpUseTexture();
      CompositableHost* compositable = AsCompositable(op);

      nsAutoTArray<CompositableHost::TimedTexture,4> textures;
      for (auto& timedTexture : op.textures()) {
        CompositableHost::TimedTexture* t = textures.AppendElement();
        t->mTexture =
            TextureHost::AsTextureHost(timedTexture.textureParent());
        MOZ_ASSERT(t->mTexture);
        t->mTimeStamp = timedTexture.timeStamp();
        t->mPictureRect = timedTexture.picture();
        t->mFrameID = timedTexture.frameID();
        t->mProducerID = timedTexture.producerID();
        MOZ_ASSERT(ValidatePictureRect(t->mTexture->GetSize(), t->mPictureRect));

        MaybeFence maybeFence = timedTexture.fence();
        if (maybeFence.type() == MaybeFence::TFenceHandle) {
          FenceHandle fence = maybeFence.get_FenceHandle();
          if (fence.IsValid()) {
            t->mTexture->SetAcquireFenceHandle(fence);
          }
        }
      }
      compositable->UseTextureHost(textures);

      if (IsAsync() && compositable->GetLayer()) {
        ScheduleComposition(op);
      }
      break;
    }
    case CompositableOperation::TOpUseComponentAlphaTextures: {
      const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures();
      CompositableHost* compositable = AsCompositable(op);
      RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent());
      RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent());

      MOZ_ASSERT(texOnBlack && texOnWhite);
      compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite);

      if (IsAsync()) {
        ScheduleComposition(op);
      }
      break;
    }
#ifdef MOZ_WIDGET_GONK
    case CompositableOperation::TOpUseOverlaySource: {
      const OpUseOverlaySource& op = aEdit.get_OpUseOverlaySource();
      CompositableHost* compositable = AsCompositable(op);
      MOZ_ASSERT(compositable->GetType() == CompositableType::IMAGE_OVERLAY, "Invalid operation!");
      if (!ValidatePictureRect(op.overlay().size(), op.picture())) {
        return false;
      }
      compositable->UseOverlaySource(op.overlay(), op.picture());
      break;
    }
#endif
    default: {
      MOZ_ASSERT(false, "bad type");
    }
  }

  return true;
}
예제 #8
0
void
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
{
  mPhase = PHASE_FORWARD;

  // forward this transaction's changeset to our LayerManagerComposite
  bool sent;
  AutoInfallibleTArray<EditReply, 10> replies;
  if (HasShadowManager() && mForwarder->EndTransaction(&replies, mRegionToClear, aScheduleComposite, &sent)) {
    for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
      const EditReply& reply = replies[i];

      switch (reply.type()) {
      case EditReply::TOpContentBufferSwap: {
        MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));

        const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();

        CompositableClient* compositable =
          CompositableClient::FromIPDLActor(obs.compositableChild());
        ContentClientRemote* contentClient =
          static_cast<ContentClientRemote*>(compositable);
        MOZ_ASSERT(contentClient);

        contentClient->SwapBuffers(obs.frontUpdatedRegion());

        break;
      }
      case EditReply::TOpTextureSwap: {
        MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));

        const OpTextureSwap& ots = reply.get_OpTextureSwap();

        CompositableClient* compositable =
          CompositableClient::FromIPDLActor(ots.compositableChild());
        MOZ_ASSERT(compositable);
        compositable->SetDescriptorFromReply(ots.textureId(), ots.image());
        break;
      }
      case EditReply::TReturnReleaseFence: {
        const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence();
        FenceHandle fence = rep.fence();
        PTextureChild* child = rep.textureChild();

        if (!fence.IsValid() || !child) {
          break;
        }
        RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
        if (texture) {
          texture->SetReleaseFenceHandle(fence);
        }
        break;
      }

      default:
        NS_RUNTIMEABORT("not reached");
      }
    }

    if (sent) {
      mNeedsComposite = false;
    }
  } else if (HasShadowManager()) {
    NS_WARNING("failed to forward Layers transaction");
  }

  mForwarder->RemoveTexturesIfNecessary();
  mForwarder->SendPendingAsyncMessge();
  mPhase = PHASE_NONE;

  // this may result in Layers being deleted, which results in
  // PLayer::Send__delete__() and DeallocShmem()
  mKeepAlive.Clear();
}