Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef MOZILLA_GFX_COMPOSITINGRENDERTARGETOGL_H
7 : #define MOZILLA_GFX_COMPOSITINGRENDERTARGETOGL_H
8 :
9 : #include "GLContextTypes.h" // for GLContext
10 : #include "GLDefs.h" // for GLenum, LOCAL_GL_FRAMEBUFFER, etc
11 : #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
12 : #include "mozilla/Attributes.h" // for override
13 : #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed
14 : #include "mozilla/gfx/Point.h" // for IntSize, IntSizeTyped
15 : #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
16 : #include "mozilla/layers/Compositor.h" // for SurfaceInitMode, etc
17 : #include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget
18 : #include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
19 : #include "mozilla/mozalloc.h" // for operator new
20 : #include "nsAString.h"
21 : #include "nsCOMPtr.h" // for already_AddRefed
22 : #include "nsDebug.h" // for NS_ERROR, NS_WARNING
23 : #include "nsString.h" // for nsAutoCString
24 :
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 : {
40 : typedef mozilla::gl::GLContext GLContext;
41 :
42 : friend class CompositorOGL;
43 :
44 : // For lazy initialisation of the GL stuff
45 : struct InitParams
46 : {
47 0 : InitParams() : mStatus(NO_PARAMS) {}
48 0 : InitParams(const gfx::IntSize& aSize,
49 : const gfx::IntSize& aPhySize,
50 : GLenum aFBOTextureTarget,
51 : SurfaceInitMode aInit)
52 0 : : mStatus(READY)
53 : , mSize(aSize)
54 : , mPhySize(aPhySize)
55 : , mFBOTextureTarget(aFBOTextureTarget)
56 0 : , mInit(aInit)
57 0 : {}
58 :
59 : enum {
60 : NO_PARAMS,
61 : READY,
62 : INITIALIZED
63 : } mStatus;
64 : /*
65 : * Users of render target would draw in logical size, but it is
66 : * actually drawn to a surface in physical size. GL surfaces have
67 : * a limitation on their size, a smaller surface would be
68 : * allocated for the render target if the caller requests in a
69 : * size too big.
70 : */
71 : gfx::IntSize mSize; // Logical size, the expected by callers.
72 : gfx::IntSize mPhySize; // Physical size, the real size of the surface.
73 : GLenum mFBOTextureTarget;
74 : SurfaceInitMode mInit;
75 : };
76 :
77 : public:
78 0 : CompositingRenderTargetOGL(CompositorOGL* aCompositor, const gfx::IntPoint& aOrigin,
79 : GLuint aTexure, GLuint aFBO)
80 0 : : CompositingRenderTarget(aOrigin)
81 : , mInitParams()
82 : , mCompositor(aCompositor)
83 0 : , mGL(aCompositor->gl())
84 : , mTextureHandle(aTexure)
85 0 : , mFBO(aFBO)
86 : {
87 0 : MOZ_ASSERT(mGL);
88 0 : }
89 :
90 : ~CompositingRenderTargetOGL();
91 :
92 0 : virtual const char* Name() const override { return "CompositingRenderTargetOGL"; }
93 :
94 : /**
95 : * Create a render target around the default FBO, for rendering straight to
96 : * the window.
97 : */
98 : static already_AddRefed<CompositingRenderTargetOGL>
99 0 : RenderTargetForWindow(CompositorOGL* aCompositor,
100 : const gfx::IntSize& aSize)
101 : {
102 : RefPtr<CompositingRenderTargetOGL> result
103 0 : = new CompositingRenderTargetOGL(aCompositor, gfx::IntPoint(), 0, 0);
104 0 : result->mInitParams = InitParams(aSize, aSize, 0, INIT_MODE_NONE);
105 0 : result->mInitParams.mStatus = InitParams::INITIALIZED;
106 0 : return result.forget();
107 : }
108 :
109 : /**
110 : * Some initialisation work on the backing FBO and texture.
111 : * We do this lazily so that when we first set this render target on the
112 : * compositor we do not have to re-bind the FBO after unbinding it, or
113 : * alternatively leave the FBO bound after creation.
114 : */
115 0 : void Initialize(const gfx::IntSize& aSize,
116 : const gfx::IntSize& aPhySize,
117 : GLenum aFBOTextureTarget,
118 : SurfaceInitMode aInit)
119 : {
120 0 : MOZ_ASSERT(mInitParams.mStatus == InitParams::NO_PARAMS, "Initialized twice?");
121 : // postpone initialization until we actually want to use this render target
122 0 : mInitParams = InitParams(aSize, aPhySize, aFBOTextureTarget, aInit);
123 0 : }
124 :
125 : void BindTexture(GLenum aTextureUnit, GLenum aTextureTarget);
126 :
127 : /**
128 : * Call when we want to draw into our FBO
129 : */
130 : void BindRenderTarget();
131 :
132 0 : bool IsWindow() { return GetFBO() == 0; }
133 :
134 0 : GLuint GetFBO() const
135 : {
136 0 : MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED);
137 0 : return mFBO;
138 : }
139 :
140 0 : GLuint GetTextureHandle() const
141 : {
142 0 : MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED);
143 0 : return mTextureHandle;
144 : }
145 :
146 : // TextureSourceOGL
147 0 : TextureSourceOGL* AsSourceOGL() override
148 : {
149 : // XXX - Bug 900770
150 0 : MOZ_ASSERT(false, "CompositingRenderTargetOGL should not be used as a TextureSource");
151 : return nullptr;
152 : }
153 0 : gfx::IntSize GetSize() const override
154 : {
155 0 : return mInitParams.mSize;
156 : }
157 :
158 0 : gfx::SurfaceFormat GetFormat() const override
159 : {
160 : // XXX - Should it be implemented ? is the above assert true ?
161 0 : MOZ_ASSERT(false, "Not implemented");
162 : return gfx::SurfaceFormat::UNKNOWN;
163 : }
164 :
165 : #ifdef MOZ_DUMP_PAINTING
166 : virtual already_AddRefed<gfx::DataSourceSurface> Dump(Compositor* aCompositor) override;
167 : #endif
168 :
169 : const gfx::IntSize& GetInitSize() const {
170 : return mInitParams.mSize;
171 : }
172 :
173 : private:
174 : /**
175 : * Actually do the initialisation. Note that we leave our FBO bound, and so
176 : * calling this method is only suitable when about to use this render target.
177 : */
178 : void InitializeImpl();
179 :
180 : InitParams mInitParams;
181 : /**
182 : * There is temporary a cycle between the compositor and the render target,
183 : * each having a strong ref to the other. The compositor's reference to
184 : * the target is always cleared at the end of a frame.
185 : */
186 : RefPtr<CompositorOGL> mCompositor;
187 : GLContext* mGL;
188 : GLuint mTextureHandle;
189 : GLuint mFBO;
190 : };
191 :
192 : } // namespace layers
193 : } // namespace mozilla
194 :
195 : #endif /* MOZILLA_GFX_SURFACEOGL_H */
|