Bug 1794380 - Fix RemoteTexture with WebGL sync present on Android r=gfx-reviewers,lsalzman

The change addressed followings problems.

- Recycling of gl::SharedSurface by RemoteTextureMap is not handled by gl::SwapChain.
- PrepareForUse()/NotifyNotUsed() of remote texture's TextureHost(SurfaceTextureHost) is not handled
- Wrapping of RenderAndroidSurfaceTextureHost by RenderTextureHostWrapper is not handled

PrepareForUse()/NotifyNotUsed() is called based on compositor ref count of TextureHost. Normally TextureHost is wrapped by WebRenderTextureHost, then the WebRenderTextureHost handles PrepareForUse()/NotifyNotUsed(). But in remote texture case, WebRenderTextureHost wraps RemoteTextureHostWrapper. And compositable ref of remote texture's TextureHost is updated within RemoteTextureMap::mMutex. Then PrepareForUse()/NotifyNotUsed() happen outside of WebRenderTextureHost in non compositor thread.

With pref gfx.canvas.accelerated=true, canvas renderings were broken on android emulator. The boroken rendering seemed to happen by GL of android emulator. The boroken rendering did not happen with tests on android hardware.

Differential Revision: https://phabricator.services.mozilla.com/D159261
This commit is contained in:
sotaro 2022-12-07 12:40:02 +00:00
Родитель 7e770c016b
Коммит ad6c294e3c
14 изменённых файлов: 66 добавлений и 7 удалений

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

