Bug 1088414. Use a single synchronized texture for d3d11. r=bas,f=jrmuizel

Calling AcquireSync on textures created with
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX appears to be really slow, this really
bites us with the number of textures involved when tiling.

I've also tested using ID3D11Query to check when work is completed, this also
appears to be pretty slow.

This instead just uses a single texture with a keyedmutex, and makes sure we
draw to it last and lock it first. It's pretty hacky, but seems to work really
well so far.

--HG--
extra : rebase_source : bf5f56751f993e507fcd1e5c386fb1fc9a3f73af
This commit is contained in:
Matt Woodrow 2014-10-22 15:37:00 +13:00
parent 0579846e7e
commit a543eacc24
6 changed files with 121 additions and 2 deletions

View File

@ -529,6 +529,8 @@ ClientLayerManager::StopFrameTimeRecording(uint32_t aStartIndex,
void
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
{
gfxPlatform::GetPlatform()->FenceContentDrawing();
mPhase = PHASE_FORWARD;
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId();

View File

@ -829,6 +829,8 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
UpdateRenderTarget();
gfxPlatform::GetPlatform()->WaitContentDrawing();
// Failed to create a render target or the view.
if (!mDefaultRT || !mDefaultRT->mRTView ||
mSize.width == 0 || mSize.height == 0) {

View File

@ -357,7 +357,7 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
aSize.width, aSize.height, 1, 1,
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
hr = d3d11device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
} else
@ -369,7 +369,7 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
aSize.width, aSize.height, 1, 1,
D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;
hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture10));
}

View File

@ -247,6 +247,8 @@ public:
return false;
}
virtual void FenceContentDrawing() {}
virtual void WaitContentDrawing() {}
/**
* Returns true if we should use Azure to render content with aTarget. For
* example, it is possible that we are using Direct2D for rendering and thus

View File

@ -1434,6 +1434,106 @@ gfxWindowsPlatform::GetD3D9DeviceManager()
return mDeviceManager;
}
ID3D11Texture2D*
gfxWindowsPlatform::GetD3D11Texture()
{
if (mD3D11Texture) {
return mD3D11Texture;
}
MOZ_ASSERT(mD3D10Texture || mD3D11ContentTexture);
RefPtr<IDXGIResource> resource;
if (mD3D10Texture) {
mD3D10Texture->QueryInterface((IDXGIResource**)byRef(resource));
} else {
mD3D11ContentTexture->QueryInterface((IDXGIResource**)byRef(resource));
}
HANDLE sharedHandle;
HRESULT hr = resource->GetSharedHandle(&sharedHandle);
hr = GetD3D11Device()->OpenSharedResource(sharedHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)byRef(mD3D11Texture));
return mD3D11Texture;
}
ID3D11Texture2D*
gfxWindowsPlatform::GetD3D11ContentTexture()
{
if (mD3D11ContentTexture) {
return mD3D11ContentTexture;
}
ID3D11Device* device = GetD3D11ContentDevice();
CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
1, 1, 1, 1,
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mD3D11ContentTexture));
return mD3D11ContentTexture;
}
ID3D10Texture2D*
gfxWindowsPlatform::GetD3D10Texture()
{
if (mD3D10Texture) {
return mD3D10Texture;
}
ID3D10Device* device = GetD3D10Device();
CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
1, 1, 1, 1,
D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mD3D10Texture));
return mD3D10Texture;
}
void
gfxWindowsPlatform::FenceContentDrawing()
{
#ifdef USE_D2D1_1
if (gfxPrefs::Direct2DUse1_1() && GetD3D11ContentDevice()) {
ID3D11Texture2D* tex = GetD3D11ContentTexture();
RefPtr<IDXGIKeyedMutex> mutex;
tex->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
mutex->AcquireSync(0, INFINITE);
RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForD3D11Texture(tex, SurfaceFormat::B8G8R8A8);
dt->ClearRect(Rect(0, 0, 1, 1));
dt->Flush();
dt = nullptr;
mutex->ReleaseSync(0);
} else
#endif
if (GetD3D10Device()) {
ID3D10Texture2D* tex = GetD3D10Texture();
RefPtr<IDXGIKeyedMutex> mutex;
tex->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
mutex->AcquireSync(0, INFINITE);
RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForD3D10Texture(tex, SurfaceFormat::B8G8R8A8);
dt->ClearRect(Rect(0, 0, 1, 1));
dt->Flush();
dt = nullptr;
mutex->ReleaseSync(0);
}
}
void
gfxWindowsPlatform::WaitContentDrawing()
{
ID3D11Texture2D *sentinelTexture = GetD3D11Texture();
RefPtr<IDXGIKeyedMutex> mutex;
sentinelTexture->QueryInterface((IDXGIKeyedMutex**)byRef(mutex));
mutex->AcquireSync(0, INFINITE);
mutex->ReleaseSync(0);
}
ID3D11Device*
gfxWindowsPlatform::GetD3D11Device()
{

View File

@ -55,6 +55,7 @@ class ReadbackManagerD3D11;
struct IDirect3DDevice9;
struct ID3D11Device;
struct IDXGIAdapter1;
struct ID3D11Texture2D;
class nsIMemoryReporter;
@ -255,6 +256,13 @@ public:
ID3D11Device *GetD3D11Device();
ID3D11Device *GetD3D11ContentDevice();
ID3D10Texture2D* GetD3D10Texture();
ID3D11Texture2D* GetD3D11Texture();
ID3D11Texture2D* GetD3D11ContentTexture();
virtual void FenceContentDrawing();
virtual void WaitContentDrawing();
mozilla::layers::ReadbackManagerD3D11* GetReadbackManager();
static bool IsOptimus();
@ -289,6 +297,11 @@ private:
bool mD3D11DeviceInitialized;
mozilla::RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
mozilla::RefPtr<ID3D10Texture2D> mD3D10Texture;
mozilla::RefPtr<ID3D11Texture2D> mD3D11Texture;
mozilla::RefPtr<ID3D11Texture2D> mD3D11ContentTexture;
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
// TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList