diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index 768547bdb72e..160ba5f64f98 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -77,9 +77,11 @@ enum class TextureFlags : uint32_t { NON_BLOCKING_READ_LOCK = 1 << 15, // Enable a blocking read lock. BLOCKING_READ_LOCK = 1 << 16, + // Keep TextureClient alive when host side is used + WAIT_HOST_USAGE_END = 1 << 17, // OR union of all valid bits - ALL_BITS = (1 << 17) - 1, + ALL_BITS = (1 << 18) - 1, // the default flags DEFAULT = NO_FLAGS }; diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 528ca137108e..9ff85ff2163e 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -553,6 +553,17 @@ void D3D11TextureData::GetDXGIResource(IDXGIResource** aOutResource) { mTexture->QueryInterface(aOutResource); } +TextureFlags D3D11TextureData::GetTextureFlags() const { + TextureFlags flags = TextureFlags::NO_FLAGS; + // With WebRender, resource open happens asynchronously on RenderThread. + // During opening the resource on host side, TextureClient needs to be alive. + // With WAIT_HOST_USAGE_END, keep TextureClient alive during host side usage. + if (gfx::gfxVars::UseWebRender()) { + flags |= TextureFlags::WAIT_HOST_USAGE_END; + } + return flags; +} + DXGIYCbCrTextureData* DXGIYCbCrTextureData::Create( IDirect3DTexture9* aTextureY, IDirect3DTexture9* aTextureCb, IDirect3DTexture9* aTextureCr, HANDLE aHandleY, HANDLE aHandleCb, @@ -681,6 +692,17 @@ void DXGIYCbCrTextureData::Deallocate(LayersIPCChannel*) { mD3D11Textures[2] = nullptr; } +TextureFlags DXGIYCbCrTextureData::GetTextureFlags() const { + TextureFlags flags = TextureFlags::DEALLOCATE_MAIN_THREAD; + // With WebRender, resource open happens asynchronously on RenderThread. + // During opening the resource on host side, TextureClient needs to be alive. + // With WAIT_HOST_USAGE_END, keep TextureClient alive during host side usage. + if (gfx::gfxVars::UseWebRender()) { + flags |= TextureFlags::WAIT_HOST_USAGE_END; + } + return flags; +} + already_AddRefed CreateTextureHostD3D11( const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, LayersBackend aBackend, TextureFlags aFlags) { diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index d13b58e80be5..d469bd8ffb57 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -91,6 +91,8 @@ class D3D11TextureData final : public TextureData { gfx::IntSize GetSize() const { return mSize; } gfx::SurfaceFormat GetSurfaceFormat() const { return mFormat; } + TextureFlags GetTextureFlags() const override; + private: D3D11TextureData(ID3D11Texture2D* aTexture, gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags); @@ -159,9 +161,7 @@ class DXGIYCbCrTextureData : public TextureData { bool UpdateFromSurface(gfx::SourceSurface*) override { return false; } - TextureFlags GetTextureFlags() const override { - return TextureFlags::DEALLOCATE_MAIN_THREAD; - } + TextureFlags GetTextureFlags() const override; DXGIYCbCrTextureData* AsDXGIYCbCrTextureData() override { return this; } diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index db497034fd68..445cc58921f1 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -829,7 +829,10 @@ void CompositorBridgeChild::HoldUntilCompositableRefReleasedIfNecessary( return; } - if (!(aClient->GetFlags() & TextureFlags::RECYCLE)) { + bool waitNotifyNotUsed = + aClient->GetFlags() & TextureFlags::RECYCLE || + aClient->GetFlags() & TextureFlags::WAIT_HOST_USAGE_END; + if (!waitNotifyNotUsed) { return; } diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 450488744ccc..142891247a10 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -135,11 +135,18 @@ void ImageBridgeChild::UseComponentAlphaTextures( void ImageBridgeChild::HoldUntilCompositableRefReleasedIfNecessary( TextureClient* aClient) { - // Wait ReleaseCompositableRef only when TextureFlags::RECYCLE is set on - // ImageBridge. - if (!aClient || !(aClient->GetFlags() & TextureFlags::RECYCLE)) { + if (!aClient) { return; } + // Wait ReleaseCompositableRef only when TextureFlags::RECYCLE or + // TextureFlags::WAIT_HOST_USAGE_END is set on ImageBridge. + bool waitNotifyNotUsed = + aClient->GetFlags() & TextureFlags::RECYCLE || + aClient->GetFlags() & TextureFlags::WAIT_HOST_USAGE_END; + if (!waitNotifyNotUsed) { + return; + } + aClient->SetLastFwdTransactionId(GetFwdTransactionId()); mTexturesWaitingNotifyNotUsed.emplace(aClient->GetSerial(), aClient); }