void
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
{
  TimeStamp start = TimeStamp::Now();

  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;
      }
      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->RemoveCompositablesIfNecessary();
  mForwarder->SendPendingAsyncMessges();
  mPhase = PHASE_NONE;

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

  TabChild* window = mWidget->GetOwningTabChild();
  if (window) {
    TimeStamp end = TimeStamp::Now();
    window->DidRequestComposite(start, end);
  }
}
Example #2
0
void
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
{
  AutoProfilerTracing tracing("Paint", "ForwardTransaction");
  TimeStamp start = TimeStamp::Now();

  // Skip the synchronization for buffer since we also skip the painting during
  // device-reset status.
  if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
    if (mForwarder->GetSyncObject() &&
        mForwarder->GetSyncObject()->IsSyncObjectValid()) {
      mForwarder->GetSyncObject()->Synchronize();
    }
  }

  mPhase = PHASE_FORWARD;

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

  if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) {
    mForwarder->SendPaintTime(mLatestTransactionId, mLastPaintTime);
  }

  // forward this transaction's changeset to our LayerManagerComposite
  bool sent = false;
  bool ok = mForwarder->EndTransaction(
    mRegionToClear, mLatestTransactionId, aScheduleComposite,
    mPaintSequenceNumber, mIsRepeatTransaction, transactionStart,
    &sent);
  if (ok) {
    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);
  }

  mPhase = PHASE_NONE;

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

  TabChild* window = mWidget ? mWidget->GetOwningTabChild() : nullptr;
  if (window) {
    TimeStamp end = TimeStamp::Now();
    window->DidRequestComposite(start, end);
  }
}