Bug 1046550 - Part 3: Use Direct2D 1.1 when preffed on. r=bas

This commit is contained in:
Matt Woodrow 2014-09-14 23:51:27 +02:00
parent 8c5c06f212
commit b14244ee9a
7 changed files with 94 additions and 25 deletions

View File

@ -11,6 +11,7 @@
#include "gfxWindowsPlatform.h"
#include "gfxD2DSurface.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#include "ReadbackManagerD3D11.h"
namespace mozilla {
@ -172,8 +173,12 @@ TextureClientD3D11::TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags
TextureClientD3D11::~TextureClientD3D11()
{
if (mTexture && mActor) {
KeepUntilFullDeallocation(new TKeepAlive<ID3D10Texture2D>(mTexture));
if (mActor) {
if (mTexture) {
KeepUntilFullDeallocation(new TKeepAlive<ID3D10Texture2D>(mTexture10));
} else if (mTexture10) {
KeepUntilFullDeallocation(new TKeepAlive<ID3D11Texture2D>(mTexture));
}
}
#ifdef DEBUG
// An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
@ -181,11 +186,19 @@ TextureClientD3D11::~TextureClientD3D11()
// shouldn't -really- need the lock but the debug layer chokes on this.
if (mDrawTarget) {
MOZ_ASSERT(!mIsLocked);
MOZ_ASSERT(mTexture);
MOZ_ASSERT(mTexture || mTexture10);
MOZ_ASSERT(mDrawTarget->refCount() == 1);
LockD3DTexture(mTexture.get());
if (mTexture) {
LockD3DTexture(mTexture.get());
} else {
LockD3DTexture(mTexture10.get());
}
mDrawTarget = nullptr;
UnlockD3DTexture(mTexture.get());
if (mTexture) {
UnlockD3DTexture(mTexture.get());
} else {
UnlockD3DTexture(mTexture10.get());
}
}
#endif
}
@ -206,12 +219,18 @@ TextureClientD3D11::CreateSimilar(TextureFlags aFlags,
bool
TextureClientD3D11::Lock(OpenMode aMode)
{
if (!mTexture) {
if (!IsAllocated()) {
return false;
}
MOZ_ASSERT(!mIsLocked, "The Texture is already locked!");
mIsLocked = LockD3DTexture(mTexture.get());
if (mTexture) {
MOZ_ASSERT(!mTexture10);
mIsLocked = LockD3DTexture(mTexture.get());
} else {
MOZ_ASSERT(!mTexture);
mIsLocked = LockD3DTexture(mTexture10.get());
}
if (!mIsLocked) {
return false;
}
@ -254,11 +273,11 @@ TextureClientD3D11::Unlock()
mDrawTarget->Flush();
}
if (mReadbackSink) {
if (mReadbackSink && mTexture10) {
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
mTexture10->GetDesc(&desc);
desc.BindFlags = 0;
desc.Usage = D3D10_USAGE_STAGING;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
@ -268,7 +287,7 @@ TextureClientD3D11::Unlock()
HRESULT hr = device->CreateTexture2D(&desc, nullptr, byRef(tex));
if (SUCCEEDED(hr)) {
device->CopyResource(tex, mTexture);
device->CopyResource(tex, mTexture10);
gfxWindowsPlatform::GetPlatform()->GetReadbackManager()->PostTask(tex, mReadbackSink);
} else {
@ -278,7 +297,11 @@ TextureClientD3D11::Unlock()
// The DrawTarget is created only once, and is only usable between calls
// to Lock and Unlock.
UnlockD3DTexture(mTexture.get());
if (mTexture) {
UnlockD3DTexture(mTexture.get());
} else {
UnlockD3DTexture(mTexture10.get());
}
mIsLocked = false;
}
@ -287,7 +310,7 @@ TextureClientD3D11::BorrowDrawTarget()
{
MOZ_ASSERT(mIsLocked, "Calling TextureClient::BorrowDrawTarget without locking :(");
if (!mTexture) {
if (!mTexture && !mTexture10) {
return nullptr;
}
@ -296,7 +319,15 @@ TextureClientD3D11::BorrowDrawTarget()
}
// This may return a null DrawTarget
mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture, mFormat);
#if USE_D2D1_1
if (mTexture) {
mDrawTarget = Factory::CreateDrawTargetForD3D11Texture(mTexture, mFormat);
} else
#endif
{
MOZ_ASSERT(mTexture10);
mDrawTarget = Factory::CreateDrawTargetForD3D10Texture(mTexture10, mFormat);
}
return mDrawTarget;
}
@ -304,15 +335,32 @@ bool
TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
{
mSize = aSize;
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
HRESULT hr;
#ifdef USE_D2D1_1
ID3D11Device* d3d11device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
aSize.width, aSize.height, 1, 1,
D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
if (gfxPrefs::Direct2DUse1_1() && d3d11device) {
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
aSize.width, aSize.height, 1, 1,
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
hr = d3d11device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
} else
#endif
{
ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
aSize.width, aSize.height, 1, 1,
D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture10));
}
if (FAILED(hr)) {
LOGD3D11("Error creating texture for client!");
@ -332,9 +380,13 @@ TextureClientD3D11::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
if (!IsAllocated()) {
return false;
}
RefPtr<IDXGIResource> resource;
mTexture->QueryInterface((IDXGIResource**)byRef(resource));
if (mTexture) {
mTexture->QueryInterface((IDXGIResource**)byRef(resource));
} else {
mTexture10->QueryInterface((IDXGIResource**)byRef(resource));
}
HANDLE sharedHandle;
HRESULT hr = resource->GetSharedHandle(&sharedHandle);

View File

@ -34,7 +34,7 @@ public:
// TextureClient
virtual bool IsAllocated() const MOZ_OVERRIDE { return !!mTexture; }
virtual bool IsAllocated() const MOZ_OVERRIDE { return mTexture || mTexture10; }
virtual bool Lock(OpenMode aOpenMode) MOZ_OVERRIDE;
@ -65,7 +65,8 @@ public:
protected:
gfx::IntSize mSize;
RefPtr<ID3D10Texture2D> mTexture;
RefPtr<ID3D10Texture2D> mTexture10;
RefPtr<ID3D11Texture2D> mTexture;
RefPtr<gfx::DrawTarget> mDrawTarget;
gfx::SurfaceFormat mFormat;
bool mIsLocked;

View File

@ -98,7 +98,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
SOURCES += [
'd3d11/CompositorD3D11.cpp',
'd3d11/ReadbackManagerD3D11.cpp',
]
]
if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
DEFINES['USE_D2D1_1'] = True
EXPORTS.gfxipc += [
'ipc/ShadowLayerUtils.h',

View File

@ -993,6 +993,8 @@ gfxPlatform::BackendTypeForName(const nsCString& aName)
return BackendType::SKIA;
if (aName.EqualsLiteral("direct2d"))
return BackendType::DIRECT2D;
if (aName.EqualsLiteral("direct2d1.1"))
return BackendType::DIRECT2D1_1;
if (aName.EqualsLiteral("cg"))
return BackendType::COREGRAPHICS;
return BackendType::NONE;

View File

@ -192,6 +192,7 @@ private:
DECL_GFX_PREF(Once, "gfx.direct2d.disabled", Direct2DDisabled, bool, false);
DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled", Direct2DForceEnabled, bool, false);
DECL_GFX_PREF(Live, "gfx.direct2d.use1_1", Direct2DUse1_1, bool, false);
DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels", GrallocFenceWithReadPixels, bool, false);
DECL_GFX_PREF(Live, "gfx.layerscope.enabled", LayerScopeEnabled, bool, false);
DECL_GFX_PREF(Live, "gfx.layerscope.port", LayerScopePort, int32_t, 23456);

View File

@ -312,6 +312,10 @@ gfxWindowsPlatform::gfxWindowsPlatform()
UpdateRenderMode();
if (gfxPrefs::Direct2DUse1_1()) {
InitD3D11Devices();
}
RegisterStrongMemoryReporter(new GPUAdapterReporter());
}
@ -438,7 +442,12 @@ gfxWindowsPlatform::UpdateRenderMode()
if (mRenderMode == RENDER_DIRECT2D) {
canvasMask |= BackendTypeBit(BackendType::DIRECT2D);
contentMask |= BackendTypeBit(BackendType::DIRECT2D);
defaultBackend = BackendType::DIRECT2D;
if (gfxPrefs::Direct2DUse1_1() && Factory::SupportsD2D1()) {
contentMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
defaultBackend = BackendType::DIRECT2D1_1;
} else {
defaultBackend = BackendType::DIRECT2D;
}
} else {
canvasMask |= BackendTypeBit(BackendType::SKIA);
}

View File

@ -184,6 +184,8 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'gfxDWriteFontList.cpp',
'gfxDWriteFonts.cpp',
]
if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
DEFINES['USE_D2D1_1'] = True
# Are we targeting x86 or x64? If so, build gfxAlphaRecoverySSE2.cpp.
if CONFIG['INTEL_ARCHITECTURE']: