Allow asynchronous D3D11 TextureClients on the main thread. (bug 1217665 part 5, r=nical)

--HG--
extra : rebase_source : a06aecbf63b0cb55b388da75c50e211fbb95d5c8
This commit is contained in:
David Anderson 2015-12-02 11:31:17 -08:00
Родитель 7dfba52625
Коммит 978468f6f4
5 изменённых файлов: 44 добавлений и 23 удалений

Просмотреть файл

@ -714,7 +714,8 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
#ifdef XP_WIN
if (parentBackend == LayersBackend::LAYERS_D3D11 &&
(moz2DBackend == gfx::BackendType::DIRECT2D ||
moz2DBackend == gfx::BackendType::DIRECT2D1_1) &&
moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT)) &&
aSize.width <= maxTextureSize &&
aSize.height <= maxTextureSize)
{

Просмотреть файл

@ -69,10 +69,15 @@ class KeepAlive;
*/
enum TextureAllocationFlags {
ALLOC_DEFAULT = 0,
ALLOC_CLEAR_BUFFER = 1,
ALLOC_CLEAR_BUFFER_WHITE = 2,
ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 4
ALLOC_DEFAULT = 0x0,
ALLOC_CLEAR_BUFFER = 0x1,
ALLOC_CLEAR_BUFFER_WHITE = 0x2,
ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 0x4,
// Allocate the texture for out-of-band content updates. This is mostly for
// TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
// surfaces when used on the main thread.
ALLOC_FOR_OUT_OF_BAND_CONTENT = 0x8
};
#ifdef XP_WIN

Просмотреть файл

@ -80,9 +80,10 @@ TextureClientRecycleAllocator::CreateOrRecycle(gfx::SurfaceFormat aFormat,
TextureAllocationFlags aAllocFlags)
{
// TextureAllocationFlags is actually used only by ContentClient.
// This class does not handle ConteClient's TextureClient allocation.
// This class does not handle ContentClient's TextureClient allocation.
MOZ_ASSERT(aAllocFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
aAllocFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
aAllocFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT ||
aAllocFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT);
MOZ_ASSERT(!(aTextureFlags & TextureFlags::RECYCLE));
aTextureFlags = aTextureFlags | TextureFlags::RECYCLE; // Set recycle flag

Просмотреть файл

@ -214,18 +214,21 @@ static void UnlockD3DTexture(T* aTexture)
}
DXGITextureData::DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite)
bool aNeedsClear, bool aNeedsClearWhite,
bool aIsForOutOfBandContent)
: mSize(aSize)
, mFormat(aFormat)
, mNeedsClear(aNeedsClear)
, mNeedsClearWhite(aNeedsClearWhite)
, mHasSynchronization(false)
, mIsForOutOfBandContent(aIsForOutOfBandContent)
{}
D3D11TextureData::D3D11TextureData(ID3D11Texture2D* aTexture,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite)
: DXGITextureData(aSize, aFormat, aNeedsClear, aNeedsClearWhite)
bool aNeedsClear, bool aNeedsClearWhite,
bool aIsForOutOfBandContent)
: DXGITextureData(aSize, aFormat, aNeedsClear, aNeedsClearWhite, aIsForOutOfBandContent)
, mTexture(aTexture)
{
MOZ_ASSERT(aTexture);
@ -248,8 +251,9 @@ D3D11TextureData::~D3D11TextureData()
D3D10TextureData::D3D10TextureData(ID3D10Texture2D* aTexture,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite)
: DXGITextureData(aSize, aFormat, aNeedsClear, aNeedsClearWhite)
bool aNeedsClear, bool aNeedsClearWhite,
bool aIsForOutOfBandContent)
: DXGITextureData(aSize, aFormat, aNeedsClear, aNeedsClearWhite, aIsForOutOfBandContent)
, mTexture(aTexture)
{
MOZ_ASSERT(aTexture);
@ -277,7 +281,7 @@ D3D11TextureData::Lock(OpenMode aMode, FenceHandle*)
return false;
}
if (NS_IsMainThread()) {
if (NS_IsMainThread() && !mIsForOutOfBandContent) {
if (!PrepareDrawTargetInLock(aMode)) {
Unlock();
return false;
@ -294,7 +298,7 @@ D3D10TextureData::Lock(OpenMode aMode, FenceHandle*)
return false;
}
if (NS_IsMainThread()) {
if (NS_IsMainThread() && !mIsForOutOfBandContent) {
if (!PrepareDrawTargetInLock(aMode)) {
Unlock();
return false;
@ -343,7 +347,7 @@ D3D10TextureData::Unlock()
void
D3D11TextureData::SyncWithObject(SyncObject* aSyncObject)
{
if (!aSyncObject || !NS_IsMainThread()) {
if (!aSyncObject || !NS_IsMainThread() || mIsForOutOfBandContent) {
// When off the main thread we sync using a keyed mutex per texture.
return;
}
@ -424,9 +428,12 @@ DXGITextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocationF
gfxWindowsPlatform* windowsPlatform = gfxWindowsPlatform::GetPlatform();
// When we're not on the main thread we're not going to be using Direct2D
// to access the contents of this texture client so we will always use D3D11.
bool haveD3d11Backend = windowsPlatform->GetContentBackendFor(LayersBackend::LAYERS_D3D11) == BackendType::DIRECT2D1_1 || !NS_IsMainThread();
bool useD3D11 =
windowsPlatform->GetContentBackendFor(LayersBackend::LAYERS_D3D11) == BackendType::DIRECT2D1_1 ||
!NS_IsMainThread() ||
(aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT);
if (haveD3d11Backend) {
if (useD3D11) {
return D3D11TextureData::Create(aSize, aFormat, aFlags);
} else {
return D3D10TextureData::Create(aSize, aFormat, aFlags);
@ -450,7 +457,7 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
if (!NS_IsMainThread()) {
if (!NS_IsMainThread() || !!(aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT)) {
// On the main thread we use the syncobject to handle synchronization.
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
}
@ -465,7 +472,8 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
new TextureMemoryMeasurer(newDesc.Width * newDesc.Height * 4));
return new D3D11TextureData(texture11, aSize, aFormat,
aFlags & ALLOC_CLEAR_BUFFER,
aFlags & ALLOC_CLEAR_BUFFER_WHITE);
aFlags & ALLOC_CLEAR_BUFFER_WHITE,
aFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT);
}
void
@ -518,7 +526,8 @@ D3D10TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
return new D3D10TextureData(texture10, aSize, aFormat,
aFlags & ALLOC_CLEAR_BUFFER,
aFlags & ALLOC_CLEAR_BUFFER_WHITE);
aFlags & ALLOC_CLEAR_BUFFER_WHITE,
false /* aIsForOutOfBandContent */);
}
void

Просмотреть файл

@ -42,7 +42,9 @@ public:
protected:
bool PrepareDrawTargetInLock(OpenMode aMode);
DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aNeedsClear, bool aNeedsClearWhite);
DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite,
bool aIsForOutOfBandContent);
virtual void GetDXGIResource(IDXGIResource** aOutResource) = 0;
@ -53,6 +55,7 @@ protected:
bool mNeedsClear;
bool mNeedsClearWhite;
bool mHasSynchronization;
bool mIsForOutOfBandContent;
};
class D3D11TextureData : public DXGITextureData
@ -88,7 +91,8 @@ public:
protected:
D3D11TextureData(ID3D11Texture2D* aTexture,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite);
bool aNeedsClear, bool aNeedsClearWhite,
bool aIsForOutOfBandContent);
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
@ -132,7 +136,8 @@ public:
protected:
D3D10TextureData(ID3D10Texture2D* aTexture,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite);
bool aNeedsClear, bool aNeedsClearWhite,
bool aIsForOutOfBandContent);
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;