1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOZILLA_GFX_COMPOSITINGRENDERTARGETOGL_H 8 #define MOZILLA_GFX_COMPOSITINGRENDERTARGETOGL_H 9 10 #include "GLContextTypes.h" // for GLContext 11 #include "GLDefs.h" // for GLenum, LOCAL_GL_FRAMEBUFFER, etc 12 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 13 #include "mozilla/Attributes.h" // for override 14 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed 15 #include "mozilla/gfx/Point.h" // for IntSize, IntSizeTyped 16 #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc 17 #include "mozilla/layers/Compositor.h" // for SurfaceInitMode, etc 18 #include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget 19 #include "mozilla/layers/CompositorOGL.h" // for CompositorOGL 20 #include "mozilla/mozalloc.h" // for operator new 21 #include "nsAString.h" 22 #include "nsCOMPtr.h" // for already_AddRefed 23 #include "nsDebug.h" // for NS_ERROR, NS_WARNING 24 #include "nsString.h" // for nsAutoCString 25 26 namespace mozilla { 27 namespace gl { 28 class BindableTexture; 29 } // namespace gl 30 namespace gfx { 31 class DataSourceSurface; 32 } // namespace gfx 33 34 namespace layers { 35 36 class TextureSource; 37 38 class CompositingRenderTargetOGL : public CompositingRenderTarget { 39 typedef mozilla::gl::GLContext GLContext; 40 41 friend class CompositorOGL; 42 43 enum class GLResourceOwnership : uint8_t { 44 // Framebuffer and texture will be deleted when the RenderTarget is 45 // destroyed. 46 OWNED_BY_RENDER_TARGET, 47 48 // Framebuffer and texture are only used by the RenderTarget, but never 49 // deleted. 50 EXTERNALLY_OWNED 51 }; 52 53 struct InitParams { 54 GLenum mFBOTextureTarget; 55 SurfaceInitMode mInitMode; 56 }; 57 58 public: 59 ~CompositingRenderTargetOGL(); 60 Name()61 const char* Name() const override { return "CompositingRenderTargetOGL"; } 62 63 /** 64 * Create a render target around the default FBO, for rendering straight to 65 * the window. 66 */ CreateForWindow(CompositorOGL * aCompositor,const gfx::IntSize & aSize)67 static already_AddRefed<CompositingRenderTargetOGL> CreateForWindow( 68 CompositorOGL* aCompositor, const gfx::IntSize& aSize) { 69 RefPtr<CompositingRenderTargetOGL> result = new CompositingRenderTargetOGL( 70 aCompositor, gfx::IntRect(gfx::IntPoint(), aSize), gfx::IntPoint(), 71 aSize, GLResourceOwnership::EXTERNALLY_OWNED, 0, 0, Nothing()); 72 return result.forget(); 73 } 74 75 static already_AddRefed<CompositingRenderTargetOGL> CreateForNewFBOAndTakeOwnership(CompositorOGL * aCompositor,GLuint aTexture,GLuint aFBO,const gfx::IntRect & aRect,const gfx::IntPoint & aClipSpaceOrigin,const gfx::IntSize & aPhySize,GLenum aFBOTextureTarget,SurfaceInitMode aInit)76 CreateForNewFBOAndTakeOwnership(CompositorOGL* aCompositor, GLuint aTexture, 77 GLuint aFBO, const gfx::IntRect& aRect, 78 const gfx::IntPoint& aClipSpaceOrigin, 79 const gfx::IntSize& aPhySize, 80 GLenum aFBOTextureTarget, 81 SurfaceInitMode aInit) { 82 RefPtr<CompositingRenderTargetOGL> result = new CompositingRenderTargetOGL( 83 aCompositor, aRect, aClipSpaceOrigin, aPhySize, 84 GLResourceOwnership::OWNED_BY_RENDER_TARGET, aTexture, aFBO, 85 Some(InitParams{aFBOTextureTarget, aInit})); 86 return result.forget(); 87 } 88 89 static already_AddRefed<CompositingRenderTargetOGL> CreateForExternallyOwnedFBO(CompositorOGL * aCompositor,GLuint aFBO,const gfx::IntRect & aRect,const gfx::IntPoint & aClipSpaceOrigin)90 CreateForExternallyOwnedFBO(CompositorOGL* aCompositor, GLuint aFBO, 91 const gfx::IntRect& aRect, 92 const gfx::IntPoint& aClipSpaceOrigin) { 93 RefPtr<CompositingRenderTargetOGL> result = new CompositingRenderTargetOGL( 94 aCompositor, aRect, aClipSpaceOrigin, aRect.Size(), 95 GLResourceOwnership::EXTERNALLY_OWNED, 0, aFBO, Nothing()); 96 return result.forget(); 97 } 98 99 void BindTexture(GLenum aTextureUnit, GLenum aTextureTarget); 100 101 /** 102 * Call when we want to draw into our FBO 103 */ 104 void BindRenderTarget(); 105 IsWindow()106 bool IsWindow() { return mFBO == 0; } 107 108 GLuint GetFBO() const; 109 GetTextureHandle()110 GLuint GetTextureHandle() const { 111 MOZ_ASSERT(!mNeedInitialization); 112 return mTextureHandle; 113 } 114 115 // TextureSourceOGL AsSourceOGL()116 TextureSourceOGL* AsSourceOGL() override { 117 // XXX - Bug 900770 118 MOZ_ASSERT( 119 false, 120 "CompositingRenderTargetOGL should not be used as a TextureSource"); 121 return nullptr; 122 } GetSize()123 gfx::IntSize GetSize() const override { return mSize; } 124 125 // The point that DrawGeometry's aClipRect is relative to. Will be (0, 0) for 126 // root render targets and equal to GetOrigin() for non-root render targets. GetClipSpaceOrigin()127 gfx::IntPoint GetClipSpaceOrigin() const { return mClipSpaceOrigin; } 128 GetFormat()129 gfx::SurfaceFormat GetFormat() const override { 130 // XXX - Should it be implemented ? is the above assert true ? 131 MOZ_ASSERT(false, "Not implemented"); 132 return gfx::SurfaceFormat::UNKNOWN; 133 } 134 135 // In render target coordinates, i.e. the same space as GetOrigin(). 136 // NOT relative to mClipSpaceOrigin! SetClipRect(const Maybe<gfx::IntRect> & aRect)137 void SetClipRect(const Maybe<gfx::IntRect>& aRect) { mClipRect = aRect; } GetClipRect()138 const Maybe<gfx::IntRect>& GetClipRect() const { return mClipRect; } 139 140 #ifdef MOZ_DUMP_PAINTING 141 already_AddRefed<gfx::DataSourceSurface> Dump( 142 Compositor* aCompositor) override; 143 #endif 144 GetInitSize()145 const gfx::IntSize& GetInitSize() const { return mSize; } GetPhysicalSize()146 const gfx::IntSize& GetPhysicalSize() const { return mPhySize; } 147 148 protected: CompositingRenderTargetOGL(CompositorOGL * aCompositor,const gfx::IntRect & aRect,const gfx::IntPoint & aClipSpaceOrigin,const gfx::IntSize & aPhySize,GLResourceOwnership aGLResourceOwnership,GLuint aTexure,GLuint aFBO,const Maybe<InitParams> & aNeedInitialization)149 CompositingRenderTargetOGL(CompositorOGL* aCompositor, 150 const gfx::IntRect& aRect, 151 const gfx::IntPoint& aClipSpaceOrigin, 152 const gfx::IntSize& aPhySize, 153 GLResourceOwnership aGLResourceOwnership, 154 GLuint aTexure, GLuint aFBO, 155 const Maybe<InitParams>& aNeedInitialization) 156 : CompositingRenderTarget(aRect.TopLeft()), 157 mNeedInitialization(aNeedInitialization), 158 mSize(aRect.Size()), 159 mPhySize(aPhySize), 160 mCompositor(aCompositor), 161 mGL(aCompositor->gl()), 162 mClipSpaceOrigin(aClipSpaceOrigin), 163 mGLResourceOwnership(aGLResourceOwnership), 164 mTextureHandle(aTexure), 165 mFBO(aFBO) { 166 MOZ_ASSERT(mGL); 167 } 168 169 /** 170 * Actually do the initialisation. 171 * We do this lazily so that when we first set this render target on the 172 * compositor we do not have to re-bind the FBO after unbinding it, or 173 * alternatively leave the FBO bound after creation. Note that we leave our 174 * FBO bound, and so calling this method is only suitable when about to use 175 * this render target. 176 */ 177 void Initialize(GLenum aFBOTextureTarget); 178 179 /** 180 * Some() between construction and Initialize, if initialization was 181 * requested. 182 */ 183 Maybe<InitParams> mNeedInitialization; 184 185 /* 186 * Users of render target would draw in logical size, but it is 187 * actually drawn to a surface in physical size. GL surfaces have 188 * a limitation on their size, a smaller surface would be 189 * allocated for the render target if the caller requests in a 190 * size too big. 191 */ 192 gfx::IntSize mSize; // Logical size, the expected by callers. 193 gfx::IntSize mPhySize; // Physical size, the real size of the surface. 194 195 /** 196 * There is temporary a cycle between the compositor and the render target, 197 * each having a strong ref to the other. The compositor's reference to 198 * the target is always cleared at the end of a frame. 199 */ 200 RefPtr<CompositorOGL> mCompositor; 201 RefPtr<GLContext> mGL; 202 Maybe<gfx::IntRect> mClipRect; 203 gfx::IntPoint mClipSpaceOrigin; 204 GLResourceOwnership mGLResourceOwnership; 205 GLuint mTextureHandle; 206 GLuint mFBO; 207 }; 208 209 } // namespace layers 210 } // namespace mozilla 211 212 #endif /* MOZILLA_GFX_SURFACEOGL_H */ 213