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
Родитель 2e685a448e
Коммит 6680aadc04
5 изменённых файлов: 42 добавлений и 8 удалений

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

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

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

@ -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) {

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

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

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

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

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

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