Bug 1557858 - Add multiple WebRenderBridgeParents support in WebRenderImageHost r=nical

Uses wr::PipelineId to identify user of WebRenderImageHost.

Differential Revision: https://phabricator.services.mozilla.com/D42462

--HG--
extra : moz-landing-system : lando
This commit is contained in:
sotaro 2019-08-22 10:20:02 +00:00
Родитель 6b8d2e3f18
Коммит c423c98aca
4 изменённых файлов: 65 добавлений и 47 удалений

Просмотреть файл

@ -205,7 +205,8 @@ Maybe<TextureHost::ResourceUpdateOp> AsyncImagePipelineManager::UpdateImageKeys(
MOZ_ASSERT(aKeys.IsEmpty());
MOZ_ASSERT(aPipeline);
TextureHost* texture = aPipeline->mImageHost->GetAsTextureHostForComposite();
TextureHost* texture =
aPipeline->mImageHost->GetAsTextureHostForComposite(this);
TextureHost* previousTexture = aPipeline->mCurrentTexture.get();
if (texture == previousTexture) {

Просмотреть файл

@ -1789,7 +1789,7 @@ void WebRenderBridgeParent::AddPipelineIdForCompositable(
return;
}
wrHost->SetWrBridge(this);
wrHost->SetWrBridge(aPipelineId, this);
asyncCompositables.emplace(wr::AsUint64(aPipelineId), wrHost);
mAsyncImageManager->AddAsyncImagePipeline(aPipelineId, wrHost,
RenderRootForExternal(aRenderRoot));
@ -1821,7 +1821,7 @@ void WebRenderBridgeParent::RemovePipelineIdForCompositable(
}
RefPtr<WebRenderImageHost>& wrHost = it->second;
wrHost->ClearWrBridge(this);
wrHost->ClearWrBridge(aPipelineId, this);
mAsyncImageManager->RemoveAsyncImagePipeline(aPipelineId, aTxn);
aTxn.RemovePipeline(aPipelineId);
asyncCompositables.erase(wr::AsUint64(aPipelineId));
@ -2603,7 +2603,7 @@ void WebRenderBridgeParent::ClearResources() {
for (const auto& entry : mAsyncCompositables[renderRoot]) {
wr::PipelineId pipelineId = wr::AsPipelineId(entry.first);
RefPtr<WebRenderImageHost> host = entry.second;
host->ClearWrBridge(this);
host->ClearWrBridge(pipelineId, this);
mAsyncImageManager->RemoveAsyncImagePipeline(pipelineId, txn);
txn.RemovePipeline(pipelineId);
}

Просмотреть файл

@ -8,6 +8,7 @@
#include "LayersLogging.h"
#include "mozilla/Move.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorVsyncScheduler.h" // for CompositorVsyncScheduler
#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
@ -29,9 +30,11 @@ namespace layers {
class ISurfaceAllocator;
WebRenderImageHost::WebRenderImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo), ImageComposite(), mWrBridgeBindings(0) {}
: CompositableHost(aTextureInfo),
ImageComposite(),
mCurrentAsyncImageManager(nullptr) {}
WebRenderImageHost::~WebRenderImageHost() { MOZ_ASSERT(!mWrBridge); }
WebRenderImageHost::~WebRenderImageHost() { MOZ_ASSERT(mWrBridges.empty()); }
void WebRenderImageHost::UseTextureHost(
const nsTArray<TimedTexture>& aTextures) {
@ -63,9 +66,13 @@ void WebRenderImageHost::UseTextureHost(
SetImages(std::move(newImages));
if (mWrBridge && mWrBridge->CompositorScheduler() && GetAsyncRef()) {
// Will check if we will generate frame.
mWrBridge->CompositorScheduler()->ScheduleComposition();
if (GetAsyncRef()) {
for (const auto& it : mWrBridges) {
WebRenderBridgeParent* wrBridge = it.second;
if (wrBridge && wrBridge->CompositorScheduler()) {
wrBridge->CompositorScheduler()->ScheduleComposition();
}
}
}
// Video producers generally send replacement images with the same frameID but
@ -73,14 +80,18 @@ void WebRenderImageHost::UseTextureHost(
// means that any CompositeUntil() call we made in Composite() may no longer
// guarantee that we'll composite until the next frame is ready. Fix that
// here.
if (mWrBridge && mLastFrameID >= 0) {
MOZ_ASSERT(mWrBridge->AsyncImageManager());
if (mLastFrameID >= 0 && !mWrBridges.empty()) {
for (const auto& img : Images()) {
bool frameComesAfter =
img.mFrameID > mLastFrameID || img.mProducerID != mLastProducerID;
if (frameComesAfter && !img.mTimeStamp.IsNull()) {
mWrBridge->AsyncImageManager()->CompositeUntil(
for (const auto& it : mWrBridges) {
WebRenderBridgeParent* wrBridge = it.second;
if (wrBridge) {
wrBridge->AsyncImageManager()->CompositeUntil(
img.mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
}
}
break;
}
}
@ -104,9 +115,10 @@ void WebRenderImageHost::RemoveTextureHost(TextureHost* aTexture) {
TimeStamp WebRenderImageHost::GetCompositionTime() const {
TimeStamp time;
if (mWrBridge) {
MOZ_ASSERT(mWrBridge->AsyncImageManager());
time = mWrBridge->AsyncImageManager()->GetCompositionTime();
MOZ_ASSERT(mCurrentAsyncImageManager);
if (mCurrentAsyncImageManager) {
time = mCurrentAsyncImageManager->GetCompositionTime();
}
return time;
}
@ -119,10 +131,11 @@ TextureHost* WebRenderImageHost::GetAsTextureHost(IntRect* aPictureRect) {
return nullptr;
}
TextureHost* WebRenderImageHost::GetAsTextureHostForComposite() {
if (!mWrBridge) {
return nullptr;
}
TextureHost* WebRenderImageHost::GetAsTextureHostForComposite(
AsyncImagePipelineManager* aAsyncImageManager) {
mCurrentAsyncImageManager = aAsyncImageManager;
const auto onExit =
mozilla::MakeScopeExit([&]() { mCurrentAsyncImageManager = nullptr; });
int imageIndex = ChooseImageIndex();
if (imageIndex < 0) {
@ -131,8 +144,7 @@ TextureHost* WebRenderImageHost::GetAsTextureHostForComposite() {
}
if (uint32_t(imageIndex) + 1 < ImagesCount()) {
MOZ_ASSERT(mWrBridge->AsyncImageManager());
mWrBridge->AsyncImageManager()->CompositeUntil(
mCurrentAsyncImageManager->CompositeUntil(
GetImage(imageIndex + 1)->mTimeStamp +
TimeDuration::FromMilliseconds(BIAS_TIME_MS));
}
@ -145,9 +157,9 @@ TextureHost* WebRenderImageHost::GetAsTextureHostForComposite() {
info.mImageBridgeProcessId = mAsyncRef.mProcessId;
info.mNotification = ImageCompositeNotification(
mAsyncRef.mHandle, img->mTimeStamp,
mWrBridge->AsyncImageManager()->GetCompositionTime(), img->mFrameID,
mCurrentAsyncImageManager->GetCompositionTime(), img->mFrameID,
img->mProducerID);
mWrBridge->AsyncImageManager()->AppendImageCompositeNotification(info);
mCurrentAsyncImageManager->AppendImageCompositeNotification(info);
}
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
@ -236,29 +248,28 @@ IntSize WebRenderImageHost::GetImageSize() {
return IntSize();
}
void WebRenderImageHost::SetWrBridge(WebRenderBridgeParent* aWrBridge) {
// For image hosts created through ImageBridgeParent, there may be multiple
// references to it due to the order of creation and freeing of layers by
// the layer tree. However this should be limited to things such as video
// which will not be reused across different WebRenderBridgeParent objects.
void WebRenderImageHost::SetWrBridge(const wr::PipelineId& aPipelineId,
WebRenderBridgeParent* aWrBridge) {
MOZ_ASSERT(aWrBridge);
MOZ_ASSERT(!mWrBridge || mWrBridge == aWrBridge);
mWrBridge = aWrBridge;
++mWrBridgeBindings;
#ifdef DEBUG
const auto it = mWrBridges.find(wr::AsUint64(aPipelineId));
MOZ_ASSERT(it == mWrBridges.end());
#endif
mWrBridges.emplace(wr::AsUint64(aPipelineId), aWrBridge);
}
void WebRenderImageHost::ClearWrBridge(WebRenderBridgeParent* aWrBridge) {
void WebRenderImageHost::ClearWrBridge(const wr::PipelineId& aPipelineId,
WebRenderBridgeParent* aWrBridge) {
MOZ_ASSERT(aWrBridge);
MOZ_ASSERT(mWrBridgeBindings > 0);
--mWrBridgeBindings;
if (mWrBridgeBindings == 0) {
MOZ_ASSERT(aWrBridge == mWrBridge);
if (aWrBridge != mWrBridge) {
const auto it = mWrBridges.find(wr::AsUint64(aPipelineId));
MOZ_ASSERT(it != mWrBridges.end());
if (it == mWrBridges.end()) {
gfxCriticalNote << "WrBridge mismatch happened";
return;
}
mWrBridges.erase(it);
SetCurrentTextureHost(nullptr);
mWrBridge = nullptr;
}
}
} // namespace layers

Просмотреть файл

@ -7,6 +7,8 @@
#ifndef MOZILLA_GFX_WEBRENDERIMAGEHOST_H
#define MOZILLA_GFX_WEBRENDERIMAGEHOST_H
#include <unordered_map>
#include "CompositableHost.h" // for CompositableHost
#include "mozilla/layers/ImageComposite.h" // for ImageComposite
#include "mozilla/WeakPtr.h"
@ -14,6 +16,7 @@
namespace mozilla {
namespace layers {
class AsyncImagePipelineManager;
class WebRenderBridgeParent;
/**
@ -65,11 +68,14 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite {
WebRenderImageHost* AsWebRenderImageHost() override { return this; }
TextureHost* GetAsTextureHostForComposite();
TextureHost* GetAsTextureHostForComposite(
AsyncImagePipelineManager* aAsyncImageManager);
void SetWrBridge(WebRenderBridgeParent* aWrBridge);
void SetWrBridge(const wr::PipelineId& aPipelineId,
WebRenderBridgeParent* aWrBridge);
void ClearWrBridge(WebRenderBridgeParent* aWrBridge);
void ClearWrBridge(const wr::PipelineId& aPipelineId,
WebRenderBridgeParent* aWrBridge);
TextureHost* GetCurrentTextureHost() { return mCurrentTextureHost; }
@ -79,9 +85,9 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite {
void SetCurrentTextureHost(TextureHost* aTexture);
WeakPtr<WebRenderBridgeParent> mWrBridge;
std::unordered_map<uint64_t, WeakPtr<WebRenderBridgeParent>> mWrBridges;
uint32_t mWrBridgeBindings;
AsyncImagePipelineManager* mCurrentAsyncImageManager;
CompositableTextureHostRef mCurrentTextureHost;
};