From a8b71fcd721ba11d6239d22e0d991ba9b2c34966 Mon Sep 17 00:00:00 2001 From: sotaro Date: Fri, 10 Nov 2017 18:15:54 +0900 Subject: [PATCH] Bug 1415763 - Fix DXGIYCbCrTextureData as to deliver YUVColorSpace r=mattwoodrow --- gfx/layers/D3D11YCbCrImage.cpp | 106 +++++++++++++++++++--------- gfx/layers/D3D11YCbCrImage.h | 3 - gfx/layers/IMFYCbCrImage.cpp | 3 +- gfx/layers/client/TextureClient.h | 4 ++ gfx/layers/d3d11/TextureD3D11.cpp | 11 ++- gfx/layers/d3d11/TextureD3D11.h | 30 ++++++-- gfx/layers/ipc/LayersSurfaces.ipdlh | 1 + 7 files changed, 114 insertions(+), 44 deletions(-) diff --git a/gfx/layers/D3D11YCbCrImage.cpp b/gfx/layers/D3D11YCbCrImage.cpp index f983dc3e6f91..7117da150e79 100644 --- a/gfx/layers/D3D11YCbCrImage.cpp +++ b/gfx/layers/D3D11YCbCrImage.cpp @@ -16,6 +16,22 @@ using namespace mozilla::gfx; namespace mozilla { namespace layers { +class DXGIYCbCrTextureAllocationHelper : public ITextureClientAllocationHelper +{ +public: + DXGIYCbCrTextureAllocationHelper(const PlanarYCbCrData& aData, + TextureFlags aTextureFlags, + ID3D11Device* aDevice); + + bool IsCompatible(TextureClient* aTextureClient) override; + + already_AddRefed Allocate(KnowsCompositor* aAllocator) override; + +protected: + const PlanarYCbCrData& mData; + RefPtr mDevice; +}; + D3D11YCbCrImage::D3D11YCbCrImage() : Image(NULL, ImageFormat::D3D11_YCBCR_IMAGE) { @@ -39,18 +55,18 @@ D3D11YCbCrImage::SetData(KnowsCompositor* aAllocator, if (!allocator) { return false; } - allocator->SetSizes(aData.mYSize, aData.mCbCrSize); - mTextureClient = allocator->CreateOrRecycle(SurfaceFormat::A8, - mYSize, - BackendSelector::Content, - TextureFlags::DEFAULT); + { + DXGIYCbCrTextureAllocationHelper helper(aData, TextureFlags::DEFAULT, allocator->GetDevice()); + mTextureClient = allocator->CreateOrRecycle(helper); + } + if (!mTextureClient) { return false; } - DXGIYCbCrTextureData *data = - static_cast(mTextureClient->GetInternalData()); + DXGIYCbCrTextureData* data = + mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData(); ID3D11Texture2D* textureY = data->GetD3D11Texture(0); ID3D11Texture2D* textureCb = data->GetD3D11Texture(1); @@ -124,7 +140,7 @@ D3D11YCbCrImage::GetData() const if (!mTextureClient) return nullptr; - return static_cast(mTextureClient->GetInternalData()); + return mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData(); } already_AddRefed @@ -143,8 +159,8 @@ D3D11YCbCrImage::GetAsSourceSurface() PlanarYCbCrData data; - DXGIYCbCrTextureData *dxgiData = - static_cast(mTextureClient->GetInternalData()); + DXGIYCbCrTextureData* dxgiData = + mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData(); if (!dxgiData) { gfxCriticalError() << "Failed to get texture client internal data."; @@ -274,27 +290,39 @@ D3D11YCbCrImage::GetAsSourceSurface() return surface.forget(); } -void -D3D11YCbCrRecycleAllocator::SetSizes(const gfx::IntSize& aYSize, - const gfx::IntSize& aCbCrSize) +DXGIYCbCrTextureAllocationHelper::DXGIYCbCrTextureAllocationHelper(const PlanarYCbCrData& aData, + TextureFlags aTextureFlags, + ID3D11Device* aDevice) + : ITextureClientAllocationHelper(gfx::SurfaceFormat::YUV, + aData.mYSize, + BackendSelector::Content, + aTextureFlags, + ALLOC_DEFAULT) + , mData(aData) + , mDevice(aDevice) { - mYSize = Some(aYSize); - mCbCrSize = Some(aCbCrSize); +} + +bool +DXGIYCbCrTextureAllocationHelper::IsCompatible(TextureClient* aTextureClient) +{ + MOZ_ASSERT(aTextureClient->GetFormat() == gfx::SurfaceFormat::YUV); + + DXGIYCbCrTextureData* dxgiData = aTextureClient->GetInternalData()->AsDXGIYCbCrTextureData(); + if (!dxgiData || + aTextureClient->GetSize() != mData.mYSize || + dxgiData->GetYSize() != mData.mYSize || + dxgiData->GetCbCrSize() != mData.mCbCrSize || + dxgiData->GetYUVColorSpace() != mData.mYUVColorSpace) { + return false; + } + return true; } already_AddRefed -D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat, - IntSize aSize, - BackendSelector aSelector, - TextureFlags aTextureFlags, - TextureAllocationFlags aAllocFlags) +DXGIYCbCrTextureAllocationHelper::Allocate(KnowsCompositor* aAllocator) { - MOZ_ASSERT(aFormat == SurfaceFormat::A8); - - gfx::IntSize YSize = mYSize.refOr(aSize); - gfx::IntSize CbCrSize = - mCbCrSize.refOr(gfx::IntSize(YSize.width, YSize.height)); - CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, YSize.width, YSize.height, + CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; @@ -318,8 +346,8 @@ D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat, hr = mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); - newDesc.Width = CbCrSize.width; - newDesc.Height = CbCrSize.height; + newDesc.Width = mData.mCbCrSize.width; + newDesc.Height = mData.mCbCrSize.height; RefPtr textureCb; hr = mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); @@ -334,11 +362,23 @@ D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat, textureY, textureCb, textureCr, - aSize, - YSize, - CbCrSize), - TextureFlags::DEFAULT, - mSurfaceAllocator->GetTextureForwarder()); + mData.mYSize, + mData.mYSize, + mData.mCbCrSize, + mData.mYUVColorSpace), + mTextureFlags, + aAllocator->GetTextureForwarder()); +} + +already_AddRefed +D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat, + IntSize aSize, + BackendSelector aSelector, + TextureFlags aTextureFlags, + TextureAllocationFlags aAllocFlags) +{ + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + return nullptr; } } // namespace layers diff --git a/gfx/layers/D3D11YCbCrImage.h b/gfx/layers/D3D11YCbCrImage.h index b4423ff34637..6857f27c00f4 100644 --- a/gfx/layers/D3D11YCbCrImage.h +++ b/gfx/layers/D3D11YCbCrImage.h @@ -34,7 +34,6 @@ public: ID3D11Device* GetDevice() { return mDevice; } KnowsCompositor* GetAllocator() { return mSurfaceAllocator; } - void SetSizes(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize); protected: already_AddRefed @@ -45,8 +44,6 @@ protected: TextureAllocationFlags aAllocFlags) override; RefPtr mDevice; - Maybe mYSize; - Maybe mCbCrSize; }; class D3D11YCbCrImage : public Image diff --git a/gfx/layers/IMFYCbCrImage.cpp b/gfx/layers/IMFYCbCrImage.cpp index d638100eea63..411d93d8cffe 100644 --- a/gfx/layers/IMFYCbCrImage.cpp +++ b/gfx/layers/IMFYCbCrImage.cpp @@ -187,7 +187,8 @@ IMFYCbCrImage::GetD3D11TextureData(Data aData, gfx::IntSize aSize) } return DXGIYCbCrTextureData::Create(textureY, textureCb, textureCr, - aSize, aData.mYSize, aData.mCbCrSize); + aSize, aData.mYSize, aData.mCbCrSize, + aData.mYUVColorSpace); } TextureClient* diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 683ea7f4692b..e56ea21841ad 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -225,6 +225,7 @@ public: #ifdef XP_WIN class D3D11TextureData; +class DXGIYCbCrTextureData; #endif class TextureData { @@ -292,6 +293,9 @@ public: virtual D3D11TextureData* AsD3D11TextureData() { return nullptr; } + virtual DXGIYCbCrTextureData* AsDXGIYCbCrTextureData() { + return nullptr; + } #endif virtual BufferTextureData* AsBufferTextureData() { return nullptr; } diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 9b37e61312f8..4645643ad658 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -603,7 +603,8 @@ DXGIYCbCrTextureData::Create(IDirect3DTexture9* aTextureY, HANDLE aHandleCr, const gfx::IntSize& aSize, const gfx::IntSize& aSizeY, - const gfx::IntSize& aSizeCbCr) + const gfx::IntSize& aSizeCbCr, + YUVColorSpace aYUVColorSpace) { if (!aHandleY || !aHandleCb || !aHandleCr || !aTextureY || !aTextureCb || !aTextureCr) { @@ -620,6 +621,7 @@ DXGIYCbCrTextureData::Create(IDirect3DTexture9* aTextureY, texture->mSize = aSize; texture->mSizeY = aSizeY; texture->mSizeCbCr = aSizeCbCr; + texture->mYUVColorSpace = aYUVColorSpace; return texture; } @@ -630,7 +632,8 @@ DXGIYCbCrTextureData::Create(ID3D11Texture2D* aTextureY, ID3D11Texture2D* aTextureCr, const gfx::IntSize& aSize, const gfx::IntSize& aSizeY, - const gfx::IntSize& aSizeCbCr) + const gfx::IntSize& aSizeCbCr, + YUVColorSpace aYUVColorSpace) { if (!aTextureY || !aTextureCb || !aTextureCr) { return nullptr; @@ -678,6 +681,7 @@ DXGIYCbCrTextureData::Create(ID3D11Texture2D* aTextureY, texture->mSize = aSize; texture->mSizeY = aSizeY; texture->mSizeCbCr = aSizeCbCr; + texture->mYUVColorSpace = aYUVColorSpace; return texture; } @@ -697,7 +701,7 @@ DXGIYCbCrTextureData::SerializeSpecific(SurfaceDescriptorDXGIYCbCr* const aOutDe { *aOutDesc = SurfaceDescriptorDXGIYCbCr( (WindowsHandle)mHandles[0], (WindowsHandle)mHandles[1], (WindowsHandle)mHandles[2], - mSize, mSizeY, mSizeCbCr + mSize, mSizeY, mSizeCbCr, mYUVColorSpace ); } @@ -1142,6 +1146,7 @@ DXGIYCbCrTextureHostD3D11::DXGIYCbCrTextureHostD3D11(TextureFlags aFlags, : TextureHost(aFlags) , mSize(aDescriptor.size()) , mIsLocked(false) + , mYUVColorSpace(aDescriptor.yUVColorSpace()) { mHandles[0] = aDescriptor.handleY(); mHandles[1] = aDescriptor.handleCb(); diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 2858268ec833..37cba6d64000 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -144,7 +144,8 @@ public: HANDLE aHandleCr, const gfx::IntSize& aSize, const gfx::IntSize& aSizeY, - const gfx::IntSize& aSizeCbCr); + const gfx::IntSize& aSizeCbCr, + YUVColorSpace aYUVColorSpace); static DXGIYCbCrTextureData* Create(ID3D11Texture2D* aTextureCb, @@ -152,7 +153,8 @@ public: ID3D11Texture2D* aTextureCr, const gfx::IntSize& aSize, const gfx::IntSize& aSizeY, - const gfx::IntSize& aSizeCbCr); + const gfx::IntSize& aSizeCbCr, + YUVColorSpace aYUVColorSpace); virtual bool Lock(OpenMode) override { return true; } @@ -175,6 +177,25 @@ public: return TextureFlags::DEALLOCATE_MAIN_THREAD; } + DXGIYCbCrTextureData* AsDXGIYCbCrTextureData() override { + return this; + } + + gfx::IntSize GetYSize() const + { + return mSizeY; + } + + gfx::IntSize GetCbCrSize() const + { + return mSizeCbCr; + } + + YUVColorSpace GetYUVColorSpace() const + { + return mYUVColorSpace; + } + ID3D11Texture2D* GetD3D11Texture(size_t index) { return mD3D11Textures[index]; } protected: @@ -184,6 +205,7 @@ protected: gfx::IntSize mSize; gfx::IntSize mSizeY; gfx::IntSize mSizeCbCr; + YUVColorSpace mYUVColorSpace; }; /** @@ -383,8 +405,7 @@ public: virtual gfx::SurfaceFormat GetFormat() const override{ return gfx::SurfaceFormat::YUV; } - // Bug 1305906 fixes YUVColorSpace handling - virtual YUVColorSpace GetYUVColorSpace() const override { return YUVColorSpace::BT601; } + virtual YUVColorSpace GetYUVColorSpace() const override { return mYUVColorSpace; } virtual bool Lock() override; @@ -426,6 +447,7 @@ protected: gfx::IntSize mSize; WindowsHandle mHandles[3]; bool mIsLocked; + YUVColorSpace mYUVColorSpace; }; class CompositingRenderTargetD3D11 : public CompositingRenderTarget, diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index ff93a17ebec4..0615d92d5a4f 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -52,6 +52,7 @@ struct SurfaceDescriptorDXGIYCbCr { IntSize size; IntSize sizeY; IntSize sizeCbCr; + YUVColorSpace yUVColorSpace; }; struct SurfaceDescriptorMacIOSurface {