michael@0: /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef SHARED_SURFACE_GL_H_ michael@0: #define SHARED_SURFACE_GL_H_ michael@0: michael@0: #include "ScopedGLHelpers.h" michael@0: #include "SharedSurface.h" michael@0: #include "SurfaceFactory.h" michael@0: #include "SurfaceTypes.h" michael@0: #include "GLContextTypes.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "gfxTypes.h" michael@0: #include "mozilla/Mutex.h" michael@0: michael@0: #include michael@0: michael@0: // Forwards: michael@0: namespace mozilla { michael@0: namespace gl { michael@0: class GLContext; michael@0: } michael@0: namespace gfx { michael@0: class DataSourceSurface; michael@0: } michael@0: } michael@0: michael@0: namespace mozilla { michael@0: namespace gl { michael@0: michael@0: class SurfaceFactory_GL; michael@0: michael@0: class SharedSurface_GL michael@0: : public gfx::SharedSurface michael@0: { michael@0: protected: michael@0: typedef class gfx::SharedSurface SharedSurface; michael@0: typedef gfx::SharedSurfaceType SharedSurfaceType; michael@0: typedef gfx::APITypeT APITypeT; michael@0: typedef gfx::AttachmentType AttachmentType; michael@0: michael@0: GLContext* const mGL; michael@0: michael@0: SharedSurface_GL(SharedSurfaceType type, michael@0: AttachmentType attachType, michael@0: GLContext* gl, michael@0: const gfx::IntSize& size, michael@0: bool hasAlpha) michael@0: : SharedSurface(type, APITypeT::OpenGL, attachType, size, hasAlpha) michael@0: , mGL(gl) michael@0: {} michael@0: michael@0: public: michael@0: static void ProdCopy(SharedSurface_GL* src, SharedSurface_GL* dest, michael@0: SurfaceFactory_GL* factory); michael@0: michael@0: static SharedSurface_GL* Cast(SharedSurface* surf) { michael@0: MOZ_ASSERT(surf->APIType() == APITypeT::OpenGL); michael@0: michael@0: return (SharedSurface_GL*)surf; michael@0: } michael@0: michael@0: // For use when AttachType is correct. michael@0: virtual GLuint ProdTexture() { michael@0: MOZ_ASSERT(AttachType() == AttachmentType::GLTexture); michael@0: MOZ_CRASH("Did you forget to override this function?"); michael@0: } michael@0: michael@0: virtual GLenum ProdTextureTarget() const { michael@0: return LOCAL_GL_TEXTURE_2D; michael@0: } michael@0: michael@0: virtual GLuint ProdRenderbuffer() { michael@0: MOZ_ASSERT(AttachType() == AttachmentType::GLRenderbuffer); michael@0: MOZ_CRASH("Did you forget to override this function?"); michael@0: } michael@0: michael@0: virtual bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, michael@0: GLenum format, GLenum type, GLvoid *pixels) { michael@0: return false; michael@0: } michael@0: michael@0: virtual void LockProd() MOZ_OVERRIDE; michael@0: virtual void UnlockProd() MOZ_OVERRIDE; michael@0: michael@0: GLContext* GL() const { michael@0: return mGL; michael@0: } michael@0: }; michael@0: michael@0: class SurfaceFactory_GL michael@0: : public gfx::SurfaceFactory michael@0: { michael@0: protected: michael@0: typedef struct gfx::SurfaceCaps SurfaceCaps; michael@0: typedef class gfx::SurfaceFactory SurfaceFactory; michael@0: typedef class gfx::SharedSurface SharedSurface; michael@0: typedef gfx::SharedSurfaceType SharedSurfaceType; michael@0: michael@0: GLContext* const mGL; michael@0: const GLFormats mFormats; michael@0: michael@0: SurfaceCaps mDrawCaps; michael@0: SurfaceCaps mReadCaps; michael@0: michael@0: // This uses ChooseBufferBits to pick drawBits/readBits. michael@0: SurfaceFactory_GL(GLContext* gl, michael@0: SharedSurfaceType type, michael@0: const SurfaceCaps& caps); michael@0: michael@0: virtual void ChooseBufferBits(const SurfaceCaps& caps, michael@0: SurfaceCaps& drawCaps, michael@0: SurfaceCaps& readCaps) const; michael@0: michael@0: public: michael@0: GLContext* GL() const { michael@0: return mGL; michael@0: } michael@0: michael@0: const GLFormats& Formats() const { michael@0: return mFormats; michael@0: } michael@0: michael@0: const SurfaceCaps& DrawCaps() const { michael@0: return mDrawCaps; michael@0: } michael@0: michael@0: const SurfaceCaps& ReadCaps() const { michael@0: return mReadCaps; michael@0: } michael@0: }; michael@0: michael@0: // For readback and bootstrapping: michael@0: class SharedSurface_Basic michael@0: : public SharedSurface_GL michael@0: { michael@0: public: michael@0: static SharedSurface_Basic* Create(GLContext* gl, michael@0: const GLFormats& formats, michael@0: const gfx::IntSize& size, michael@0: bool hasAlpha); michael@0: michael@0: static SharedSurface_Basic* Cast(SharedSurface* surf) { michael@0: MOZ_ASSERT(surf->Type() == SharedSurfaceType::Basic); michael@0: michael@0: return (SharedSurface_Basic*)surf; michael@0: } michael@0: michael@0: protected: michael@0: const GLuint mTex; michael@0: GLuint mFB; michael@0: michael@0: RefPtr mData; michael@0: michael@0: SharedSurface_Basic(GLContext* gl, michael@0: const gfx::IntSize& size, michael@0: bool hasAlpha, michael@0: gfx::SurfaceFormat format, michael@0: GLuint tex); michael@0: michael@0: public: michael@0: virtual ~SharedSurface_Basic(); michael@0: michael@0: virtual void LockProdImpl() MOZ_OVERRIDE {} michael@0: virtual void UnlockProdImpl() MOZ_OVERRIDE {} michael@0: michael@0: michael@0: virtual void Fence() MOZ_OVERRIDE; michael@0: michael@0: virtual bool WaitSync() MOZ_OVERRIDE { michael@0: // Since we already store the data in Fence, we're always done already. michael@0: return true; michael@0: } michael@0: michael@0: virtual GLuint ProdTexture() MOZ_OVERRIDE { michael@0: return mTex; michael@0: } michael@0: michael@0: // Implementation-specific functions below: michael@0: gfx::DataSourceSurface* GetData() { michael@0: return mData; michael@0: } michael@0: }; michael@0: michael@0: class SurfaceFactory_Basic michael@0: : public SurfaceFactory_GL michael@0: { michael@0: public: michael@0: SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps) michael@0: : SurfaceFactory_GL(gl, SharedSurfaceType::Basic, caps) michael@0: {} michael@0: michael@0: virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { michael@0: bool hasAlpha = mReadCaps.alpha; michael@0: return SharedSurface_Basic::Create(mGL, mFormats, size, hasAlpha); michael@0: } michael@0: }; michael@0: michael@0: michael@0: // Using shared GL textures: michael@0: class SharedSurface_GLTexture michael@0: : public SharedSurface_GL michael@0: { michael@0: public: michael@0: static SharedSurface_GLTexture* Create(GLContext* prodGL, michael@0: GLContext* consGL, michael@0: const GLFormats& formats, michael@0: const gfx::IntSize& size, michael@0: bool hasAlpha, michael@0: GLuint texture = 0); michael@0: michael@0: static SharedSurface_GLTexture* Cast(SharedSurface* surf) { michael@0: MOZ_ASSERT(surf->Type() == SharedSurfaceType::GLTextureShare); michael@0: michael@0: return (SharedSurface_GLTexture*)surf; michael@0: } michael@0: michael@0: protected: michael@0: GLContext* mConsGL; michael@0: const GLuint mTex; michael@0: const bool mOwnsTex; michael@0: GLsync mSync; michael@0: mutable Mutex mMutex; michael@0: michael@0: SharedSurface_GLTexture(GLContext* prodGL, michael@0: GLContext* consGL, michael@0: const gfx::IntSize& size, michael@0: bool hasAlpha, michael@0: GLuint tex, michael@0: bool ownsTex) michael@0: : SharedSurface_GL(SharedSurfaceType::GLTextureShare, michael@0: AttachmentType::GLTexture, michael@0: prodGL, michael@0: size, michael@0: hasAlpha) michael@0: , mConsGL(consGL) michael@0: , mTex(tex) michael@0: , mOwnsTex(ownsTex) michael@0: , mSync(0) michael@0: , mMutex("SharedSurface_GLTexture mutex") michael@0: { michael@0: } michael@0: michael@0: public: michael@0: virtual ~SharedSurface_GLTexture(); michael@0: michael@0: virtual void LockProdImpl() MOZ_OVERRIDE {} michael@0: virtual void UnlockProdImpl() MOZ_OVERRIDE {} michael@0: michael@0: michael@0: virtual void Fence() MOZ_OVERRIDE; michael@0: virtual bool WaitSync() MOZ_OVERRIDE; michael@0: michael@0: michael@0: virtual GLuint ProdTexture() MOZ_OVERRIDE { michael@0: return mTex; michael@0: } michael@0: michael@0: // Custom: michael@0: michael@0: GLuint ConsTexture(GLContext* consGL); michael@0: michael@0: GLenum ConsTextureTarget() const { michael@0: return ProdTextureTarget(); michael@0: } michael@0: }; michael@0: michael@0: class SurfaceFactory_GLTexture michael@0: : public SurfaceFactory_GL michael@0: { michael@0: protected: michael@0: GLContext* const mConsGL; michael@0: michael@0: public: michael@0: // If we don't know `consGL` at construction time, use `nullptr`, and call michael@0: // `SetConsumerGL()` on each `SharedSurface_GLTexture` before calling its michael@0: // `WaitSync()`. michael@0: SurfaceFactory_GLTexture(GLContext* prodGL, michael@0: GLContext* consGL, michael@0: const SurfaceCaps& caps) michael@0: : SurfaceFactory_GL(prodGL, SharedSurfaceType::GLTextureShare, caps) michael@0: , mConsGL(consGL) michael@0: { michael@0: MOZ_ASSERT(consGL != prodGL); michael@0: } michael@0: michael@0: virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { michael@0: bool hasAlpha = mReadCaps.alpha; michael@0: return SharedSurface_GLTexture::Create(mGL, mConsGL, mFormats, size, hasAlpha); michael@0: } michael@0: }; michael@0: michael@0: } /* namespace gfx */ michael@0: } /* namespace mozilla */ michael@0: michael@0: #endif /* SHARED_SURFACE_GL_H_ */