@ -1193,6 +1193,7 @@ bool WebGLContext::PushRemoteTexture(WebGLFramebuffer* fb,
switch (desc->type()) {
case layers::SurfaceDescriptor::TSurfaceDescriptorD3D10:
case layers::SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
case layers::SurfaceDescriptor::TSurfaceTextureDescriptor:
keepAlive = surf;
break;
default:

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

@ -42,7 +42,11 @@ UniquePtr<SwapChainPresenter> SwapChain::Acquire(
}
}
if (!mPool.empty() && (!kPoolSize || mPool.size() == kPoolSize)) {
// When mDestroyedCallback exists, recycling of SharedSurfaces is managed by
// the owner of the SwapChain by calling StoreRecycledSurface().
const auto poolSize = mDestroyedCallback ? 0 : kPoolSize;
if (!mPool.empty() && (!poolSize || mPool.size() == poolSize)) {
surf = mPool.front();
mPool.pop();
}
@ -52,7 +56,7 @@ UniquePtr<SwapChainPresenter> SwapChain::Acquire(
surf.reset(uniquePtrSurf.release());
}
mPool.push(surf);
while (mPool.size() > kPoolSize) {
while (mPool.size() > poolSize) {
mPool.pop();
}

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

@ -77,6 +77,7 @@ class SwapChain final {
void SetDestroyedCallback(std::function<void()>&& aDestroyedCallback) {
MOZ_ASSERT(!mDestroyedCallback);
mDestroyedCallback = std::move(aDestroyedCallback);
mPool = {};
}
};

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

@ -206,6 +206,13 @@ bool GPUVideoTextureHost::IsWrappingBufferTextureHost() {
return false;
}
bool GPUVideoTextureHost::IsWrappingSurfaceTextureHost() {
if (EnsureWrappedTextureHost()) {
return EnsureWrappedTextureHost()->IsWrappingSurfaceTextureHost();
}
return false;
}
TextureHostType GPUVideoTextureHost::GetTextureHostType() {
if (!mWrappedTextureHost) {
return TextureHostType::Unknown;

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

@ -64,6 +64,7 @@ class GPUVideoTextureHost : public TextureHost {
void NotifyNotUsed() override;
bool IsWrappingBufferTextureHost() override;
bool IsWrappingSurfaceTextureHost() override;
TextureHostType GetTextureHostType() override;

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

@ -163,7 +163,7 @@ void RemoteTextureHostWrapper::UnbindTextureSource() {}
void RemoteTextureHostWrapper::NotifyNotUsed() {
if (mRemoteTextureForDisplayList) {
// Release mRemoteTextureHost.
// Release mRemoteTextureForDisplayList.
RemoteTextureMap::Get()->ReleaseRemoteTextureHostForDisplayList(this);
}
MOZ_ASSERT(!mRemoteTextureForDisplayList);
@ -208,4 +208,11 @@ void RemoteTextureHostWrapper::SetRemoteTextureHostForDisplayList(
mRemoteTextureForDisplayList = aTextureHost;
}
bool RemoteTextureHostWrapper::IsWrappingSurfaceTextureHost() {
if (!mRemoteTextureForDisplayList) {
return false;
}
return mRemoteTextureForDisplayList->IsWrappingSurfaceTextureHost();
}
} // namespace mozilla::layers

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

@ -74,6 +74,8 @@ class RemoteTextureHostWrapper : public TextureHost {
TextureHostType GetTextureHostType() override;
bool IsWrappingSurfaceTextureHost() override;
bool CheckIsReadyForRendering();
void ApplyTextureFlagsToRemoteTexture();

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

@ -391,8 +391,21 @@ void TextureHost::RecycleTexture(TextureFlags aFlags) {
mFlags = aFlags;
}
void TextureHost::PrepareForUse() {
if ((mFlags & TextureFlags::REMOTE_TEXTURE) && AsSurfaceTextureHost()) {
MOZ_ASSERT(mExternalImageId.isSome());
// Call PrepareForUse on render thread.
// See RenderAndroidSurfaceTextureHostOGL::PrepareForUse.
wr::RenderThread::Get()->PrepareForUse(*mExternalImageId);
}
}
void TextureHost::NotifyNotUsed() {
if (!mActor) {
if ((mFlags & TextureFlags::REMOTE_TEXTURE) && AsSurfaceTextureHost()) {
MOZ_ASSERT(mExternalImageId.isSome());
wr::RenderThread::Get()->NotifyNotUsed(*mExternalImageId);
}
return;
}

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

@ -609,6 +609,7 @@ class TextureHost : public AtomicRefCountedWithFinalize<TextureHost> {
}
virtual bool IsWrappingBufferTextureHost() { return false; }
virtual bool IsWrappingSurfaceTextureHost() { return false; }
// Create the corresponding RenderTextureHost type of this texture, and
// register the RenderTextureHost into render thread.
@ -726,7 +727,7 @@ class TextureHost : public AtomicRefCountedWithFinalize<TextureHost> {
/**
* Called when mCompositableCount becomes from 0 to 1.
*/
virtual void PrepareForUse() {}
virtual void PrepareForUse();
/**
* Called when mCompositableCount becomes 0.

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

@ -408,6 +408,8 @@ class SurfaceTextureHost : public TextureHost {
SurfaceTextureHost* AsSurfaceTextureHost() override { return this; }
bool IsWrappingSurfaceTextureHost() override { return true; }
void CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) override;

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

@ -101,7 +101,10 @@ gfx::SurfaceFormat WebRenderTextureHost::GetFormat() const {
void WebRenderTextureHost::NotifyNotUsed() {
#ifdef MOZ_WIDGET_ANDROID
if (mWrappedTextureHost->AsSurfaceTextureHost()) {
// When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
// NotifyNotUsed() is handled by SurfaceTextureHost.
if (IsWrappingSurfaceTextureHost() &&
!mWrappedTextureHost->AsRemoteTextureHostWrapper()) {
wr::RenderThread::Get()->NotifyNotUsed(GetExternalImageKey());
}
#endif
@ -113,7 +116,7 @@ void WebRenderTextureHost::NotifyNotUsed() {
void WebRenderTextureHost::MaybeNotifyForUse(wr::TransactionBuilder& aTxn) {
#if defined(MOZ_WIDGET_ANDROID)
if (mWrappedTextureHost->AsSurfaceTextureHost()) {
if (IsWrappingSurfaceTextureHost()) {
wr::RenderThread::Get()->NotifyForUse(GetExternalImageKey());
aTxn.Notify(wr::Checkpoint::FrameTexturesUpdated,
MakeUnique<ScheduleHandleRenderTextureOps>());
@ -125,8 +128,15 @@ bool WebRenderTextureHost::IsWrappingBufferTextureHost() {
return mWrappedTextureHost->IsWrappingBufferTextureHost();
}
bool WebRenderTextureHost::IsWrappingSurfaceTextureHost() {
return mWrappedTextureHost->IsWrappingSurfaceTextureHost();
}
void WebRenderTextureHost::PrepareForUse() {
if (mWrappedTextureHost->AsSurfaceTextureHost() ||
// When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
// PrepareForUse() is handled by SurfaceTextureHost.
if ((IsWrappingSurfaceTextureHost() &&
!mWrappedTextureHost->AsRemoteTextureHostWrapper()) ||
mWrappedTextureHost->IsWrappingBufferTextureHost()) {
// Call PrepareForUse on render thread.
// See RenderAndroidSurfaceTextureHostOGL::PrepareForUse.

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

@ -62,6 +62,7 @@ class WebRenderTextureHost : public TextureHost {
}
bool IsWrappingBufferTextureHost() override;
bool IsWrappingSurfaceTextureHost() override;
virtual void PrepareForUse() override;

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

@ -170,6 +170,14 @@ RenderTextureHostSWGL* RenderTextureHostWrapper::AsRenderTextureHostSWGL() {
return mTextureHost->AsRenderTextureHostSWGL();
}
RenderAndroidSurfaceTextureHost*
RenderTextureHostWrapper::AsRenderAndroidSurfaceTextureHost() {
if (!mTextureHost) {
return nullptr;
}
return mTextureHost->AsRenderAndroidSurfaceTextureHost();
}
RenderTextureHostSWGL* RenderTextureHostWrapper::EnsureRenderTextureHostSWGL()
const {
if (mTextureId.isSome()) {

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

@ -43,6 +43,7 @@ class RenderTextureHostWrapper final : public RenderTextureHostSWGL {
RenderDXGITextureHost* AsRenderDXGITextureHost() override;
RenderDXGIYCbCrTextureHost* AsRenderDXGIYCbCrTextureHost() override;
RenderDcompSurfaceTextureHost* AsRenderDcompSurfaceTextureHost() override;
RenderAndroidSurfaceTextureHost* AsRenderAndroidSurfaceTextureHost() override;
RenderTextureHostSWGL* AsRenderTextureHostSWGL() override;
bool IsWrappingAsyncRemoteTexture() override;