Clean up and relax some assertions in SyncObjectD3D11.cpp. (bug 1319557, r=mattwoodrow)

--HG--
extra : rebase_source : d72c9a74fdfdfbcbf0303b550404ccd7a900c88d
This commit is contained in:
David Anderson 2016-11-29 14:07:27 -08:00
parent afc3fce143
commit 51df7c6290
4 changed files with 92 additions and 61 deletions

View File

@ -13,6 +13,7 @@
#include "ReadbackManagerD3D11.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/CompositorBridgeChild.h"
namespace mozilla {
@ -1194,11 +1195,42 @@ CompositingRenderTargetD3D11::GetSize() const
return TextureSourceD3D11::GetSize();
}
SyncObjectD3D11::SyncObjectD3D11(SyncHandle aHandle)
SyncObjectD3D11::SyncObjectD3D11(SyncHandle aSyncHandle)
: mSyncHandle(aSyncHandle)
{
MOZ_ASSERT(aHandle);
}
mHandle = aHandle;
bool
SyncObjectD3D11::Init()
{
if (mKeyedMutex) {
return true;
}
RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
HRESULT hr = device->OpenSharedResource(
mSyncHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
if (FAILED(hr) || !mD3D11Texture) {
gfxCriticalNote << "Failed to OpenSharedResource for SyncObjectD3D11: " << hexa(hr);
if (!CompositorBridgeChild::CompositorIsInGPUProcess() &&
!DeviceManagerDx::Get()->HasDeviceReset())
{
gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
}
}
hr = mD3D11Texture->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.
gfxCriticalError() << "Failed to get KeyedMutex (2): " << hexa(hr);
MOZ_CRASH("GFX: Cannot get D3D11 KeyedMutex");
}
return true;
}
void
@ -1210,71 +1242,44 @@ SyncObjectD3D11::RegisterTexture(ID3D11Texture2D* aTexture)
void
SyncObjectD3D11::FinalizeFrame()
{
if (!mD3D11SyncedTextures.size()) {
return;
}
if (!Init()) {
return;
}
HRESULT hr;
AutoTextureLock lock(mKeyedMutex, hr, 20000);
if (!mD3D11Texture && mD3D11SyncedTextures.size()) {
RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
hr = device->OpenSharedResource(mHandle, __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
if (FAILED(hr) || !mD3D11Texture) {
gfxCriticalError() << "Failed to D3D11 OpenSharedResource for frame finalization: " << hexa(hr);
if (DeviceManagerDx::Get()->HasDeviceReset()) {
return;
}
gfxDevCrash(LogReason::D3D11FinalizeFrame) << "Without device reset: " << hexa(hr);
}
// test QI
RefPtr<IDXGIKeyedMutex> mutex;
hr = mD3D11Texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
if (FAILED(hr) || !mutex) {
// 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.
gfxCriticalError() << "Failed to get KeyedMutex (2): " << hexa(hr);
MOZ_CRASH("GFX: Cannot get D3D11 KeyedMutex");
if (hr == WAIT_TIMEOUT) {
if (DeviceManagerDx::Get()->HasDeviceReset()) {
gfxWarning() << "AcquireSync timed out because of device reset.";
return;
}
gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
}
if (mD3D11SyncedTextures.size()) {
RefPtr<IDXGIKeyedMutex> mutex;
hr = mD3D11Texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
{
AutoTextureLock lock(mutex, hr, 20000);
D3D11_BOX box;
box.front = box.top = box.left = 0;
box.back = box.bottom = box.right = 1;
if (hr == WAIT_TIMEOUT) {
if (DeviceManagerDx::Get()->HasDeviceReset()) {
gfxWarning() << "AcquireSync timed out because of device reset.";
return;
}
gfxDevCrash(LogReason::D3D11SyncLock) << "Timeout on the D3D11 sync lock";
}
D3D11_BOX box;
box.front = box.top = box.left = 0;
box.back = box.bottom = box.right = 1;
RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
if (!dev) {
if (DeviceManagerDx::Get()->HasDeviceReset()) {
return;
}
MOZ_CRASH("GFX: Invalid D3D11 content device");
}
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);
}
RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
if (!dev) {
if (DeviceManagerDx::Get()->HasDeviceReset()) {
return;
}
mD3D11SyncedTextures.clear();
MOZ_CRASH("GFX: Invalid D3D11 content device");
}
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);
}
mD3D11SyncedTextures.clear();
}
}

View File

@ -421,9 +421,13 @@ public:
void RegisterTexture(ID3D11Texture2D* aTexture);
private:
bool Init();
private:
SyncHandle mSyncHandle;
RefPtr<ID3D11Texture2D> mD3D11Texture;
RefPtr<IDXGIKeyedMutex> mKeyedMutex;
std::vector<ID3D11Texture2D*> mD3D11SyncedTextures;
SyncHandle mHandle;
};
inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)

View File

@ -296,6 +296,24 @@ CompositorBridgeChild::ChildProcessHasCompositorBridge()
return sCompositorBridge != nullptr;
}
/* static */ bool
CompositorBridgeChild::CompositorIsInGPUProcess()
{
MOZ_ASSERT(NS_IsMainThread());
if (XRE_IsParentProcess()) {
return !!GPUProcessManager::Get()->GetGPUChild();
}
MOZ_ASSERT(XRE_IsContentProcess());
CompositorBridgeChild* bridge = CompositorBridgeChild::Get();
if (!bridge) {
return false;
}
return bridge->OtherPid() != dom::ContentChild::GetSingleton()->OtherPid();
}
PLayerTransactionChild*
CompositorBridgeChild::AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId,

View File

@ -88,6 +88,10 @@ public:
static bool ChildProcessHasCompositorBridge();
// Returns whether the compositor is in the GPU process (false if in the UI
// process). This may only be called on the main thread.
static bool CompositorIsInGPUProcess();
void AddOverfillObserver(ClientLayerManager* aLayerManager);
virtual mozilla::ipc::IPCResult