mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 1357299 - P9: Do the refactoring for SyncObject. v2. r=mattwoodrow,dvander
The MLGDeviceD3D11, CompositorD3D11 and TextureClient use the same synchronization mechanism. Create the new SyncObjectClient/Host types for reusing code. Add SyncObject.cpp/h and create two new data types: SyncObjectClient and SyncObjectHost. The SyncObjectClient is used for the TextureClient synchronization at client side. The SyncObjectHost is used for the TextureHost synchronization in renderers such as MLGDeviceD3D11 and CompositorD3D11. MozReview-Commit-ID: 3l56WK1aZ15
This commit is contained in:
parent
384661a8d6
commit
50bd333891
49
gfx/layers/SyncObject.cpp
Normal file
49
gfx/layers/SyncObject.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SyncObject.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/TextureD3D11.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
already_AddRefed<SyncObjectHost>
|
||||
SyncObjectHost::CreateSyncObjectHost(
|
||||
#ifdef XP_WIN
|
||||
ID3D11Device* aDevice
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
return MakeAndAddRef<SyncObjectD3D11Host>(aDevice);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<SyncObjectClient>
|
||||
SyncObjectClient::CreateSyncObjectClient(SyncHandle aHandle
|
||||
#ifdef XP_WIN
|
||||
, ID3D11Device* aDevice
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (!aHandle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
return MakeAndAddRef<SyncObjectD3D11Client>(aHandle, aDevice);
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE();
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
73
gfx/layers/SyncObject.h
Normal file
73
gfx/layers/SyncObject.h
Normal file
@ -0,0 +1,73 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_LAYERS_SYNCOBJECT_H
|
||||
#define MOZILLA_GFX_LAYERS_SYNCOBJECT_H
|
||||
|
||||
#include "mozilla/RefCounted.h"
|
||||
|
||||
struct ID3D11Device;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef void* SyncHandle;
|
||||
#else
|
||||
typedef uintptr_t SyncHandle;
|
||||
#endif // XP_WIN
|
||||
|
||||
class SyncObjectHost : public RefCounted<SyncObjectHost>
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SyncObjectHost)
|
||||
virtual ~SyncObjectHost() { }
|
||||
|
||||
static already_AddRefed<SyncObjectHost> CreateSyncObjectHost(
|
||||
#ifdef XP_WIN
|
||||
ID3D11Device* aDevice = nullptr
|
||||
#endif
|
||||
);
|
||||
|
||||
virtual bool Init() = 0;
|
||||
|
||||
virtual SyncHandle GetSyncHandle() = 0;
|
||||
|
||||
virtual bool Synchronize() = 0;
|
||||
|
||||
protected:
|
||||
SyncObjectHost() { }
|
||||
};
|
||||
|
||||
class SyncObjectClient : public RefCounted<SyncObjectClient>
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SyncObjectClient)
|
||||
virtual ~SyncObjectClient() { }
|
||||
|
||||
static already_AddRefed<SyncObjectClient> CreateSyncObjectClient(SyncHandle aHandle
|
||||
#ifdef XP_WIN
|
||||
, ID3D11Device* aDevice = nullptr
|
||||
#endif
|
||||
);
|
||||
|
||||
enum class SyncType {
|
||||
D3D11,
|
||||
};
|
||||
|
||||
virtual SyncType GetSyncType() = 0;
|
||||
|
||||
virtual void Synchronize() = 0;
|
||||
|
||||
virtual bool IsSyncObjectValid() = 0;
|
||||
|
||||
protected:
|
||||
SyncObjectClient() { }
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif //MOZILLA_GFX_LAYERS_SYNCOBJECT_H
|
@ -1745,25 +1745,6 @@ UpdateYCbCrTextureClient(TextureClient* aTexture, const PlanarYCbCrData& aData)
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<SyncObject>
|
||||
SyncObject::CreateSyncObject(SyncHandle aHandle
|
||||
#ifdef XP_WIN
|
||||
, ID3D11Device* aDevice
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (!aHandle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
return MakeAndAddRef<SyncObjectD3D11>(aHandle, aDevice);
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE();
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, LayersIPCChannel* aAllocator)
|
||||
{
|
||||
|
@ -93,36 +93,6 @@ enum TextureAllocationFlags {
|
||||
ALLOC_UPDATE_FROM_SURFACE = 1 << 7,
|
||||
};
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef void* SyncHandle;
|
||||
#else
|
||||
typedef uintptr_t SyncHandle;
|
||||
#endif // XP_WIN
|
||||
|
||||
class SyncObject : public RefCounted<SyncObject>
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SyncObject)
|
||||
virtual ~SyncObject() { }
|
||||
|
||||
static already_AddRefed<SyncObject> CreateSyncObject(SyncHandle aHandle
|
||||
#ifdef XP_WIN
|
||||
, ID3D11Device* aDevice = nullptr
|
||||
#endif
|
||||
);
|
||||
|
||||
enum class SyncType {
|
||||
D3D11,
|
||||
};
|
||||
|
||||
virtual SyncType GetSyncType() = 0;
|
||||
virtual void FinalizeFrame() = 0;
|
||||
virtual bool IsSyncObjectValid() = 0;
|
||||
|
||||
protected:
|
||||
SyncObject() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* This class may be used to asynchronously receive an update when the content
|
||||
* drawn to this texture client is available for reading in CPU memory. This
|
||||
|
@ -1525,17 +1525,6 @@ CompositingRenderTargetD3D11::GetSize() const
|
||||
return TextureSourceD3D11::GetSize();
|
||||
}
|
||||
|
||||
SyncObjectD3D11::SyncObjectD3D11(SyncHandle aSyncHandle, ID3D11Device* aDevice)
|
||||
: mSyncHandle(aSyncHandle)
|
||||
{
|
||||
if (!aDevice) {
|
||||
mD3D11Device = DeviceManagerDx::Get()->GetContentDevice();
|
||||
return;
|
||||
}
|
||||
|
||||
mD3D11Device = aDevice;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ShouldDevCrashOnSyncInitFailure()
|
||||
{
|
||||
@ -1551,18 +1540,107 @@ ShouldDevCrashOnSyncInitFailure()
|
||||
!DeviceManagerDx::Get()->HasDeviceReset();
|
||||
}
|
||||
|
||||
SyncObjectD3D11Host::SyncObjectD3D11Host(ID3D11Device* aDevice)
|
||||
: mSyncHandle(0)
|
||||
, mDevice(aDevice)
|
||||
{
|
||||
MOZ_ASSERT(aDevice);
|
||||
}
|
||||
|
||||
bool
|
||||
SyncObjectD3D11::Init()
|
||||
SyncObjectD3D11Host::Init()
|
||||
{
|
||||
CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1,
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
|
||||
if (FAILED(hr) || !texture) {
|
||||
gfxWarning() << "Could not create a sync texture: " << gfx::hexa(hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = texture->QueryInterface((IDXGIResource**)getter_AddRefs(mSyncTexture));
|
||||
if (FAILED(hr) || !mSyncTexture) {
|
||||
gfxWarning() << "Could not QI sync texture: " << gfx::hexa(hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mSyncTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mKeyedMutex));
|
||||
if (FAILED(hr) || !mKeyedMutex) {
|
||||
gfxWarning() << "Could not QI keyed-mutex: " << gfx::hexa(hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mSyncTexture->GetSharedHandle(&mSyncHandle);
|
||||
if (FAILED(hr) || !mSyncHandle) {
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction("layers::SyncObjectD3D11Renderer::Init",
|
||||
[] () -> void {
|
||||
Accumulate(Telemetry::D3D11_SYNC_HANDLE_FAILURE, 1);
|
||||
}));
|
||||
gfxWarning() << "Could not get sync texture shared handle: " << gfx::hexa(hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SyncHandle
|
||||
SyncObjectD3D11Host::GetSyncHandle()
|
||||
{
|
||||
return mSyncHandle;
|
||||
}
|
||||
|
||||
bool
|
||||
SyncObjectD3D11Host::Synchronize()
|
||||
{
|
||||
HRESULT hr;
|
||||
AutoTextureLock lock(mKeyedMutex, hr, 10000);
|
||||
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
hr = mDevice->GetDeviceRemovedReason();
|
||||
if (hr == S_OK) {
|
||||
// There is no driver-removed event. Crash with this timeout.
|
||||
MOZ_CRASH("GFX: D3D11 normal status timeout");
|
||||
}
|
||||
|
||||
// Since the timeout is related to the driver-removed. Return false for
|
||||
// error handling.
|
||||
gfxCriticalNote << "GFX: D3D11 timeout with device-removed:" << gfx::hexa(hr);
|
||||
|
||||
return false;
|
||||
}
|
||||
if (hr == WAIT_ABANDONED) {
|
||||
gfxCriticalNote << "GFX: AL_D3D11 abandoned sync";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SyncObjectD3D11Client::SyncObjectD3D11Client(SyncHandle aSyncHandle, ID3D11Device* aDevice)
|
||||
: mSyncHandle(aSyncHandle)
|
||||
{
|
||||
if (!aDevice) {
|
||||
mDevice = DeviceManagerDx::Get()->GetContentDevice();
|
||||
return;
|
||||
}
|
||||
|
||||
mDevice = aDevice;
|
||||
}
|
||||
|
||||
bool
|
||||
SyncObjectD3D11Client::Init()
|
||||
{
|
||||
if (mKeyedMutex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT hr = mD3D11Device->OpenSharedResource(
|
||||
HRESULT hr = mDevice->OpenSharedResource(
|
||||
mSyncHandle,
|
||||
__uuidof(ID3D11Texture2D),
|
||||
(void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
|
||||
if (FAILED(hr) || !mD3D11Texture) {
|
||||
(void**)(ID3D11Texture2D**)getter_AddRefs(mSyncTexture));
|
||||
if (FAILED(hr) || !mSyncTexture) {
|
||||
gfxCriticalNote << "Failed to OpenSharedResource for SyncObjectD3D11: " << hexa(hr);
|
||||
if (ShouldDevCrashOnSyncInitFailure()) {
|
||||
gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
|
||||
@ -1570,10 +1648,10 @@ SyncObjectD3D11::Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = mD3D11Texture->QueryInterface(__uuidof(IDXGIKeyedMutex), getter_AddRefs(mKeyedMutex));
|
||||
hr = mSyncTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), getter_AddRefs(mKeyedMutex));
|
||||
if (FAILED(hr) || !mKeyedMutex) {
|
||||
// Leave both the critical error and MOZ_CRASH for now; the critical error lets
|
||||
// us "save" the hr value. We will probably eventuall replace this with gfxDevCrash.
|
||||
// us "save" the hr value. We will probably eventually replace this with gfxDevCrash.
|
||||
gfxCriticalError() << "Failed to get KeyedMutex (2): " << hexa(hr);
|
||||
MOZ_CRASH("GFX: Cannot get D3D11 KeyedMutex");
|
||||
}
|
||||
@ -1582,25 +1660,25 @@ SyncObjectD3D11::Init()
|
||||
}
|
||||
|
||||
void
|
||||
SyncObjectD3D11::RegisterTexture(ID3D11Texture2D* aTexture)
|
||||
SyncObjectD3D11Client::RegisterTexture(ID3D11Texture2D* aTexture)
|
||||
{
|
||||
mD3D11SyncedTextures.push_back(aTexture);
|
||||
mSyncedTextures.push_back(aTexture);
|
||||
}
|
||||
|
||||
bool
|
||||
SyncObjectD3D11::IsSyncObjectValid()
|
||||
SyncObjectD3D11Client::IsSyncObjectValid()
|
||||
{
|
||||
RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
|
||||
if (!dev || (NS_IsMainThread() && dev != mD3D11Device)) {
|
||||
if (!dev || (NS_IsMainThread() && dev != mDevice)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SyncObjectD3D11::FinalizeFrame()
|
||||
SyncObjectD3D11Client::Synchronize()
|
||||
{
|
||||
if (!mD3D11SyncedTextures.size()) {
|
||||
if (!mSyncedTextures.size()) {
|
||||
return;
|
||||
}
|
||||
if (!Init()) {
|
||||
@ -1623,7 +1701,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
box.back = box.bottom = box.right = 1;
|
||||
|
||||
RefPtr<ID3D11Device> dev;
|
||||
mD3D11Texture->GetDevice(getter_AddRefs(dev));
|
||||
mSyncTexture->GetDevice(getter_AddRefs(dev));
|
||||
|
||||
if (dev == DeviceManagerDx::Get()->GetContentDevice()) {
|
||||
if (DeviceManagerDx::Get()->HasDeviceReset()) {
|
||||
@ -1631,7 +1709,7 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
}
|
||||
}
|
||||
|
||||
if (dev != mD3D11Device) {
|
||||
if (dev != mDevice) {
|
||||
gfxWarning() << "Attempt to sync texture from invalid device.";
|
||||
return;
|
||||
}
|
||||
@ -1639,11 +1717,11 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
RefPtr<ID3D11DeviceContext> ctx;
|
||||
dev->GetImmediateContext(getter_AddRefs(ctx));
|
||||
|
||||
for (auto iter = mD3D11SyncedTextures.begin(); iter != mD3D11SyncedTextures.end(); iter++) {
|
||||
ctx->CopySubresourceRegion(mD3D11Texture, 0, 0, 0, 0, *iter, 0, &box);
|
||||
for (auto iter = mSyncedTextures.begin(); iter != mSyncedTextures.end(); iter++) {
|
||||
ctx->CopySubresourceRegion(mSyncTexture, 0, 0, 0, 0, *iter, 0, &box);
|
||||
}
|
||||
|
||||
mD3D11SyncedTextures.clear();
|
||||
mSyncedTextures.clear();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -440,26 +440,47 @@ private:
|
||||
RefPtr<ID3D11RenderTargetView> mRTView;
|
||||
};
|
||||
|
||||
class SyncObjectD3D11 : public SyncObject
|
||||
class SyncObjectD3D11Host : public SyncObjectHost
|
||||
{
|
||||
public:
|
||||
explicit SyncObjectD3D11(SyncHandle aSyncHandle, ID3D11Device* aDevice);
|
||||
virtual void FinalizeFrame();
|
||||
virtual bool IsSyncObjectValid();
|
||||
explicit SyncObjectD3D11Host(ID3D11Device* aDevice);
|
||||
|
||||
virtual SyncType GetSyncType() { return SyncType::D3D11; }
|
||||
virtual bool Init() override;
|
||||
|
||||
virtual SyncHandle GetSyncHandle() override;
|
||||
|
||||
virtual bool Synchronize() override;
|
||||
|
||||
private:
|
||||
virtual ~SyncObjectD3D11Host() { }
|
||||
|
||||
SyncHandle mSyncHandle;
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<IDXGIResource> mSyncTexture;
|
||||
RefPtr<IDXGIKeyedMutex> mKeyedMutex;
|
||||
};
|
||||
|
||||
class SyncObjectD3D11Client : public SyncObjectClient
|
||||
{
|
||||
public:
|
||||
explicit SyncObjectD3D11Client(SyncHandle aSyncHandle, ID3D11Device* aDevice);
|
||||
|
||||
virtual void Synchronize() override;
|
||||
|
||||
virtual bool IsSyncObjectValid() override;
|
||||
|
||||
virtual SyncType GetSyncType() override { return SyncType::D3D11; }
|
||||
|
||||
void RegisterTexture(ID3D11Texture2D* aTexture);
|
||||
|
||||
private:
|
||||
bool Init();
|
||||
|
||||
private:
|
||||
SyncHandle mSyncHandle;
|
||||
RefPtr<ID3D11Device> mD3D11Device;
|
||||
RefPtr<ID3D11Texture2D> mD3D11Texture;
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<ID3D11Texture2D> mSyncTexture;
|
||||
RefPtr<IDXGIKeyedMutex> mKeyedMutex;
|
||||
std::vector<ID3D11Texture2D*> mD3D11SyncedTextures;
|
||||
std::vector<ID3D11Texture2D*> mSyncedTextures;
|
||||
};
|
||||
|
||||
inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)
|
||||
|
@ -224,6 +224,7 @@ EXPORTS.mozilla.layers += [
|
||||
'ShareableCanvasRenderer.h',
|
||||
'SourceSurfaceSharedData.h',
|
||||
'SourceSurfaceVolatileData.h',
|
||||
'SyncObject.h',
|
||||
'TextureSourceProvider.h',
|
||||
'TextureWrapperImage.h',
|
||||
'TransactionIdAllocator.h',
|
||||
@ -456,6 +457,7 @@ UNIFIED_SOURCES += [
|
||||
'ShareableCanvasRenderer.cpp',
|
||||
'SourceSurfaceSharedData.cpp',
|
||||
'SourceSurfaceVolatileData.cpp',
|
||||
'SyncObject.cpp',
|
||||
'TextureSourceProvider.cpp',
|
||||
'TextureWrapperImage.cpp',
|
||||
'wr/AsyncImagePipelineManager.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user