diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 9abdd76052fb..dba72480ac4a 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -21,6 +21,7 @@ #include "ScopedGLHelpers.h" #include "gfx2DGlue.h" #include "../layers/ipc/ShadowLayers.h" +#include "mozilla/layers/TextureClientSharedSurface.h" namespace mozilla { namespace gl { @@ -39,40 +40,36 @@ GLScreenBuffer::Create(GLContext* gl, return Move(ret); } - UniquePtr factory; -#ifdef MOZ_WIDGET_GONK - /* On B2G, we want a Gralloc factory, and we want one right at the start */ - layers::ISurfaceAllocator* allocator = caps.surfaceAllocator; - if (!factory && - allocator && - XRE_GetProcessType() != GeckoProcessType_Default) - { - layers::TextureFlags flags = layers::TextureFlags::DEALLOCATE_CLIENT | - layers::TextureFlags::ORIGIN_BOTTOM_LEFT; - if (!caps.premultAlpha) { - flags |= layers::TextureFlags::NON_PREMULTIPLIED; - } + layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT; + if (!caps.premultAlpha) { + flags |= layers::TextureFlags::NON_PREMULTIPLIED; + } - factory = MakeUnique(gl, caps, flags, - allocator); - } -#endif -#ifdef XP_MACOSX - /* On OSX, we want an IOSurface factory, and we want one right at the start */ - if (!factory) { - factory = SurfaceFactory_IOSurface::Create(gl, caps); - } -#endif - - if (!factory) { - factory = MakeUnique(gl, caps); - } + UniquePtr factory = MakeUnique(gl, caps, flags); ret.reset( new GLScreenBuffer(gl, caps, Move(factory)) ); return Move(ret); } +GLScreenBuffer::GLScreenBuffer(GLContext* gl, + const SurfaceCaps& caps, + UniquePtr factory) + : mGL(gl) + , mCaps(caps) + , mFactory(Move(factory)) + , mNeedsBlit(true) + , mUserReadBufferMode(LOCAL_GL_BACK) + , mUserDrawFB(0) + , mUserReadFB(0) + , mInternalDrawFB(0) + , mInternalReadFB(0) +#ifdef DEBUG + , mInInternalMode_DrawFB(true) + , mInInternalMode_ReadFB(true) +#endif +{ } + GLScreenBuffer::~GLScreenBuffer() { mDraw = nullptr; @@ -465,7 +462,7 @@ GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size) bool GLScreenBuffer::Swap(const gfx::IntSize& size) { - RefPtr newBack = mFactory->NewShSurfHandle(size); + RefPtr newBack = mFactory->NewTexClient(size); if (!newBack) return false; @@ -522,7 +519,7 @@ GLScreenBuffer::PublishFrame(const gfx::IntSize& size) bool GLScreenBuffer::Resize(const gfx::IntSize& size) { - RefPtr newBack = mFactory->NewShSurfHandle(size); + RefPtr newBack = mFactory->NewTexClient(size); if (!newBack) return false; diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index 965f068455a6..b9dd9f74eee2 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -24,6 +24,10 @@ #include "SurfaceTypes.h" namespace mozilla { +namespace layers { +class SharedSurfaceTextureClient; +} + namespace gl { class GLContext; @@ -136,8 +140,8 @@ public: protected: UniquePtr mFactory; - RefPtr mBack; - RefPtr mFront; + RefPtr mBack; + RefPtr mFront; UniquePtr mDraw; UniquePtr mRead; @@ -159,21 +163,7 @@ protected: GLScreenBuffer(GLContext* gl, const SurfaceCaps& caps, - UniquePtr factory) - : mGL(gl) - , mCaps(caps) - , mFactory(Move(factory)) - , mNeedsBlit(true) - , mUserReadBufferMode(LOCAL_GL_BACK) - , mUserDrawFB(0) - , mUserReadFB(0) - , mInternalDrawFB(0) - , mInternalReadFB(0) -#ifdef DEBUG - , mInInternalMode_DrawFB(true) - , mInInternalMode_ReadFB(true) -#endif - {} + UniquePtr factory); public: virtual ~GLScreenBuffer(); @@ -182,7 +172,7 @@ public: return mFactory.get(); } - ShSurfHandle* Front() const { + const RefPtr& Front() const { return mFront; } diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp index f4280f91a86c..4cefb5532c7a 100644 --- a/gfx/gl/SharedSurface.cpp +++ b/gfx/gl/SharedSurface.cpp @@ -12,6 +12,8 @@ #include "nsThreadUtils.h" #include "ScopedGLHelpers.h" #include "SharedSurfaceGL.h" +#include "mozilla/layers/CompositorTypes.h" +#include "mozilla/layers/TextureClientSharedSurface.h" namespace mozilla { namespace gl { @@ -32,12 +34,9 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, dest->mAttachType == AttachmentType::Screen) { // Here, we actually need to blit through a temp surface, so let's make one. - UniquePtr tempSurf; - tempSurf = SharedSurface_GLTexture::Create(gl, - gl, - factory->mFormats, - src->mSize, - factory->mCaps.alpha); + UniquePtr tempSurf; + tempSurf = SharedSurface_Basic::Create(gl, factory->mFormats, src->mSize, + factory->mCaps.alpha); ProdCopy(src, tempSurf.get(), factory); ProdCopy(tempSurf.get(), dest, factory); @@ -203,20 +202,21 @@ SharedSurface::SharedSurface(SharedSurfaceType type, AttachmentType attachType, GLContext* gl, const gfx::IntSize& size, - bool hasAlpha) + bool hasAlpha, + bool canRecycle) : mType(type) , mAttachType(attachType) , mGL(gl) , mSize(size) , mHasAlpha(hasAlpha) + , mCanRecycle(canRecycle) , mIsLocked(false) , mIsProducerAcquired(false) , mIsConsumerAcquired(false) #ifdef DEBUG , mOwningThread(NS_GetCurrentThread()) #endif -{ -} +{ } void SharedSurface::LockProd() @@ -262,8 +262,6 @@ SharedSurface::PollSync_ContentThread() return PollSync_ContentThread_Impl(); } - - //////////////////////////////////////////////////////////////////////// // SurfaceFactory @@ -301,12 +299,15 @@ ChooseBufferBits(const SurfaceCaps& caps, } } -SurfaceFactory::SurfaceFactory(GLContext* gl, - SharedSurfaceType type, - const SurfaceCaps& caps) - : mGL(gl) +SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl, + const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags) + : mType(type) + , mGL(gl) , mCaps(caps) - , mType(type) + , mAllocator(allocator) + , mFlags(flags) , mFormats(gl->ChooseGLFormats(caps)) { ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps); @@ -314,51 +315,67 @@ SurfaceFactory::SurfaceFactory(GLContext* gl, SurfaceFactory::~SurfaceFactory() { - while (!mScraps.Empty()) { - mScraps.Pop(); + while (!mRecyclePool.empty()) { + RefPtr cur = mRecyclePool.front(); + mRecyclePool.pop(); + + cur->StopRecycling(); } } -UniquePtr -SurfaceFactory::NewSharedSurface(const gfx::IntSize& size) +TemporaryRef +SurfaceFactory::NewTexClient(const gfx::IntSize& size) { - // Attempt to reuse an old surface. - while (!mScraps.Empty()) { - UniquePtr cur = mScraps.Pop(); + while (!mRecyclePool.empty()) { + RefPtr cur = mRecyclePool.front(); + mRecyclePool.pop(); - if (cur->mSize == size) - return Move(cur); + if (cur->Surf()->mSize == size) { + return cur.forget(); + } - // Let `cur` be destroyed as it falls out of scope, if it wasn't - // moved. + // Let it die. + cur->StopRecycling(); } - return CreateShared(size); -} - -TemporaryRef -SurfaceFactory::NewShSurfHandle(const gfx::IntSize& size) -{ - auto surf = NewSharedSurface(size); + UniquePtr surf = Move(CreateShared(size)); if (!surf) return nullptr; - // Before next use, wait until SharedSurface's buffer - // is no longer being used. - surf->WaitForBufferOwnership(); - - return new ShSurfHandle(this, Move(surf)); + RefPtr ret; + ret = new layers::SharedSurfaceTextureClient(mAllocator, mFlags, Move(surf), this); + return ret.forget(); } -// Auto-deletes surfs of the wrong type. -void -SurfaceFactory::Recycle(UniquePtr surf) +/*static*/ void +SurfaceFactory::RecycleCallback(layers::TextureClient* tc, void* /*closure*/) { - MOZ_ASSERT(surf); + MOZ_ASSERT(NS_IsMainThread()); - if (surf->mType == mType) { - mScraps.Push(Move(surf)); + layers::SharedSurfaceTextureClient* sstc = (layers::SharedSurfaceTextureClient*)tc; + + if (sstc->mSurf->mCanRecycle && sstc->mFactory) { + if (sstc->mFactory->Recycle(sstc)) + return; } + + // Did not recover the tex client. End the (re)cycle! + sstc->StopRecycling(); +} + +bool +SurfaceFactory::Recycle(layers::SharedSurfaceTextureClient* texClient) +{ + MOZ_ASSERT(texClient); + MOZ_ASSERT(texClient->mFactory == this); + + if (mRecyclePool.size() >= 2) { + return false; + } + + RefPtr texClientRef = texClient; + mRecyclePool.push(texClientRef); + return true; } //////////////////////////////////////////////////////////////////////////////// diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h index 6b88a4c27080..f2ef751feeaf 100644 --- a/gfx/gl/SharedSurface.h +++ b/gfx/gl/SharedSurface.h @@ -34,6 +34,15 @@ namespace mozilla { namespace gfx { class DrawTarget; } + +namespace layers { +class ISurfaceAllocator; +class SharedSurfaceTextureClient; +enum class TextureFlags : uint32_t; +class SurfaceDescriptor; +class TextureClient; +} + namespace gl { class GLContext; @@ -51,6 +60,7 @@ public: GLContext* const mGL; const gfx::IntSize mSize; const bool mHasAlpha; + const bool mCanRecycle; protected: bool mIsLocked; bool mIsProducerAcquired; @@ -61,7 +71,8 @@ protected: AttachmentType attachType, GLContext* gl, const gfx::IntSize& size, - bool hasAlpha); + bool hasAlpha, + bool canRecycle); public: virtual ~SharedSurface() { @@ -173,37 +184,8 @@ public: virtual bool NeedsIndirectReads() const { return false; } -}; -template -class UniquePtrQueue -{ - std::queue mQueue; - -public: - ~UniquePtrQueue() { - MOZ_ASSERT(Empty()); - } - - bool Empty() const { - return mQueue.empty(); - } - - void Push(UniquePtr up) { - T* p = up.release(); - mQueue.push(p); - } - - UniquePtr Pop() { - UniquePtr ret; - - if (!mQueue.empty()) { - ret.reset(mQueue.front()); - mQueue.pop(); - } - - return Move(ret); - } + virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) = 0; }; class SurfaceFactory : public SupportsWeakPtr @@ -213,18 +195,20 @@ public: // with SupportsWeakPtr. (bug 1049278) MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory) + const SharedSurfaceType mType; GLContext* const mGL; const SurfaceCaps mCaps; - const SharedSurfaceType mType; + const RefPtr mAllocator; + const layers::TextureFlags mFlags; const GLFormats mFormats; - protected: SurfaceCaps mDrawCaps; SurfaceCaps mReadCaps; + std::queue> mRecyclePool; - SurfaceFactory(GLContext* gl, - SharedSurfaceType type, - const SurfaceCaps& caps); + SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags); public: virtual ~SurfaceFactory(); @@ -240,44 +224,15 @@ public: protected: virtual UniquePtr CreateShared(const gfx::IntSize& size) = 0; - UniquePtrQueue mScraps; - public: UniquePtr NewSharedSurface(const gfx::IntSize& size); - TemporaryRef NewShSurfHandle(const gfx::IntSize& size); + //TemporaryRef NewShSurfHandle(const gfx::IntSize& size); + TemporaryRef NewTexClient(const gfx::IntSize& size); + + static void RecycleCallback(layers::TextureClient* tc, void* /*closure*/); // Auto-deletes surfs of the wrong type. - void Recycle(UniquePtr surf); -}; - -class ShSurfHandle : public RefCounted -{ -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(ShSurfHandle) - -private: - const WeakPtr mFactory; - UniquePtr mSurf; - -public: - ShSurfHandle(SurfaceFactory* factory, UniquePtr surf) - : mFactory(factory) - , mSurf(Move(surf)) - { - MOZ_ASSERT(mFactory); - MOZ_ASSERT(mSurf); - } - - ~ShSurfHandle() { - if (mFactory) { - mFactory->Recycle(Move(mSurf)); - } - } - - SharedSurface* Surf() const { - MOZ_ASSERT(mSurf.get()); - return mSurf.get(); - } + bool Recycle(layers::SharedSurfaceTextureClient* texClient); }; class ScopedReadbackFB diff --git a/gfx/gl/SharedSurfaceANGLE.cpp b/gfx/gl/SharedSurfaceANGLE.cpp index 5960f9042d5d..681d3ebc2b64 100644 --- a/gfx/gl/SharedSurfaceANGLE.cpp +++ b/gfx/gl/SharedSurfaceANGLE.cpp @@ -4,11 +4,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SharedSurfaceANGLE.h" -#include "GLContextEGL.h" -#include "GLLibraryEGL.h" #include #include "gfxWindowsPlatform.h" +#include "GLContextEGL.h" +#include "GLLibraryEGL.h" +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc namespace mozilla { namespace gl { @@ -105,7 +106,8 @@ SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl, AttachmentType::Screen, gl, size, - hasAlpha) + hasAlpha, + true) , mEGL(egl) , mContext(context) , mPBuffer(pbuffer) @@ -253,6 +255,16 @@ SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl() return PollSync(); } +bool +SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) +{ + gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8 + : gfx::SurfaceFormat::B8G8R8X8; + *out_descriptor = layers::SurfaceDescriptorD3D10((WindowsHandle)mShareHandle, format, + mSize); + return true; +} + //////////////////////////////////////////////////////////////////////////////// // Factory @@ -388,8 +400,9 @@ ChooseConfig(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps) } /*static*/ UniquePtr -SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, - const SurfaceCaps& caps) +SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags) { GLLibraryEGL* egl = &sEGLLibrary; if (!egl) @@ -401,7 +414,7 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, bool success; typedef SurfaceFactory_ANGLEShareHandle ptrT; - UniquePtr ret( new ptrT(gl, egl, caps, &success) ); + UniquePtr ret( new ptrT(gl, caps, allocator, flags, egl, &success) ); if (!success) return nullptr; @@ -410,10 +423,12 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, } SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl, - GLLibraryEGL* egl, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags, + GLLibraryEGL* egl, bool* const out_success) - : SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps) + : SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags) , mProdGL(gl) , mEGL(egl) { diff --git a/gfx/gl/SharedSurfaceANGLE.h b/gfx/gl/SharedSurfaceANGLE.h index 9823b2dc1c9f..ded695167e99 100644 --- a/gfx/gl/SharedSurfaceANGLE.h +++ b/gfx/gl/SharedSurfaceANGLE.h @@ -38,7 +38,9 @@ protected: GLLibraryEGL* const mEGL; const EGLContext mContext; const EGLSurface mPBuffer; +public: const HANDLE mShareHandle; +protected: RefPtr mKeyedMutex; RefPtr mConsumerKeyedMutex; RefPtr mConsumerTexture; @@ -75,14 +77,11 @@ public: virtual bool WaitSync_ContentThread_Impl() override; virtual bool PollSync_ContentThread_Impl() override; - // Implementation-specific functions below: - HANDLE GetShareHandle() { - return mShareHandle; - } - const RefPtr& GetConsumerTexture() const { return mConsumerTexture; } + + virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override; }; @@ -98,12 +97,14 @@ protected: public: static UniquePtr Create(GLContext* gl, - const SurfaceCaps& caps); + const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags); protected: - SurfaceFactory_ANGLEShareHandle(GLContext* gl, - GLLibraryEGL* egl, - const SurfaceCaps& caps, + SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags, GLLibraryEGL* egl, bool* const out_success); virtual UniquePtr CreateShared(const gfx::IntSize& size) override { diff --git a/gfx/gl/SharedSurfaceEGL.cpp b/gfx/gl/SharedSurfaceEGL.cpp index 8241f8554ff9..c309ce097047 100644 --- a/gfx/gl/SharedSurfaceEGL.cpp +++ b/gfx/gl/SharedSurfaceEGL.cpp @@ -9,6 +9,7 @@ #include "GLContextEGL.h" #include "GLLibraryEGL.h" #include "GLReadTexImageHelper.h" +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc #include "ScopedGLHelpers.h" #include "SharedSurface.h" #include "TextureGarbageBin.h" @@ -72,7 +73,8 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, AttachmentType::GLTexture, gl, size, - hasAlpha) + hasAlpha, + false) // Can't recycle, as mSync changes never update TextureHost. , mMutex("SharedSurface_EGLImage mutex") , mEGL(egl) , mFormats(formats) @@ -215,10 +217,20 @@ SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_te *out_target = LOCAL_GL_TEXTURE_EXTERNAL; } +bool +SharedSurface_EGLImage::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) +{ + *out_descriptor = layers::EGLImageDescriptor((uintptr_t)mImage, (uintptr_t)mSync, + mSize); + return true; +} + +//////////////////////////////////////////////////////////////////////// /*static*/ UniquePtr -SurfaceFactory_EGLImage::Create(GLContext* prodGL, - const SurfaceCaps& caps) +SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags) { EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext(); @@ -227,7 +239,7 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, GLLibraryEGL* egl = &sEGLLibrary; if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) { - ret.reset( new ptrT(prodGL, context, caps) ); + ret.reset( new ptrT(prodGL, caps, allocator, flags, context) ); } return Move(ret); diff --git a/gfx/gl/SharedSurfaceEGL.h b/gfx/gl/SharedSurfaceEGL.h index a27d3b669b53..e3524f078424 100644 --- a/gfx/gl/SharedSurfaceEGL.h +++ b/gfx/gl/SharedSurfaceEGL.h @@ -77,6 +77,8 @@ public: // Implementation-specific functions below: // Returns texture and target void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target); + + virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override; }; @@ -87,17 +89,20 @@ class SurfaceFactory_EGLImage public: // Fallible: static UniquePtr Create(GLContext* prodGL, - const SurfaceCaps& caps); + const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags); protected: const EGLContext mContext; - SurfaceFactory_EGLImage(GLContext* prodGL, - EGLContext context, - const SurfaceCaps& caps) - : SurfaceFactory(prodGL, SharedSurfaceType::EGLImageShare, caps) + SurfaceFactory_EGLImage(GLContext* prodGL, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags, + EGLContext context) + : SurfaceFactory(SharedSurfaceType::EGLImageShare, prodGL, caps, allocator, flags) , mContext(context) - {} + { } public: virtual UniquePtr CreateShared(const gfx::IntSize& size) override { diff --git a/gfx/gl/SharedSurfaceGL.cpp b/gfx/gl/SharedSurfaceGL.cpp index ab170b250935..09dcadd2f50f 100644 --- a/gfx/gl/SharedSurfaceGL.cpp +++ b/gfx/gl/SharedSurfaceGL.cpp @@ -39,40 +39,37 @@ SharedSurface_Basic::Create(GLContext* gl, return Move(ret); } - SurfaceFormat format = SurfaceFormat::B8G8R8X8; - switch (formats.color_texInternalFormat) { - case LOCAL_GL_RGB: - case LOCAL_GL_RGB8: - if (formats.color_texType == LOCAL_GL_UNSIGNED_SHORT_5_6_5) - format = SurfaceFormat::R5G6B5; - else - format = SurfaceFormat::B8G8R8X8; - break; - case LOCAL_GL_RGBA: - case LOCAL_GL_RGBA8: - case LOCAL_GL_BGRA: - case LOCAL_GL_BGRA8_EXT: - format = SurfaceFormat::B8G8R8A8; - break; - default: - MOZ_CRASH("Unhandled Tex format."); - } + bool ownsTex = true; + ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, tex, ownsTex) ); + return Move(ret); +} - ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, format, tex) ); + +/*static*/ UniquePtr +SharedSurface_Basic::Wrap(GLContext* gl, + const IntSize& size, + bool hasAlpha, + GLuint tex) +{ + bool ownsTex = false; + UniquePtr ret( new SharedSurface_Basic(gl, size, hasAlpha, tex, + ownsTex) ); return Move(ret); } SharedSurface_Basic::SharedSurface_Basic(GLContext* gl, const IntSize& size, bool hasAlpha, - SurfaceFormat format, - GLuint tex) + GLuint tex, + bool ownsTex) : SharedSurface(SharedSurfaceType::Basic, AttachmentType::GLTexture, gl, size, - hasAlpha) + hasAlpha, + true) , mTex(tex) + , mOwnsTex(ownsTex) , mFB(0) { mGL->MakeCurrent(); @@ -97,150 +94,16 @@ SharedSurface_Basic::~SharedSurface_Basic() if (mFB) mGL->fDeleteFramebuffers(1, &mFB); - mGL->fDeleteTextures(1, &mTex); + if (mOwnsTex) + mGL->fDeleteTextures(1, &mTex); } //////////////////////////////////////////////////////////////////////// -// SharedSurface_GLTexture -/*static*/ UniquePtr -SharedSurface_GLTexture::Create(GLContext* prodGL, - GLContext* consGL, - const GLFormats& formats, - const IntSize& size, - bool hasAlpha, - GLuint texture) -{ - MOZ_ASSERT(prodGL); - MOZ_ASSERT(!consGL || prodGL->SharesWith(consGL)); - - prodGL->MakeCurrent(); - - GLuint tex = texture; - - bool ownsTex = false; - - UniquePtr ret; - - if (!tex) { - GLContext::LocalErrorScope localError(*prodGL); - - tex = CreateTextureForOffscreen(prodGL, formats, size); - - GLenum err = localError.GetError(); - MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY); - if (err) { - prodGL->fDeleteTextures(1, &tex); - return Move(ret); - } - - ownsTex = true; - } - - ret.reset( new SharedSurface_GLTexture(prodGL, consGL, size, - hasAlpha, tex, ownsTex) ); - return Move(ret); -} - -SharedSurface_GLTexture::~SharedSurface_GLTexture() -{ - if (!mGL->MakeCurrent()) - return; - - if (mOwnsTex) { - mGL->fDeleteTextures(1, &mTex); - } - - if (mSync) { - mGL->fDeleteSync(mSync); - } -} - -void -SharedSurface_GLTexture::Fence() -{ - MutexAutoLock lock(mMutex); - mGL->MakeCurrent(); - - if (mConsGL && mGL->IsExtensionSupported(GLContext::ARB_sync)) { - if (mSync) { - mGL->fDeleteSync(mSync); - mSync = 0; - } - - mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - if (mSync) { - mGL->fFlush(); - return; - } - } - MOZ_ASSERT(!mSync); - - mGL->fFinish(); -} - -bool -SharedSurface_GLTexture::WaitSync() -{ - MutexAutoLock lock(mMutex); - if (!mSync) { - // We either used glFinish, or we passed this fence already. - // (PollSync/WaitSync returned true previously) - return true; - } - - mConsGL->MakeCurrent(); - MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync)); - - mConsGL->fWaitSync(mSync, - 0, - LOCAL_GL_TIMEOUT_IGNORED); - mConsGL->fDeleteSync(mSync); - mSync = 0; - - return true; -} - -bool -SharedSurface_GLTexture::PollSync() -{ - MutexAutoLock lock(mMutex); - if (!mSync) { - // We either used glFinish, or we passed this fence already. - // (PollSync/WaitSync returned true previously) - return true; - } - - mConsGL->MakeCurrent(); - MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync)); - - GLint status = 0; - mConsGL->fGetSynciv(mSync, - LOCAL_GL_SYNC_STATUS, - 1, - nullptr, - &status); - if (status != LOCAL_GL_SIGNALED) - return false; - - mConsGL->fDeleteSync(mSync); - mSync = 0; - - return true; -} - -GLuint -SharedSurface_GLTexture::ConsTexture(GLContext* consGL) -{ - MutexAutoLock lock(mMutex); - MOZ_ASSERT(consGL); - MOZ_ASSERT(mGL->SharesWith(consGL)); - MOZ_ASSERT_IF(mConsGL, consGL == mConsGL); - - mConsGL = consGL; - - return mTex; -} +SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps, + const layers::TextureFlags& flags) + : SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags) +{ } } /* namespace gfx */ } /* namespace mozilla */ diff --git a/gfx/gl/SharedSurfaceGL.h b/gfx/gl/SharedSurfaceGL.h index 28e831bf0141..9ecf76f270d7 100644 --- a/gfx/gl/SharedSurfaceGL.h +++ b/gfx/gl/SharedSurfaceGL.h @@ -38,6 +38,11 @@ public: const gfx::IntSize& size, bool hasAlpha); + static UniquePtr Wrap(GLContext* gl, + const gfx::IntSize& size, + bool hasAlpha, + GLuint tex); + static SharedSurface_Basic* Cast(SharedSurface* surf) { MOZ_ASSERT(surf->mType == SharedSurfaceType::Basic); @@ -46,13 +51,14 @@ public: protected: const GLuint mTex; + const bool mOwnsTex; GLuint mFB; SharedSurface_Basic(GLContext* gl, const gfx::IntSize& size, bool hasAlpha, - gfx::SurfaceFormat format, - GLuint tex); + GLuint tex, + bool ownsTex); public: virtual ~SharedSurface_Basic(); @@ -67,15 +73,19 @@ public: virtual GLuint ProdTexture() override { return mTex; } + + virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override { + MOZ_CRASH("don't do this"); + return false; + } }; class SurfaceFactory_Basic : public SurfaceFactory { public: - SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps) - : SurfaceFactory(gl, SharedSurfaceType::Basic, caps) - {} + SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps, + const layers::TextureFlags& flags); virtual UniquePtr CreateShared(const gfx::IntSize& size) override { bool hasAlpha = mReadCaps.alpha; @@ -83,99 +93,6 @@ public: } }; - -// Using shared GL textures: -class SharedSurface_GLTexture - : public SharedSurface -{ -public: - static UniquePtr Create(GLContext* prodGL, - GLContext* consGL, - const GLFormats& formats, - const gfx::IntSize& size, - bool hasAlpha, - GLuint texture = 0); - - static SharedSurface_GLTexture* Cast(SharedSurface* surf) { - MOZ_ASSERT(surf->mType == SharedSurfaceType::GLTextureShare); - - return (SharedSurface_GLTexture*)surf; - } - -protected: - GLContext* mConsGL; - const GLuint mTex; - const bool mOwnsTex; - GLsync mSync; - mutable Mutex mMutex; - - SharedSurface_GLTexture(GLContext* prodGL, - GLContext* consGL, - const gfx::IntSize& size, - bool hasAlpha, - GLuint tex, - bool ownsTex) - : SharedSurface(SharedSurfaceType::GLTextureShare, - AttachmentType::GLTexture, - prodGL, - size, - hasAlpha) - , mConsGL(consGL) - , mTex(tex) - , mOwnsTex(ownsTex) - , mSync(0) - , mMutex("SharedSurface_GLTexture mutex") - { - } - -public: - virtual ~SharedSurface_GLTexture(); - - virtual void LockProdImpl() override {} - virtual void UnlockProdImpl() override {} - - virtual void Fence() override; - virtual bool WaitSync() override; - virtual bool PollSync() override; - - virtual GLuint ProdTexture() override { - return mTex; - } - - // Custom: - - GLuint ConsTexture(GLContext* consGL); - - GLenum ConsTextureTarget() const { - return ProdTextureTarget(); - } -}; - -class SurfaceFactory_GLTexture - : public SurfaceFactory -{ -protected: - GLContext* const mConsGL; - -public: - // If we don't know `consGL` at construction time, use `nullptr`, and call - // `SetConsumerGL()` on each `SharedSurface_GLTexture` before calling its - // `WaitSync()`. - SurfaceFactory_GLTexture(GLContext* prodGL, - GLContext* consGL, - const SurfaceCaps& caps) - : SurfaceFactory(prodGL, SharedSurfaceType::GLTextureShare, caps) - , mConsGL(consGL) - { - MOZ_ASSERT(consGL != prodGL); - } - - virtual UniquePtr CreateShared(const gfx::IntSize& size) override { - bool hasAlpha = mReadCaps.alpha; - return SharedSurface_GLTexture::Create(mGL, mConsGL, mFormats, size, hasAlpha); - } -}; - } /* namespace gfx */ } /* namespace mozilla */ diff --git a/gfx/gl/SharedSurfaceGralloc.cpp b/gfx/gl/SharedSurfaceGralloc.cpp index 329e0a0fd8ad..3fb86d565d1f 100644 --- a/gfx/gl/SharedSurfaceGralloc.cpp +++ b/gfx/gl/SharedSurfaceGralloc.cpp @@ -35,13 +35,10 @@ namespace gl { using namespace mozilla::layers; using namespace android; -SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, - const SurfaceCaps& caps, - layers::TextureFlags flags, - layers::ISurfaceAllocator* allocator) - : SurfaceFactory(prodGL, SharedSurfaceType::Gralloc, caps) - , mFlags(flags) - , mAllocator(allocator) +SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags) + : SurfaceFactory(SharedSurfaceType::Gralloc, prodGL, caps, allocator, flags) { MOZ_ASSERT(mAllocator); } @@ -132,7 +129,8 @@ SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL, AttachmentType::GLTexture, prodGL, size, - hasAlpha) + hasAlpha, + true) , mEGL(egl) , mSync(0) , mAllocator(allocator) @@ -284,5 +282,11 @@ SharedSurface_Gralloc::WaitForBufferOwnership() mTextureClient->WaitForBufferOwnership(); } +bool +SharedSurface_Gralloc::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) +{ + return mTextureClient->ToSurfaceDescriptor(*out_descriptor); } -} + +} // namespace gl +} // namespace mozilla diff --git a/gfx/gl/SharedSurfaceGralloc.h b/gfx/gl/SharedSurfaceGralloc.h index 3137a189371f..14097224cde3 100644 --- a/gfx/gl/SharedSurfaceGralloc.h +++ b/gfx/gl/SharedSurfaceGralloc.h @@ -73,20 +73,17 @@ public: layers::GrallocTextureClientOGL* GetTextureClient() { return mTextureClient; } + + virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override; }; class SurfaceFactory_Gralloc : public SurfaceFactory { -protected: - const layers::TextureFlags mFlags; - RefPtr mAllocator; - public: - SurfaceFactory_Gralloc(GLContext* prodGL, - const SurfaceCaps& caps, - layers::TextureFlags flags, - layers::ISurfaceAllocator* allocator); + SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags); virtual UniquePtr CreateShared(const gfx::IntSize& size) override { bool hasAlpha = mReadCaps.alpha; diff --git a/gfx/gl/SharedSurfaceIO.cpp b/gfx/gl/SharedSurfaceIO.cpp index 75cfeb4c70c6..67f83bdc1fe3 100644 --- a/gfx/gl/SharedSurfaceIO.cpp +++ b/gfx/gl/SharedSurfaceIO.cpp @@ -6,8 +6,9 @@ #include "SharedSurfaceIO.h" #include "GLContextCGL.h" -#include "mozilla/gfx/MacIOSurface.h" #include "mozilla/DebugOnly.h" +#include "mozilla/gfx/MacIOSurface.h" +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc #include "ScopedGLHelpers.h" namespace mozilla { @@ -152,7 +153,8 @@ SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr& ioS AttachmentType::GLTexture, gl, size, - hasAlpha) + hasAlpha, + true) , mIOSurf(ioSurf) { gl->MakeCurrent(); @@ -170,18 +172,29 @@ SharedSurface_IOSurface::~SharedSurface_IOSurface() } } +bool +SharedSurface_IOSurface::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) +{ + bool isOpaque = !mHasAlpha; + *out_descriptor = layers::SurfaceDescriptorMacIOSurface(mIOSurf->GetIOSurfaceID(), + mIOSurf->GetContentsScaleFactor(), + isOpaque); + return true; +} + //////////////////////////////////////////////////////////////////////// // SurfaceFactory_IOSurface /*static*/ UniquePtr -SurfaceFactory_IOSurface::Create(GLContext* gl, - const SurfaceCaps& caps) +SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags) { gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(), MacIOSurface::GetMaxHeight()); typedef SurfaceFactory_IOSurface ptrT; - UniquePtr ret( new ptrT(gl, caps, maxDims) ); + UniquePtr ret( new ptrT(gl, caps, allocator, flags, maxDims) ); return Move(ret); } diff --git a/gfx/gl/SharedSurfaceIO.h b/gfx/gl/SharedSurfaceIO.h index d1a3724ebd81..88a495ad616f 100644 --- a/gfx/gl/SharedSurfaceIO.h +++ b/gfx/gl/SharedSurfaceIO.h @@ -16,11 +16,21 @@ namespace gl { class SharedSurface_IOSurface : public SharedSurface { +private: + const RefPtr mIOSurf; + GLuint mProdTex; + public: static UniquePtr Create(const RefPtr& ioSurf, GLContext* gl, bool hasAlpha); +private: + SharedSurface_IOSurface(const RefPtr& ioSurf, + GLContext* gl, const gfx::IntSize& size, + bool hasAlpha); + +public: ~SharedSurface_IOSurface(); virtual void LockProdImpl() override { } @@ -57,13 +67,7 @@ public: return true; } -private: - SharedSurface_IOSurface(const RefPtr& ioSurf, - GLContext* gl, const gfx::IntSize& size, - bool hasAlpha); - - RefPtr mIOSurf; - GLuint mProdTex; + virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override; }; class SurfaceFactory_IOSurface : public SurfaceFactory @@ -71,17 +75,19 @@ class SurfaceFactory_IOSurface : public SurfaceFactory public: // Infallible. static UniquePtr Create(GLContext* gl, - const SurfaceCaps& caps); + const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags); protected: const gfx::IntSize mMaxDims; - SurfaceFactory_IOSurface(GLContext* gl, - const SurfaceCaps& caps, + SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps, + const RefPtr& allocator, + const layers::TextureFlags& flags, const gfx::IntSize& maxDims) - : SurfaceFactory(gl, SharedSurfaceType::IOSurface, caps) + : SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags) , mMaxDims(maxDims) - { - } + { } virtual UniquePtr CreateShared(const gfx::IntSize& size) override; }; diff --git a/gfx/gl/SurfaceTypes.h b/gfx/gl/SurfaceTypes.h index a9fad2095019..7d3564093b4e 100644 --- a/gfx/gl/SurfaceTypes.h +++ b/gfx/gl/SurfaceTypes.h @@ -70,7 +70,6 @@ enum class SharedSurfaceType : uint8_t { Unknown = 0, Basic, - GLTextureShare, EGLImageShare, EGLSurfaceANGLE, DXGLInterop, diff --git a/gfx/layers/AtomicRefCountedWithFinalize.h b/gfx/layers/AtomicRefCountedWithFinalize.h index 82ac76b17f0d..9339b05ccf78 100644 --- a/gfx/layers/AtomicRefCountedWithFinalize.h +++ b/gfx/layers/AtomicRefCountedWithFinalize.h @@ -12,16 +12,27 @@ #include "base/message_loop.h" #include "base/task.h" +#define ADDREF_MANUALLY(obj) (obj)->AddRefManually(__FUNCTION__, __FILE__, __LINE__) +#define RELEASE_MANUALLY(obj) (obj)->ReleaseManually(__FUNCTION__, __FILE__, __LINE__) + namespace mozilla { +template +class StaticRefPtr; + template class AtomicRefCountedWithFinalize { - protected: +protected: AtomicRefCountedWithFinalize() : mRecycleCallback(nullptr) , mRefCount(0) , mMessageLoopToPostDestructionTo(nullptr) +#ifdef DEBUG + , mSpew(false) + , mManualAddRefs(0) + , mManualReleases(0) +#endif {} ~AtomicRefCountedWithFinalize() {} @@ -36,14 +47,63 @@ class AtomicRefCountedWithFinalize delete ptr; } - public: +public: + // Mark user classes that are considered flawless. + template + friend class RefPtr; + + template + friend class ::mozilla::StaticRefPtr; + + template + friend class TemporaryRef; + + template + friend class ::nsRefPtr; + + template + friend struct ::RunnableMethodTraits; + + //friend class mozilla::gl::SurfaceFactory; + + void AddRefManually(const char* funcName, const char* fileName, uint32_t lineNum) { +#ifdef DEBUG + uint32_t count = ++mManualAddRefs; + if (mSpew) { + printf_stderr("AddRefManually() #%u in %s at %s:%u\n", count, funcName, + fileName, lineNum); + } +#else + (void)funcName; + (void)fileName; + (void)lineNum; +#endif + AddRef(); + } + + void ReleaseManually(const char* funcName, const char* fileName, uint32_t lineNum) { +#ifdef DEBUG + uint32_t count = ++mManualReleases; + if (mSpew) { + printf_stderr("ReleaseManually() #%u in %s at %s:%u\n", count, funcName, + fileName, lineNum); + } +#else + (void)funcName; + (void)fileName; + (void)lineNum; +#endif + Release(); + } + +private: void AddRef() { - MOZ_ASSERT(mRefCount >= 0); + MOZ_ASSERT(mRefCount >= 0, "AddRef() during/after Finalize()/dtor."); ++mRefCount; } void Release() { - MOZ_ASSERT(mRefCount > 0); + MOZ_ASSERT(mRefCount > 0, "Release() during/after Finalize()/dtor."); // Read mRecycleCallback early so that it does not get set to // deleted memory, if the object is goes away. RecycleCallback recycleCallback = mRecycleCallback; @@ -52,6 +112,7 @@ class AtomicRefCountedWithFinalize // Recycle listeners must call ClearRecycleCallback // before releasing their strong reference. MOZ_ASSERT(mRecycleCallback == nullptr); + MOZ_ASSERT(mManualAddRefs == mManualReleases); #ifdef DEBUG mRefCount = detail::DEAD; #endif @@ -74,6 +135,7 @@ class AtomicRefCountedWithFinalize } } +public: typedef void (*RecycleCallback)(T* aObject, void* aClosure); /** * Set a callback responsible for recycling this object @@ -96,8 +158,15 @@ private: void *mClosure; Atomic mRefCount; MessageLoop *mMessageLoopToPostDestructionTo; +#ifdef DEBUG +public: + bool mSpew; +private: + Atomic mManualAddRefs; + Atomic mManualReleases; +#endif }; -} +} // namespace mozilla #endif diff --git a/gfx/layers/CopyableCanvasLayer.cpp b/gfx/layers/CopyableCanvasLayer.cpp index 4df37a850106..c7b1adf27dcd 100644 --- a/gfx/layers/CopyableCanvasLayer.cpp +++ b/gfx/layers/CopyableCanvasLayer.cpp @@ -3,8 +3,9 @@ * 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 "BasicLayersImpl.h" // for FillWithMask, etc #include "CopyableCanvasLayer.h" + +#include "BasicLayersImpl.h" // for FillWithMask, etc #include "GLContext.h" // for GLContext #include "GLScreenBuffer.h" // for GLScreenBuffer #include "SharedSurface.h" // for SharedSurface @@ -21,6 +22,7 @@ #include "nsRect.h" // for nsIntRect #include "nsSize.h" // for nsIntSize #include "gfxUtils.h" +#include "client/TextureClientSharedSurface.h" namespace mozilla { namespace layers { @@ -56,11 +58,8 @@ CopyableCanvasLayer::Initialize(const Data& aData) if (aData.mFrontbufferGLTex) { gfx::IntSize size(aData.mSize.width, aData.mSize.height); - mGLFrontbuffer = SharedSurface_GLTexture::Create(aData.mGLContext, - nullptr, - aData.mGLContext->GetGLFormats(), - size, aData.mHasAlpha, - aData.mFrontbufferGLTex); + mGLFrontbuffer = SharedSurface_Basic::Wrap(aData.mGLContext, size, aData.mHasAlpha, + aData.mFrontbufferGLTex); } } else if (aData.mDrawTarget) { mDrawTarget = aData.mDrawTarget; @@ -108,7 +107,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget) frontbuffer = mGLFrontbuffer.get(); } else { GLScreenBuffer* screen = mGLContext->Screen(); - ShSurfHandle* front = screen->Front(); + const auto& front = screen->Front(); if (front) { frontbuffer = front->Surf(); } @@ -137,7 +136,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget) Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat); mGLContext->Readback(frontbuffer, data); if (needsPremult) { - gfxUtils::PremultiplyDataSurface(data, data); + gfxUtils::PremultiplyDataSurface(data, data); } aDestTarget->ReleaseBits(destData); return; diff --git a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp index 891d02c130f2..46eef0bf6a36 100644 --- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp +++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp @@ -39,7 +39,7 @@ MacIOSurfaceTextureHostBasic::MacIOSurfaceTextureHostBasic( ) : TextureHost(aFlags) { - mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(), + mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(), aDescriptor.scaleFactor(), !aDescriptor.isOpaque()); } diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index 0b08a0c3fdc6..254549da8a87 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -22,9 +22,7 @@ #include "nsAutoPtr.h" // for nsRefPtr #include "nsDebug.h" // for printf_stderr, NS_ASSERTION #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc -#ifdef MOZ_WIDGET_GONK -#include "SharedSurfaceGralloc.h" -#endif +#include "TextureClientSharedSurface.h" using namespace mozilla::gfx; using namespace mozilla::gl; @@ -37,13 +35,6 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType, CompositableForwarder* aForwarder, TextureFlags aFlags) { -#ifndef MOZ_WIDGET_GONK - if (XRE_GetProcessType() != GeckoProcessType_Default) { - NS_WARNING("Most platforms still need an optimized way to share GL cross process."); - return new CanvasClient2D(aForwarder, aFlags); - } -#endif - switch (aType) { case CanvasClientTypeShSurf: return new CanvasClientSharedSurface(aForwarder, aFlags); @@ -147,28 +138,11 @@ CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat, CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder, TextureFlags aFlags) : CanvasClient(aLayerForwarder, aFlags) +{ } + +CanvasClientSharedSurface::~CanvasClientSharedSurface() { -} - -//////////////////////////////////////// -// Accelerated backends - -static TemporaryRef -TexClientFromShSurf(ISurfaceAllocator* aAllocator, SharedSurface* surf, - TextureFlags flags) -{ - switch (surf->mType) { - case SharedSurfaceType::Basic: - return nullptr; - -#ifdef MOZ_WIDGET_GONK - case SharedSurfaceType::Gralloc: - return GrallocTextureClientOGL::FromSharedSurface(surf, flags); -#endif - - default: - return new SharedSurfaceTextureClient(aAllocator, flags, surf); - } + ClearSurfaces(); } //////////////////////////////////////// @@ -328,91 +302,92 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator, //////////////////////////////////////// -static TemporaryRef +static TemporaryRef CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory) { - RefPtr dest = factory->NewShSurfHandle(src->mSize); + RefPtr dest = factory->NewTexClient(src->mSize); if (!dest) { - return nullptr; + return nullptr; } SharedSurface::ProdCopy(src, dest->Surf(), factory); + dest->Surf()->Fence(); return dest.forget(); } void CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { - if (mFront) { - mPrevFront = mFront; - mFront = nullptr; - } - auto gl = aLayer->mGLContext; gl->MakeCurrent(); + RefPtr newFront; + if (aLayer->mGLFrontbuffer) { - mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get()); - if (mFront) - mFront->Surf()->Fence(); + mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get()); + if (!mShSurfClient) { + gfxCriticalError() << "Invalid canvas front buffer"; + return; + } } else { - mFront = gl->Screen()->Front(); - } - if (!mFront) { - gfxCriticalError() << "Invalid canvas front buffer"; - return; + mShSurfClient = gl->Screen()->Front(); + if (!mShSurfClient) { + return; + } } + MOZ_ASSERT(mShSurfClient); + + newFront = mShSurfClient; + + SharedSurface* surf = mShSurfClient->Surf(); + + // Readback if needed. + mReadbackClient = nullptr; - // Alright, now sort out the IPC goop. - SharedSurface* surf = mFront->Surf(); auto forwarder = GetForwarder(); - auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE; - // Get a TexClient from our surf. - RefPtr newTex = TexClientFromShSurf(GetForwarder(), surf, flags); - if (!newTex) { + bool needsReadback = (surf->mType == SharedSurfaceType::Basic); + if (needsReadback) { + TextureFlags flags = aLayer->Flags() | + TextureFlags::IMMUTABLE; + auto manager = aLayer->ClientManager(); auto shadowForwarder = manager->AsShadowForwarder(); auto layersBackend = shadowForwarder->GetCompositorBackendType(); + mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend); - newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend); + newFront = mReadbackClient; + } else { + mReadbackClient = nullptr; } - if (!newTex) { + MOZ_ASSERT(newFront); + if (!newFront) { // May happen in a release build in case of memory pressure. - gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. size: " << aSize; + gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize; return; } - // Add the new TexClient. - MOZ_ALWAYS_TRUE( AddTextureClient(newTex) ); - - // Remove the old TexClient. - if (mFrontTex) { - // remove old buffer from CompositableHost - RefPtr tracker = new RemoveTextureFromCompositableTracker(); - // Hold TextureClient until transaction complete. - tracker->SetTextureClient(mFrontTex); - mFrontTex->SetRemoveFromCompositableTracker(tracker); - // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. - GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontTex); - - mFrontTex = nullptr; + if (mFront) { + if (mFront->GetFlags() & TextureFlags::RECYCLE) { + mFront->WaitForCompositorRecycle(); + } } - // Use the new TexClient. - mFrontTex = newTex; + mFront = newFront; - forwarder->UseTexture(this, mFrontTex); + // Add the new TexClient. + MOZ_ALWAYS_TRUE( AddTextureClient(mFront) ); + + forwarder->UseTexture(this, mFront); } void CanvasClientSharedSurface::ClearSurfaces() { - mFrontTex = nullptr; - // It is important to destroy the SharedSurface *after* the TextureClient. mFront = nullptr; - mPrevFront = nullptr; + mShSurfClient = nullptr; + mReadbackClient = nullptr; } -} -} +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/client/CanvasClient.h b/gfx/layers/client/CanvasClient.h index 3b3bb3fe0bd6..a96d1e7f23e0 100644 --- a/gfx/layers/client/CanvasClient.h +++ b/gfx/layers/client/CanvasClient.h @@ -18,18 +18,12 @@ #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/gfx/Types.h" // for SurfaceFormat -namespace mozilla { -namespace gl { -class SharedSurface; -class ShSurfHandle; -} -} - namespace mozilla { namespace layers { class ClientCanvasLayer; class CompositableForwarder; +class SharedSurfaceTextureClient; /** * Compositable client for 2d and webgl canvas. @@ -114,10 +108,9 @@ private: class CanvasClientSharedSurface : public CanvasClient { private: - RefPtr mFront; - RefPtr mPrevFront; - - RefPtr mFrontTex; + RefPtr mShSurfClient; + RefPtr mReadbackClient; + RefPtr mFront; void ClearSurfaces(); @@ -125,10 +118,7 @@ public: CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder, TextureFlags aFlags); - ~CanvasClientSharedSurface() - { - ClearSurfaces(); - } + ~CanvasClientSharedSurface(); virtual TextureInfo GetTextureInfo() const override { return TextureInfo(CompositableType::IMAGE); diff --git a/gfx/layers/client/ClientCanvasLayer.cpp b/gfx/layers/client/ClientCanvasLayer.cpp index fadfd5d230b1..f114c9cf60d4 100644 --- a/gfx/layers/client/ClientCanvasLayer.cpp +++ b/gfx/layers/client/ClientCanvasLayer.cpp @@ -70,49 +70,41 @@ ClientCanvasLayer::Initialize(const Data& aData) } MOZ_ASSERT(caps.alpha == aData.mHasAlpha); + auto forwarder = ClientManager()->AsShadowForwarder(); + + mFlags = TextureFlags::ORIGIN_BOTTOM_LEFT; + if (!aData.mIsGLAlphaPremult) { + mFlags |= TextureFlags::NON_PREMULTIPLIED; + } + UniquePtr factory; if (!gfxPrefs::WebGLForceLayersReadback()) { - switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) { + switch (forwarder->GetCompositorBackendType()) { case mozilla::layers::LayersBackend::LAYERS_OPENGL: { +#if defined(XP_MACOSX) + factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags); +#elif defined(MOZ_WIDGET_GONK) + factory = MakeUnique(mGLContext, caps, forwarder, mFlags); +#else if (mGLContext->GetContextType() == GLContextType::EGL) { -#ifdef MOZ_WIDGET_GONK - TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT | - TextureFlags::ORIGIN_BOTTOM_LEFT; - if (!aData.mIsGLAlphaPremult) { - flags |= TextureFlags::NON_PREMULTIPLIED; - } - factory = MakeUnique(mGLContext, - caps, - flags, - ClientManager()->AsShadowForwarder()); -#else - bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); + bool isCrossProcess = (XRE_GetProcessType() != GeckoProcessType_Default); if (!isCrossProcess) { - // [Basic/OGL Layers, OMTC] WebGL layer init. - factory = SurfaceFactory_EGLImage::Create(mGLContext, caps); - } else { - // we could do readback here maybe - NS_NOTREACHED("isCrossProcess but not on native B2G!"); + factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder, + mFlags); } -#endif - } else { - // [Basic Layers, OMTC] WebGL layer init. - // Well, this *should* work... -#ifdef XP_MACOSX - factory = SurfaceFactory_IOSurface::Create(mGLContext, caps); -#else - GLContext* nullConsGL = nullptr; // Bug 1050044. - factory = MakeUnique(mGLContext, nullConsGL, caps); -#endif } +#endif break; } case mozilla::layers::LayersBackend::LAYERS_D3D10: case mozilla::layers::LayersBackend::LAYERS_D3D11: { #ifdef XP_WIN - if (mGLContext->IsANGLE() && DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) { - factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps); + if (mGLContext->IsANGLE() && + DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) + { + factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps, forwarder, + mFlags); } #endif break; @@ -128,7 +120,7 @@ ClientCanvasLayer::Initialize(const Data& aData) mFactory = Move(factory); if (!mFactory) { // Absolutely must have a factory here, so create a basic one - mFactory = MakeUnique(mGLContext, caps); + mFactory = MakeUnique(mGLContext, caps, mFlags); } } else { if (factory) diff --git a/gfx/layers/client/ClientCanvasLayer.h b/gfx/layers/client/ClientCanvasLayer.h index 0001f7e1d6fd..072b1c0b14b3 100644 --- a/gfx/layers/client/ClientCanvasLayer.h +++ b/gfx/layers/client/ClientCanvasLayer.h @@ -6,7 +6,7 @@ #ifndef GFX_CLIENTCANVASLAYER_H #define GFX_CLIENTCANVASLAYER_H -#include "mozilla/layers/CanvasClient.h" // for CanvasClient, etc +#include "CanvasClient.h" // for CanvasClient, etc #include "ClientLayerManager.h" // for ClientLayerManager, etc #include "CopyableCanvasLayer.h" // for CopyableCanvasLayer #include "Layers.h" // for CanvasLayer, etc @@ -21,7 +21,6 @@ namespace mozilla { namespace gl { -class SharedSurface; class SurfaceFactory; } @@ -81,6 +80,9 @@ public: { return mCanvasClient; } + + const TextureFlags& Flags() const { return mFlags; } + protected: ClientLayerManager* ClientManager() { @@ -93,6 +95,8 @@ protected: UniquePtr mFactory; + TextureFlags mFlags; + friend class DeprecatedCanvasClient2D; friend class CanvasClient2D; friend class CanvasClientSharedSurface; diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index de47f99ebeac..1bb4b666bbcd 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -20,8 +20,6 @@ #include "mozilla/gfx/Logging.h" // for gfxDebug #include "mozilla/layers/TextureClientOGL.h" #include "mozilla/layers/PTextureChild.h" -#include "SharedSurface.h" -#include "GLContext.h" #include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning #include "nsPrintfCString.h" // for nsPrintfCString #include "LayersLogging.h" // for AppendToString @@ -113,7 +111,7 @@ public: bool RecvCompositorRecycle() override { - RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get()); + RECYCLE_LOG("[CLIENT] Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get()); mWaitForRecycle = nullptr; return true; } @@ -121,7 +119,7 @@ public: void WaitForCompositorRecycle() { mWaitForRecycle = mTextureClient; - RECYCLE_LOG("Wait for recycle %p\n", mWaitForRecycle.get()); + RECYCLE_LOG("[CLIENT] Wait for recycle %p\n", mWaitForRecycle.get()); SendClientRecycle(); } @@ -584,6 +582,10 @@ TextureClient::Finalize() // Null it before RemoveTexture calls to avoid invalid actor->mTextureClient // when calling TextureChild::ActorDestroy() actor->mTextureClient = nullptr; + + // `actor->mWaitForRecycle` may not be null, as we may be being called from setting + // this RefPtr to null! Clearing it here will double-Release() it. + // this will call ForceRemove in the right thread, using a sync proxy if needed if (actor->GetForwarder()) { actor->GetForwarder()->RemoveTexture(this); @@ -913,32 +915,6 @@ BufferTextureClient::GetLockedData() const return serializer.GetData(); } -//////////////////////////////////////////////////////////////////////// -// SharedSurfaceTextureClient - -SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, - TextureFlags aFlags, - gl::SharedSurface* surf) - : TextureClient(aAllocator, aFlags) - , mIsLocked(false) - , mSurf(surf) - , mGL(mSurf->mGL) -{ - AddFlags(TextureFlags::DEALLOCATE_CLIENT); -} - -SharedSurfaceTextureClient::~SharedSurfaceTextureClient() -{ - // the data is owned externally. -} - -bool -SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) -{ - aOutDescriptor = SharedSurfaceDescriptor((uintptr_t)mSurf); - return true; -} - TemporaryRef SyncObject::CreateSyncObject(SyncHandle aHandle) { diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index ae6095666824..3852237541c1 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -8,7 +8,6 @@ #include // for size_t #include // for uint32_t, uint8_t, uint64_t -#include "GLContextTypes.h" // for GLContext (ptr only), etc #include "GLTextureImage.h" // for TextureImage #include "ImageTypes.h" // for StereoMode #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc @@ -32,10 +31,6 @@ class gfxImageSurface; namespace mozilla { -namespace gl { -class GLContext; -class SharedSurface; -} // When defined, we track which pool the tile came from and test for // any inconsistencies. This can be defined in release build as well. @@ -474,7 +469,7 @@ public: virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) { mReadbackSink = aReadbackSink; } - + virtual void SyncWithObject(SyncObject* aSyncObject) { } private: @@ -688,66 +683,6 @@ protected: size_t mBufSize; }; -/** - * A TextureClient implementation to share SharedSurfaces. - */ -class SharedSurfaceTextureClient : public TextureClient -{ -public: - SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags, - gl::SharedSurface* surf); - -protected: - ~SharedSurfaceTextureClient(); - -public: - // Boilerplate start - virtual bool IsAllocated() const override { return true; } - - virtual bool Lock(OpenMode) override { - MOZ_ASSERT(!mIsLocked); - mIsLocked = true; - return true; - } - - virtual void Unlock() override { - MOZ_ASSERT(mIsLocked); - mIsLocked = false; - } - - virtual bool IsLocked() const override { return mIsLocked; } - - virtual bool HasInternalBuffer() const override { return false; } - - virtual gfx::SurfaceFormat GetFormat() const override { - return gfx::SurfaceFormat::UNKNOWN; - } - - virtual gfx::IntSize GetSize() const override { return gfx::IntSize(); } - - // This TextureClient should not be used in a context where we use CreateSimilar - // (ex. component alpha) because the underlying texture data is always created by - // an external producer. - virtual TemporaryRef - CreateSimilar(TextureFlags, TextureAllocationFlags) const override { - return nullptr; - } - - virtual bool AllocateForSurface(gfx::IntSize, - TextureAllocationFlags) override { - MOZ_CRASH("Should never hit this."); - return false; - } - // Boilerplate end - - virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override; - -protected: - bool mIsLocked; - gl::SharedSurface* const mSurf; - RefPtr mGL; // Just for reference holding. -}; - struct TextureClientAutoUnlock { TextureClient* mTexture; diff --git a/gfx/layers/client/TextureClientSharedSurface.cpp b/gfx/layers/client/TextureClientSharedSurface.cpp new file mode 100644 index 000000000000..80f8d61f71b9 --- /dev/null +++ b/gfx/layers/client/TextureClientSharedSurface.cpp @@ -0,0 +1,68 @@ +/* -*- 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 "TextureClientSharedSurface.h" + +#include "GLContext.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Logging.h" // for gfxDebug +#include "mozilla/layers/ISurfaceAllocator.h" +#include "mozilla/unused.h" +#include "nsThreadUtils.h" +#include "SharedSurface.h" + +namespace mozilla { +namespace layers { + +SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, + TextureFlags aFlags, + UniquePtr surf, + gl::SurfaceFactory* factory) + : TextureClient(aAllocator, aFlags | TextureFlags::RECYCLE) + , mSurf(Move(surf)) + , mFactory(factory) + , mRecyclingRef(this) +{ + // AtomicRefCountedWithFinalize is a little strange. It attempts to recycle when + // Release drops the ref count to 1. The idea is that the recycler holds a strong ref. + // Here, we want to keep it simple, and always have a recycle callback, but only recycle + // if the WeakPtr mFactory is still non-null. Therefore, we keep mRecyclingRef as ref to + // ourself! Call StopRecycling() to end the cycle. + mRecyclingRef->SetRecycleCallback(&gl::SurfaceFactory::RecycleCallback, nullptr); +} + +SharedSurfaceTextureClient::~SharedSurfaceTextureClient() +{ + // Free the ShSurf implicitly. + + // Tricky issue! We will often call the dtor via Release via StopRecycling, where we + // null out mRecyclingRef. Right now, we call Release before actually clearing the + // value. This means the dtor will see that mRecyclingRef is non-null, and try to + // Release it, even though we're mid-Release! We need to clear mRecyclingRef so the dtor + // doesn't try to Release it. + mozilla::unused << mRecyclingRef.forget().take(); +} + +gfx::IntSize +SharedSurfaceTextureClient::GetSize() const +{ + return mSurf->mSize; +} + +bool +SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) +{ + return mSurf->ToSurfaceDescriptor(&aOutDescriptor); +} + +void +SharedSurfaceTextureClient::StopRecycling() +{ + mRecyclingRef->ClearRecycleCallback(); + mRecyclingRef = nullptr; +} + +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/client/TextureClientSharedSurface.h b/gfx/layers/client/TextureClientSharedSurface.h new file mode 100644 index 000000000000..e8dcbecfbfbc --- /dev/null +++ b/gfx/layers/client/TextureClientSharedSurface.h @@ -0,0 +1,79 @@ +/* -*- 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_TEXTURECLIENT_SHAREDSURFACE_H +#define MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H + +#include // for size_t +#include // for uint32_t, uint8_t, uint64_t +#include "GLContextTypes.h" // for GLContext (ptr only), etc +#include "TextureClient.h" +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc +#include "mozilla/RefPtr.h" // for RefPtr, RefCounted +#include "mozilla/gfx/Point.h" // for IntSize +#include "mozilla/gfx/Types.h" // for SurfaceFormat +#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc +#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor + +namespace mozilla { +namespace gl { +class GLContext; +class SharedSurface; +class SurfaceFactory; +} + +namespace layers { + +class SharedSurfaceTextureClient : public TextureClient +{ +protected: + const UniquePtr mSurf; + const WeakPtr mFactory; + RefPtr mRecyclingRef; + + friend class gl::SurfaceFactory; + + SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags, + UniquePtr surf, + gl::SurfaceFactory* factory); + + ~SharedSurfaceTextureClient(); + +public: + virtual bool IsAllocated() const override { return true; } + virtual bool Lock(OpenMode) override { return false; } + virtual bool IsLocked() const override { return false; } + virtual bool HasInternalBuffer() const override { return false; } + + virtual gfx::SurfaceFormat GetFormat() const override { + return gfx::SurfaceFormat::UNKNOWN; + } + + virtual TemporaryRef + CreateSimilar(TextureFlags, TextureAllocationFlags) const override { + return nullptr; + } + + virtual bool AllocateForSurface(gfx::IntSize, + TextureAllocationFlags) override { + MOZ_CRASH("Should never hit this."); + return false; + } + + virtual gfx::IntSize GetSize() const override; + + virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override; + + gl::SharedSurface* Surf() const { + return mSurf.get(); + } + + void StopRecycling(); +}; + +} // namespace layers +} // namespace mozilla + +#endif // MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H diff --git a/gfx/layers/composite/FPSCounter.cpp b/gfx/layers/composite/FPSCounter.cpp index f03eb778b5a3..9c34c5b20394 100644 --- a/gfx/layers/composite/FPSCounter.cpp +++ b/gfx/layers/composite/FPSCounter.cpp @@ -25,7 +25,6 @@ namespace mozilla { namespace layers { using namespace mozilla::gfx; -using namespace mozilla::gl; FPSCounter::FPSCounter(const char* aName) : mWriteIndex(0) @@ -395,7 +394,7 @@ static void DrawDigits(unsigned int aValue, Rect drawRect = Rect(aOffsetX + n * FontWidth, aOffsetY, FontWidth, FontHeight); Rect clipRect = Rect(0, 0, 300, 100); aCompositor->DrawQuad(drawRect, clipRect, - aEffectChain, opacity, transform); + aEffectChain, opacity, transform); } } diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index c1e9e9409a7f..f06e0b9f57bc 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -34,8 +34,7 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo) {} ImageHost::~ImageHost() -{ -} +{} void ImageHost::UseTextureHost(TextureHost* aTexture) diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index d685f38f8b87..57de256fc8a7 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -22,9 +22,6 @@ #include "mozilla/layers/PTextureParent.h" #include "mozilla/unused.h" #include -#include "SharedSurface.h" -#include "SharedSurfaceEGL.h" -#include "SharedSurfaceGL.h" #include "../opengl/CompositorOGL.h" #include "gfxUtils.h" @@ -35,7 +32,6 @@ #ifdef MOZ_WIDGET_GONK #include "../opengl/GrallocTextureClient.h" #include "../opengl/GrallocTextureHost.h" -#include "SharedSurfaceGralloc.h" #endif #ifdef MOZ_X11 @@ -43,12 +39,10 @@ #endif #ifdef XP_MACOSX -#include "SharedSurfaceIO.h" #include "../opengl/MacIOSurfaceTextureHostOGL.h" #endif #ifdef XP_WIN -#include "SharedSurfaceANGLE.h" #include "mozilla/layers/TextureDIB.h" #endif @@ -96,6 +90,8 @@ public: RefPtr mTextureHost; }; +//////////////////////////////////////////////////////////////////////////////// + // static PTextureParent* TextureHost::CreateIPDLActor(CompositableParentManager* aManager, @@ -187,9 +183,6 @@ TextureHost::Create(const SurfaceDescriptor& aDesc, case SurfaceDescriptor::TSurfaceTextureDescriptor: return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); - case SurfaceDescriptor::TSharedSurfaceDescriptor: - return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor()); - case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) { return CreateTextureHostOGL(aDesc, aDeallocator, aFlags); @@ -835,153 +828,6 @@ TextureParent::RecvRecycleTexture(const TextureFlags& aTextureFlags) return true; } -//////////////////////////////////////////////////////////////////////////////// - -static RefPtr -SharedSurfaceToTexSource(gl::SharedSurface* abstractSurf, Compositor* compositor) -{ - MOZ_ASSERT(abstractSurf); - MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Basic); - MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Gralloc); - - if (!compositor) { - return nullptr; - } - - gfx::SurfaceFormat format = abstractSurf->mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 - : gfx::SurfaceFormat::R8G8B8X8; - - RefPtr texSource; - switch (abstractSurf->mType) { -#ifdef XP_WIN - case gl::SharedSurfaceType::EGLSurfaceANGLE: { - auto surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf); - - MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_D3D11); - CompositorD3D11* compositorD3D11 = static_cast(compositor); - RefPtr tex = surf->GetConsumerTexture(); - - if (!tex) { - NS_WARNING("Failed to open shared resource."); - break; - } - texSource = new DataTextureSourceD3D11(format, compositorD3D11, tex); - break; - } -#endif - case gl::SharedSurfaceType::GLTextureShare: { - auto surf = gl::SharedSurface_GLTexture::Cast(abstractSurf); - - MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); - CompositorOGL* compositorOGL = static_cast(compositor); - gl::GLContext* gl = compositorOGL->gl(); - - GLenum target = surf->ConsTextureTarget(); - GLuint tex = surf->ConsTexture(gl); - texSource = new GLTextureSource(compositorOGL, tex, target, - surf->mSize, format, - true/*externally owned*/); - break; - } - case gl::SharedSurfaceType::EGLImageShare: { - auto surf = gl::SharedSurface_EGLImage::Cast(abstractSurf); - - MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); - CompositorOGL* compositorOGL = static_cast(compositor); - gl::GLContext* gl = compositorOGL->gl(); - MOZ_ASSERT(gl->IsCurrent()); - - GLenum target = 0; - GLuint tex = 0; - surf->AcquireConsumerTexture(gl, &tex, &target); - - texSource = new GLTextureSource(compositorOGL, tex, target, - surf->mSize, format, - true/*externally owned*/); - break; - } -#ifdef XP_MACOSX - case gl::SharedSurfaceType::IOSurface: { - auto surf = gl::SharedSurface_IOSurface::Cast(abstractSurf); - MacIOSurface* ioSurf = surf->GetIOSurface(); - - MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL); - CompositorOGL* compositorOGL = static_cast(compositor); - - texSource = new MacIOSurfaceTextureSourceOGL(compositorOGL, ioSurf); - break; - } -#endif - default: - break; - } - - MOZ_ASSERT(texSource.get(), "TextureSource creation failed."); - return texSource; -} - -//////////////////////////////////////////////////////////////////////////////// -// SharedSurfaceTextureHost - -SharedSurfaceTextureHost::SharedSurfaceTextureHost(TextureFlags aFlags, - const SharedSurfaceDescriptor& aDesc) - : TextureHost(aFlags) - , mIsLocked(false) - , mSurf((gl::SharedSurface*)aDesc.surf()) - , mCompositor(nullptr) -{ - MOZ_ASSERT(mSurf); -} - -gfx::SurfaceFormat -SharedSurfaceTextureHost::GetFormat() const -{ - MOZ_ASSERT(mTexSource); - return mTexSource->GetFormat(); -} - -gfx::IntSize -SharedSurfaceTextureHost::GetSize() const -{ - MOZ_ASSERT(mTexSource); - return mTexSource->GetSize(); -} - -void -SharedSurfaceTextureHost::EnsureTexSource() -{ - MOZ_ASSERT(mIsLocked); - - if (mTexSource) - return; - - mTexSource = SharedSurfaceToTexSource(mSurf, mCompositor); - MOZ_ASSERT(mTexSource); -} - -bool -SharedSurfaceTextureHost::Lock() -{ - MOZ_ASSERT(!mIsLocked); - - mSurf->ConsumerAcquire(); - - mIsLocked = true; - - EnsureTexSource(); - - return true; -} - -void -SharedSurfaceTextureHost::Unlock() -{ - MOZ_ASSERT(mIsLocked); - mSurf->ConsumerRelease(); - mIsLocked = false; -} - - //////////////////////////////////////////////////////////////////////////////// } // namespace diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 68e8093385d5..cc3d8059766f 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -31,9 +31,6 @@ #include "mozilla/gfx/Rect.h" namespace mozilla { -namespace gl { -class SharedSurface; -} namespace ipc { class Shmem; } @@ -43,7 +40,6 @@ namespace layers { class Compositor; class CompositableParentManager; class SurfaceDescriptor; -class SharedSurfaceDescriptor; class ISurfaceAllocator; class TextureHostOGL; class TextureSourceOGL; @@ -662,64 +658,6 @@ protected: uint8_t* mBuffer; }; -/** - * A TextureHost for SharedSurfaces - */ -class SharedSurfaceTextureHost : public TextureHost -{ -public: - SharedSurfaceTextureHost(TextureFlags aFlags, - const SharedSurfaceDescriptor& aDesc); - - virtual ~SharedSurfaceTextureHost() { - MOZ_ASSERT(!mIsLocked); - } - - virtual void DeallocateDeviceData() override {}; - - virtual TemporaryRef GetAsSurface() override { - return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING) - } - - virtual void SetCompositor(Compositor* aCompositor) override { - MOZ_ASSERT(!mIsLocked); - - if (aCompositor == mCompositor) - return; - - mTexSource = nullptr; - mCompositor = aCompositor; - } - -public: - - virtual bool Lock() override; - virtual void Unlock() override; - - virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override { - MOZ_ASSERT(mIsLocked); - MOZ_ASSERT(mTexSource); - aTexture = mTexSource; - return !!aTexture; - } - - virtual gfx::SurfaceFormat GetFormat() const override; - - virtual gfx::IntSize GetSize() const override; - -#ifdef MOZ_LAYERS_HAVE_LOG - virtual const char* Name() override { return "SharedSurfaceTextureHost"; } -#endif - -protected: - void EnsureTexSource(); - - bool mIsLocked; - gl::SharedSurface* const mSurf; - RefPtr mCompositor; - RefPtr mTexSource; -}; - class MOZ_STACK_CLASS AutoLockTextureHost { public: diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index fa048ea55e05..a1b29e3b891d 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -351,7 +351,7 @@ void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient) static void ReleaseTextureClientNow(TextureClient* aClient) { MOZ_ASSERT(InImageBridgeChildThread()); - aClient->Release(); + RELEASE_MANUALLY(aClient); } // static @@ -368,7 +368,7 @@ void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient) // has already shut down, along with the TextureChild, which means no // message will be sent and it is safe to run this code from any thread. MOZ_ASSERT(aClient->GetIPDLActor() == nullptr); - aClient->Release(); + RELEASE_MANUALLY(aClient); return; } diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index 46354fb74535..0218501a2f76 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -189,7 +189,7 @@ bool ImageBridgeParent::RecvWillStop() static void ReleaseImageBridgeParent(ImageBridgeParent* aImageBridgeParent) { - aImageBridgeParent->Release(); + RELEASE_MANUALLY(aImageBridgeParent); } bool ImageBridgeParent::RecvStop() @@ -201,7 +201,7 @@ bool ImageBridgeParent::RecvStop() // the handling of this sync message can't race with the destruction of // the ImageBridgeParent, which would trigger the dreaded "mismatched CxxStackFrames" // assertion of MessageChannel. - AddRef(); + ADDREF_MANUALLY(this); MessageLoop::current()->PostTask( FROM_HERE, NewRunnableFunction(&ReleaseImageBridgeParent, this)); diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index d63a3117d6b9..baf5ca79f2c3 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -160,12 +160,12 @@ protected: void AddIPDLReference() { MOZ_ASSERT(mIPCOpen == false); mIPCOpen = true; - AddRef(); + ADDREF_MANUALLY(this); } void ReleaseIPDLReference() { MOZ_ASSERT(mIPCOpen == true); mIPCOpen = false; - Release(); + RELEASE_MANUALLY(this); } friend class CompositorParent; friend class CrossProcessCompositorParent; diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 0ef312d736a6..6aa492aa0e7b 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -59,7 +59,7 @@ struct SurfaceDescriptorDXGIYCbCr { }; struct SurfaceDescriptorMacIOSurface { - uint32_t surface; + uint32_t surfaceId; double scaleFactor; bool isOpaque; }; @@ -86,10 +86,6 @@ struct NewSurfaceDescriptorGralloc { bool isOpaque; }; -struct SharedSurfaceDescriptor { - uintptr_t surf; -}; - /** * Used for shmem-backed YCbCr and (flavors of) RGBA textures */ @@ -101,7 +97,7 @@ struct SurfaceDescriptorShmem { /** * Used for "raw memory"-backed YCbCr and (flavors of) RGBA textures */ - struct SurfaceDescriptorMemory { +struct SurfaceDescriptorMemory { uintptr_t data; SurfaceFormat format; }; @@ -118,7 +114,6 @@ union SurfaceDescriptor { EGLImageDescriptor; SurfaceDescriptorMacIOSurface; NewSurfaceDescriptorGralloc; - SharedSurfaceDescriptor; null_t; }; diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp index 69acfc78b6ee..b0b76b840937 100644 --- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp @@ -37,7 +37,10 @@ SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() { if (mCompositable->GetAsyncID() != 0 && !InImageBridgeChildThread()) { - ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take()); + ADDREF_MANUALLY(mTextureClient); + ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient); + mTextureClient = nullptr; + ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take()); } } diff --git a/gfx/layers/ipc/SharedRGBImage.cpp b/gfx/layers/ipc/SharedRGBImage.cpp index d601748c3537..385233fcc47f 100644 --- a/gfx/layers/ipc/SharedRGBImage.cpp +++ b/gfx/layers/ipc/SharedRGBImage.cpp @@ -69,7 +69,10 @@ SharedRGBImage::~SharedRGBImage() if (mCompositable->GetAsyncID() != 0 && !InImageBridgeChildThread()) { - ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take()); + ADDREF_MANUALLY(mTextureClient); + ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient); + mTextureClient = nullptr; + ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take()); } } diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 22c38f4ba399..d7a8e4539b46 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -118,6 +118,7 @@ EXPORTS.mozilla.layers += [ 'client/TextureClient.h', 'client/TextureClientPool.h', 'client/TextureClientRecycleAllocator.h', + 'client/TextureClientSharedSurface.h', 'client/TiledContentClient.h', 'composite/AsyncCompositionManager.h', 'composite/CanvasLayerComposite.h', @@ -269,6 +270,7 @@ UNIFIED_SOURCES += [ 'client/TextureClient.cpp', 'client/TextureClientPool.cpp', 'client/TextureClientRecycleAllocator.cpp', + 'client/TextureClientSharedSurface.cpp', 'client/TiledContentClient.cpp', 'composite/AsyncCompositionManager.cpp', 'composite/CanvasLayerComposite.cpp', diff --git a/gfx/layers/opengl/GrallocTextureClient.h b/gfx/layers/opengl/GrallocTextureClient.h index a352d51d48f1..a67450628a44 100644 --- a/gfx/layers/opengl/GrallocTextureClient.h +++ b/gfx/layers/opengl/GrallocTextureClient.h @@ -19,6 +19,10 @@ class MediaBuffer; }; namespace mozilla { +namespace gl { +class SharedSurface; +} + namespace layers { /** diff --git a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp index ec993b44a2fc..6bf3d8ed8364 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp +++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp @@ -14,7 +14,7 @@ MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags, const SurfaceDescriptorMacIOSurface& aDescriptor) : TextureHost(aFlags) { - mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(), + mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(), aDescriptor.scaleFactor(), !aDescriptor.isOpaque()); } diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index ea426107214b..737772dbebc7 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -15,10 +15,6 @@ #include "mozilla/gfx/2D.h" // for DataSourceSurface #include "mozilla/gfx/BaseSize.h" // for BaseSize #include "mozilla/gfx/Logging.h" // for gfxCriticalError -#ifdef MOZ_WIDGET_GONK -# include "GrallocImages.h" // for GrallocImage -# include "EGLImageHelpers.h" -#endif #include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/YCbCrImageDataSerializer.h" #include "mozilla/layers/GrallocTextureHost.h" @@ -26,11 +22,17 @@ #include "AndroidSurfaceTexture.h" #include "GfxTexturesReporter.h" // for GfxTexturesReporter #include "GLBlitTextureImageHelper.h" +#include "GeckoProfiler.h" + +#ifdef MOZ_WIDGET_GONK +# include "GrallocImages.h" // for GrallocImage +# include "EGLImageHelpers.h" +#endif + #ifdef XP_MACOSX -#include "SharedSurfaceIO.h" #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h" #endif -#include "GeckoProfiler.h" + using namespace mozilla::gl; using namespace mozilla::gfx; @@ -589,6 +591,8 @@ EGLImageTextureSource::EGLImageTextureSource(CompositorOGL* aCompositor, , mWrapMode(aWrapMode) , mSize(aSize) { + MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D || + mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL); } void @@ -602,13 +606,12 @@ EGLImageTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl()), "EGLImage not supported or disabled in runtime"); - GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit); + GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit); gl()->fActiveTexture(aTextureUnit); gl()->fBindTexture(mTextureTarget, tex); - MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D); - gl()->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage); + gl()->fEGLImageTargetTexture2D(mTextureTarget, mImage); ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget); } @@ -650,12 +653,10 @@ EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags, , mSync(aSync) , mSize(aSize) , mCompositor(nullptr) -{ -} +{} EGLImageTextureHost::~EGLImageTextureHost() -{ -} +{} gl::GLContext* EGLImageTextureHost::gl() const @@ -671,13 +672,16 @@ EGLImageTextureHost::Lock() } EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER); + if (status != LOCAL_EGL_CONDITION_SATISFIED) { + MOZ_ASSERT(status != 0, + "ClientWaitSync generated an error. Has mSync already been destroyed?"); return false; } if (!mTextureSource) { gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8; - GLenum target = LOCAL_GL_TEXTURE_2D; + GLenum target = LOCAL_GL_TEXTURE_EXTERNAL; GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE; mTextureSource = new EGLImageTextureSource(mCompositor, mImage,