mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-22 10:27:03 +00:00
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
This commit is contained in:
parent
896eec30a3
commit
51d9f4be53
@ -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<D3D11ShareHandleImage> 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<IMFMediaBuffer> 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;
|
||||
}
|
||||
|
||||
|
@ -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.");
|
||||
|
@ -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<ID3D11Texture2D> 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<ID3D11Device> 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<TextureClient> 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<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
|
||||
@ -258,8 +264,8 @@ already_AddRefed<TextureClient> 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> textureClient = CreateOrRecycle(helper);
|
||||
|
@ -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<TextureClient> CreateOrRecycleClient(
|
||||
gfx::SurfaceFormat aFormat, gfx::YUVColorSpace aColorSpace,
|
||||
const gfx::IntSize& aSize);
|
||||
gfx::YUVColorSpace aColorSpace, const gfx::IntSize& aSize);
|
||||
|
||||
protected:
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
void SetPreferredSurfaceFormat(gfx::SurfaceFormat aPreferredFormat);
|
||||
|
||||
private:
|
||||
const RefPtr<ID3D11Device> mDevice;
|
||||
const bool mCanUseNV12;
|
||||
const bool mCanUseP010;
|
||||
const bool mCanUseP016;
|
||||
/**
|
||||
* Used for checking if CompositorDevice/ContentDevice is updated.
|
||||
*/
|
||||
RefPtr<ID3D11Device> 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<TextureClient> mTextureClient;
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
|
Loading…
x
Reference in New Issue
Block a user