mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1257013 - Part 2: Use readback to synchronize d3d11 video. r=cpearce, r=Bas
This commit is contained in:
parent
a4e47cb2a8
commit
bb3b79e71e
@ -523,6 +523,7 @@ private:
|
||||
RefPtr<IMFDXGIDeviceManager> mDXGIDeviceManager;
|
||||
RefPtr<MFTDecoder> mTransform;
|
||||
RefPtr<D3D11RecycleAllocator> mTextureClientAllocator;
|
||||
RefPtr<ID3D11Texture2D> mSyncSurface;
|
||||
GUID mDecoderGUID;
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
@ -702,6 +703,22 @@ D3D11DXVA2Manager::Init(nsACString& aFailureReason)
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
desc.Width = kSyncSurfaceSize;
|
||||
desc.Height = kSyncSurfaceSize;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.BindFlags = 0;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
hr = mDevice->CreateTexture2D(&desc, NULL, getter_AddRefs(mSyncSurface));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
mTextureClientAllocator = new D3D11RecycleAllocator(layers::ImageBridgeChild::GetSingleton(),
|
||||
mDevice);
|
||||
mTextureClientAllocator->SetMaxPoolSize(5);
|
||||
@ -753,18 +770,22 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
||||
hr = CreateOutputSample(sample, texture);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> keyedMutex;
|
||||
hr = texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(getter_AddRefs(keyedMutex)));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && keyedMutex, hr);
|
||||
|
||||
hr = keyedMutex->AcquireSync(0, INFINITE);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = mTransform->Output(&sample);
|
||||
|
||||
keyedMutex->ReleaseSync(0);
|
||||
RefPtr<ID3D11DeviceContext> ctx;
|
||||
mDevice->GetImmediateContext(getter_AddRefs(ctx));
|
||||
|
||||
// Copy a small rect into our sync surface, and then map it
|
||||
// to block until decoding/color conversion completes.
|
||||
D3D11_BOX rect = { 0, 0, 0, kSyncSurfaceSize, kSyncSurfaceSize, 1 };
|
||||
ctx->CopySubresourceRegion(mSyncSurface, 0, 0, 0, 0, texture, 0, &rect);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
hr = ctx->Map(mSyncSurface, 0, D3D11_MAP_READ, 0, &mapped);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
ctx->Unmap(mSyncSurface, 0);
|
||||
|
||||
image.forget(aOutImage);
|
||||
|
||||
return S_OK;
|
||||
|
@ -55,17 +55,6 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
RefPtr<ID3D11Device> device;
|
||||
texture->GetDevice(getter_AddRefs(device));
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> keyedMutex;
|
||||
if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(getter_AddRefs(keyedMutex))))) {
|
||||
NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (FAILED(keyedMutex->AcquireSync(0, 0))) {
|
||||
NS_WARNING("Failed to acquire sync for keyedMutex, plugin failed to release?");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
texture->GetDesc(&desc);
|
||||
|
||||
@ -83,19 +72,16 @@ D3D11ShareHandleImage::GetAsSourceSurface()
|
||||
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to create 2D staging texture.");
|
||||
keyedMutex->ReleaseSync(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11DeviceContext> context;
|
||||
device->GetImmediateContext(getter_AddRefs(context));
|
||||
if (!context) {
|
||||
keyedMutex->ReleaseSync(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
context->CopyResource(softTexture, texture);
|
||||
keyedMutex->ReleaseSync(0);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surface =
|
||||
gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
|
||||
@ -152,7 +138,8 @@ D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
CreateOrRecycle(aFormat,
|
||||
aSize,
|
||||
BackendSelector::Content,
|
||||
layers::TextureFlags::DEFAULT);
|
||||
layers::TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
|
||||
return textureClient.forget();
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,10 @@ enum TextureAllocationFlags {
|
||||
// TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
|
||||
// surfaces when used on the main thread.
|
||||
ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5,
|
||||
|
||||
// Disable any cross-device synchronization. This is also for TextureClientD3D11,
|
||||
// and creates a texture without KeyedMutex.
|
||||
ALLOC_MANUAL_SYNCHRONIZATION = 1 << 6,
|
||||
};
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -135,7 +135,8 @@ TextureClientRecycleAllocator::CreateOrRecycle(ITextureClientAllocationHelper& a
|
||||
// This class does not handle ContentClient's TextureClient allocation.
|
||||
MOZ_ASSERT(aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
|
||||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT ||
|
||||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT);
|
||||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT ||
|
||||
aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
|
||||
MOZ_ASSERT(aHelper.mTextureFlags & TextureFlags::RECYCLE);
|
||||
|
||||
RefPtr<TextureClientHolder> textureHolder;
|
||||
|
@ -362,7 +362,9 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
|
||||
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
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;
|
||||
if (!(aFlags & ALLOC_MANUAL_SYNCHRONIZATION)) {
|
||||
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = d3d11device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(texture11));
|
||||
|
Loading…
Reference in New Issue
Block a user