From 51d9f4be53de1958335b94e3aa4bd68239af4d40 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Thu, 11 Apr 2019 12:39:12 +0000 Subject: [PATCH] Bug 1540581 - P18. Move destination texture type choice to the D3D11 texture allocator. r=mattwoodrow It allows for more readable code, not having to store multiple times different storage type across multiple objects. Now each class does one task and only deal with a single texture data type. Differential Revision: https://phabricator.services.mozilla.com/D26473 --HG-- extra : moz-landing-system : lando --- dom/media/platforms/wmf/DXVA2Manager.cpp | 45 +++++++++++++++--- dom/media/platforms/wmf/DXVA2Manager.h | 1 - gfx/layers/D3D11ShareHandleImage.cpp | 58 +++++++++++++----------- gfx/layers/D3D11ShareHandleImage.h | 19 ++++---- 4 files changed, 81 insertions(+), 42 deletions(-) diff --git a/dom/media/platforms/wmf/DXVA2Manager.cpp b/dom/media/platforms/wmf/DXVA2Manager.cpp index 5cc428122720..80a00371bd9f 100644 --- a/dom/media/platforms/wmf/DXVA2Manager.cpp +++ b/dom/media/platforms/wmf/DXVA2Manager.cpp @@ -589,7 +589,7 @@ class D3D11DXVA2Manager : public DXVA2Manager { HRESULT CopyToImage(IMFSample* aVideoSample, const gfx::IntRect& aRegion, Image** aOutImage) override; - HRESULT CopyToBGRATexture(ID3D11Texture2D* aInTexture, const GUID& aSubType, + HRESULT CopyToBGRATexture(ID3D11Texture2D* aInTexture, ID3D11Texture2D** aOutTexture) override; HRESULT ConfigureForSize(IMFMediaType* aInputType, @@ -676,7 +676,8 @@ D3D11DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor, // There's no proper KnowsCompositor for ImageBridge currently (and it // implements the interface), so just use that if it's available. mTextureClientAllocator = new D3D11RecycleAllocator( - layers::ImageBridgeChild::GetSingleton().get(), mDevice); + layers::ImageBridgeChild::GetSingleton().get(), mDevice, + gfx::SurfaceFormat::NV12); if (ImageBridgeChild::GetSingleton() && gfxPrefs::PDMWMFUseSyncTexture() && mDevice != DeviceManagerDx::Get()->GetCompositorDevice()) { @@ -691,8 +692,8 @@ D3D11DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor, mDevice); } } else { - mTextureClientAllocator = - new D3D11RecycleAllocator(aKnowsCompositor, mDevice); + mTextureClientAllocator = new D3D11RecycleAllocator( + aKnowsCompositor, mDevice, gfx::SurfaceFormat::NV12); if (gfxPrefs::PDMWMFUseSyncTexture()) { // We use a syncobject to avoid the cost of the mutex lock when // compositing, and because it allows color conversion ocurring directly @@ -886,7 +887,7 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample, MOZ_ASSERT(mTextureClientAllocator); RefPtr image = new D3D11ShareHandleImage( - gfx::IntSize(mWidth, mHeight), aRegion, mInputSubType, mYUVColorSpace); + gfx::IntSize(mWidth, mHeight), aRegion, mYUVColorSpace); // Retrieve the DXGI_FORMAT for the current video sample. RefPtr buffer; @@ -928,6 +929,8 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample, NS_ENSURE_TRUE(mSyncObject, E_FAIL); } + // The D3D11TextureClientAllocator may return a different texture format + // than preferred. In which case the destination texture will be BGRA32. if (outDesc.Format == inDesc.Format) { // Our video frame is stored in a non-sharable ID3D11Texture2D. We need // to create a copy of that frame as a sharable resource, save its share @@ -974,7 +977,6 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample, HRESULT D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D* aInTexture, - const GUID& aSubType, ID3D11Texture2D** aOutTexture) { NS_ENSURE_TRUE(aInTexture, E_POINTER); NS_ENSURE_TRUE(aOutTexture, E_POINTER); @@ -995,7 +997,21 @@ D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D* aInTexture, hr = inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); - hr = inputType->SetGUID(MF_MT_SUBTYPE, aSubType); + const GUID subType = [&]() { + switch (desc.Format) { + case DXGI_FORMAT_NV12: + return MFVideoFormat_NV12; + case DXGI_FORMAT_P010: + return MFVideoFormat_P010; + case DXGI_FORMAT_P016: + return MFVideoFormat_P016; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected texture type"); + return MFVideoFormat_NV12; + } + }(); + + hr = inputType->SetGUID(MF_MT_SUBTYPE, subType); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); hr = inputType->SetUINT32(MF_MT_INTERLACE_MODE, @@ -1136,6 +1152,21 @@ D3D11DXVA2Manager::ConfigureForSize(IMFMediaType* aInputType, mInputType = inputType; mInputSubType = subType; mYUVColorSpace = aColorSpace; + if (mTextureClientAllocator) { + gfx::SurfaceFormat format = [&]() { + if (subType == MFVideoFormat_NV12) { + return gfx::SurfaceFormat::NV12; + } else if (subType == MFVideoFormat_P010) { + return gfx::SurfaceFormat::P010; + } else if (subType == MFVideoFormat_P016) { + return gfx::SurfaceFormat::P016; + } else { + MOZ_ASSERT_UNREACHABLE("Unexpected texture type"); + return gfx::SurfaceFormat::NV12; + } + }(); + mTextureClientAllocator->SetPreferredSurfaceFormat(format); + } return S_OK; } diff --git a/dom/media/platforms/wmf/DXVA2Manager.h b/dom/media/platforms/wmf/DXVA2Manager.h index 6bae98d7c308..6a646c941ed2 100644 --- a/dom/media/platforms/wmf/DXVA2Manager.h +++ b/dom/media/platforms/wmf/DXVA2Manager.h @@ -43,7 +43,6 @@ class DXVA2Manager { layers::Image** aOutImage) = 0; virtual HRESULT CopyToBGRATexture(ID3D11Texture2D* aInTexture, - const GUID& aSubType, ID3D11Texture2D** aOutTexture) { // Not implemented! MOZ_CRASH("CopyToBGRATexture not implemented on this manager."); diff --git a/gfx/layers/D3D11ShareHandleImage.cpp b/gfx/layers/D3D11ShareHandleImage.cpp index 34178acc3d5c..a054ec5fbf81 100644 --- a/gfx/layers/D3D11ShareHandleImage.cpp +++ b/gfx/layers/D3D11ShareHandleImage.cpp @@ -25,35 +25,16 @@ using namespace gfx; D3D11ShareHandleImage::D3D11ShareHandleImage(const gfx::IntSize& aSize, const gfx::IntRect& aRect, - const GUID& aSourceFormat, gfx::YUVColorSpace aColorSpace) : Image(nullptr, ImageFormat::D3D11_SHARE_HANDLE_TEXTURE), mSize(aSize), mPictureRect(aRect), - mSourceFormat(aSourceFormat), mYUVColorSpace(aColorSpace) {} bool D3D11ShareHandleImage::AllocateTexture(D3D11RecycleAllocator* aAllocator, ID3D11Device* aDevice) { if (aAllocator) { - if (mSourceFormat == MFVideoFormat_NV12 && - gfxPrefs::PDMWMFUseNV12Format() && - gfx::DeviceManagerDx::Get()->CanUseNV12()) { - mTextureClient = aAllocator->CreateOrRecycleClient( - gfx::SurfaceFormat::NV12, mYUVColorSpace, mSize); - } else if (((mSourceFormat == MFVideoFormat_P010 && - gfx::DeviceManagerDx::Get()->CanUseP010()) || - (mSourceFormat == MFVideoFormat_P016 && - gfx::DeviceManagerDx::Get()->CanUseP016())) && - gfxPrefs::PDMWMFUseNV12Format()) { - mTextureClient = aAllocator->CreateOrRecycleClient( - mSourceFormat == MFVideoFormat_P010 ? gfx::SurfaceFormat::P010 - : gfx::SurfaceFormat::P016, - mYUVColorSpace, mSize); - } else { - mTextureClient = aAllocator->CreateOrRecycleClient( - gfx::SurfaceFormat::B8G8R8A8, gfx::YUVColorSpace::UNKNOWN, mSize); - } + mTextureClient = aAllocator->CreateOrRecycleClient(mYUVColorSpace, mSize); if (mTextureClient) { D3D11TextureData* textureData = mTextureClient->GetInternalData()->AsD3D11TextureData(); @@ -111,8 +92,7 @@ D3D11ShareHandleImage::GetAsSourceSurface() { RefPtr outTexture; - hr = manager->CopyToBGRATexture(texture, mSourceFormat, - getter_AddRefs(outTexture)); + hr = manager->CopyToBGRATexture(texture, getter_AddRefs(outTexture)); if (FAILED(hr)) { gfxWarning() << "Failed to copy to BGRA texture."; @@ -239,9 +219,35 @@ class MOZ_RAII D3D11TextureClientAllocationHelper const RefPtr mDevice; }; +D3D11RecycleAllocator::D3D11RecycleAllocator( + KnowsCompositor* aAllocator, ID3D11Device* aDevice, + gfx::SurfaceFormat aPreferredFormat) + : TextureClientRecycleAllocator(aAllocator), + mDevice(aDevice), + mCanUseNV12(gfxPrefs::PDMWMFUseNV12Format() && + gfx::DeviceManagerDx::Get()->CanUseNV12()), + mCanUseP010(gfxPrefs::PDMWMFUseNV12Format() && + gfx::DeviceManagerDx::Get()->CanUseP010()), + mCanUseP016(gfxPrefs::PDMWMFUseNV12Format() && + gfx::DeviceManagerDx::Get()->CanUseP016()) { + SetPreferredSurfaceFormat(aPreferredFormat); +} + +void D3D11RecycleAllocator::SetPreferredSurfaceFormat( + gfx::SurfaceFormat aPreferredFormat) { + if ((aPreferredFormat == gfx::SurfaceFormat::NV12 && mCanUseNV12) || + (aPreferredFormat == gfx::SurfaceFormat::P010 && mCanUseP010) || + (aPreferredFormat == gfx::SurfaceFormat::P016 && mCanUseP016)) { + mUsableSurfaceFormat = aPreferredFormat; + return; + } + // We can't handle the native source format, set it to BGRA which will + // force the caller to convert it later. + mUsableSurfaceFormat = gfx::SurfaceFormat::B8G8R8A8; +} + already_AddRefed D3D11RecycleAllocator::CreateOrRecycleClient( - gfx::SurfaceFormat aFormat, gfx::YUVColorSpace aColorSpace, - const gfx::IntSize& aSize) { + gfx::YUVColorSpace aColorSpace, const gfx::IntSize& aSize) { // When CompositorDevice or ContentDevice is updated, // we could not reuse old D3D11Textures. It could cause video flickering. RefPtr device = gfx::DeviceManagerDx::Get()->GetImageDevice(); @@ -258,8 +264,8 @@ already_AddRefed D3D11RecycleAllocator::CreateOrRecycleClient( allocFlags = TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION; } - D3D11TextureClientAllocationHelper helper(aFormat, aColorSpace, aSize, - allocFlags, mDevice, + D3D11TextureClientAllocationHelper helper(mUsableSurfaceFormat, aColorSpace, + aSize, allocFlags, mDevice, layers::TextureFlags::DEFAULT); RefPtr textureClient = CreateOrRecycle(helper); diff --git a/gfx/layers/D3D11ShareHandleImage.h b/gfx/layers/D3D11ShareHandleImage.h index d700e412f73f..e0fdb664ac30 100644 --- a/gfx/layers/D3D11ShareHandleImage.h +++ b/gfx/layers/D3D11ShareHandleImage.h @@ -21,19 +21,24 @@ namespace layers { class D3D11RecycleAllocator final : public TextureClientRecycleAllocator { public: - D3D11RecycleAllocator(KnowsCompositor* aAllocator, ID3D11Device* aDevice) - : TextureClientRecycleAllocator(aAllocator), mDevice(aDevice) {} + D3D11RecycleAllocator(KnowsCompositor* aAllocator, ID3D11Device* aDevice, + gfx::SurfaceFormat aPreferredFormat); already_AddRefed CreateOrRecycleClient( - gfx::SurfaceFormat aFormat, gfx::YUVColorSpace aColorSpace, - const gfx::IntSize& aSize); + gfx::YUVColorSpace aColorSpace, const gfx::IntSize& aSize); - protected: - RefPtr mDevice; + void SetPreferredSurfaceFormat(gfx::SurfaceFormat aPreferredFormat); + + private: + const RefPtr mDevice; + const bool mCanUseNV12; + const bool mCanUseP010; + const bool mCanUseP016; /** * Used for checking if CompositorDevice/ContentDevice is updated. */ RefPtr mImageDevice; + gfx::SurfaceFormat mUsableSurfaceFormat; }; // Image class that wraps a ID3D11Texture2D. This class copies the image @@ -43,7 +48,6 @@ class D3D11RecycleAllocator final : public TextureClientRecycleAllocator { class D3D11ShareHandleImage final : public Image { public: D3D11ShareHandleImage(const gfx::IntSize& aSize, const gfx::IntRect& aRect, - const GUID& aSourceFormat, gfx::YUVColorSpace aColorSpace); virtual ~D3D11ShareHandleImage() = default; @@ -62,7 +66,6 @@ class D3D11ShareHandleImage final : public Image { private: gfx::IntSize mSize; gfx::IntRect mPictureRect; - const GUID mSourceFormat; gfx::YUVColorSpace mYUVColorSpace; RefPtr mTextureClient; RefPtr mTexture;