/work/obj-fuzz/dist/include/GLScreenBuffer.h
Line | Count | Source (jump to first uncovered line) |
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 "GLContextTypes.h" |
19 | | #include "GLDefs.h" |
20 | | #include "mozilla/gfx/2D.h" |
21 | | #include "mozilla/gfx/Point.h" |
22 | | #include "mozilla/UniquePtr.h" |
23 | | #include "SharedSurface.h" |
24 | | #include "SurfaceTypes.h" |
25 | | |
26 | | namespace mozilla { |
27 | | namespace layers { |
28 | | class KnowsCompositor; |
29 | | class LayersIPCChannel; |
30 | | class SharedSurfaceTextureClient; |
31 | | } // namespace layers |
32 | | |
33 | | namespace gl { |
34 | | |
35 | | class GLContext; |
36 | | class SharedSurface; |
37 | | class ShSurfHandle; |
38 | | class SurfaceFactory; |
39 | | |
40 | | class DrawBuffer |
41 | | { |
42 | | public: |
43 | | // Fallible! |
44 | | // But it may return true with *out_buffer==nullptr if unneeded. |
45 | | static bool Create(GLContext* const gl, |
46 | | const SurfaceCaps& caps, |
47 | | const GLFormats& formats, |
48 | | const gfx::IntSize& size, |
49 | | UniquePtr<DrawBuffer>* out_buffer); |
50 | | |
51 | | protected: |
52 | | GLContext* const mGL; |
53 | | public: |
54 | | const gfx::IntSize mSize; |
55 | | const GLsizei mSamples; |
56 | | const GLuint mFB; |
57 | | protected: |
58 | | const GLuint mColorMSRB; |
59 | | const GLuint mDepthRB; |
60 | | const GLuint mStencilRB; |
61 | | |
62 | | DrawBuffer(GLContext* gl, |
63 | | const gfx::IntSize& size, |
64 | | GLsizei samples, |
65 | | GLuint fb, |
66 | | GLuint colorMSRB, |
67 | | GLuint depthRB, |
68 | | GLuint stencilRB) |
69 | | : mGL(gl) |
70 | | , mSize(size) |
71 | | , mSamples(samples) |
72 | | , mFB(fb) |
73 | | , mColorMSRB(colorMSRB) |
74 | | , mDepthRB(depthRB) |
75 | | , mStencilRB(stencilRB) |
76 | | {} |
77 | | |
78 | | public: |
79 | | virtual ~DrawBuffer(); |
80 | | }; |
81 | | |
82 | | class ReadBuffer |
83 | | { |
84 | | public: |
85 | | // Infallible, always non-null. |
86 | | static UniquePtr<ReadBuffer> Create(GLContext* gl, |
87 | | const SurfaceCaps& caps, |
88 | | const GLFormats& formats, |
89 | | SharedSurface* surf); |
90 | | |
91 | | protected: |
92 | | GLContext* const mGL; |
93 | | public: |
94 | | const GLuint mFB; |
95 | | protected: |
96 | | // mFB has the following attachments: |
97 | | const GLuint mDepthRB; |
98 | | const GLuint mStencilRB; |
99 | | // note no mColorRB here: this is provided by mSurf. |
100 | | SharedSurface* mSurf; |
101 | | |
102 | | ReadBuffer(GLContext* gl, |
103 | | GLuint fb, |
104 | | GLuint depthRB, |
105 | | GLuint stencilRB, |
106 | | SharedSurface* surf) |
107 | | : mGL(gl) |
108 | | , mFB(fb) |
109 | | , mDepthRB(depthRB) |
110 | | , mStencilRB(stencilRB) |
111 | | , mSurf(surf) |
112 | | {} |
113 | | |
114 | | public: |
115 | | virtual ~ReadBuffer(); |
116 | | |
117 | | // Cannot attach a surf of a different AttachType or Size than before. |
118 | | void Attach(SharedSurface* surf); |
119 | | |
120 | | const gfx::IntSize& Size() const; |
121 | | |
122 | | SharedSurface* SharedSurf() const { |
123 | | return mSurf; |
124 | | } |
125 | | |
126 | | void SetReadBuffer(GLenum mode) const; |
127 | | }; |
128 | | |
129 | | |
130 | | class GLScreenBuffer |
131 | | { |
132 | | public: |
133 | | // Infallible. |
134 | | static UniquePtr<GLScreenBuffer> Create(GLContext* gl, |
135 | | const gfx::IntSize& size, |
136 | | const SurfaceCaps& caps); |
137 | | |
138 | | static UniquePtr<SurfaceFactory> |
139 | | CreateFactory(GLContext* gl, |
140 | | const SurfaceCaps& caps, |
141 | | layers::KnowsCompositor* compositorConnection, |
142 | | const layers::TextureFlags& flags); |
143 | | |
144 | | protected: |
145 | | GLContext* const mGL; // Owns us. |
146 | | public: |
147 | | const SurfaceCaps mCaps; |
148 | | protected: |
149 | | UniquePtr<SurfaceFactory> mFactory; |
150 | | |
151 | | RefPtr<layers::SharedSurfaceTextureClient> mBack; |
152 | | RefPtr<layers::SharedSurfaceTextureClient> mFront; |
153 | | |
154 | | UniquePtr<DrawBuffer> mDraw; |
155 | | UniquePtr<ReadBuffer> mRead; |
156 | | |
157 | | bool mNeedsBlit; |
158 | | |
159 | | GLenum mUserReadBufferMode; |
160 | | GLenum mUserDrawBufferMode; |
161 | | |
162 | | // Below are the parts that help us pretend to be framebuffer 0: |
163 | | GLuint mUserDrawFB; |
164 | | GLuint mUserReadFB; |
165 | | GLuint mInternalDrawFB; |
166 | | GLuint mInternalReadFB; |
167 | | |
168 | | #ifdef DEBUG |
169 | | bool mInInternalMode_DrawFB; |
170 | | bool mInInternalMode_ReadFB; |
171 | | #endif |
172 | | |
173 | | GLScreenBuffer(GLContext* gl, |
174 | | const SurfaceCaps& caps, |
175 | | UniquePtr<SurfaceFactory> factory); |
176 | | |
177 | | public: |
178 | | virtual ~GLScreenBuffer(); |
179 | | |
180 | 0 | SurfaceFactory* Factory() const { |
181 | 0 | return mFactory.get(); |
182 | 0 | } |
183 | | |
184 | 0 | const RefPtr<layers::SharedSurfaceTextureClient>& Front() const { |
185 | 0 | return mFront; |
186 | 0 | } |
187 | | |
188 | | SharedSurface* SharedSurf() const { |
189 | | MOZ_ASSERT(mRead); |
190 | | return mRead->SharedSurf(); |
191 | | } |
192 | | |
193 | | bool ShouldPreserveBuffer() const { |
194 | | return mCaps.preserve; |
195 | | } |
196 | | |
197 | | GLuint DrawFB() const { |
198 | | if (!mDraw) |
199 | | return ReadFB(); |
200 | | |
201 | | return mDraw->mFB; |
202 | | } |
203 | | |
204 | | GLuint ReadFB() const { |
205 | | return mRead->mFB; |
206 | | } |
207 | | |
208 | | GLsizei Samples() const { |
209 | | if (!mDraw) |
210 | | return 0; |
211 | | |
212 | | return mDraw->mSamples; |
213 | | } |
214 | | |
215 | | uint32_t DepthBits() const; |
216 | | |
217 | | void DeletingFB(GLuint fb); |
218 | | |
219 | | const gfx::IntSize& Size() const { |
220 | | MOZ_ASSERT(mRead); |
221 | | MOZ_ASSERT(!mDraw || mDraw->mSize == mRead->Size()); |
222 | | return mRead->Size(); |
223 | | } |
224 | | |
225 | | bool IsReadBufferReady() const { |
226 | | return mRead.get() != nullptr; |
227 | | } |
228 | | |
229 | | void BindAsFramebuffer(GLContext* const gl, GLenum target) const; |
230 | | |
231 | | void RequireBlit(); |
232 | | void AssureBlitted(); |
233 | | void AfterDrawCall(); |
234 | | void BeforeReadCall(); |
235 | | |
236 | | bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, |
237 | | GLint y, GLsizei width, GLsizei height, GLint border); |
238 | | |
239 | | void SetReadBuffer(GLenum userMode); |
240 | | void SetDrawBuffer(GLenum userMode); |
241 | | |
242 | | GLenum GetReadBufferMode() const { return mUserReadBufferMode; } |
243 | | GLenum GetDrawBufferMode() const { return mUserDrawBufferMode; } |
244 | | |
245 | | /** |
246 | | * Attempts to read pixels from the current bound framebuffer, if |
247 | | * it is backed by a SharedSurface. |
248 | | * |
249 | | * Returns true if the pixel data has been read back, false |
250 | | * otherwise. |
251 | | */ |
252 | | bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, |
253 | | GLenum format, GLenum type, GLvoid* pixels); |
254 | | |
255 | | // Morph changes the factory used to create surfaces. |
256 | | void Morph(UniquePtr<SurfaceFactory> newFactory); |
257 | | |
258 | | protected: |
259 | | // Returns false on error or inability to resize. |
260 | | bool Swap(const gfx::IntSize& size); |
261 | | |
262 | | public: |
263 | | bool PublishFrame(const gfx::IntSize& size); |
264 | | |
265 | | bool Resize(const gfx::IntSize& size); |
266 | | |
267 | | protected: |
268 | | bool Attach(SharedSurface* surf, const gfx::IntSize& size); |
269 | | |
270 | | bool CreateDraw(const gfx::IntSize& size, UniquePtr<DrawBuffer>* out_buffer); |
271 | | UniquePtr<ReadBuffer> CreateRead(SharedSurface* surf); |
272 | | |
273 | | public: |
274 | | /* `fb` in these functions is the framebuffer the GLContext is hoping to |
275 | | * bind. When this is 0, we intercept the call and bind our own |
276 | | * framebuffers. As a client of these functions, just bind 0 when you want |
277 | | * to draw to the default framebuffer/'screen'. |
278 | | */ |
279 | | void BindFB(GLuint fb); |
280 | | void BindDrawFB(GLuint fb); |
281 | | void BindReadFB(GLuint fb); |
282 | | GLuint GetFB() const; |
283 | | GLuint GetDrawFB() const; |
284 | | GLuint GetReadFB() const; |
285 | | |
286 | | // Here `fb` is the actual framebuffer you want bound. Binding 0 will |
287 | | // bind the (generally useless) default framebuffer. |
288 | | void BindFB_Internal(GLuint fb); |
289 | | void BindDrawFB_Internal(GLuint fb); |
290 | | void BindReadFB_Internal(GLuint fb); |
291 | | |
292 | | bool IsDrawFramebufferDefault() const; |
293 | | bool IsReadFramebufferDefault() const; |
294 | | }; |
295 | | |
296 | | } // namespace gl |
297 | | } // namespace mozilla |
298 | | |
299 | | #endif // SCREEN_BUFFER_H_ |