Bug 1898436 - Defer removing AsyncImagePipeline to WebRenderAPI if necessary r=gfx-reviewers,lsalzman

Need to defer AsyncImagePipeline deletion to WebRenderAPI. This is to make the deferred AsyncImagePipelineManager::ApplyAsyncImageForPipeline() work.

Differential Revision: https://phabricator.services.mozilla.com/D211358
This commit is contained in:
sotaro 2024-05-23 23:53:35 +00:00
parent 141cda749f
commit 334ddfb2cb
6 changed files with 51 additions and 10 deletions

View File

@ -176,11 +176,18 @@ void AsyncImagePipelineManager::AddAsyncImagePipeline(
}
void AsyncImagePipelineManager::RemoveAsyncImagePipeline(
const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aTxn) {
const wr::PipelineId& aPipelineId, AsyncImagePipelineOps* aPendingOps,
wr::TransactionBuilder& aTxn) {
if (mDestroyed) {
return;
}
if (aPendingOps) {
aPendingOps->mList.emplace(
AsyncImagePipelineOp::RemoveAsyncImagePipeline(this, aPipelineId));
return;
}
uint64_t id = wr::AsUint64(aPipelineId);
if (auto entry = mAsyncImagePipelines.Lookup(id)) {
const auto& holder = entry.Data();

View File

@ -100,6 +100,7 @@ class AsyncImagePipelineManager final {
void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId,
WebRenderImageHost* aImageHost);
void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId,
AsyncImagePipelineOps* aPendingOps,
wr::TransactionBuilder& aTxn);
void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId,

View File

@ -16,12 +16,23 @@ void AsyncImagePipelineOps::HandleOps(wr::TransactionBuilder& aTxn) {
while (!mList.empty()) {
auto& frontOp = mList.front();
auto* manager = frontOp.mAsyncImageManager;
const auto& pipelineId = frontOp.mPipelineId;
const auto& textureHost = frontOp.mTextureHost;
manager->ApplyAsyncImageForPipeline(pipelineId, textureHost, aTxn);
switch (frontOp.mTag) {
case AsyncImagePipelineOp::Tag::ApplyAsyncImageForPipeline: {
auto* manager = frontOp.mAsyncImageManager;
const auto& pipelineId = frontOp.mPipelineId;
const auto& textureHost = frontOp.mTextureHost;
manager->ApplyAsyncImageForPipeline(pipelineId, textureHost, aTxn);
break;
}
case AsyncImagePipelineOp::Tag::RemoveAsyncImagePipeline: {
auto* manager = frontOp.mAsyncImageManager;
const auto& pipelineId = frontOp.mPipelineId;
manager->RemoveAsyncImagePipeline(pipelineId, /* aPendingOps */ nullptr,
aTxn);
break;
}
}
mList.pop();
}
}

View File

@ -28,6 +28,7 @@ class AsyncImagePipelineOp {
public:
enum class Tag {
ApplyAsyncImageForPipeline,
RemoveAsyncImagePipeline,
};
const Tag mTag;
@ -48,6 +49,15 @@ class AsyncImagePipelineOp {
MOZ_ASSERT(mTag == Tag::ApplyAsyncImageForPipeline);
}
AsyncImagePipelineOp(const Tag aTag,
AsyncImagePipelineManager* aAsyncImageManager,
const wr::PipelineId& aPipelineId)
: mTag(aTag),
mAsyncImageManager(aAsyncImageManager),
mPipelineId(aPipelineId) {
MOZ_ASSERT(mTag == Tag::RemoveAsyncImagePipeline);
}
public:
static AsyncImagePipelineOp ApplyAsyncImageForPipeline(
AsyncImagePipelineManager* aAsyncImageManager,
@ -55,6 +65,13 @@ class AsyncImagePipelineOp {
return AsyncImagePipelineOp(Tag::ApplyAsyncImageForPipeline,
aAsyncImageManager, aPipelineId, aTextureHost);
}
static AsyncImagePipelineOp RemoveAsyncImagePipeline(
AsyncImagePipelineManager* aAsyncImageManager,
const wr::PipelineId& aPipelineId) {
return AsyncImagePipelineOp(Tag::RemoveAsyncImagePipeline,
aAsyncImageManager, aPipelineId);
}
};
struct AsyncImagePipelineOps {

View File

@ -1458,7 +1458,9 @@ bool WebRenderBridgeParent::ProcessWebRenderParentCommands(
case WebRenderParentCommand::TOpRemovePipelineIdForCompositable: {
const OpRemovePipelineIdForCompositable& op =
cmd.get_OpRemovePipelineIdForCompositable();
RemovePipelineIdForCompositable(op.pipelineId(), aTxn);
auto* pendingOps = mApi->GetPendingAsyncImagePipelineOps(aTxn);
RemovePipelineIdForCompositable(op.pipelineId(), pendingOps, aTxn);
break;
}
case WebRenderParentCommand::TOpReleaseTextureOfImage: {
@ -1840,7 +1842,8 @@ void WebRenderBridgeParent::AddPipelineIdForCompositable(
}
void WebRenderBridgeParent::RemovePipelineIdForCompositable(
const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aTxn) {
const wr::PipelineId& aPipelineId, AsyncImagePipelineOps* aPendingOps,
wr::TransactionBuilder& aTxn) {
if (mDestroyed) {
return;
}
@ -1852,7 +1855,7 @@ void WebRenderBridgeParent::RemovePipelineIdForCompositable(
RefPtr<WebRenderImageHost>& wrHost = it->second;
wrHost->ClearWrBridge(aPipelineId, this);
mAsyncImageManager->RemoveAsyncImagePipeline(aPipelineId, aTxn);
mAsyncImageManager->RemoveAsyncImagePipeline(aPipelineId, aPendingOps, aTxn);
aTxn.RemovePipeline(aPipelineId);
mAsyncCompositables.erase(wr::AsUint64(aPipelineId));
}
@ -2724,7 +2727,8 @@ void WebRenderBridgeParent::ClearResources() {
wr::PipelineId pipelineId = wr::AsPipelineId(entry.first);
RefPtr<WebRenderImageHost> host = entry.second;
host->ClearWrBridge(pipelineId, this);
mAsyncImageManager->RemoveAsyncImagePipeline(pipelineId, txn);
mAsyncImageManager->RemoveAsyncImagePipeline(
pipelineId, /* aPendingOps */ nullptr, txn);
txn.RemovePipeline(pipelineId);
}
mAsyncCompositables.clear();

View File

@ -365,6 +365,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
wr::TransactionBuilder& aTxn,
wr::TransactionBuilder& aTxnForImageBridge);
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId,
AsyncImagePipelineOps* aPendingOps,
wr::TransactionBuilder& aTxn);
void DeleteImage(const wr::ImageKey& aKey, wr::TransactionBuilder& aUpdates);