Bug 1526213 - Enable WebRenderTextureHostWrapper for canvas r=nical

By using WebRenderTextureHostWrapper for canvas, we could avoid triggering frame build on WebRender backend if WebRenderTextureHostWrapper is only change.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
sotaro 2019-02-18 09:33:32 +00:00
Родитель ba95495155
Коммит 087c420a72
7 изменённых файлов: 47 добавлений и 19 удалений

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

@ -234,8 +234,7 @@ Maybe<TextureHost::ResourceUpdateOp> AsyncImagePipelineManager::UpdateImageKeys(
// Use WebRenderTextureHostWrapper only for video.
// And WebRenderTextureHostWrapper could be used only with
// WebRenderTextureHost that supports NativeTexture
bool useWrTextureWrapper = aPipeline->mImageHost->GetAsyncRef() &&
useExternalImage && wrTexture &&
bool useWrTextureWrapper = useExternalImage && wrTexture &&
wrTexture->SupportsWrNativeTexture();
// The non-external image code path falls back to converting the texture into
@ -280,13 +279,13 @@ Maybe<TextureHost::ResourceUpdateOp> AsyncImagePipelineManager::UpdateImageKeys(
MOZ_ASSERT(canUpdate);
// Reuse WebRenderTextureHostWrapper. With it, rendered frame could be
// updated without batch re-creation.
aPipeline->mWrTextureWrapper->UpdateWebRenderTextureHost(wrTexture);
aPipeline->mWrTextureWrapper->UpdateWebRenderTextureHost(aMaybeFastTxn, wrTexture);
// Ensure frame generation.
SetWillGenerateFrame();
} else {
if (useWrTextureWrapper) {
aPipeline->mWrTextureWrapper = new WebRenderTextureHostWrapper(this);
aPipeline->mWrTextureWrapper->UpdateWebRenderTextureHost(wrTexture);
aPipeline->mWrTextureWrapper->UpdateWebRenderTextureHost(aMaybeFastTxn, wrTexture);
}
Range<wr::ImageKey> keys(&aKeys[0], aKeys.Length());
auto externalImageKey =

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

@ -10,10 +10,35 @@
#include "mozilla/layers/WebRenderTextureHost.h"
#include "mozilla/webrender/RenderTextureHostWrapper.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/RenderThread.h"
namespace mozilla {
namespace layers {
class ScheduleUpdateRenderTextureHost : public wr::NotificationHandler {
public:
ScheduleUpdateRenderTextureHost(uint64_t aSrcExternalImageId,
uint64_t aWrappedExternalImageId)
: mSrcExternalImageId(aSrcExternalImageId),
mWrappedExternalImageId(aWrappedExternalImageId) {}
virtual void Notify(wr::Checkpoint aCheckpoint) override {
if (aCheckpoint == wr::Checkpoint::FrameTexturesUpdated) {
MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
wr::RenderThread::Get()->UpdateRenderTextureHost(
mSrcExternalImageId,
mWrappedExternalImageId);
} else {
MOZ_ASSERT(aCheckpoint == wr::Checkpoint::TransactionDropped);
}
}
protected:
uint64_t mSrcExternalImageId;
uint64_t mWrappedExternalImageId;
};
WebRenderTextureHostWrapper::WebRenderTextureHostWrapper(
AsyncImagePipelineManager* aManager)
: mExternalImageId(aManager->GetNextExternalImageId()) {
@ -32,12 +57,20 @@ WebRenderTextureHostWrapper::~WebRenderTextureHostWrapper() {
}
void WebRenderTextureHostWrapper::UpdateWebRenderTextureHost(
wr::TransactionBuilder& aTxn,
WebRenderTextureHost* aTextureHost) {
MOZ_ASSERT(aTextureHost);
mWrTextureHost = aTextureHost;
wr::RenderThread::Get()->UpdateRenderTextureHost(
// AsyncImagePipelineManager is responsible of holding compositable ref of
// wrapped WebRenderTextureHost by using ForwardingTextureHost.
// ScheduleUpdateRenderTextureHost does not need to handle it.
aTxn.Notify(wr::Checkpoint::FrameTexturesUpdated,
MakeUnique<ScheduleUpdateRenderTextureHost>(
wr::AsUint64(mExternalImageId),
wr::AsUint64(aTextureHost->GetExternalImageKey()));
wr::AsUint64(aTextureHost->GetExternalImageKey())));
mWrTextureHost = aTextureHost;
}
} // namespace layers

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

@ -21,7 +21,8 @@ class WebRenderTextureHostWrapper {
public:
explicit WebRenderTextureHostWrapper(AsyncImagePipelineManager* aManager);
void UpdateWebRenderTextureHost(WebRenderTextureHost* aTextureHost);
void UpdateWebRenderTextureHost(wr::TransactionBuilder& aTxn,
WebRenderTextureHost* aTextureHost);
wr::ExternalImageId GetExternalImageKey() { return mExternalImageId; }

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

@ -49,7 +49,7 @@ void RenderTextureHostWrapper::ClearCachedResources() {
void RenderTextureHostWrapper::UpdateRenderTextureHost(
RenderTextureHost* aTextureHost) {
MOZ_ASSERT(!mInited || RenderThread::IsInRenderThread());
MOZ_ASSERT(RenderThread::IsInRenderThread());
MOZ_RELEASE_ASSERT(!mLocked);
mInited = true;

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

@ -594,6 +594,7 @@ void RenderThread::UnregisterExternalImage(uint64_t aExternalImageId) {
void RenderThread::UpdateRenderTextureHost(uint64_t aSrcExternalImageId,
uint64_t aWrappedExternalImageId) {
MOZ_ASSERT(aSrcExternalImageId != aWrappedExternalImageId);
MOZ_ASSERT(RenderThread::IsInRenderThread());
MutexAutoLock lock(mRenderTextureMapLock);
if (mHasShutdown) {
@ -611,14 +612,7 @@ void RenderThread::UpdateRenderTextureHost(uint64_t aSrcExternalImageId,
MOZ_ASSERT_UNREACHABLE("unexpected to happen");
return;
}
if (!wrapper->IsInited()) {
wrapper->UpdateRenderTextureHost(wrapped->second);
MOZ_ASSERT(wrapper->IsInited());
} else {
Loop()->PostTask(NewRunnableMethod<RenderTextureHost*>(
"RenderTextureHostWrapper::UpdateRenderTextureHost", wrapper,
&RenderTextureHostWrapper::UpdateRenderTextureHost, wrapped->second));
}
}
void RenderThread::UnregisterExternalImageDuringShutdown(

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

@ -185,7 +185,7 @@ class RenderThread final {
/// Can be called from any thread.
void UnregisterExternalImage(uint64_t aExternalImageId);
/// Can be called from any thread.
/// Can only be called from the render thread.
void UpdateRenderTextureHost(uint64_t aSrcExternalImageId,
uint64_t aWrappedExternalImageId);

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

@ -580,6 +580,7 @@ impl SceneBuilder {
let scene_swap_start_time = precise_time_ns();
let has_resources_updates = !txn.resource_updates.is_empty();
let invalidate_rendered_frame = txn.invalidate_rendered_frame;
self.tx.send(SceneBuilderResult::Transaction(txn, result_tx)).unwrap();
@ -597,7 +598,7 @@ impl SceneBuilder {
},
_ => (),
};
} else if has_resources_updates {
} else if has_resources_updates || invalidate_rendered_frame {
if let &Some(ref hooks) = &self.hooks {
hooks.post_resource_update();
}