Bug 1415763 - Fix DXGIYCbCrTextureData as to deliver YUVColorSpace r=mattwoodrow

This commit is contained in:
sotaro 2017-11-10 18:15:54 +09:00
Родитель f1d1a3edc1
Коммит a8b71fcd72
7 изменённых файлов: 114 добавлений и 44 удалений

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

@ -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<TextureClient> Allocate(KnowsCompositor* aAllocator) override;
protected:
const PlanarYCbCrData& mData;
RefPtr<ID3D11Device> 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<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData());
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<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData());
return mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData();
}
already_AddRefed<SourceSurface>
@ -144,7 +160,7 @@ D3D11YCbCrImage::GetAsSourceSurface()
PlanarYCbCrData data;
DXGIYCbCrTextureData* dxgiData =
static_cast<DXGIYCbCrTextureData*>(mTextureClient->GetInternalData());
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<TextureClient>
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<ID3D11Texture2D> 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<TextureClient>
D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat,
IntSize aSize,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;
}
} // namespace layers

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

@ -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<TextureClient>
@ -45,8 +44,6 @@ protected:
TextureAllocationFlags aAllocFlags) override;
RefPtr<ID3D11Device> mDevice;
Maybe<gfx::IntSize> mYSize;
Maybe<gfx::IntSize> mCbCrSize;
};
class D3D11YCbCrImage : public Image

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

@ -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*

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

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

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

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

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

@ -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,

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

@ -52,6 +52,7 @@ struct SurfaceDescriptorDXGIYCbCr {
IntSize size;
IntSize sizeY;
IntSize sizeCbCr;
YUVColorSpace yUVColorSpace;
};
struct SurfaceDescriptorMacIOSurface {