diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 85be62aa8d32..2025de0008e4 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -650,12 +650,11 @@ CairoImage::GetTextureClient(CompositableClient *aClient) return nullptr; } - if (!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) { + TextureClientAutoLock autoLock(textureClient, OpenMode::OPEN_WRITE_ONLY); + if (!autoLock.Succeeded()) { return nullptr; } - TextureClientAutoUnlock autoUnlock(textureClient); - textureClient->UpdateFromSurface(surface); textureClient->SyncWithObject(forwarder->GetSyncObject()); diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index f7710db22aa4..469efed1d88e 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -12,6 +12,7 @@ #include "ImageTypes.h" // for StereoMode #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/Attributes.h" // for override +#include "mozilla/DebugOnly.h" #include "mozilla/RefPtr.h" // for RefPtr, RefCounted #include "mozilla/gfx/2D.h" // for DrawTarget #include "mozilla/gfx/Point.h" // for IntSize @@ -720,17 +721,39 @@ protected: size_t mBufSize; }; -struct TextureClientAutoUnlock +// Automatically lock and unlock a texture. Since texture locking is fallible, +// Succeeded() must be checked on the guard object before proceeding. +class MOZ_RAII TextureClientAutoLock { - TextureClient* mTexture; + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER; - explicit TextureClientAutoUnlock(TextureClient* aTexture) - : mTexture(aTexture) {} - - ~TextureClientAutoUnlock() +public: + TextureClientAutoLock(TextureClient* aTexture, OpenMode aMode + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : mTexture(aTexture), + mSucceeded(false) { - mTexture->Unlock(); + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + + mSucceeded = mTexture->Lock(aMode); + mChecked = false; } + ~TextureClientAutoLock() { + MOZ_ASSERT(mChecked); + if (mSucceeded) { + mTexture->Unlock(); + } + } + + bool Succeeded() { + mChecked = true; + return mSucceeded; + } + +private: + TextureClient* mTexture; + DebugOnly mChecked; + bool mSucceeded; }; class KeepAlive diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp index 719fa0e4b10a..cb75f2a6c99b 100644 --- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp @@ -90,11 +90,13 @@ SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData) } MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr()); - if (!mTextureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) { + + TextureClientAutoLock autoLock(mTextureClient, OpenMode::OPEN_WRITE_ONLY); + if (!autoLock.Succeeded()) { MOZ_ASSERT(false, "Failed to lock the texture."); return false; } - TextureClientAutoUnlock unlock(mTextureClient); + if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) { MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient"); return false;