Bumping manifests a=b2g-bump
[gecko.git] / gfx / gl / GLScreenBuffer.h
blob9eab5fb020ad2f2951a56742b82920638d8696a9
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/. */
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.
15 #ifndef SCREEN_BUFFER_H_
16 #define SCREEN_BUFFER_H_
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 #include "mozilla/UniquePtr.h"
26 namespace mozilla {
27 namespace gl {
29 class GLContext;
30 class SharedSurface;
31 class SurfaceStream;
33 class DrawBuffer
35 public:
36 // Fallible!
37 // But it may return true with *out_buffer==nullptr if unneeded.
38 static bool Create(GLContext* const gl,
39 const SurfaceCaps& caps,
40 const GLFormats& formats,
41 const gfx::IntSize& size,
42 UniquePtr<DrawBuffer>* out_buffer);
44 protected:
45 GLContext* const mGL;
46 public:
47 const gfx::IntSize mSize;
48 const GLuint mFB;
49 protected:
50 const GLuint mColorMSRB;
51 const GLuint mDepthRB;
52 const GLuint mStencilRB;
54 DrawBuffer(GLContext* gl,
55 const gfx::IntSize& size,
56 GLuint fb,
57 GLuint colorMSRB,
58 GLuint depthRB,
59 GLuint stencilRB)
60 : mGL(gl)
61 , mSize(size)
62 , mFB(fb)
63 , mColorMSRB(colorMSRB)
64 , mDepthRB(depthRB)
65 , mStencilRB(stencilRB)
68 public:
69 virtual ~DrawBuffer();
72 class ReadBuffer
74 public:
75 // Infallible, always non-null.
76 static UniquePtr<ReadBuffer> Create(GLContext* gl,
77 const SurfaceCaps& caps,
78 const GLFormats& formats,
79 SharedSurface* surf);
81 protected:
82 GLContext* const mGL;
83 public:
84 const GLuint mFB;
85 protected:
86 // mFB has the following attachments:
87 const GLuint mDepthRB;
88 const GLuint mStencilRB;
89 // note no mColorRB here: this is provided by mSurf.
90 SharedSurface* mSurf; // Owned by GLScreenBuffer's SurfaceStream.
92 ReadBuffer(GLContext* gl,
93 GLuint fb,
94 GLuint depthRB,
95 GLuint stencilRB,
96 SharedSurface* surf)
97 : mGL(gl)
98 , mFB(fb)
99 , mDepthRB(depthRB)
100 , mStencilRB(stencilRB)
101 , mSurf(surf)
104 public:
105 virtual ~ReadBuffer();
107 // Cannot attach a surf of a different AttachType or Size than before.
108 void Attach(SharedSurface* surf);
110 const gfx::IntSize& Size() const;
112 SharedSurface* SharedSurf() const {
113 return mSurf;
118 class GLScreenBuffer
120 public:
121 // Infallible.
122 static UniquePtr<GLScreenBuffer> Create(GLContext* gl,
123 const gfx::IntSize& size,
124 const SurfaceCaps& caps);
126 protected:
127 GLContext* const mGL; // Owns us.
128 public:
129 const SurfaceCaps mCaps;
130 protected:
131 UniquePtr<SurfaceFactory> mFactory;
132 RefPtr<SurfaceStream> mStream;
134 UniquePtr<DrawBuffer> mDraw;
135 UniquePtr<ReadBuffer> mRead;
137 bool mNeedsBlit;
139 // Below are the parts that help us pretend to be framebuffer 0:
140 GLuint mUserDrawFB;
141 GLuint mUserReadFB;
142 GLuint mInternalDrawFB;
143 GLuint mInternalReadFB;
145 #ifdef DEBUG
146 bool mInInternalMode_DrawFB;
147 bool mInInternalMode_ReadFB;
148 #endif
150 GLScreenBuffer(GLContext* gl,
151 const SurfaceCaps& caps,
152 UniquePtr<SurfaceFactory> factory,
153 const RefPtr<SurfaceStream>& stream)
154 : mGL(gl)
155 , mCaps(caps)
156 , mFactory(Move(factory))
157 , mStream(stream)
158 , mDraw(nullptr)
159 , mRead(nullptr)
160 , mNeedsBlit(true)
161 , mUserDrawFB(0)
162 , mUserReadFB(0)
163 , mInternalDrawFB(0)
164 , mInternalReadFB(0)
165 #ifdef DEBUG
166 , mInInternalMode_DrawFB(true)
167 , mInInternalMode_ReadFB(true)
168 #endif
171 public:
172 virtual ~GLScreenBuffer();
174 SurfaceStream* Stream() const {
175 return mStream;
178 SurfaceFactory* Factory() const {
179 return mFactory.get();
182 SharedSurface* SharedSurf() const {
183 MOZ_ASSERT(mRead);
184 return mRead->SharedSurf();
187 bool PreserveBuffer() const {
188 return mCaps.preserve;
191 GLuint DrawFB() const {
192 if (!mDraw)
193 return ReadFB();
195 return mDraw->mFB;
198 GLuint ReadFB() const {
199 return mRead->mFB;
202 void DeletingFB(GLuint fb);
204 const gfx::IntSize& Size() const {
205 MOZ_ASSERT(mRead);
206 MOZ_ASSERT(!mDraw || mDraw->mSize == mRead->Size());
207 return mRead->Size();
210 void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
212 void RequireBlit();
213 void AssureBlitted();
214 void AfterDrawCall();
215 void BeforeReadCall();
218 * Attempts to read pixels from the current bound framebuffer, if
219 * it is backed by a SharedSurface.
221 * Returns true if the pixel data has been read back, false
222 * otherwise.
224 bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
225 GLenum format, GLenum type, GLvoid *pixels);
227 /* Morph swaps out our SurfaceStream mechanism and replaces it with
228 * one best suited to our platform and compositor configuration.
230 * Must be called on the producing thread.
231 * We haven't made any guarantee that rendering is actually
232 * done when Morph is run, just that it can't run concurrently
233 * with rendering. This means that we can't just drop the contents
234 * of the buffer, since we may only be partially done rendering.
236 * Once you pass newFactory into Morph, newFactory will be owned by
237 * GLScreenBuffer, so `forget` any references to it that still exist.
239 void Morph(UniquePtr<SurfaceFactory> newFactory,
240 SurfaceStreamType streamType);
242 protected:
243 // Returns false on error or inability to resize.
244 bool Swap(const gfx::IntSize& size);
246 public:
247 bool PublishFrame(const gfx::IntSize& size);
249 bool Resize(const gfx::IntSize& size);
251 void Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
253 protected:
254 bool Attach(SharedSurface* surf, const gfx::IntSize& size);
256 bool CreateDraw(const gfx::IntSize& size, UniquePtr<DrawBuffer>* out_buffer);
257 UniquePtr<ReadBuffer> CreateRead(SharedSurface* surf);
259 public:
260 /* `fb` in these functions is the framebuffer the GLContext is hoping to
261 * bind. When this is 0, we intercept the call and bind our own
262 * framebuffers. As a client of these functions, just bind 0 when you want
263 * to draw to the default framebuffer/'screen'.
265 void BindFB(GLuint fb);
266 void BindDrawFB(GLuint fb);
267 void BindReadFB(GLuint fb);
268 GLuint GetFB() const;
269 GLuint GetDrawFB() const;
270 GLuint GetReadFB() const;
272 // Here `fb` is the actual framebuffer you want bound. Binding 0 will
273 // bind the (generally useless) default framebuffer.
274 void BindFB_Internal(GLuint fb);
275 void BindDrawFB_Internal(GLuint fb);
276 void BindReadFB_Internal(GLuint fb);
279 } // namespace gl
280 } // namespace mozilla
282 #endif // SCREEN_BUFFER_H_