mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1195527 - Part 1: Move D3D11 texture allocation into the TextureClient. r=jrmuizel
This commit is contained in:
parent
41c06ffb4f
commit
d07dcdfcf6
@ -415,7 +415,7 @@ private:
|
||||
HRESULT CreateFormatConverter();
|
||||
|
||||
HRESULT CreateOutputSample(RefPtr<IMFSample>& aSample,
|
||||
RefPtr<ID3D11Texture2D>& aTexture);
|
||||
ID3D11Texture2D* aTexture);
|
||||
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
@ -490,37 +490,19 @@ D3D11DXVA2Manager::Init(nsACString& aFailureReason)
|
||||
}
|
||||
|
||||
HRESULT
|
||||
D3D11DXVA2Manager::CreateOutputSample(RefPtr<IMFSample>& aSample, RefPtr<ID3D11Texture2D>& aTexture)
|
||||
D3D11DXVA2Manager::CreateOutputSample(RefPtr<IMFSample>& aSample, ID3D11Texture2D* aTexture)
|
||||
{
|
||||
RefPtr<IMFSample> sample;
|
||||
HRESULT hr = wmf::MFCreateSample(byRef(sample));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
desc.Width = mWidth;
|
||||
desc.Height = mHeight;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(texture));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
RefPtr<IMFMediaBuffer> buffer;
|
||||
hr = wmf::MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), texture, 0, FALSE, byRef(buffer));
|
||||
hr = wmf::MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), aTexture, 0, FALSE, byRef(buffer));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
sample->AddBuffer(buffer);
|
||||
|
||||
aSample = sample;
|
||||
aTexture = texture;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -538,11 +520,21 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
||||
// to create a copy of that frame as a sharable resource, save its share
|
||||
// handle, and put that handle into the rendering pipeline.
|
||||
|
||||
HRESULT hr = mTransform->Input(aVideoSample);
|
||||
ImageFormat format = ImageFormat::D3D11_SHARE_HANDLE_TEXTURE;
|
||||
nsRefPtr<Image> image(aContainer->CreateImage(format));
|
||||
NS_ENSURE_TRUE(image, E_FAIL);
|
||||
NS_ASSERTION(image->GetFormat() == ImageFormat::D3D11_SHARE_HANDLE_TEXTURE,
|
||||
"Wrong format?");
|
||||
|
||||
D3D11ShareHandleImage* videoImage = static_cast<D3D11ShareHandleImage*>(image.get());
|
||||
HRESULT hr = videoImage->SetData(D3D11ShareHandleImage::Data(mDevice, gfx::IntSize(mWidth, mHeight), aRegion));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = mTransform->Input(aVideoSample);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
RefPtr<IMFSample> sample;
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
RefPtr<ID3D11Texture2D> texture = videoImage->GetTexture();
|
||||
hr = CreateOutputSample(sample, texture);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
@ -558,16 +550,6 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
||||
keyedMutex->ReleaseSync(0);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
ImageFormat format = ImageFormat::D3D11_SHARE_HANDLE_TEXTURE;
|
||||
nsRefPtr<Image> image(aContainer->CreateImage(format));
|
||||
NS_ENSURE_TRUE(image, E_FAIL);
|
||||
NS_ASSERTION(image->GetFormat() == ImageFormat::D3D11_SHARE_HANDLE_TEXTURE,
|
||||
"Wrong format?");
|
||||
|
||||
D3D11ShareHandleImage* videoImage = static_cast<D3D11ShareHandleImage*>(image.get());
|
||||
hr = videoImage->SetData(D3D11ShareHandleImage::Data(texture, mDevice, mContext, aRegion));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
image.forget(aOutImage);
|
||||
|
||||
return S_OK;
|
||||
|
@ -19,16 +19,17 @@ namespace layers {
|
||||
HRESULT
|
||||
D3D11ShareHandleImage::SetData(const Data& aData)
|
||||
{
|
||||
NS_ENSURE_TRUE(aData.mTexture, E_POINTER);
|
||||
mTexture = aData.mTexture;
|
||||
mPictureRect = aData.mRegion;
|
||||
mSize = aData.mSize;
|
||||
|
||||
D3D11_TEXTURE2D_DESC frameDesc;
|
||||
mTexture->GetDesc(&frameDesc);
|
||||
|
||||
mFormat = gfx::SurfaceFormat::B8G8R8A8;
|
||||
mSize.width = frameDesc.Width;
|
||||
mSize.height = frameDesc.Height;
|
||||
mTextureClient = TextureClientD3D11::Create(nullptr,
|
||||
gfx::SurfaceFormat::B8G8R8A8,
|
||||
TextureFlags::DEFAULT,
|
||||
aData.mDevice,
|
||||
mSize);
|
||||
if (!mTextureClient) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -42,29 +43,23 @@ D3D11ShareHandleImage::GetSize()
|
||||
TextureClient*
|
||||
D3D11ShareHandleImage::GetTextureClient(CompositableClient* aClient)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
mTextureClient = TextureClientD3D11::Create(aClient->GetForwarder(),
|
||||
mFormat,
|
||||
TextureFlags::DEFAULT,
|
||||
mTexture,
|
||||
mSize);
|
||||
}
|
||||
return mTextureClient;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
{
|
||||
if (!mTexture) {
|
||||
RefPtr<ID3D11Texture2D> texture = GetTexture();
|
||||
if (!texture) {
|
||||
NS_WARNING("Cannot readback from shared texture because no texture is available.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11Device> device;
|
||||
mTexture->GetDevice(byRef(device));
|
||||
texture->GetDevice(byRef(device));
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> keyedMutex;
|
||||
if (FAILED(mTexture->QueryInterface(static_cast<IDXGIKeyedMutex**>(byRef(keyedMutex))))) {
|
||||
if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(byRef(keyedMutex))))) {
|
||||
NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
|
||||
return nullptr;
|
||||
}
|
||||
@ -75,7 +70,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
mTexture->GetDesc(&desc);
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
|
||||
softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
@ -102,7 +97,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
context->CopyResource(softTexture, mTexture);
|
||||
context->CopyResource(softTexture, texture);
|
||||
keyedMutex->ReleaseSync(0);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
@ -137,7 +132,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
|
||||
ID3D11Texture2D*
|
||||
D3D11ShareHandleImage::GetTexture() const {
|
||||
return mTexture;
|
||||
return mTextureClient->GetD3D11Texture();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "d3d11.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -23,17 +24,14 @@ class D3D11ShareHandleImage : public Image {
|
||||
public:
|
||||
|
||||
struct Data {
|
||||
Data(ID3D11Texture2D* aTexture,
|
||||
ID3D11Device* aDevice,
|
||||
ID3D11DeviceContext* aContext,
|
||||
Data(ID3D11Device* aDevice,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntRect& aRegion)
|
||||
: mTexture(aTexture),
|
||||
mDevice(aDevice),
|
||||
mContext(aContext),
|
||||
mRegion(aRegion) {}
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
: mDevice(aDevice)
|
||||
, mSize(aSize)
|
||||
, mRegion(aRegion) {}
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntRect mRegion;
|
||||
};
|
||||
|
||||
@ -58,11 +56,7 @@ private:
|
||||
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntRect mPictureRect;
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
HANDLE mShareHandle;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
|
||||
RefPtr<TextureClientD3D11> mTextureClient;
|
||||
};
|
||||
|
||||
} // namepace layers
|
||||
|
@ -244,6 +244,22 @@ TextureClientD3D11::Create(ISurfaceAllocator* aAllocator,
|
||||
return texture.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClientD3D11>
|
||||
TextureClientD3D11::Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Device* aDevice,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
RefPtr<TextureClientD3D11> texture = new TextureClientD3D11(aAllocator,
|
||||
aFormat,
|
||||
aFlags);
|
||||
if (!texture->AllocateD3D11Surface(aDevice, aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
return texture.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClientD3D11::CreateSimilar(TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const
|
||||
@ -513,6 +529,35 @@ private:
|
||||
int mMemoryUsed;
|
||||
};
|
||||
|
||||
bool
|
||||
TextureClientD3D11::AllocateD3D11Surface(ID3D11Device* aDevice, const gfx::IntSize& aSize)
|
||||
{
|
||||
MOZ_ASSERT(aDevice != nullptr);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC newDesc(mFormat == SurfaceFormat::A8 ? DXGI_FORMAT_R8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
aSize.width, aSize.height, 1, 1,
|
||||
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
|
||||
|
||||
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
// On the main thread we use the syncobject to handle synchronization.
|
||||
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
}
|
||||
|
||||
HRESULT hr = aDevice->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
|
||||
if (FAILED(hr)) {
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
|
||||
return false;
|
||||
}
|
||||
mTexture->SetPrivateDataInterface(sD3D11TextureUsage,
|
||||
new TextureMemoryMeasurer(newDesc.Width * newDesc.Height *
|
||||
(mFormat == SurfaceFormat::A8 ?
|
||||
1 : 4)));
|
||||
mSize = aSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
|
||||
{
|
||||
@ -532,30 +577,10 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
|
||||
bool haveD3d11Backend = windowsPlatform->GetContentBackend() == BackendType::DIRECT2D1_1 || !NS_IsMainThread();
|
||||
|
||||
if (haveD3d11Backend) {
|
||||
MOZ_ASSERT(d3d11device != nullptr);
|
||||
|
||||
CD3D11_TEXTURE2D_DESC newDesc(mFormat == SurfaceFormat::A8 ? DXGI_FORMAT_R8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
aSize.width, aSize.height, 1, 1,
|
||||
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
|
||||
|
||||
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
// On the main thread we use the syncobject to handle synchronization.
|
||||
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
}
|
||||
|
||||
hr = d3d11device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
|
||||
if (FAILED(hr)) {
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
|
||||
if (!AllocateD3D11Surface(d3d11device, aSize)) {
|
||||
return false;
|
||||
}
|
||||
mTexture->SetPrivateDataInterface(sD3D11TextureUsage,
|
||||
new TextureMemoryMeasurer(newDesc.Width * newDesc.Height *
|
||||
(mFormat == SurfaceFormat::A8 ?
|
||||
1 : 4)));
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
|
||||
|
||||
CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
|
@ -40,6 +40,13 @@ public:
|
||||
ID3D11Texture2D* aTexture,
|
||||
gfx::IntSize aSize);
|
||||
|
||||
static already_AddRefed<TextureClientD3D11>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
ID3D11Device* aDevice,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override { return mTexture || mTexture10; }
|
||||
@ -75,7 +82,11 @@ public:
|
||||
|
||||
virtual void SyncWithObject(SyncObject* aSyncObject) override;
|
||||
|
||||
ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
|
||||
|
||||
protected:
|
||||
bool AllocateD3D11Surface(ID3D11Device* aDevice, const gfx::IntSize& aSize);
|
||||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<ID3D10Texture2D> mTexture10;
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
|
Loading…
Reference in New Issue
Block a user