Bug 1877726. Revert "Bug 1664063 - Ensure we consistently handle all errors from IDXGIKeyedMutex::AcquireSync.".

This reverts commit e25a5f344af32bdd689500bae7b4f24f205ba9f0.

We believe bug 1664063 was causing to hit some broken device reset
handling code.

Differential Revision: https://phabricator.services.mozilla.com/D201658
This commit is contained in:
Jeff Muizelaar 2024-02-13 04:25:35 +00:00
parent 6cdcc2b550
commit 239afc7998
27 changed files with 174 additions and 261 deletions

View file

@ -1357,12 +1357,11 @@ Maybe<uvec2> WebGLContext::FrontBufferSnapshotInto(
front->WaitForBufferOwnership();
front->LockProd();
auto resetLock = MakeScopeExit([&] { front->UnlockProd(); });
if (NS_WARN_IF(!front->ProducerReadAcquire())) {
gfxCriticalNote << "SnapshotInto: failed to acquire producer";
return {};
}
auto resetProducer = MakeScopeExit([&] { front->ProducerReadRelease(); });
front->ProducerReadAcquire();
auto reset = MakeScopeExit([&] {
front->ProducerReadRelease();
front->UnlockProd();
});
// -

View file

@ -24,7 +24,6 @@
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/Telemetry.h"
#include "mozilla/gfx/D3D11Checks.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/D3D11TextureIMFSampleImage.h"
@ -791,9 +790,9 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
texture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
{
AutoTextureLock lock("D3D11DXVA2Manager::CopyToImage", mutex, hr, 2000);
if (NS_WARN_IF(!lock.Succeeded())) {
return E_FAIL;
AutoTextureLock(mutex, hr, 2000);
if (mutex && (FAILED(hr) || hr == WAIT_TIMEOUT || hr == WAIT_ABANDONED)) {
return hr;
}
if (!mutex && mDevice != DeviceManagerDx::Get()->GetCompositorDevice()) {
@ -1018,13 +1017,12 @@ D3D11DXVA2Manager::CopyToBGRATexture(ID3D11Texture2D* aInTexture,
hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(newTexture));
NS_ENSURE_TRUE(SUCCEEDED(hr) && newTexture, E_FAIL);
AutoTextureLock lock("D3D11DXVA2Manager::CopyToBGRASurface", mutex, hr,
2000);
if (NS_WARN_IF(!lock.Succeeded())) {
return E_FAIL;
}
hr = mutex->AcquireSync(0, 2000);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mContext->CopyResource(newTexture, inTexture);
mutex->ReleaseSync(0);
inTexture = newTexture;
}

View file

@ -52,7 +52,6 @@
# include "HelpersD2D.h"
# include "DXVA2Manager.h"
# include "ImageContainer.h"
# include "mozilla/gfx/D3D11Checks.h"
# include "mozilla/layers/LayersSurfaces.h"
# include "mozilla/layers/TextureD3D11.h"
# include "nsWindowsHelpers.h"
@ -1297,33 +1296,40 @@ bool Factory::ReadbackTexture(uint8_t* aDestData, int32_t aDestStride,
return false;
}
RefPtr<IDXGIKeyedMutex> mutex;
HRESULT hr = aSrcTexture->QueryInterface(__uuidof(IDXGIKeyedMutex),
(void**)getter_AddRefs(mutex));
if (SUCCEEDED(hr) && mutex) {
hr = mutex->AcquireSync(0, 2000);
if (hr != S_OK) {
gfxWarning() << "Could not acquire DXGI surface lock in 2 seconds";
return false;
}
}
D3D11_TEXTURE2D_DESC srcDesc = {0};
aSrcTexture->GetDesc(&srcDesc);
srcDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
srcDesc.Usage = D3D11_USAGE_STAGING;
srcDesc.BindFlags = 0;
srcDesc.MiscFlags = 0;
srcDesc.MipLevels = 1;
RefPtr<ID3D11Texture2D> srcCpuTexture;
HRESULT hr;
{
RefPtr<IDXGIKeyedMutex> mutex;
hr = aSrcTexture->QueryInterface(__uuidof(IDXGIKeyedMutex),
(void**)getter_AddRefs(mutex));
layers::AutoTextureLock lock(__func__, mutex, hr, 2000);
if (NS_WARN_IF(!lock.Succeeded())) {
return false;
hr =
device->CreateTexture2D(&srcDesc, nullptr, getter_AddRefs(srcCpuTexture));
if (FAILED(hr)) {
gfxWarning() << "Could not create source texture for mapping";
if (mutex) {
mutex->ReleaseSync(0);
}
return false;
}
aSrcTexture->GetDesc(&srcDesc);
srcDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
srcDesc.Usage = D3D11_USAGE_STAGING;
srcDesc.BindFlags = 0;
srcDesc.MiscFlags = 0;
srcDesc.MipLevels = 1;
hr = device->CreateTexture2D(&srcDesc, nullptr,
getter_AddRefs(srcCpuTexture));
if (FAILED(hr)) {
gfxWarning() << "Could not create source texture for mapping";
return false;
}
context->CopyResource(srcCpuTexture, aSrcTexture);
context->CopyResource(srcCpuTexture, aSrcTexture);
if (mutex) {
mutex->ReleaseSync(0);
mutex = nullptr;
}
D3D11_MAPPED_SUBRESOURCE srcMap;

View file

@ -14,7 +14,6 @@
#include "GPUVideoImage.h"
#include "ScopedGLHelpers.h"
#include "mozilla/gfx/D3D11Checks.h"
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/D3D11TextureIMFSampleImage.h"
#include "mozilla/layers/D3D11YCbCrImage.h"
@ -137,18 +136,9 @@ class BindAnglePlanes final {
(void**)getter_AddRefs(mutex));
if (mutex) {
const auto hr = mutex->AcquireSync(0, 100);
if (!gfx::D3D11Checks::DidAcquireSyncSucceed(__func__, hr)) {
if (FAILED(hr)) {
NS_WARNING("BindAnglePlanes failed to acquire KeyedMutex.");
NOTE_IF_FALSE(egl->fStreamConsumerReleaseKHR(mStreams[i]));
while (i > 0) {
--i;
NOTE_IF_FALSE(egl->fStreamConsumerReleaseKHR(mStreams[i]));
if (mMutexList[i]) {
mMutexList[i]->ReleaseSync(0);
}
}
mSuccess = false;
break;
}
}
}

View file

@ -60,13 +60,9 @@ UniquePtr<SwapChainPresenter> SwapChain::Acquire(
mPool.pop();
}
bool success = false;
auto ret = MakeUnique<SwapChainPresenter>(*this);
const auto old = ret->SwapBackBuffer(surf, success);
const auto old = ret->SwapBackBuffer(surf);
MOZ_ALWAYS_TRUE(!old);
if (NS_WARN_IF(!success)) {
return nullptr;
}
return ret;
}
@ -100,8 +96,7 @@ SwapChainPresenter::~SwapChainPresenter() {
MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == this);
mSwapChain->mPresenter = nullptr;
bool success;
auto newFront = SwapBackBuffer(nullptr, success);
auto newFront = SwapBackBuffer(nullptr);
if (newFront) {
mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
mSwapChain->mFrontBuffer = newFront;
@ -109,7 +104,7 @@ SwapChainPresenter::~SwapChainPresenter() {
}
std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
std::shared_ptr<SharedSurface> back, bool& aSuccess) {
std::shared_ptr<SharedSurface> back) {
if (mBackBuffer) {
mBackBuffer->UnlockProd();
mBackBuffer->ProducerRelease();
@ -119,14 +114,9 @@ std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
mBackBuffer = back;
if (mBackBuffer) {
mBackBuffer->WaitForBufferOwnership();
if (NS_WARN_IF(!mBackBuffer->ProducerAcquire())) {
mBackBuffer = nullptr;
aSuccess = false;
return old;
}
mBackBuffer->ProducerAcquire();
mBackBuffer->LockProd();
}
aSuccess = true;
return old;
}
@ -145,8 +135,7 @@ SwapChain::SwapChain() = default;
SwapChain::~SwapChain() {
if (mPresenter) {
// Out of order destruction, but ok.
bool success;
(void)mPresenter->SwapBackBuffer(nullptr, success);
(void)mPresenter->SwapBackBuffer(nullptr);
mPresenter->mSwapChain = nullptr;
mPresenter = nullptr;
}

View file

@ -42,8 +42,7 @@ class SwapChainPresenter final {
const auto& BackBuffer() const { return mBackBuffer; }
std::shared_ptr<SharedSurface> SwapBackBuffer(std::shared_ptr<SharedSurface>,
bool& aSuccess);
std::shared_ptr<SharedSurface> SwapBackBuffer(std::shared_ptr<SharedSurface>);
GLuint Fb() const;
};

View file

@ -111,27 +111,27 @@ class SharedSurface {
virtual void LockProdImpl(){};
virtual void UnlockProdImpl(){};
virtual bool ProducerAcquireImpl() { return true; };
virtual void ProducerAcquireImpl(){};
virtual void ProducerReleaseImpl(){};
virtual bool ProducerReadAcquireImpl() { return ProducerAcquireImpl(); }
virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); }
virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); }
public:
bool ProducerAcquire() {
void ProducerAcquire() {
MOZ_ASSERT(!mIsProducerAcquired);
mIsProducerAcquired = ProducerAcquireImpl();
return mIsProducerAcquired;
ProducerAcquireImpl();
mIsProducerAcquired = true;
}
void ProducerRelease() {
MOZ_ASSERT(mIsProducerAcquired);
ProducerReleaseImpl();
mIsProducerAcquired = false;
}
bool ProducerReadAcquire() {
void ProducerReadAcquire() {
MOZ_ASSERT(!mIsProducerAcquired);
mIsProducerAcquired = ProducerReadAcquireImpl();
return mIsProducerAcquired;
ProducerReadAcquireImpl();
mIsProducerAcquired = true;
}
void ProducerReadRelease() {
MOZ_ASSERT(mIsProducerAcquired);

View file

@ -8,7 +8,6 @@
#include <d3d11.h>
#include "GLContextEGL.h"
#include "GLLibraryEGL.h"
#include "mozilla/gfx/D3D11Checks.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/gfx/FileHandleWrapper.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
@ -147,9 +146,11 @@ void SharedSurface_ANGLEShareHandle::LockProdImpl() {
void SharedSurface_ANGLEShareHandle::UnlockProdImpl() {}
bool SharedSurface_ANGLEShareHandle::ProducerAcquireImpl() {
void SharedSurface_ANGLEShareHandle::ProducerAcquireImpl() {
HRESULT hr = mKeyedMutex->AcquireSync(0, 10000);
return gfx::D3D11Checks::DidAcquireSyncSucceed(__func__, hr);
if (hr == WAIT_TIMEOUT) {
MOZ_CRASH("GFX: ANGLE share handle timeout");
}
}
void SharedSurface_ANGLEShareHandle::ProducerReleaseImpl() {
@ -161,8 +162,8 @@ void SharedSurface_ANGLEShareHandle::ProducerReleaseImpl() {
mKeyedMutex->ReleaseSync(0);
}
bool SharedSurface_ANGLEShareHandle::ProducerReadAcquireImpl() {
return ProducerAcquireImpl();
void SharedSurface_ANGLEShareHandle::ProducerReadAcquireImpl() {
ProducerAcquireImpl();
}
void SharedSurface_ANGLEShareHandle::ProducerReadReleaseImpl() {

View file

@ -47,9 +47,9 @@ class SharedSurface_ANGLEShareHandle final : public SharedSurface {
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual bool ProducerAcquireImpl() override;
virtual void ProducerAcquireImpl() override;
virtual void ProducerReleaseImpl() override;
virtual bool ProducerReadAcquireImpl() override;
virtual void ProducerReadAcquireImpl() override;
virtual void ProducerReadReleaseImpl() override;
Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() override;

View file

@ -39,7 +39,7 @@ class SharedSurface_AndroidHardwareBuffer final : public SharedSurface {
void LockProdImpl() override {}
void UnlockProdImpl() override {}
bool ProducerAcquireImpl() override { return true; }
void ProducerAcquireImpl() override {}
void ProducerReleaseImpl() override;
Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() override;

View file

@ -415,12 +415,13 @@ SharedSurface_D3D11Interop::~SharedSurface_D3D11Interop() {
}
}
bool SharedSurface_D3D11Interop::ProducerAcquireImpl() {
void SharedSurface_D3D11Interop::ProducerAcquireImpl() {
MOZ_ASSERT(!mLockedForGL);
// Now we have the mutex, we can lock for GL.
mLockedForGL = mData.interop->LockObject(mData.lockHandle);
return mLockedForGL;
MOZ_ALWAYS_TRUE(mData.interop->LockObject(mData.lockHandle));
mLockedForGL = true;
}
void SharedSurface_D3D11Interop::ProducerReleaseImpl() {

View file

@ -52,7 +52,7 @@ class SharedSurface_D3D11Interop final : public SharedSurface {
void LockProdImpl() override {}
void UnlockProdImpl() override {}
bool ProducerAcquireImpl() override;
void ProducerAcquireImpl() override;
void ProducerReleaseImpl() override;
Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() override;

View file

@ -35,11 +35,11 @@ class SharedSurface_DMABUF final : public SharedSurface {
virtual void UnlockProdImpl() override {}
// Non-exclusive Content/WebGL lock/unlock of surface for write
virtual bool ProducerAcquireImpl() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
// Non-exclusive Content/WebGL lock/unlock for read from surface
virtual bool ProducerReadAcquireImpl() override { return true; }
virtual void ProducerReadAcquireImpl() override {}
virtual void ProducerReadReleaseImpl() override {}
Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() override;

View file

@ -110,7 +110,7 @@ void SharedSurface_EGLImage::ProducerReleaseImpl() {
gl->fFinish();
}
bool SharedSurface_EGLImage::ProducerReadAcquireImpl() {
void SharedSurface_EGLImage::ProducerReadAcquireImpl() {
const auto& gle = GLContextEGL::Cast(mDesc.gl);
const auto& egl = gle->mEgl;
// Wait on the fence, because presumably we're going to want to read this
@ -118,7 +118,6 @@ bool SharedSurface_EGLImage::ProducerReadAcquireImpl() {
if (mSync) {
egl->fClientWaitSync(mSync, 0, LOCAL_EGL_FOREVER);
}
return true;
}
Maybe<layers::SurfaceDescriptor> SharedSurface_EGLImage::ToSurfaceDescriptor() {

View file

@ -45,10 +45,10 @@ class SharedSurface_EGLImage final : public SharedSurface {
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual bool ProducerAcquireImpl() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual bool ProducerReadAcquireImpl() override;
virtual void ProducerReadAcquireImpl() override;
virtual void ProducerReadReleaseImpl() override{};
Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() override;
@ -96,7 +96,7 @@ class SharedSurface_SurfaceTexture final : public SharedSurface {
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual bool ProducerAcquireImpl() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override {}
virtual void ProducerReadReleaseImpl() override;

View file

@ -33,7 +33,7 @@ class SharedSurface_IOSurface final : public SharedSurface {
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual bool ProducerAcquireImpl() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual bool NeedsIndirectReads() const override { return true; }

View file

@ -117,10 +117,6 @@ D3D11ShareHandleImage::MaybeCreateNV12ImageAndSetData(
D3D11MTAutoEnter mtAutoEnter(mt.forget());
AutoLockD3D11Texture lockSt(stagingTexture);
if (NS_WARN_IF(!lockSt.Succeeded())) {
gfxCriticalNoteOnce << "Locking D3D11 staging texture failed";
return nullptr;
}
D3D11_MAP mapType = D3D11_MAP_WRITE;
D3D11_MAPPED_SUBRESOURCE mappedResource;

View file

@ -8,7 +8,6 @@
#include "YCbCrUtils.h"
#include "gfx2DGlue.h"
#include "mozilla/gfx/D3D11Checks.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/CompositableClient.h"
@ -87,11 +86,6 @@ bool D3D11YCbCrImage::SetData(KnowsCompositor* aAllocator,
AutoLockD3D11Texture lockY(textureY);
AutoLockD3D11Texture lockCb(textureCb);
AutoLockD3D11Texture lockCr(textureCr);
if (NS_WARN_IF(!lockY.Succeeded()) || NS_WARN_IF(!lockCb.Succeeded()) ||
NS_WARN_IF(!lockCr.Succeeded())) {
gfxCriticalNote << "D3D11YCbCrImage::SetData failed to lock";
return false;
}
ctx->UpdateSubresource(textureY, 0, nullptr, aData.mYChannel, aData.mYStride,
aData.mYStride * aData.YDataSize().height);
@ -218,11 +212,6 @@ nsresult D3D11YCbCrImage::ReadIntoBuffer(
AutoLockD3D11Texture lockY(texY);
AutoLockD3D11Texture lockCb(texCb);
AutoLockD3D11Texture lockCr(texCr);
if (NS_WARN_IF(!lockY.Succeeded()) || NS_WARN_IF(!lockCb.Succeeded()) ||
NS_WARN_IF(!lockCr.Succeeded())) {
gfxCriticalNote << "D3D11YCbCrImage::ReadIntoBuffer lock failed";
return NS_ERROR_FAILURE;
}
ctx->CopyResource(softTexY, texY);
ctx->CopyResource(softTexCb, texCb);
ctx->CopyResource(softTexCr, texCr);
@ -332,7 +321,8 @@ nsresult D3D11YCbCrImage::BuildSurfaceDescriptorBuffer(
class AutoCheckLockD3D11Texture final {
public:
explicit AutoCheckLockD3D11Texture(ID3D11Texture2D* aTexture) {
explicit AutoCheckLockD3D11Texture(ID3D11Texture2D* aTexture)
: mIsLocked(false) {
aTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mMutex));
if (!mMutex) {
// If D3D11Texture does not have keyed mutex, we think that the
@ -343,24 +333,34 @@ class AutoCheckLockD3D11Texture final {
// Test to see if the keyed mutex has been released
HRESULT hr = mMutex->AcquireSync(0, 0);
mIsLocked = D3D11Checks::DidAcquireSyncSucceed(__func__, hr);
if (hr == S_OK || hr == WAIT_ABANDONED) {
mIsLocked = true;
// According to Microsoft documentation:
// WAIT_ABANDONED - The shared surface and keyed mutex are no longer in a
// consistent state. If AcquireSync returns this value, you should release
// and recreate both the keyed mutex and the shared surface
// So even if we do get WAIT_ABANDONED, the keyed mutex will have to be
// released.
mSyncAcquired = true;
}
}
~AutoCheckLockD3D11Texture() {
if (!mIsLocked) {
if (!mSyncAcquired) {
return;
}
HRESULT hr = mMutex->ReleaseSync(0);
if (NS_WARN_IF(FAILED(hr))) {
gfxCriticalNote << __func__ << " ReleaseSync failed " << gfx::hexa(hr);
if (FAILED(hr)) {
NS_WARNING("Failed to unlock the texture");
}
}
bool IsLocked() const { return mIsLocked; }
private:
bool mIsLocked;
bool mSyncAcquired = false;
RefPtr<IDXGIKeyedMutex> mMutex;
bool mIsLocked = false;
};
DXGIYCbCrTextureAllocationHelper::DXGIYCbCrTextureAllocationHelper(

View file

@ -79,11 +79,6 @@ bool IMFYCbCrImage::CopyDataToTexture(const Data& aData, ID3D11Device* aDevice,
AutoLockD3D11Texture lockY(textureY);
AutoLockD3D11Texture lockCr(textureCr);
AutoLockD3D11Texture lockCb(textureCb);
if (NS_WARN_IF(!lockY.Succeeded()) || NS_WARN_IF(!lockCr.Succeeded()) ||
NS_WARN_IF(!lockCb.Succeeded())) {
gfxCriticalNote << "IMFYCbCrImage::CopyDataToTexture lock failed";
return false;
}
D3D11MTAutoEnter mtAutoEnter(mt.forget());
D3D11_BOX box;

View file

@ -985,24 +985,32 @@ void CompositorD3D11::Present() {
params.pDirtyRects = params.DirtyRectsCount ? rects.data() : nullptr;
AutoTextureLock lock("CompositorD3D11::Present", mutex, hr, 2000);
if (NS_WARN_IF(!lock.Succeeded())) {
return;
if (mutex) {
hr = mutex->AcquireSync(0, 2000);
NS_ENSURE_TRUE_VOID(SUCCEEDED(hr));
}
chain->Present1(
presentInterval,
mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0,
&params);
if (mutex) {
mutex->ReleaseSync(0);
}
} else {
AutoTextureLock lock("CompositorD3D11::Present", mutex, hr, 2000);
if (NS_WARN_IF(!lock.Succeeded())) {
return;
if (mutex) {
hr = mutex->AcquireSync(0, 2000);
NS_ENSURE_TRUE_VOID(SUCCEEDED(hr));
}
hr = mSwapChain->Present(
0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
if (mutex) {
mutex->ReleaseSync(0);
}
if (FAILED(hr)) {
gfxCriticalNote << "D3D11 swap chain preset failed " << hexa(hr);
HandleError(hr);

View file

@ -350,11 +350,6 @@ RefPtr<ID3D11Texture2D> GpuProcessD3D11TextureMap::UpdateTextureData(
D3D11MTAutoEnter mtAutoEnter(mt.forget());
AutoLockD3D11Texture lockSt(stagingTexture);
if (NS_WARN_IF(!lockSt.Succeeded())) {
gfxCriticalNote
<< "GpuProcessD3D11TextureMap::UpdateTextureData lock failed";
return nullptr;
}
D3D11_MAP mapType = D3D11_MAP_WRITE;
D3D11_MAPPED_SUBRESOURCE mappedResource;

View file

@ -133,23 +133,21 @@ static IntRect GetTileRectD3D11(uint32_t aID, IntSize aSize,
verticalTile < (verticalTiles - 1) ? aMaxSize : aSize.height % aMaxSize);
}
AutoTextureLock::AutoTextureLock(const char* aCaller, IDXGIKeyedMutex* aMutex,
HRESULT& aResult, uint32_t aTimeout)
: mCaller(aCaller), mMutex(aMutex) {
AutoTextureLock::AutoTextureLock(IDXGIKeyedMutex* aMutex, HRESULT& aResult,
uint32_t aTimeout) {
mMutex = aMutex;
if (mMutex) {
aResult = mMutex->AcquireSync(0, aTimeout);
mSuccess = D3D11Checks::DidAcquireSyncSucceed(mCaller, aResult);
mResult = mMutex->AcquireSync(0, aTimeout);
aResult = mResult;
} else {
mSuccess = true;
aResult = E_INVALIDARG;
}
}
AutoTextureLock::~AutoTextureLock() {
if (mMutex && mSuccess) {
HRESULT hr = mMutex->ReleaseSync(0);
if (NS_WARN_IF(FAILED(hr))) {
gfxCriticalNote << mCaller << " ReleaseSync failed " << gfx::hexa(hr);
}
if (mMutex && !FAILED(mResult) && mResult != WAIT_TIMEOUT &&
mResult != WAIT_ABANDONED) {
mMutex->ReleaseSync(0);
}
}
@ -249,14 +247,12 @@ static bool LockD3DTexture(
gfxDevCrash(LogReason::D3DLockTimeout)
<< "D3D lock mutex timeout - device not removed";
}
return false;
} else if (hr == WAIT_ABANDONED) {
gfxCriticalNote << "GFX: D3D11 lock mutex abandoned";
return false;
}
if (FAILED(hr)) {
gfxCriticalNote << "GFX: D3D11 lock failed " << gfx::hexa(hr);
NS_WARNING("Failed to lock the texture");
return false;
}
}
@ -1539,31 +1535,30 @@ bool SyncObjectD3D11Host::Init() {
SyncHandle SyncObjectD3D11Host::GetSyncHandle() { return mSyncHandle; }
bool SyncObjectD3D11Host::Synchronize(bool aFallible) {
MOZ_DIAGNOSTIC_ASSERT(mKeyedMutex);
HRESULT hr;
AutoTextureLock lock(mKeyedMutex, hr, 10000);
if (mKeyedMutex) {
HRESULT hr;
AutoTextureLock lock("SyncObjectD3D11Host::Synchronize", mKeyedMutex, hr,
10000);
if (lock.Succeeded()) {
return true;
if (hr == WAIT_TIMEOUT) {
hr = mDevice->GetDeviceRemovedReason();
if (hr != S_OK) {
// Since the timeout is related to the driver-removed. Return false for
// error handling.
gfxCriticalNote << "GFX: D3D11 timeout with device-removed:"
<< gfx::hexa(hr);
} else if (aFallible) {
gfxCriticalNote << "GFX: D3D11 timeout on the D3D11 sync lock.";
} else {
// There is no driver-removed event. Crash with this timeout.
MOZ_CRASH("GFX: D3D11 normal status timeout");
}
return false;
}
if (hr == WAIT_ABANDONED) {
gfxCriticalNote << "GFX: AL_D3D11 abandoned sync";
}
HRESULT removedReason = mDevice->GetDeviceRemovedReason();
if (removedReason != S_OK) {
// Since the timeout is related to the driver-removed. Return false for
// error handling.
gfxCriticalNote << "GFX: D3D11 sync failure with device-removed:"
<< gfx::hexa(removedReason);
} else if (aFallible) {
gfxCriticalNote << "GFX: D3D11 failure on the D3D11 sync lock.";
} else {
// There is no driver-removed event. Crash with this timeout.
MOZ_CRASH("GFX: D3D11 normal status timeout");
}
return false;
return true;
}
SyncObjectD3D11Client::SyncObjectD3D11Client(SyncHandle aSyncHandle,
@ -1657,30 +1652,19 @@ bool SyncObjectD3D11Client::SynchronizeInternal(ID3D11Device* aDevice,
bool aFallible) {
mSyncLock.AssertCurrentThreadOwns();
MOZ_DIAGNOSTIC_ASSERT(mKeyedMutex);
if (NS_WARN_IF(!mKeyedMutex)) {
if (aFallible) {
gfxWarning() << "Missing D3D11 sync lock.";
} else {
gfxDevCrash(LogReason::D3D11SyncLock) << "Missing D3D11 sync lock.";
}
return false;
}
HRESULT hr;
AutoTextureLock lock("SyncObjectD3D11Client::SynchronizeInternal",
mKeyedMutex, hr, 20000);
AutoTextureLock lock(mKeyedMutex, hr, 20000);
if (NS_WARN_IF(!lock.Succeeded())) {
if (hr == WAIT_TIMEOUT) {
if (DeviceManagerDx::Get()->HasDeviceReset()) {
gfxWarning() << "AcquireSync failed because of device reset.";
gfxWarning() << "AcquireSync timed out because of device reset.";
return false;
}
if (aFallible) {
gfxWarning() << "Failure on the D3D11 sync lock.";
gfxWarning() << "Timeout on the D3D11 sync lock.";
} else {
gfxDevCrash(LogReason::D3D11SyncLock)
<< "Failure on the D3D11 sync lock.";
<< "Timeout on the D3D11 sync lock.";
}
return false;
}
@ -1709,29 +1693,25 @@ uint32_t GetMaxTextureSizeFromDevice(ID3D11Device* aDevice) {
AutoLockD3D11Texture::AutoLockD3D11Texture(ID3D11Texture2D* aTexture) {
aTexture->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mMutex));
if (!mMutex) {
mSuccess = true;
return;
}
HRESULT hr = mMutex->AcquireSync(0, 10000);
if (hr == WAIT_TIMEOUT) {
MOZ_CRASH("GFX: IMFYCbCrImage timeout");
} else if (hr == WAIT_ABANDONED) {
gfxCriticalNote << "AutoLockD3D11Texture abandoned";
} else if (NS_WARN_IF(FAILED(hr))) {
gfxCriticalNote << "AutoLockD3D11Texture failed " << gfx::hexa(hr);
} else {
mSuccess = true;
}
if (FAILED(hr)) {
NS_WARNING("Failed to lock the texture");
}
}
AutoLockD3D11Texture::~AutoLockD3D11Texture() {
if (!mMutex || !mSuccess) {
if (!mMutex) {
return;
}
HRESULT hr = mMutex->ReleaseSync(0);
if (NS_WARN_IF(FAILED(hr))) {
gfxCriticalNote << "~AutoLockD3D11Texture failed " << gfx::hexa(hr);
if (FAILED(hr)) {
NS_WARNING("Failed to unlock the texture");
}
}

View file

@ -41,16 +41,13 @@ already_AddRefed<TextureHost> CreateTextureHostD3D11(
class MOZ_RAII AutoTextureLock final {
public:
AutoTextureLock(const char* aCaller, IDXGIKeyedMutex* aMutex,
HRESULT& aResult, uint32_t aTimeout);
AutoTextureLock(IDXGIKeyedMutex* aMutex, HRESULT& aResult,
uint32_t aTimeout = 0);
~AutoTextureLock();
bool Succeeded() const { return mSuccess; }
private:
const char* mCaller;
RefPtr<IDXGIKeyedMutex> mMutex;
bool mSuccess = false;
HRESULT mResult;
};
class CompositorD3D11;
@ -579,11 +576,8 @@ class AutoLockD3D11Texture {
explicit AutoLockD3D11Texture(ID3D11Texture2D* aTexture);
~AutoLockD3D11Texture();
bool Succeeded() const { return mSuccess; }
private:
RefPtr<IDXGIKeyedMutex> mMutex;
bool mSuccess = false;
};
class D3D11MTAutoEnter {

View file

@ -89,20 +89,14 @@ bool D3D11Checks::DoesRenderTargetViewNeedRecreating(ID3D11Device* aDevice) {
{
// Acquire and clear
HRESULT hr;
AutoTextureLock lock(__func__, keyedMutex, hr, INFINITE);
if (NS_WARN_IF(!lock.Succeeded())) {
return false;
}
AutoTextureLock lock(keyedMutex, hr, INFINITE);
FLOAT color1[4] = {1, 1, 0.5, 1};
deviceContext->ClearRenderTargetView(offscreenRTView, color1);
}
{
HRESULT hr;
AutoTextureLock lock(__func__, keyedMutex, hr, INFINITE);
if (NS_WARN_IF(!lock.Succeeded())) {
return false;
}
AutoTextureLock lock(keyedMutex, hr, INFINITE);
FLOAT color2[4] = {1, 1, 0, 1};
deviceContext->ClearRenderTargetView(offscreenRTView, color2);
@ -263,26 +257,23 @@ static bool DoesTextureSharingWorkInternal(ID3D11Device* device,
RefPtr<IDXGIKeyedMutex> sourceSharedMutex;
texture->QueryInterface(__uuidof(IDXGIKeyedMutex),
(void**)getter_AddRefs(sourceSharedMutex));
if (NS_WARN_IF(!sourceSharedMutex)) {
gfxCriticalNote << "DoesD3D11TextureSharingWork_QueryInterfaceKeyedMutex";
if (FAILED(sourceSharedMutex->AcquireSync(0, 30 * 1000))) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceMutexTimeout";
// only wait for 30 seconds
return false;
}
RefPtr<ID3D11DeviceContext> deviceContext;
device->GetImmediateContext(getter_AddRefs(deviceContext));
{
HRESULT hr;
AutoTextureLock lock(__func__, sourceSharedMutex, hr, 30 * 1000);
if (NS_WARN_IF(!lock.Succeeded())) {
// only wait for 30 seconds
return false;
}
int stride = texture_size * 4;
deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride,
stride * texture_size);
device->GetImmediateContext(getter_AddRefs(deviceContext));
int stride = texture_size * 4;
deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride,
stride * texture_size);
if (FAILED(sourceSharedMutex->ReleaseSync(0))) {
gfxCriticalError()
<< "DoesD3D11TextureSharingWork_SourceReleaseSyncTimeout";
return false;
}
RefPtr<IDXGIResource1> otherResource;
@ -342,8 +333,8 @@ static bool DoesTextureSharingWorkInternal(ID3D11Device* device,
(void**)getter_AddRefs(sharedMutex));
{
HRESULT hr;
AutoTextureLock lock(__func__, sharedMutex, hr, 30 * 1000);
if (!lock.Succeeded()) {
AutoTextureLock lock(sharedMutex, hr, 30 * 1000);
if (FAILED(hr)) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_AcquireSyncTimeout";
// only wait for 30 seconds
return false;
@ -351,6 +342,9 @@ static bool DoesTextureSharingWorkInternal(ID3D11Device* device,
// Copy to the cpu texture so that we can readback
deviceContext->CopyResource(cpuTexture, sharedTexture);
// We only need to hold on to the mutex during the copy.
sharedMutex->ReleaseSync(0);
}
D3D11_MAPPED_SUBRESOURCE mapped;
@ -507,23 +501,5 @@ bool D3D11Checks::DoesRemotePresentWork(IDXGIAdapter* adapter) {
return options;
}
/* static */ bool D3D11Checks::DidAcquireSyncSucceed(const char* aCaller,
HRESULT aResult) {
MOZ_ASSERT(aCaller);
if (aResult == WAIT_TIMEOUT) {
gfxCriticalNote << aCaller << " AcquireSync timed out";
return false;
}
if (aResult == WAIT_ABANDONED) {
gfxCriticalNote << aCaller << " AcquireSync abandoned";
return false;
}
if (FAILED(aResult)) {
gfxCriticalNote << aCaller << " AcquireSync failed " << gfx::hexa(aResult);
return false;
}
return true;
}
} // namespace gfx
} // namespace mozilla

View file

@ -9,10 +9,6 @@
#include "mozilla/EnumSet.h"
#include "mozilla/EnumTypeTraits.h"
#ifdef XP_WIN
# include <winerror.h>
#endif
struct ID3D11Device;
struct IDXGIAdapter;
struct DXGI_ADAPTER_DESC;
@ -36,9 +32,6 @@ struct D3D11Checks {
static bool GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out);
static bool DoesRemotePresentWork(IDXGIAdapter* adapter);
static VideoFormatOptionSet FormatOptions(ID3D11Device* device);
#ifdef XP_WIN
static bool DidAcquireSyncSucceed(const char* aCaller, HRESULT aResult);
#endif
};
} // namespace gfx

View file

@ -123,7 +123,7 @@ bool VRSession::SubmitFrame(
gfxCriticalNote << "GFX: D3D11 lock mutex abandoned";
}
# endif
if (SUCCEEDED(hr) && hr != WAIT_TIMEOUT && hr != WAIT_ABANDONED) {
if (SUCCEEDED(hr)) {
success = SubmitFrame(aLayer, dxTexture);
hr = mutex->ReleaseSync(0);
if (FAILED(hr)) {

View file

@ -662,18 +662,12 @@ bool RenderDXGIYCbCrTextureHost::EnsureD3D11Texture2D(ID3D11Device* aDevice) {
bool RenderDXGIYCbCrTextureHost::LockInternal() {
if (!mLocked) {
if (mKeyedMutexs[0]) {
for (int i = 0; i < 3; ++i) {
HRESULT hr = mKeyedMutexs[i]->AcquireSync(0, 10000);
for (const auto& mutex : mKeyedMutexs) {
HRESULT hr = mutex->AcquireSync(0, 10000);
if (hr != S_OK) {
gfxCriticalError()
<< "RenderDXGIYCbCrTextureHost AcquireSync timeout, hr="
<< gfx::hexa(hr);
// Ensure that we release all of the mutexes in the event of failure.
while (i > 0) {
--i;
mKeyedMutexs[i]->ReleaseSync(0);
}
return false;
}
}