Bug 1138967 - Part 3: Add D3D11 YCbCr texture clients and upload on the client side. r=nical, a=lmandel
new file mode 100644
--- /dev/null
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "IMFYCbCrImage.h"
+#include "mozilla/layers/TextureD3D11.h"
+#include "mozilla/layers/CompositableClient.h"
+#include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/layers/TextureClient.h"
+
+namespace mozilla {
+namespace layers {
+
+IMFYCbCrImage::IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer)
+ : PlanarYCbCrImage(nullptr)
+ , mBuffer(aBuffer)
+ , m2DBuffer(a2DBuffer)
+{}
+
+IMFYCbCrImage::~IMFYCbCrImage()
+{
+ if (m2DBuffer) {
+ m2DBuffer->Unlock2D();
+ }
+ else {
+ mBuffer->Unlock();
+ }
+}
+
+struct AutoLockTexture
+{
+ AutoLockTexture(ID3D11Texture2D* aTexture)
+ {
+ aTexture->QueryInterface((IDXGIKeyedMutex**)byRef(mMutex));
+ HRESULT hr = mMutex->AcquireSync(0, 10000);
+ if (hr == WAIT_TIMEOUT) {
+ MOZ_CRASH();
+ }
+
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to lock the texture");
+ }
+ }
+
+ ~AutoLockTexture()
+ {
+ HRESULT hr = mMutex->ReleaseSync(0);
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to unlock the texture");
+ }
+ }
+
+ RefPtr<IDXGIKeyedMutex> mMutex;
+};
+
+TextureClient*
+IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
+{
+ ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11MediaDevice();
+ if (!device ||
+ aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) {
+ return nullptr;
+ }
+
+ if (mTextureClient) {
+ return mTextureClient;
+ }
+
+ RefPtr<ID3D11DeviceContext> ctx;
+ device->GetImmediateContext(byRef(ctx));
+
+ CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_A8_UNORM,
+ mData.mYSize.width, mData.mYSize.height, 1, 1);
+
+ newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+
+ RefPtr<ID3D11Texture2D> textureY;
+ HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureY));
+ NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+ newDesc.Width = mData.mCbCrSize.width;
+ newDesc.Height = mData.mCbCrSize.height;
+
+ RefPtr<ID3D11Texture2D> textureCb;
+ hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCb));
+ NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+ RefPtr<ID3D11Texture2D> textureCr;
+ hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCr));
+ NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+ {
+ AutoLockTexture lockY(textureY);
+ AutoLockTexture lockCb(textureCb);
+ AutoLockTexture lockCr(textureCr);
+
+ ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel,
+ mData.mYStride, mData.mYStride * mData.mYSize.height);
+ ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel,
+ mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height);
+ ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel,
+ mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height);
+ }
+
+ RefPtr<DXGIYCbCrTextureClientD3D11> texClient =
+ new DXGIYCbCrTextureClientD3D11(aClient->GetForwarder(), TextureFlags::DEFAULT);
+ texClient->InitWith(textureY, textureCb, textureCr, GetSize());
+ mTextureClient = texClient;
+
+ return mTextureClient;
+}
+
+
+} /* layers */
+} /* mozilla */
--- a/gfx/layers/IMFYCbCrImage.h
+++ b/gfx/layers/IMFYCbCrImage.h
@@ -11,40 +11,31 @@
#include "Mfidl.h"
namespace mozilla {
namespace layers {
class IMFYCbCrImage : public PlanarYCbCrImage
{
public:
- IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer)
- : PlanarYCbCrImage(nullptr)
- , mBuffer(aBuffer)
- , m2DBuffer(a2DBuffer)
- {}
+ IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer);
virtual bool IsValid() { return true; }
+ virtual TextureClient* GetTextureClient(CompositableClient* aClient) MOZ_OVERRIDE;
+
protected:
virtual uint8_t* AllocateBuffer(uint32_t aSize) MOZ_OVERRIDE {
MOZ_CRASH("Can't do manual allocations with IMFYCbCrImage");
return nullptr;
}
- ~IMFYCbCrImage()
- {
- if (m2DBuffer) {
- m2DBuffer->Unlock2D();
- }
- else {
- mBuffer->Unlock();
- }
- }
+ ~IMFYCbCrImage();
RefPtr<IMFMediaBuffer> mBuffer;
RefPtr<IMF2DBuffer> m2DBuffer;
+ RefPtr<TextureClient> mTextureClient;
};
} // namepace layers
} // namespace mozilla
#endif // GFX_D3DSURFACEIMAGE_H
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -227,16 +227,17 @@ TextureHost::Create(const SurfaceDescrip
}
#endif
#ifdef XP_WIN
case SurfaceDescriptor::TSurfaceDescriptorD3D9:
return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
+ case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr:
if (Compositor::GetBackend() == LayersBackend::LAYERS_D3D9) {
return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
} else {
return CreateTextureHostD3D11(aDesc, aDeallocator, aFlags);
}
#endif
default:
MOZ_CRASH("Unsupported Surface type");
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -153,16 +153,21 @@ CreateTextureHostD3D11(const SurfaceDesc
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
break;
}
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
result = new DXGITextureHostD3D11(aFlags,
aDesc.get_SurfaceDescriptorD3D10());
break;
}
+ case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr: {
+ result = new DXGIYCbCrTextureHostD3D11(aFlags,
+ aDesc.get_SurfaceDescriptorDXGIYCbCr());
+ break;
+ }
default: {
NS_WARNING("Unsupported SurfaceDescriptor type");
}
}
return result;
}
TextureClientD3D11::TextureClientD3D11(ISurfaceAllocator* aAllocator,
@@ -491,16 +496,92 @@ TextureClientD3D11::ToSurfaceDescriptor(
LOGD3D11("Error getting shared handle for texture.");
return false;
}
aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, mFormat, mSize);
return true;
}
+DXGIYCbCrTextureClientD3D11::DXGIYCbCrTextureClientD3D11(ISurfaceAllocator* aAllocator,
+ TextureFlags aFlags)
+ : TextureClient(aAllocator, aFlags)
+ , mIsLocked(false)
+{
+ MOZ_COUNT_CTOR(DXGIYCbCrTextureClientD3D11);
+}
+
+class YCbCrKeepAliveD3D11 : public KeepAlive
+{
+public:
+ YCbCrKeepAliveD3D11(RefPtr<ID3D11Texture2D> aTextures[3])
+ {
+ mTextures[0] = aTextures[0];
+ mTextures[1] = aTextures[1];
+ mTextures[2] = aTextures[2];
+ }
+
+protected:
+ RefPtr<ID3D11Texture2D> mTextures[3];
+};
+
+DXGIYCbCrTextureClientD3D11::~DXGIYCbCrTextureClientD3D11()
+{
+ if (mTextures[0] && mActor) {
+ KeepUntilFullDeallocation(MakeUnique<YCbCrKeepAliveD3D11>(mTextures));
+ }
+ MOZ_COUNT_DTOR(DXGIYCbCrTextureClientD3D11);
+}
+
+bool
+DXGIYCbCrTextureClientD3D11::Lock(OpenMode)
+{
+ MOZ_ASSERT(!mIsLocked);
+ if (!IsValid()) {
+ return false;
+ }
+ mIsLocked = true;
+ return true;
+}
+
+void
+DXGIYCbCrTextureClientD3D11::Unlock()
+{
+ MOZ_ASSERT(mIsLocked, "Unlock called while the texture is not locked!");
+ mIsLocked = false;
+}
+
+bool
+DXGIYCbCrTextureClientD3D11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+{
+ MOZ_ASSERT(IsValid());
+ if (!IsAllocated()) {
+ return false;
+ }
+
+ RefPtr<IDXGIResource> resource;
+ mTextures[0]->QueryInterface((IDXGIResource**)byRef(resource));
+
+ HANDLE sharedHandleY;
+ HRESULT hr = resource->GetSharedHandle(&sharedHandleY);
+
+ mTextures[1]->QueryInterface((IDXGIResource**)byRef(resource));
+
+ HANDLE sharedHandleCb;
+ hr = resource->GetSharedHandle(&sharedHandleCb);
+
+ mTextures[2]->QueryInterface((IDXGIResource**)byRef(resource));
+
+ HANDLE sharedHandleCr;
+ hr = resource->GetSharedHandle(&sharedHandleCr);
+
+ aOutDescriptor = SurfaceDescriptorDXGIYCbCr((WindowsHandle)sharedHandleY, (WindowsHandle)sharedHandleCb, (WindowsHandle)sharedHandleCr, GetSize());
+ return true;
+}
+
DXGITextureHostD3D11::DXGITextureHostD3D11(TextureFlags aFlags,
const SurfaceDescriptorD3D10& aDescriptor)
: TextureHost(aFlags)
, mSize(aDescriptor.size())
, mHandle(aDescriptor.handle())
, mFormat(aDescriptor.format())
, mIsLocked(false)
{
@@ -571,16 +652,118 @@ TextureSource*
DXGITextureHostD3D11::GetTextureSources()
{
MOZ_ASSERT(mIsLocked);
// If Lock was successful we must have a valid TextureSource.
MOZ_ASSERT(mTextureSource);
return mTextureSource.get();
}
+DXGIYCbCrTextureHostD3D11::DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
+ const SurfaceDescriptorDXGIYCbCr& aDescriptor)
+ : TextureHost(aFlags)
+ , mSize(aDescriptor.size())
+ , mIsLocked(false)
+{
+ mHandles[0] = aDescriptor.handleY();
+ mHandles[1] = aDescriptor.handleCb();
+ mHandles[2] = aDescriptor.handleCr();
+}
+
+bool
+DXGIYCbCrTextureHostD3D11::OpenSharedHandle()
+{
+ if (!GetDevice()) {
+ return false;
+ }
+
+ HRESULT hr = GetDevice()->OpenSharedResource((HANDLE)mHandles[0],
+ __uuidof(ID3D11Texture2D),
+ (void**)(ID3D11Texture2D**)byRef(mTextures[0]));
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to open shared texture for Y Plane");
+ return false;
+ }
+
+ hr = GetDevice()->OpenSharedResource((HANDLE)mHandles[1],
+ __uuidof(ID3D11Texture2D),
+ (void**)(ID3D11Texture2D**)byRef(mTextures[1]));
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to open shared texture for Cb Plane");
+ return false;
+ }
+
+ hr = GetDevice()->OpenSharedResource((HANDLE)mHandles[2],
+ __uuidof(ID3D11Texture2D),
+ (void**)(ID3D11Texture2D**)byRef(mTextures[2]));
+ if (FAILED(hr)) {
+ NS_WARNING("Failed to open shared texture for Cr Plane");
+ return false;
+ }
+
+ return true;
+}
+
+ID3D11Device*
+DXGIYCbCrTextureHostD3D11::GetDevice()
+{
+ return gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
+}
+
+void
+DXGIYCbCrTextureHostD3D11::SetCompositor(Compositor* aCompositor)
+{
+ mCompositor = static_cast<CompositorD3D11*>(aCompositor);
+}
+
+bool
+DXGIYCbCrTextureHostD3D11::Lock()
+{
+ if (!GetDevice()) {
+ NS_WARNING("trying to lock a TextureHost without a D3D device");
+ return false;
+ }
+ if (!mTextureSources[0]) {
+ if (!mTextures[0] && !OpenSharedHandle()) {
+ return false;
+ }
+
+ mTextureSources[0] = new DataTextureSourceD3D11(SurfaceFormat::A8, mCompositor, mTextures[0]);
+ mTextureSources[1] = new DataTextureSourceD3D11(SurfaceFormat::A8, mCompositor, mTextures[1]);
+ mTextureSources[2] = new DataTextureSourceD3D11(SurfaceFormat::A8, mCompositor, mTextures[2]);
+ mTextureSources[0]->SetNextSibling(mTextureSources[1]);
+ mTextureSources[1]->SetNextSibling(mTextureSources[2]);
+ }
+
+ mIsLocked = LockD3DTexture(mTextureSources[0]->GetD3D11Texture()) &&
+ LockD3DTexture(mTextureSources[1]->GetD3D11Texture()) &&
+ LockD3DTexture(mTextureSources[2]->GetD3D11Texture());
+
+ return mIsLocked;
+}
+
+void
+DXGIYCbCrTextureHostD3D11::Unlock()
+{
+ MOZ_ASSERT(mIsLocked);
+ UnlockD3DTexture(mTextureSources[0]->GetD3D11Texture());
+ UnlockD3DTexture(mTextureSources[1]->GetD3D11Texture());
+ UnlockD3DTexture(mTextureSources[2]->GetD3D11Texture());
+ mIsLocked = false;
+}
+
+TextureSource*
+DXGIYCbCrTextureHostD3D11::GetTextureSources()
+{
+ MOZ_ASSERT(mIsLocked);
+ // If Lock was successful we must have a valid TextureSource.
+ MOZ_ASSERT(mTextureSources[0] && mTextureSources[1] && mTextureSources[2]);
+ return mTextureSources[0].get();
+}
+
bool
DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
nsIntRegion* aDestRegion,
IntPoint* aSrcOffset)
{
// Incremental update with a source offset is only used on Mac so it is not
// clear that we ever will need to support it for D3D.
MOZ_ASSERT(!aSrcOffset);
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -73,16 +73,69 @@ protected:
RefPtr<ID3D11Texture2D> mTexture;
RefPtr<gfx::DrawTarget> mDrawTarget;
gfx::SurfaceFormat mFormat;
bool mIsLocked;
bool mNeedsClear;
bool mNeedsClearWhite;
};
+class DXGIYCbCrTextureClientD3D11 : public TextureClient
+{
+public:
+ DXGIYCbCrTextureClientD3D11(ISurfaceAllocator* aAllocator,
+ TextureFlags aFlags);
+
+ virtual ~DXGIYCbCrTextureClientD3D11();
+
+ // TextureClient
+
+ virtual bool IsAllocated() const MOZ_OVERRIDE{ return !!mTextures[0]; }
+
+ virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE;
+
+ virtual void Unlock() MOZ_OVERRIDE;
+
+ virtual bool IsLocked() const MOZ_OVERRIDE{ return mIsLocked; }
+
+ virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
+
+ void InitWith(ID3D11Texture2D* aTextureY,
+ ID3D11Texture2D* aTextureCb,
+ ID3D11Texture2D* aTextureCr,
+ const gfx::IntSize& aSize)
+ {
+ MOZ_ASSERT(aTextureY && aTextureCb && aTextureCr);
+ MOZ_ASSERT(!mTextures[0]);
+ mTextures[0] = aTextureY;
+ mTextures[1] = aTextureCb;
+ mTextures[2] = aTextureCr;
+ mSize = aSize;
+ }
+
+ virtual gfx::IntSize GetSize() const
+ {
+ return mSize;
+ }
+
+ virtual bool HasInternalBuffer() const MOZ_OVERRIDE{ return true; }
+
+ // This TextureClient should not be used in a context where we use CreateSimilar
+ // (ex. component alpha) because the underlying texture data is always created by
+ // an external producer.
+ virtual TemporaryRef<TextureClient>
+ CreateSimilar(TextureFlags, TextureAllocationFlags) const MOZ_OVERRIDE{ return nullptr; }
+
+private:
+ RefPtr<ID3D11Texture2D> mTextures[3];
+ gfx::IntSize mSize;
+ bool mIsLocked;
+};
+
+
/**
* TextureSource that provides with the necessary APIs to be composited by a
* CompositorD3D11.
*/
class TextureSourceD3D11
{
public:
TextureSourceD3D11() {}
@@ -208,16 +261,55 @@ protected:
RefPtr<DataTextureSourceD3D11> mTextureSource;
RefPtr<CompositorD3D11> mCompositor;
gfx::IntSize mSize;
WindowsHandle mHandle;
gfx::SurfaceFormat mFormat;
bool mIsLocked;
};
+class DXGIYCbCrTextureHostD3D11 : public TextureHost
+{
+public:
+ DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
+ const SurfaceDescriptorDXGIYCbCr& aDescriptor);
+
+ virtual TextureSource* GetTextureSources() MOZ_OVERRIDE;
+
+ virtual void DeallocateDeviceData() MOZ_OVERRIDE{}
+
+ virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
+
+ virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE{ return gfx::SurfaceFormat::YUV; }
+
+ virtual bool Lock() MOZ_OVERRIDE;
+
+ virtual void Unlock() MOZ_OVERRIDE;
+
+ virtual gfx::IntSize GetSize() const MOZ_OVERRIDE{ return mSize; }
+
+ virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE
+ {
+ return nullptr;
+ }
+
+protected:
+ ID3D11Device* GetDevice();
+
+ bool OpenSharedHandle();
+
+ RefPtr<ID3D11Texture2D> mTextures[3];
+ RefPtr<DataTextureSourceD3D11> mTextureSources[3];
+
+ RefPtr<CompositorD3D11> mCompositor;
+ gfx::IntSize mSize;
+ WindowsHandle mHandles[3];
+ bool mIsLocked;
+};
+
class CompositingRenderTargetD3D11 : public CompositingRenderTarget,
public TextureSourceD3D11
{
public:
CompositingRenderTargetD3D11(ID3D11Texture2D* aTexture,
const gfx::IntPoint& aOrigin);
virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -45,16 +45,23 @@ struct SurfaceDescriptorDIB {
};
struct SurfaceDescriptorD3D10 {
WindowsHandle handle;
SurfaceFormat format;
IntSize size;
};
+struct SurfaceDescriptorDXGIYCbCr {
+ WindowsHandle handleY;
+ WindowsHandle handleCb;
+ WindowsHandle handleCr;
+ IntSize size;
+};
+
struct SurfaceDescriptorMacIOSurface {
uint32_t surface;
double scaleFactor;
bool isOpaque;
};
struct SurfaceTextureDescriptor {
uintptr_t surfTex;
@@ -99,16 +106,17 @@ struct SurfaceDescriptorShmem {
};
union SurfaceDescriptor {
SurfaceDescriptorShmem;
SurfaceDescriptorMemory;
SurfaceDescriptorD3D9;
SurfaceDescriptorDIB;
SurfaceDescriptorD3D10;
+ SurfaceDescriptorDXGIYCbCr;
SurfaceDescriptorX11;
SurfaceTextureDescriptor;
EGLImageDescriptor;
SurfaceDescriptorMacIOSurface;
NewSurfaceDescriptorGralloc;
SharedSurfaceDescriptor;
null_t;
};
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -40,16 +40,17 @@ EXPORTS += [
'protobuf/LayerScopePacket.pb.h',
'ReadbackLayer.h',
'TiledLayerBuffer.h',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
UNIFIED_SOURCES += [
'D3D9SurfaceImage.cpp',
+ 'IMFYCbCrImage.cpp',
'TextureDIB.cpp',
]
EXPORTS.mozilla.layers += [
'TextureDIB.h',
]
if CONFIG['MOZ_ENABLE_D3D9_LAYER']:
EXPORTS += [
'd3d9/DeviceManagerD3D9.h',
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1587,16 +1587,29 @@ gfxWindowsPlatform::GetD3D11ContentDevic
return mD3D11ContentDevice;
}
InitD3D11Devices();
return mD3D11ContentDevice;
}
+ID3D11Device*
+gfxWindowsPlatform::GetD3D11MediaDevice()
+{
+ if (mD3D11DeviceInitialized) {
+ return mD3D11MediaDevice;
+ }
+
+ InitD3D11Devices();
+
+ return mD3D11MediaDevice;
+}
+
+
ReadbackManagerD3D11*
gfxWindowsPlatform::GetReadbackManager()
{
if (!mD3D11ReadbackManager) {
mD3D11ReadbackManager = new ReadbackManagerD3D11();
}
return mD3D11ReadbackManager;
@@ -1947,13 +1960,32 @@ gfxWindowsPlatform::InitD3D11Devices()
return;
}
mD3D11ContentDevice->SetExceptionMode(0);
Factory::SetDirect3D11Device(mD3D11ContentDevice);
}
+ if (!useWARP || gfxPrefs::LayersD3D11ForceWARP()) {
+ hr = E_INVALIDARG;
+ MOZ_SEH_TRY{
+ hr = d3d11CreateDevice(adapter, useWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+ D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+ featureLevels.Elements(), featureLevels.Length(),
+ D3D11_SDK_VERSION, byRef(mD3D11MediaDevice), nullptr, nullptr);
+ } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+ mD3D11MediaDevice = nullptr;
+ }
+
+ if (FAILED(hr)) {
+ d3d11Module.disown();
+ return;
+ }
+
+ mD3D11MediaDevice->SetExceptionMode(0);
+ }
+
// We leak these everywhere and we need them our entire runtime anyway, let's
// leak it here as well.
d3d11Module.disown();
}
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -245,16 +245,17 @@ public:
mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager();
IDirect3DDevice9* GetD3D9Device();
#ifdef CAIRO_HAS_D2D_SURFACE
cairo_device_t *GetD2DDevice() { return mD2DDevice; }
ID3D10Device1 *GetD3D10Device() { return mD2DDevice ? cairo_d2d_device_get_device(mD2DDevice) : nullptr; }
#endif
ID3D11Device *GetD3D11Device();
ID3D11Device *GetD3D11ContentDevice();
+ ID3D11Device *GetD3D11MediaDevice();
mozilla::layers::ReadbackManagerD3D11* GetReadbackManager();
static bool IsOptimus();
bool IsWARP() { return mIsWARP; }
static mozilla::Atomic<size_t> sD3D11MemoryUsed;
@@ -284,16 +285,17 @@ private:
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
cairo_device_t *mD2DDevice;
#endif
mozilla::RefPtr<IDXGIAdapter1> mAdapter;
nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager;
mozilla::RefPtr<ID3D11Device> mD3D11Device;
mozilla::RefPtr<ID3D11Device> mD3D11ContentDevice;
+ mozilla::RefPtr<ID3D11Device> mD3D11MediaDevice;
bool mD3D11DeviceInitialized;
mozilla::RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
bool mIsWARP;
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
};
bool DoesD3D11TextureSharingWork(ID3D11Device *device);