gfx/gl/GLScreenBuffer.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:eca83a70c314
1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
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 /* GLScreenBuffer is the abstraction for the "default framebuffer" used
7 * by an offscreen GLContext. Since it's only for offscreen GLContext's,
8 * it's only useful for things like WebGL, and is NOT used by the
9 * compositor's GLContext. Remember that GLContext provides an abstraction
10 * so that even if you want to draw to the 'screen', even if that's not
11 * actually the screen, just draw to 0. This GLScreenBuffer class takes the
12 * logic handling out of GLContext.
13 */
14
15 #ifndef SCREEN_BUFFER_H_
16 #define SCREEN_BUFFER_H_
17
18 #include "SurfaceTypes.h"
19 #include "SurfaceStream.h"
20 #include "GLContextTypes.h"
21 #include "GLDefs.h"
22 #include "mozilla/gfx/2D.h"
23 #include "mozilla/gfx/Point.h"
24
25 // Forwards:
26 class gfxImageSurface;
27
28 namespace mozilla {
29 namespace gfx {
30 class SurfaceStream;
31 class SharedSurface;
32 }
33 namespace gl {
34 class GLContext;
35 class SharedSurface_GL;
36 class SurfaceFactory_GL;
37 }
38 }
39
40 namespace mozilla {
41 namespace gl {
42
43 class DrawBuffer
44 {
45 protected:
46 typedef struct gfx::SurfaceCaps SurfaceCaps;
47
48 public:
49 // Infallible, may return null if unneeded.
50 static DrawBuffer* Create(GLContext* const gl,
51 const SurfaceCaps& caps,
52 const GLFormats& formats,
53 const gfx::IntSize& size);
54
55 protected:
56 GLContext* const mGL;
57 const gfx::IntSize mSize;
58 const GLuint mFB;
59 const GLuint mColorMSRB;
60 const GLuint mDepthRB;
61 const GLuint mStencilRB;
62
63 DrawBuffer(GLContext* gl,
64 const gfx::IntSize& size,
65 GLuint fb,
66 GLuint colorMSRB,
67 GLuint depthRB,
68 GLuint stencilRB)
69 : mGL(gl)
70 , mSize(size)
71 , mFB(fb)
72 , mColorMSRB(colorMSRB)
73 , mDepthRB(depthRB)
74 , mStencilRB(stencilRB)
75 {}
76
77 public:
78 virtual ~DrawBuffer();
79
80 const gfx::IntSize& Size() const {
81 return mSize;
82 }
83
84 GLuint FB() const {
85 return mFB;
86 }
87 };
88
89 class ReadBuffer
90 {
91 protected:
92 typedef struct gfx::SurfaceCaps SurfaceCaps;
93
94 public:
95 // Infallible, always non-null.
96 static ReadBuffer* Create(GLContext* gl,
97 const SurfaceCaps& caps,
98 const GLFormats& formats,
99 SharedSurface_GL* surf);
100
101 protected:
102 GLContext* const mGL;
103
104 const GLuint mFB;
105 // mFB has the following attachments:
106 const GLuint mDepthRB;
107 const GLuint mStencilRB;
108 // note no mColorRB here: this is provided by mSurf.
109 SharedSurface_GL* mSurf; // Owned by GLScreenBuffer's SurfaceStream.
110
111 ReadBuffer(GLContext* gl,
112 GLuint fb,
113 GLuint depthRB,
114 GLuint stencilRB,
115 SharedSurface_GL* surf)
116 : mGL(gl)
117 , mFB(fb)
118 , mDepthRB(depthRB)
119 , mStencilRB(stencilRB)
120 , mSurf(surf)
121 {}
122
123 public:
124 virtual ~ReadBuffer();
125
126 // Cannot attach a surf of a different AttachType or Size than before.
127 void Attach(SharedSurface_GL* surf);
128
129 const gfx::IntSize& Size() const;
130
131 GLuint FB() const {
132 return mFB;
133 }
134
135 SharedSurface_GL* SharedSurf() const {
136 return mSurf;
137 }
138 };
139
140
141 class GLScreenBuffer
142 {
143 protected:
144 typedef class gfx::SurfaceStream SurfaceStream;
145 typedef class gfx::SharedSurface SharedSurface;
146 typedef gfx::SurfaceStreamType SurfaceStreamType;
147 typedef gfx::SharedSurfaceType SharedSurfaceType;
148 typedef struct gfx::SurfaceCaps SurfaceCaps;
149
150 public:
151 // Infallible.
152 static GLScreenBuffer* Create(GLContext* gl,
153 const gfx::IntSize& size,
154 const SurfaceCaps& caps);
155
156 protected:
157 GLContext* const mGL; // Owns us.
158 SurfaceCaps mCaps;
159 SurfaceFactory_GL* mFactory; // Owned by us.
160 RefPtr<SurfaceStream> mStream;
161
162 DrawBuffer* mDraw; // Owned by us.
163 ReadBuffer* mRead; // Owned by us.
164
165 bool mNeedsBlit;
166
167 // Below are the parts that help us pretend to be framebuffer 0:
168 GLuint mUserDrawFB;
169 GLuint mUserReadFB;
170 GLuint mInternalDrawFB;
171 GLuint mInternalReadFB;
172
173 #ifdef DEBUG
174 bool mInInternalMode_DrawFB;
175 bool mInInternalMode_ReadFB;
176 #endif
177
178 GLScreenBuffer(GLContext* gl,
179 const SurfaceCaps& caps,
180 SurfaceFactory_GL* factory,
181 SurfaceStream* stream)
182 : mGL(gl)
183 , mCaps(caps)
184 , mFactory(factory)
185 , mStream(stream)
186 , mDraw(nullptr)
187 , mRead(nullptr)
188 , mNeedsBlit(true)
189 , mUserDrawFB(0)
190 , mUserReadFB(0)
191 , mInternalDrawFB(0)
192 , mInternalReadFB(0)
193 #ifdef DEBUG
194 , mInInternalMode_DrawFB(true)
195 , mInInternalMode_ReadFB(true)
196 #endif
197 {}
198
199 public:
200 virtual ~GLScreenBuffer();
201
202 SurfaceStream* Stream() const {
203 return mStream;
204 }
205
206 SurfaceFactory_GL* Factory() const {
207 return mFactory;
208 }
209
210 SharedSurface_GL* SharedSurf() const {
211 MOZ_ASSERT(mRead);
212 return mRead->SharedSurf();
213 }
214
215 bool PreserveBuffer() const {
216 return mCaps.preserve;
217 }
218
219 const SurfaceCaps& Caps() const {
220 return mCaps;
221 }
222
223 GLuint DrawFB() const {
224 if (!mDraw)
225 return ReadFB();
226
227 return mDraw->FB();
228 }
229
230 GLuint ReadFB() const {
231 return mRead->FB();
232 }
233
234 void DeletingFB(GLuint fb);
235
236 const gfx::IntSize& Size() const {
237 MOZ_ASSERT(mRead);
238 MOZ_ASSERT(!mDraw || mDraw->Size() == mRead->Size());
239 return mRead->Size();
240 }
241
242 void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
243
244 void RequireBlit();
245 void AssureBlitted();
246 void AfterDrawCall();
247 void BeforeReadCall();
248
249 /**
250 * Attempts to read pixels from the current bound framebuffer, if
251 * it is backed by a SharedSurface_GL.
252 *
253 * Returns true if the pixel data has been read back, false
254 * otherwise.
255 */
256 bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
257 GLenum format, GLenum type, GLvoid *pixels);
258
259 /* Morph swaps out our SurfaceStream mechanism and replaces it with
260 * one best suited to our platform and compositor configuration.
261 *
262 * Must be called on the producing thread.
263 * We haven't made any guarantee that rendering is actually
264 * done when Morph is run, just that it can't run concurrently
265 * with rendering. This means that we can't just drop the contents
266 * of the buffer, since we may only be partially done rendering.
267 *
268 * Once you pass newFactory into Morph, newFactory will be owned by
269 * GLScreenBuffer, so `forget` any references to it that still exist.
270 */
271 void Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamType);
272
273 protected:
274 // Returns false on error or inability to resize.
275 bool Swap(const gfx::IntSize& size);
276
277 public:
278 bool PublishFrame(const gfx::IntSize& size);
279
280 bool Resize(const gfx::IntSize& size);
281
282 void Readback(SharedSurface_GL* src, gfx::DataSourceSurface* dest);
283 void DeprecatedReadback(SharedSurface_GL* src, gfxImageSurface* dest);
284
285 protected:
286 void Attach(SharedSurface* surface, const gfx::IntSize& size);
287
288 DrawBuffer* CreateDraw(const gfx::IntSize& size);
289 ReadBuffer* CreateRead(SharedSurface_GL* surf);
290
291 public:
292 /* `fb` in these functions is the framebuffer the GLContext is hoping to
293 * bind. When this is 0, we intercept the call and bind our own
294 * framebuffers. As a client of these functions, just bind 0 when you want
295 * to draw to the default framebuffer/'screen'.
296 */
297 void BindFB(GLuint fb);
298 void BindDrawFB(GLuint fb);
299 void BindReadFB(GLuint fb);
300 GLuint GetFB() const;
301 GLuint GetDrawFB() const;
302 GLuint GetReadFB() const;
303
304 // Here `fb` is the actual framebuffer you want bound. Binding 0 will
305 // bind the (generally useless) default framebuffer.
306 void BindDrawFB_Internal(GLuint fb);
307 void BindReadFB_Internal(GLuint fb);
308 };
309
310 } // namespace gl
311 } // namespace mozilla
312
313 #endif // SCREEN_BUFFER_H_

mercurial