Bug 1863257 - Remove sync wait in compositor thread of main thread canvas by RemoteTextureMap::WaitForRemoteTextureOwner() r=gfx-reviewers,lsalzman

Calling RemoteTextureTxnScheduler::NotifyTxn() of main thread canvas is deferred to WebRenderAPI for waiting RemoteTextureOwner at WebRenderAPI.

When RemoteTextureOwner is not registered yet, WaitingTextureOwner is used to register the callback. WaitingTextureOwner is removed in RemoteTextureMap::SuppressRemoteTextureReadyCheck() when it still exists.

Removing sync wait of off main thread canvas is going to be handled by another bug.

Differential Revision: https://phabricator.services.mozilla.com/D209647
This commit is contained in:
sotaro 2024-05-20 00:29:19 +00:00
parent 92be045106
commit 268fa0828c
8 changed files with 158 additions and 69 deletions

View file

@ -574,6 +574,13 @@ void RemoteTextureMap::RegisterTextureOwner(
owner->mRecycleBin = new RemoteTextureRecycleBin(false); owner->mRecycleBin = new RemoteTextureRecycleBin(false);
} }
auto itWaiting = mWaitingTextureOwners.find(key);
if (itWaiting != mWaitingTextureOwners.end()) {
owner->mRenderingReadyCallbackHolders.swap(
itWaiting->second->mRenderingReadyCallbackHolders);
mWaitingTextureOwners.erase(itWaiting);
}
mTextureOwners.emplace(key, std::move(owner)); mTextureOwners.emplace(key, std::move(owner));
} }
@ -1002,14 +1009,13 @@ bool RemoteTextureMap::WaitForRemoteTextureOwner(
return true; return true;
} }
bool RemoteTextureMap::GetRemoteTexture( void RemoteTextureMap::GetRemoteTexture(
RemoteTextureHostWrapper* aTextureHostWrapper, RemoteTextureHostWrapper* aTextureHostWrapper) {
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
MOZ_ASSERT(aTextureHostWrapper); MOZ_ASSERT(aTextureHostWrapper);
if (aTextureHostWrapper->IsReadyForRendering()) { if (aTextureHostWrapper->IsReadyForRendering()) {
return false; return;
} }
const auto& textureId = aTextureHostWrapper->mTextureId; const auto& textureId = aTextureHostWrapper->mTextureId;
@ -1023,7 +1029,7 @@ bool RemoteTextureMap::GetRemoteTexture(
auto* owner = GetTextureOwner(lock, ownerId, forPid); auto* owner = GetTextureOwner(lock, ownerId, forPid);
if (!owner) { if (!owner) {
return false; return;
} }
UpdateTexture(lock, owner, textureId); UpdateTexture(lock, owner, textureId);
@ -1031,7 +1037,7 @@ bool RemoteTextureMap::GetRemoteTexture(
if (owner->mLatestTextureHost && if (owner->mLatestTextureHost &&
(owner->mLatestTextureHost->GetFlags() & TextureFlags::DUMMY_TEXTURE)) { (owner->mLatestTextureHost->GetFlags() & TextureFlags::DUMMY_TEXTURE)) {
// Remote texture allocation was failed. // Remote texture allocation was failed.
return false; return;
} }
if (textureId == owner->mLatestUsingTextureId) { if (textureId == owner->mLatestUsingTextureId) {
@ -1043,14 +1049,6 @@ bool RemoteTextureMap::GetRemoteTexture(
<< " expected: " << size; << " expected: " << size;
} }
textureHost = owner->mLatestTextureHost; textureHost = owner->mLatestTextureHost;
} else {
if (aReadyCallback) {
auto callbackHolder = MakeUnique<RenderingReadyCallbackHolder>(
textureId, std::move(aReadyCallback));
owner->mRenderingReadyCallbackHolders.push_back(
std::move(callbackHolder));
return true;
}
} }
// Update mRemoteTextureHost // Update mRemoteTextureHost
@ -1070,8 +1068,6 @@ bool RemoteTextureMap::GetRemoteTexture(
aTextureHostWrapper->ApplyTextureFlagsToRemoteTexture(); aTextureHostWrapper->ApplyTextureFlagsToRemoteTexture();
} }
} }
return false;
} }
void RemoteTextureMap::NotifyTxn(const MonitorAutoLock& aProofOfLock, void RemoteTextureMap::NotifyTxn(const MonitorAutoLock& aProofOfLock,
@ -1201,6 +1197,28 @@ bool RemoteTextureMap::CheckRemoteTextureReady(
MonitorAutoLock lock(mMonitor); MonitorAutoLock lock(mMonitor);
auto* owner = GetTextureOwner(lock, aInfo.mOwnerId, aInfo.mForPid); auto* owner = GetTextureOwner(lock, aInfo.mOwnerId, aInfo.mForPid);
if (aInfo.mWaitForRemoteTextureOwner && !owner) {
// Remote texture owner is not registered yet. Waiting for remote texture
// owner
const auto key = std::pair(aInfo.mForPid, aInfo.mOwnerId);
if (!mWaitingTextureOwners[key]) {
auto waitingOwner = MakeUnique<WaitingTextureOwner>();
mWaitingTextureOwners[key] = std::move(waitingOwner);
}
MOZ_ASSERT(mWaitingTextureOwners[key]);
WaitingTextureOwner* waitingOwner = mWaitingTextureOwners[key].get();
auto callbackHolder = MakeUnique<RenderingReadyCallbackHolder>(
aInfo.mTextureId, std::move(aCallback));
waitingOwner->mRenderingReadyCallbackHolders.push_back(
std::move(callbackHolder));
return false;
}
if (!owner || owner->mIsContextLost) { if (!owner || owner->mIsContextLost) {
// Owner is already removed or context lost. No need to wait texture ready. // Owner is already removed or context lost. No need to wait texture ready.
return true; return true;
@ -1232,6 +1250,24 @@ bool RemoteTextureMap::WaitRemoteTextureReady(const RemoteTextureInfo& aInfo) {
MonitorAutoLock lock(mMonitor); MonitorAutoLock lock(mMonitor);
auto* owner = GetTextureOwner(lock, aInfo.mOwnerId, aInfo.mForPid); auto* owner = GetTextureOwner(lock, aInfo.mOwnerId, aInfo.mForPid);
if (aInfo.mWaitForRemoteTextureOwner &&
(!owner || (!owner->mLatestTextureHost &&
owner->mWaitingTextureDataHolders.empty()))) {
const TimeDuration timeout = TimeDuration::FromMilliseconds(10000);
while (!owner || (!owner->mLatestTextureHost &&
owner->mWaitingTextureDataHolders.empty())) {
if (owner && (owner->mIsContextLost || owner->mDeferUnregister)) {
// If the context was lost, no further updates are expected.
return false;
}
CVStatus status = mMonitor.Wait(timeout);
if (status == CVStatus::Timeout) {
return false;
}
owner = GetTextureOwner(lock, aInfo.mOwnerId, aInfo.mForPid);
}
}
if (!owner || owner->mIsContextLost) { if (!owner || owner->mIsContextLost) {
// Owner is already removed or context lost. // Owner is already removed or context lost.
return false; return false;
@ -1275,11 +1311,18 @@ bool RemoteTextureMap::WaitRemoteTextureReady(const RemoteTextureInfo& aInfo) {
} }
void RemoteTextureMap::SuppressRemoteTextureReadyCheck( void RemoteTextureMap::SuppressRemoteTextureReadyCheck(
const RemoteTextureId aTextureId, const base::ProcessId aForPid) { const RemoteTextureInfo& aInfo) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
MonitorAutoLock lock(mMonitor); MonitorAutoLock lock(mMonitor);
const auto key = std::pair(aForPid, aTextureId); // Clear if WaitingTextureOwner exists.
auto itWaiting =
mWaitingTextureOwners.find(std::pair(aInfo.mForPid, aInfo.mOwnerId));
if (itWaiting != mWaitingTextureOwners.end()) {
mWaitingTextureOwners.erase(itWaiting);
}
const auto key = std::pair(aInfo.mForPid, aInfo.mTextureId);
auto it = mRemoteTextureHostWrapperHolders.find(key); auto it = mRemoteTextureHostWrapperHolders.find(key);
if (it == mRemoteTextureHostWrapperHolders.end()) { if (it == mRemoteTextureHostWrapperHolders.end()) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called"); MOZ_ASSERT_UNREACHABLE("unexpected to be called");

View file

@ -55,11 +55,24 @@ struct RemoteTextureInfo {
RemoteTextureInfo(const RemoteTextureId aTextureId, RemoteTextureInfo(const RemoteTextureId aTextureId,
const RemoteTextureOwnerId aOwnerId, const RemoteTextureOwnerId aOwnerId,
const base::ProcessId aForPid) const base::ProcessId aForPid)
: mTextureId(aTextureId), mOwnerId(aOwnerId), mForPid(aForPid) {} : mTextureId(aTextureId),
mOwnerId(aOwnerId),
mForPid(aForPid),
mWaitForRemoteTextureOwner(false) {}
RemoteTextureInfo(const RemoteTextureId aTextureId,
const RemoteTextureOwnerId aOwnerId,
const base::ProcessId aForPid,
const bool aWaitForRemoteTextureOwner)
: mTextureId(aTextureId),
mOwnerId(aOwnerId),
mForPid(aForPid),
mWaitForRemoteTextureOwner(aWaitForRemoteTextureOwner) {}
const RemoteTextureId mTextureId; const RemoteTextureId mTextureId;
const RemoteTextureOwnerId mOwnerId; const RemoteTextureOwnerId mOwnerId;
const base::ProcessId mForPid; const base::ProcessId mForPid;
const bool mWaitForRemoteTextureOwner;
}; };
struct RemoteTextureInfoList { struct RemoteTextureInfoList {
@ -307,11 +320,7 @@ class RemoteTextureMap {
bool WaitForRemoteTextureOwner(RemoteTextureHostWrapper* aTextureHostWrapper); bool WaitForRemoteTextureOwner(RemoteTextureHostWrapper* aTextureHostWrapper);
// Get remote texture's TextureHost for RemoteTextureHostWrapper. // Get remote texture's TextureHost for RemoteTextureHostWrapper.
// void GetRemoteTexture(RemoteTextureHostWrapper* aTextureHostWrapper);
// return true when aReadyCallback will be called.
bool GetRemoteTexture(
RemoteTextureHostWrapper* aTextureHostWrapper,
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback);
bool WaitForTxn(const RemoteTextureOwnerId aOwnerId, bool WaitForTxn(const RemoteTextureOwnerId aOwnerId,
const base::ProcessId aForPid, RemoteTextureTxnType aTxnType, const base::ProcessId aForPid, RemoteTextureTxnType aTxnType,
@ -334,8 +343,7 @@ class RemoteTextureMap {
bool WaitRemoteTextureReady(const RemoteTextureInfo& aInfo); bool WaitRemoteTextureReady(const RemoteTextureInfo& aInfo);
void SuppressRemoteTextureReadyCheck(const RemoteTextureId aTextureId, void SuppressRemoteTextureReadyCheck(const RemoteTextureInfo& aInfo);
const base::ProcessId aForPid);
UniquePtr<TextureData> GetRecycledTextureData( UniquePtr<TextureData> GetRecycledTextureData(
const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid,
@ -387,6 +395,11 @@ class RemoteTextureMap {
std::function<void(const RemoteTextureInfo&)> mCallback; std::function<void(const RemoteTextureInfo&)> mCallback;
}; };
struct WaitingTextureOwner {
std::deque<UniquePtr<RenderingReadyCallbackHolder>>
mRenderingReadyCallbackHolders;
};
struct TextureOwner { struct TextureOwner {
bool mIsContextLost = false; bool mIsContextLost = false;
// Whether to wait for a transaction to complete before unregistering. // Whether to wait for a transaction to complete before unregistering.
@ -467,6 +480,10 @@ class RemoteTextureMap {
Monitor mMonitor MOZ_UNANNOTATED; Monitor mMonitor MOZ_UNANNOTATED;
std::map<std::pair<base::ProcessId, RemoteTextureOwnerId>,
UniquePtr<WaitingTextureOwner>>
mWaitingTextureOwners;
std::map<std::pair<base::ProcessId, RemoteTextureOwnerId>, std::map<std::pair<base::ProcessId, RemoteTextureOwnerId>,
UniquePtr<TextureOwner>> UniquePtr<TextureOwner>>
mTextureOwners; mTextureOwners;

View file

@ -7,6 +7,7 @@
#ifndef MOZILLA_GFX_RemoteTextureHostWrapper_H #ifndef MOZILLA_GFX_RemoteTextureHostWrapper_H
#define MOZILLA_GFX_RemoteTextureHostWrapper_H #define MOZILLA_GFX_RemoteTextureHostWrapper_H
#include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/layers/TextureHost.h" #include "mozilla/layers/TextureHost.h"
#include "mozilla/Monitor.h" #include "mozilla/Monitor.h"
@ -80,6 +81,15 @@ class RemoteTextureHostWrapper : public TextureHost {
void ApplyTextureFlagsToRemoteTexture(); void ApplyTextureFlagsToRemoteTexture();
void EnableWaitForRemoteTextureOwner(bool aEnable) {
mWaitForRemoteTextureOwner = true;
}
RemoteTextureInfo GetRemoteTextureInfo() const {
return RemoteTextureInfo(mTextureId, mOwnerId, mForPid,
mWaitForRemoteTextureOwner);
}
const RemoteTextureId mTextureId; const RemoteTextureId mTextureId;
const RemoteTextureOwnerId mOwnerId; const RemoteTextureOwnerId mOwnerId;
const base::ProcessId mForPid; const base::ProcessId mForPid;
@ -108,6 +118,8 @@ class RemoteTextureHostWrapper : public TextureHost {
bool mRenderTextureCreated = false; bool mRenderTextureCreated = false;
bool mWaitForRemoteTextureOwner = false;
friend class RemoteTextureMap; friend class RemoteTextureMap;
}; };

View file

@ -228,8 +228,7 @@ Maybe<TextureHost::ResourceUpdateOp> AsyncImagePipelineManager::UpdateImageKeys(
auto* wrapper = aTexture ? aTexture->AsRemoteTextureHostWrapper() : nullptr; auto* wrapper = aTexture ? aTexture->AsRemoteTextureHostWrapper() : nullptr;
if (wrapper && !aPipeline->mImageHost->GetAsyncRef()) { if (wrapper && !aPipeline->mImageHost->GetAsyncRef()) {
std::function<void(const RemoteTextureInfo&)> function; RemoteTextureMap::Get()->GetRemoteTexture(wrapper);
RemoteTextureMap::Get()->GetRemoteTexture(wrapper, std::move(function));
} }
if (!aTexture || aTexture->NumSubTextures() == 0) { if (!aTexture || aTexture->NumSubTextures() == 0) {
@ -523,8 +522,7 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
// Store pending remote texture that is used for waiting at WebRenderAPI. // Store pending remote texture that is used for waiting at WebRenderAPI.
if (aPendingRemoteTextures && texture && if (aPendingRemoteTextures && texture &&
texture != pipeline->mCurrentTexture && wrapper) { texture != pipeline->mCurrentTexture && wrapper) {
aPendingRemoteTextures->mList.emplace(wrapper->mTextureId, aPendingRemoteTextures->mList.emplace(wrapper->GetRemoteTextureInfo());
wrapper->mOwnerId, wrapper->mForPid);
} }
if (aPendingOps && !pipeline->mImageHost->GetAsyncRef()) { if (aPendingOps && !pipeline->mImageHost->GetAsyncRef()) {

View file

@ -1120,7 +1120,8 @@ bool WebRenderBridgeParent::SetDisplayList(
bool WebRenderBridgeParent::ProcessDisplayListData( bool WebRenderBridgeParent::ProcessDisplayListData(
DisplayListData& aDisplayList, wr::Epoch aWrEpoch, DisplayListData& aDisplayList, wr::Epoch aWrEpoch,
const TimeStamp& aTxnStartTime, bool aValidTransaction) { const TimeStamp& aTxnStartTime, bool aValidTransaction) {
wr::TransactionBuilder txn(mApi); wr::TransactionBuilder txn(mApi, /* aUseSceneBuilderThread */ true,
mRemoteTextureTxnScheduler, mFwdTransactionId);
Maybe<wr::AutoTransactionSender> sender; Maybe<wr::AutoTransactionSender> sender;
if (aDisplayList.mScrollData && !aDisplayList.mScrollData->Validate()) { if (aDisplayList.mScrollData && !aDisplayList.mScrollData->Validate()) {
@ -1239,10 +1240,6 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aDisplayList.mSmallShmems); wr::IpcResourceUpdateQueue::ReleaseShmems(this, aDisplayList.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, aDisplayList.mLargeShmems); wr::IpcResourceUpdateQueue::ReleaseShmems(this, aDisplayList.mLargeShmems);
if (mRemoteTextureTxnScheduler) {
mRemoteTextureTxnScheduler->NotifyTxn(aFwdTransactionId);
}
if (!success) { if (!success) {
return IPC_FAIL(this, "Failed to process DisplayListData."); return IPC_FAIL(this, "Failed to process DisplayListData.");
} }
@ -1253,7 +1250,8 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
bool WebRenderBridgeParent::ProcessEmptyTransactionUpdates( bool WebRenderBridgeParent::ProcessEmptyTransactionUpdates(
TransactionData& aData, bool* aScheduleComposite) { TransactionData& aData, bool* aScheduleComposite) {
*aScheduleComposite = false; *aScheduleComposite = false;
wr::TransactionBuilder txn(mApi); wr::TransactionBuilder txn(mApi, /* aUseSceneBuilderThread */ true,
mRemoteTextureTxnScheduler, mFwdTransactionId);
txn.SetLowPriority(!IsRootWebRenderBridgeParent()); txn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (!aData.mScrollUpdates.IsEmpty()) { if (!aData.mScrollUpdates.IsEmpty()) {
@ -1395,10 +1393,6 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEmptyTransaction(
aTransactionData->mLargeShmems); aTransactionData->mLargeShmems);
} }
if (mRemoteTextureTxnScheduler) {
mRemoteTextureTxnScheduler->NotifyTxn(aFwdTransactionId);
}
if (!success) { if (!success) {
return IPC_FAIL(this, "Failed to process empty transaction update."); return IPC_FAIL(this, "Failed to process empty transaction update.");
} }

View file

@ -199,15 +199,17 @@ void WebRenderImageHost::UseRemoteTexture() {
while (!mPendingRemoteTextureWrappers.empty()) { while (!mPendingRemoteTextureWrappers.empty()) {
auto* wrapper = auto* wrapper =
mPendingRemoteTextureWrappers.front()->AsRemoteTextureHostWrapper(); mPendingRemoteTextureWrappers.front()->AsRemoteTextureHostWrapper();
if (mWaitForRemoteTextureOwner) { if (mWaitForRemoteTextureOwner) {
// XXX remove sync wait
RemoteTextureMap::Get()->WaitForRemoteTextureOwner(wrapper); RemoteTextureMap::Get()->WaitForRemoteTextureOwner(wrapper);
} }
mWaitingReadyCallback = mWaitingReadyCallback = !RemoteTextureMap::Get()->CheckRemoteTextureReady(
RemoteTextureMap::Get()->GetRemoteTexture(wrapper, readyCallback); wrapper->GetRemoteTextureInfo(), readyCallback);
MOZ_ASSERT_IF(mWaitingReadyCallback, !wrapper->IsReadyForRendering()); if (mWaitingReadyCallback) {
if (!wrapper->IsReadyForRendering()) {
break; break;
} }
RemoteTextureMap::Get()->GetRemoteTexture(wrapper);
texture = mPendingRemoteTextureWrappers.front(); texture = mPendingRemoteTextureWrappers.front();
mPendingRemoteTextureWrappers.pop_front(); mPendingRemoteTextureWrappers.pop_front();
} }
@ -218,7 +220,7 @@ void WebRenderImageHost::UseRemoteTexture() {
MOZ_ASSERT(mPendingRemoteTextureWrappers.empty()); MOZ_ASSERT(mPendingRemoteTextureWrappers.empty());
if (mWaitForRemoteTextureOwner) { if (mWaitForRemoteTextureOwner) {
RemoteTextureMap::Get()->WaitForRemoteTextureOwner(wrapper); wrapper->EnableWaitForRemoteTextureOwner(true);
} }
mWaitForRemoteTextureOwner = false; mWaitForRemoteTextureOwner = false;
} }

View file

@ -213,18 +213,26 @@ class RemoveRenderer : public RendererEvent {
layers::SynchronousTask* mTask; layers::SynchronousTask* mTask;
}; };
TransactionBuilder::TransactionBuilder(WebRenderAPI* aApi, TransactionBuilder::TransactionBuilder(
bool aUseSceneBuilderThread) WebRenderAPI* aApi, bool aUseSceneBuilderThread,
: mUseSceneBuilderThread(aUseSceneBuilderThread), layers::RemoteTextureTxnScheduler* aRemoteTextureTxnScheduler,
layers::RemoteTextureTxnId aRemoteTextureTxnId)
: mRemoteTextureTxnScheduler(aRemoteTextureTxnScheduler),
mRemoteTextureTxnId(aRemoteTextureTxnId),
mUseSceneBuilderThread(aUseSceneBuilderThread),
mApiBackend(aApi->GetBackendType()), mApiBackend(aApi->GetBackendType()),
mOwnsData(true) { mOwnsData(true) {
mTxn = wr_transaction_new(mUseSceneBuilderThread); mTxn = wr_transaction_new(mUseSceneBuilderThread);
} }
TransactionBuilder::TransactionBuilder(WebRenderAPI* aApi, Transaction* aTxn, TransactionBuilder::TransactionBuilder(
bool aUseSceneBuilderThread, WebRenderAPI* aApi, Transaction* aTxn, bool aUseSceneBuilderThread,
bool aOwnsData) bool aOwnsData,
: mTxn(aTxn), layers::RemoteTextureTxnScheduler* aRemoteTextureTxnScheduler,
layers::RemoteTextureTxnId aRemoteTextureTxnId)
: mRemoteTextureTxnScheduler(aRemoteTextureTxnScheduler),
mRemoteTextureTxnId(aRemoteTextureTxnId),
mTxn(aTxn),
mUseSceneBuilderThread(aUseSceneBuilderThread), mUseSceneBuilderThread(aUseSceneBuilderThread),
mApiBackend(aApi->GetBackendType()), mApiBackend(aApi->GetBackendType()),
mOwnsData(aOwnsData) {} mOwnsData(aOwnsData) {}
@ -473,17 +481,19 @@ void WebRenderAPI::SendTransaction(TransactionBuilder& aTxn) {
!mPendingAsyncImagePipelineOps->mList.empty()) { !mPendingAsyncImagePipelineOps->mList.empty()) {
mPendingWrTransactionEvents.emplace( mPendingWrTransactionEvents.emplace(
WrTransactionEvent::PendingAsyncImagePipelineOps( WrTransactionEvent::PendingAsyncImagePipelineOps(
std::move(mPendingAsyncImagePipelineOps), this, aTxn.Raw(), std::move(mPendingAsyncImagePipelineOps), this, aTxn));
aTxn.UseSceneBuilderThread()));
} }
if (!mPendingWrTransactionEvents.empty()) { if (!mPendingWrTransactionEvents.empty()) {
mPendingWrTransactionEvents.emplace(WrTransactionEvent::Transaction( mPendingWrTransactionEvents.emplace(
this, aTxn.Take(), aTxn.UseSceneBuilderThread())); WrTransactionEvent::Transaction(this, aTxn));
HandleWrTransactionEvents(RemoteTextureWaitType::AsyncWait); HandleWrTransactionEvents(RemoteTextureWaitType::AsyncWait);
} else { } else {
wr_api_send_transaction(mDocHandle, aTxn.Raw(), wr_api_send_transaction(mDocHandle, aTxn.Raw(),
aTxn.UseSceneBuilderThread()); aTxn.UseSceneBuilderThread());
if (aTxn.mRemoteTextureTxnScheduler) {
aTxn.mRemoteTextureTxnScheduler->NotifyTxn(aTxn.mRemoteTextureTxnId);
}
} }
} }
@ -598,6 +608,10 @@ void WebRenderAPI::HandleWrTransactionEvents(RemoteTextureWaitType aType) {
case WrTransactionEvent::Tag::Transaction: case WrTransactionEvent::Tag::Transaction:
wr_api_send_transaction(mDocHandle, front.RawTransaction(), wr_api_send_transaction(mDocHandle, front.RawTransaction(),
front.UseSceneBuilderThread()); front.UseSceneBuilderThread());
if (front.GetTransactionBuilder()->mRemoteTextureTxnScheduler) {
front.GetTransactionBuilder()->mRemoteTextureTxnScheduler->NotifyTxn(
front.GetTransactionBuilder()->mRemoteTextureTxnId);
}
break; break;
case WrTransactionEvent::Tag::PendingRemoteTextures: { case WrTransactionEvent::Tag::PendingRemoteTextures: {
bool isReady = true; bool isReady = true;
@ -612,7 +626,7 @@ void WebRenderAPI::HandleWrTransactionEvents(RemoteTextureWaitType aType) {
while (!list->mList.empty()) { while (!list->mList.empty()) {
auto& front = list->mList.front(); auto& front = list->mList.front();
layers::RemoteTextureMap::Get()->SuppressRemoteTextureReadyCheck( layers::RemoteTextureMap::Get()->SuppressRemoteTextureReadyCheck(
front.mTextureId, front.mForPid); front);
list->mList.pop(); list->mList.pop();
} }
} }

View file

@ -103,11 +103,16 @@ struct WrHitResult {
class TransactionBuilder final { class TransactionBuilder final {
public: public:
explicit TransactionBuilder(WebRenderAPI* aApi, explicit TransactionBuilder(
bool aUseSceneBuilderThread = true); WebRenderAPI* aApi, bool aUseSceneBuilderThread = true,
layers::RemoteTextureTxnScheduler* aRemoteTextureTxnScheduler = nullptr,
layers::RemoteTextureTxnId aRemoteTextureTxnId = 0);
TransactionBuilder(WebRenderAPI* aApi, Transaction* aTxn, TransactionBuilder(
bool aUseSceneBuilderThread, bool aOwnsData); WebRenderAPI* aApi, Transaction* aTxn, bool aUseSceneBuilderThread,
bool aOwnsData,
layers::RemoteTextureTxnScheduler* aRemoteTextureTxnScheduler,
layers::RemoteTextureTxnId aRemoteTextureTxnId);
~TransactionBuilder(); ~TransactionBuilder();
@ -207,7 +212,10 @@ class TransactionBuilder final {
bool UseSceneBuilderThread() const { return mUseSceneBuilderThread; } bool UseSceneBuilderThread() const { return mUseSceneBuilderThread; }
layers::WebRenderBackend GetBackendType() { return mApiBackend; } layers::WebRenderBackend GetBackendType() { return mApiBackend; }
Transaction* Raw() { return mTxn; } Transaction* Raw() const { return mTxn; }
const RefPtr<layers::RemoteTextureTxnScheduler> mRemoteTextureTxnScheduler;
const layers::RemoteTextureTxnId mRemoteTextureTxnId;
protected: protected:
Transaction* mTxn; Transaction* mTxn;
@ -391,10 +399,10 @@ class WebRenderAPI final {
public: public:
static WrTransactionEvent Transaction(WebRenderAPI* aApi, static WrTransactionEvent Transaction(WebRenderAPI* aApi,
wr::Transaction* aTxn, TransactionBuilder& aTxn) {
bool aUseSceneBuilderThread) {
auto transaction = MakeUnique<TransactionBuilder>( auto transaction = MakeUnique<TransactionBuilder>(
aApi, aTxn, aUseSceneBuilderThread, /* aOwnsData */ true); aApi, aTxn.Take(), aTxn.UseSceneBuilderThread(), /* aOwnsData */ true,
aTxn.mRemoteTextureTxnScheduler, aTxn.mRemoteTextureTxnId);
return WrTransactionEvent(Tag::Transaction, std::move(transaction)); return WrTransactionEvent(Tag::Transaction, std::move(transaction));
} }
@ -407,10 +415,10 @@ class WebRenderAPI final {
static WrTransactionEvent PendingAsyncImagePipelineOps( static WrTransactionEvent PendingAsyncImagePipelineOps(
UniquePtr<layers::AsyncImagePipelineOps>&& UniquePtr<layers::AsyncImagePipelineOps>&&
aPendingAsyncImagePipelineOps, aPendingAsyncImagePipelineOps,
WebRenderAPI* aApi, wr::Transaction* aTxn, WebRenderAPI* aApi, const TransactionBuilder& aTxn) {
bool aUseSceneBuilderThread) {
auto transaction = MakeUnique<TransactionBuilder>( auto transaction = MakeUnique<TransactionBuilder>(
aApi, aTxn, aUseSceneBuilderThread, /* aOwnsData */ false); aApi, aTxn.Raw(), aTxn.UseSceneBuilderThread(), /* aOwnsData */ false,
aTxn.mRemoteTextureTxnScheduler, aTxn.mRemoteTextureTxnId);
return WrTransactionEvent(Tag::PendingAsyncImagePipelineOps, return WrTransactionEvent(Tag::PendingAsyncImagePipelineOps,
std::move(aPendingAsyncImagePipelineOps), std::move(aPendingAsyncImagePipelineOps),
std::move(transaction)); std::move(transaction));
@ -425,7 +433,8 @@ class WebRenderAPI final {
} }
TransactionBuilder* GetTransactionBuilder() { TransactionBuilder* GetTransactionBuilder() {
if (mTag == Tag::PendingAsyncImagePipelineOps) { if (mTag == Tag::Transaction ||
mTag == Tag::PendingAsyncImagePipelineOps) {
return mTransaction.get(); return mTransaction.get();
} }
MOZ_CRASH("Should not be called"); MOZ_CRASH("Should not be called");