Bug 1289640 - Part 4: Make SourceSurfaceImage::GetTextureClient use the threadsafe upload with D3D11 so that we no longer rely on having a separate device. r=nical

--HG--
extra : rebase_source : aa63efd52e1b013251392e3bd4ec29af0e1286f0
This commit is contained in:
Matt Woodrow 2016-08-02 17:57:41 +12:00
parent cd24a38c5a
commit 2c65f7fdb0
6 changed files with 98 additions and 39 deletions

View File

@ -842,22 +842,14 @@ SourceSurfaceImage::GetTextureClient(CompositableClient *aClient)
#endif
if (!textureClient) {
// gfx::BackendType::NONE means default to content backend
textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
surface->GetSize(),
BackendSelector::Content,
TextureFlags::DEFAULT);
textureClient = aClient->CreateTextureClientFromSurface(surface,
BackendSelector::Content,
TextureFlags::DEFAULT);
}
if (!textureClient) {
return nullptr;
}
TextureClientAutoLock autoLock(textureClient, OpenMode::OPEN_WRITE_ONLY);
if (!autoLock.Succeeded()) {
return nullptr;
}
textureClient->UpdateFromSurface(surface);
textureClient->SyncWithObject(forwarder->GetSyncObject());
mTextureClients.Put(forwarder->GetSerial(), textureClient);

View File

@ -207,6 +207,20 @@ CompositableClient::CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat,
aAllocFlags);
}
already_AddRefed<TextureClient>
CompositableClient::CreateTextureClientFromSurface(gfx::SourceSurface* aSurface,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
return TextureClient::CreateFromSurface(GetForwarder()->AsTextureForwarder(),
aSurface,
GetForwarder()->GetCompositorBackendType(),
aSelector,
aTextureFlags | mTextureFlags,
aAllocFlags);
}
bool
CompositableClient::AddTextureClient(TextureClient* aClient)
{

View File

@ -148,6 +148,12 @@ public:
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
already_AddRefed<TextureClient>
CreateTextureClientFromSurface(gfx::SourceSurface* aSurface,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT);
/**
* Establishes the connection with compositor side through IPDL
*/

View File

@ -1106,6 +1106,68 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
moz2DBackend, aTextureFlags, aAllocFlags);
}
// static
already_AddRefed<TextureClient>
TextureClient::CreateFromSurface(TextureForwarder* aAllocator,
gfx::SourceSurface* aSurface,
LayersBackend aLayersBackend,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
aAllocator = aAllocator->AsTextureForwarder();
// also test the validity of aAllocator
MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
if (!aAllocator || !aAllocator->IPCOpen()) {
return nullptr;
}
gfx::IntSize size = aSurface->GetSize();
if (!gfx::Factory::AllowedSurfaceSize(size)) {
return nullptr;
}
TextureData* data = nullptr;
#if defined(XP_WIN)
gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(aLayersBackend, aSelector);
int32_t maxTextureSize = aAllocator->GetMaxTextureSize();
if (aLayersBackend == LayersBackend::LAYERS_D3D11 &&
(moz2DBackend == gfx::BackendType::DIRECT2D ||
moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
(!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
DeviceManagerD3D11::Get()->GetContentDevice())) &&
size.width <= maxTextureSize &&
size.height <= maxTextureSize)
{
data = D3D11TextureData::Create(aSurface, aAllocFlags);
}
#endif
if (data) {
return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
}
// Fall back to using UpdateFromSurface
RefPtr<TextureClient> client = CreateForDrawing(aAllocator, aSurface->GetFormat(), size,
aLayersBackend, aSelector, aTextureFlags, aAllocFlags);
if (!client) {
return nullptr;
}
TextureClientAutoLock autoLock(client, OpenMode::OPEN_WRITE_ONLY);
if (!autoLock.Succeeded()) {
return nullptr;
}
client->UpdateFromSurface(aSurface);
return client.forget();
}
// static
already_AddRefed<TextureClient>
TextureClient::CreateForRawBufferAccess(ClientIPCAllocator* aAllocator,

View File

@ -357,6 +357,14 @@ public:
TextureFlags aTextureFlags,
TextureAllocationFlags flags = ALLOC_DEFAULT);
static already_AddRefed<TextureClient>
CreateFromSurface(TextureForwarder* aAllocator,
gfx::SourceSurface* aSurface,
LayersBackend aLayersBackend,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags);
// Creates and allocates a TextureClient supporting the YCbCr format.
static already_AddRefed<TextureClient>
CreateForYCbCr(ClientIPCAllocator* aAllocator,

View File

@ -651,34 +651,11 @@ D3D11TextureData::BorrowDrawTarget()
bool
D3D11TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
{
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
if (!srcSurf) {
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface (D3D11).";
return false;
}
DataSourceSurface::MappedSurface sourceMap;
if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface (D3D11).";
return false;
}
RefPtr<ID3D11Device> device;
mTexture->GetDevice(getter_AddRefs(device));
RefPtr<ID3D11DeviceContext> ctx;
device->GetImmediateContext(getter_AddRefs(ctx));
D3D11_BOX box;
box.front = 0;
box.back = 1;
box.top = box.left = 0;
box.right = aSurface->GetSize().width;
box.bottom = aSurface->GetSize().height;
ctx->UpdateSubresource(mTexture, 0, &box, sourceMap.mData, sourceMap.mStride, 0);
srcSurf->Unmap();
return true;
// Supporting texture updates after creation requires an ID3D11DeviceContext and those
// aren't threadsafe. We'd need to either lock, or have a device for whatever thread
// this runs on and we're trying to avoid extra devices (bug 1284672).
MOZ_ASSERT(false, "UpdateFromSurface not supported for D3D11! Use CreateFromSurface instead");
return false;
}
DXGITextureHostD3D11::DXGITextureHostD3D11(TextureFlags aFlags,