Bug 1556340 - Make D3D11TextureData and DXGIYCbCrTextureData alive during host side usage with WebRender r=nical

By Bug 1555544 , it became clear that D3D11TextureData and DXGIYCbCrTextureData should not be deleted before calling RenderDXGITextureHostOGL::EnsureLockable() / RenderDXGITextureHostOGL::EnsureLockable().

With WebRender, the EnsureLockable()s are called on RenderThread asynchronously. Then for achieving the above, it is simpler just to keep D3D11TextureData and DXGIYCbCrTextureData alive during host side usage.

There is already a mechanism to do it. By using NotifyNotUsed, it could be done.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
sotaro 2019-06-05 22:50:50 +00:00
parent 2e685a448e
commit 6680aadc04
5 changed files with 42 additions and 8 deletions

View File

@ -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
};

View File

@ -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<TextureHost> CreateTextureHostD3D11(
const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator,
LayersBackend aBackend, TextureFlags aFlags) {

View File

@ -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; }

View File

@ -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;
}

View File

@ -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);
}