Coverage Report

Created: 2018-09-25 14:53

/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_