From 8ffc85202ee45353785c9c7eddfc26678b9cd11a Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 23 Jan 2014 15:27:06 +0100 Subject: [PATCH] Bug 952507 - Fix locking in double buffered ContentClient. r=nrc --- gfx/layers/client/ContentClient.cpp | 13 ++++++++++- gfx/layers/client/TextureClient.h | 4 ++++ gfx/layers/d3d11/TextureD3D11.h | 2 ++ gfx/layers/d3d9/TextureD3D9.h | 6 +++++ gfx/layers/opengl/TextureClientOGL.cpp | 31 ++++++++++++++++++++++++++ gfx/layers/opengl/TextureClientOGL.h | 14 ++++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index d65a33b98b0..bf8e4607c0b 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -148,7 +148,9 @@ ContentClientRemoteBuffer::EndPaint() SetBufferProvider(nullptr); SetBufferProviderOnWhite(nullptr); for (unsigned i = 0; i< mOldTextures.Length(); ++i) { - mOldTextures[i]->Unlock(); + if (mOldTextures[i]->IsLocked()) { + mOldTextures[i]->Unlock(); + } } mOldTextures.Clear(); @@ -557,6 +559,15 @@ ContentClientDoubleBuffered::PrepareFrame() { mIsNewBuffer = false; + if (mTextureClient) { + DebugOnly locked = mTextureClient->Lock(OPEN_READ_WRITE); + MOZ_ASSERT(locked); + } + if (mTextureClientOnWhite) { + DebugOnly locked = mTextureClientOnWhite->Lock(OPEN_READ_WRITE); + MOZ_ASSERT(locked); + } + if (!mFrontAndBackBufferDiffer) { return; } diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 775e2061491..80d05540c73 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -172,6 +172,8 @@ public: virtual void Unlock() {} + virtual bool IsLocked() const = 0; + /** * Returns true if this texture has a lock/unlock mechanism. * Textures that do not implement locking should be immutable or should @@ -313,6 +315,8 @@ public: virtual void Unlock() MOZ_OVERRIDE; + virtual bool IsLocked() const MOZ_OVERRIDE { return mLocked; } + // TextureClientSurface virtual TextureClientSurface* AsTextureClientSurface() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 0bf6e513655..d510d96c61b 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -41,6 +41,8 @@ public: virtual void Unlock() MOZ_OVERRIDE; + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; } diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index b60d487a7fc..a845f53accf 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -194,6 +194,8 @@ public: virtual void Unlock() MOZ_OVERRIDE; + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; virtual gfx::IntSize GetSize() const { return mSize; } @@ -242,6 +244,8 @@ public: virtual void Unlock() MOZ_OVERRIDE; + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; virtual gfx::IntSize GetSize() const { return mSize; } @@ -287,6 +291,8 @@ public: virtual void Unlock() MOZ_OVERRIDE; + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; void InitWith(IDirect3DTexture9* aTexture, HANDLE aSharedHandle, D3DSURFACE_DESC aDesc) diff --git a/gfx/layers/opengl/TextureClientOGL.cpp b/gfx/layers/opengl/TextureClientOGL.cpp index 6eb406c7e5e..6ae3ac89c41 100644 --- a/gfx/layers/opengl/TextureClientOGL.cpp +++ b/gfx/layers/opengl/TextureClientOGL.cpp @@ -60,6 +60,21 @@ SharedTextureClientOGL::InitWith(gl::SharedTextureHandle aHandle, } } +bool +SharedTextureClientOGL::Lock(OpenMode mode) +{ + MOZ_ASSERT(!mIsLocked); + mIsLocked = true; + return true; +} + +void +SharedTextureClientOGL::Unlock() +{ + MOZ_ASSERT(mIsLocked); + mIsLocked = false; +} + bool SharedTextureClientOGL::IsAllocated() const { @@ -69,6 +84,7 @@ SharedTextureClientOGL::IsAllocated() const StreamTextureClientOGL::StreamTextureClientOGL(TextureFlags aFlags) : TextureClient(aFlags) , mStream(0) + , mIsLocked(false) { } @@ -77,6 +93,21 @@ StreamTextureClientOGL::~StreamTextureClientOGL() // the data is owned externally. } +bool +StreamTextureClientOGL::Lock(OpenMode mode) +{ + MOZ_ASSERT(!mIsLocked); + mIsLocked = true; + return true; +} + +void +StreamTextureClientOGL::Unlock() +{ + MOZ_ASSERT(mIsLocked); + mIsLocked = false; +} + bool StreamTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) { diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h index 6afa130711a..e8123767080 100644 --- a/gfx/layers/opengl/TextureClientOGL.h +++ b/gfx/layers/opengl/TextureClientOGL.h @@ -40,6 +40,12 @@ public: virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; + virtual bool Lock(OpenMode mode) MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + void InitWith(gl::SharedTextureHandle aHandle, gfx::IntSize aSize, gl::SharedTextureShareType aShareType, @@ -61,6 +67,7 @@ protected: gfx::IntSize mSize; gl::SharedTextureShareType mShareType; bool mInverted; + bool mIsLocked; }; /** @@ -75,6 +82,12 @@ public: virtual bool IsAllocated() const MOZ_OVERRIDE; + virtual bool Lock(OpenMode mode) MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + + virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; } + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE; virtual TextureClientData* DropTextureData() MOZ_OVERRIDE { return nullptr; } @@ -85,6 +98,7 @@ public: protected: gfx::SurfaceStream* mStream; + bool mIsLocked; }; class DeprecatedTextureClientSharedOGL : public DeprecatedTextureClient