Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/canvas/WebGLFramebuffer.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 WEBGL_FRAMEBUFFER_H_
7
#define WEBGL_FRAMEBUFFER_H_
8
9
#include <vector>
10
11
#include "mozilla/LinkedList.h"
12
#include "mozilla/WeakPtr.h"
13
#include "nsWrapperCache.h"
14
15
#include "WebGLObjectModel.h"
16
#include "WebGLRenderbuffer.h"
17
#include "WebGLStrongTypes.h"
18
#include "WebGLTexture.h"
19
#include "WebGLTypes.h"
20
21
namespace mozilla {
22
23
class WebGLFramebuffer;
24
class WebGLRenderbuffer;
25
class WebGLTexture;
26
27
template<typename T>
28
class PlacementArray;
29
30
namespace gl {
31
    class GLContext;
32
} // namespace gl
33
34
class WebGLFBAttachPoint final
35
{
36
    friend class WebGLFramebuffer;
37
public:
38
    WebGLFramebuffer* const mFB;
39
    const GLenum mAttachmentPoint;
40
41
private:
42
    WebGLRefPtr<WebGLTexture> mTexturePtr;
43
    WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
44
    TexImageTarget mTexImageTarget;
45
    GLint mTexImageLayer;
46
    uint32_t mTexImageLevel;
47
48
    ////
49
50
    WebGLFBAttachPoint();
51
    WebGLFBAttachPoint(WebGLFramebuffer* fb, GLenum attachmentPoint);
52
    explicit WebGLFBAttachPoint(WebGLFBAttachPoint&) = default; // Make this private.
53
54
public:
55
    ~WebGLFBAttachPoint();
56
57
    ////
58
59
    void Unlink();
60
61
    bool IsDefined() const;
62
    bool IsDeleteRequested() const;
63
64
    const webgl::FormatUsageInfo* Format() const;
65
    uint32_t Samples() const;
66
67
    bool HasAlpha() const;
68
    bool IsReadableFloat() const;
69
70
    void Clear();
71
72
    void SetTexImage(WebGLTexture* tex, TexImageTarget target,
73
                     GLint level, GLint layer = 0);
74
    void SetRenderbuffer(WebGLRenderbuffer* rb);
75
76
0
    WebGLTexture* Texture() const { return mTexturePtr; }
77
0
    WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
78
79
0
    TexImageTarget ImageTarget() const {
80
0
        return mTexImageTarget;
81
0
    }
82
0
    GLint Layer() const {
83
0
        return mTexImageLayer;
84
0
    }
85
0
    uint32_t MipLevel() const {
86
0
        return mTexImageLevel;
87
0
    }
88
    void AttachmentName(nsCString* out) const;
89
90
    bool HasUninitializedImageData() const;
91
    void SetImageDataStatus(WebGLImageDataStatus x) const;
92
93
    void Size(uint32_t* const out_width, uint32_t* const out_height) const;
94
95
    bool HasImage() const;
96
    bool IsComplete(WebGLContext* webgl, nsCString* const out_info) const;
97
98
    void Resolve(gl::GLContext* gl) const;
99
100
    JS::Value GetParameter(WebGLContext* webgl, JSContext* cx,
101
                           GLenum target, GLenum attachment, GLenum pname,
102
                           ErrorResult* const out_error) const;
103
104
    void OnBackingStoreRespecified() const;
105
106
0
    bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
107
0
        if (!IsDefined() || !other.IsDefined())
108
0
            return false;
109
0
110
0
#define _(X) X == other.X
111
0
        return ( _(mRenderbufferPtr) &&
112
0
                 _(mTexturePtr) &&
113
0
                 _(mTexImageTarget.get()) &&
114
0
                 _(mTexImageLevel) &&
115
0
                 _(mTexImageLayer) );
116
0
#undef _
117
0
    }
118
119
    ////
120
121
    struct Ordered {
122
        const WebGLFBAttachPoint& mRef;
123
124
        explicit Ordered(const WebGLFBAttachPoint& ref)
125
            : mRef(ref)
126
0
        { }
127
128
0
        bool operator<(const Ordered& other) const {
129
0
            MOZ_ASSERT(mRef.IsDefined() && other.mRef.IsDefined());
130
0
131
0
#define ORDER_BY(X) if (X != other.X) return X < other.X;
132
0
133
0
            ORDER_BY(mRef.mRenderbufferPtr)
134
0
            ORDER_BY(mRef.mTexturePtr)
135
0
            ORDER_BY(mRef.mTexImageTarget.get())
136
0
            ORDER_BY(mRef.mTexImageLevel)
137
0
            ORDER_BY(mRef.mTexImageLayer)
138
0
139
0
#undef ORDER_BY
140
0
            return false;
141
0
        }
142
    };
143
};
144
145
class WebGLFramebuffer final
146
    : public nsWrapperCache
147
    , public WebGLRefCountedObject<WebGLFramebuffer>
148
    , public LinkedListElement<WebGLFramebuffer>
149
    , public SupportsWeakPtr<WebGLFramebuffer>
150
{
151
    friend class WebGLContext;
152
153
public:
154
    MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
155
156
    const GLuint mGLName;
157
158
private:
159
    uint64_t mNumFBStatusInvals;
160
161
protected:
162
#ifdef ANDROID
163
    // Bug 1140459: Some drivers (including our test slaves!) don't
164
    // give reasonable answers for IsRenderbuffer, maybe others.
165
    // This shows up on Android 2.3 emulator.
166
    //
167
    // So we track the `is a Framebuffer` state ourselves.
168
    bool mIsFB;
169
#endif
170
171
    ////
172
173
    WebGLFBAttachPoint mDepthAttachment;
174
    WebGLFBAttachPoint mStencilAttachment;
175
    WebGLFBAttachPoint mDepthStencilAttachment;
176
177
    // In theory, this number can be unbounded based on the driver. However, no driver
178
    // appears to expose more than 8. We might as well stop there too, for now.
179
    // (http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COLOR_ATTACHMENTS)
180
    static const size_t kMaxColorAttachments = 8; // jgilbert's MacBook Pro exposes 8.
181
    WebGLFBAttachPoint mColorAttachments[kMaxColorAttachments];
182
183
    ////
184
185
    std::vector<const WebGLFBAttachPoint*> mColorDrawBuffers; // Non-null
186
    const WebGLFBAttachPoint* mColorReadBuffer; // Null if NONE
187
188
    ////
189
190
    struct ResolvedData {
191
        // IsFeedback
192
        std::vector<const WebGLFBAttachPoint*> texDrawBuffers; // Non-null
193
        std::set<WebGLFBAttachPoint::Ordered> drawSet;
194
        std::set<WebGLFBAttachPoint::Ordered> readSet;
195
196
        explicit ResolvedData(const WebGLFramebuffer& parent);
197
    };
198
199
    mutable UniquePtr<const ResolvedData> mResolvedCompleteData;
200
201
    ////
202
203
public:
204
    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
205
    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
206
207
    WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
208
209
0
    WebGLContext* GetParentObject() const { return mContext; }
210
    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
211
212
private:
213
0
    ~WebGLFramebuffer() {
214
0
        DeleteOnce();
215
0
    }
216
217
public:
218
    void Delete();
219
220
    ////
221
222
    bool HasDuplicateAttachments() const;
223
    bool HasDefinedAttachments() const;
224
    bool HasIncompleteAttachments(nsCString* const out_info) const;
225
    bool AllImageRectsMatch() const;
226
    bool AllImageSamplesMatch() const;
227
    FBStatus PrecheckFramebufferStatus(nsCString* const out_info) const;
228
229
protected:
230
    Maybe<WebGLFBAttachPoint*> GetAttachPoint(GLenum attachment); // Fallible
231
    Maybe<WebGLFBAttachPoint*> GetColorAttachPoint(GLenum attachment); // Fallible
232
    void ResolveAttachments() const;
233
    void RefreshDrawBuffers() const;
234
    void RefreshReadBuffer() const;
235
    bool ResolveAttachmentData() const;
236
237
public:
238
    void DetachTexture(const WebGLTexture* tex);
239
    void DetachRenderbuffer(const WebGLRenderbuffer* rb);
240
    bool ValidateAndInitAttachments() const;
241
    bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
242
                                 GLenum funcType) const;
243
244
    bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
245
                              uint32_t* out_width, uint32_t* out_height) const;
246
247
    ////////////////
248
    // Getters
249
250
0
#define GETTER(X) const decltype(m##X)& X() const { return m##X; }
Unexecuted instantiation: mozilla::WebGLFramebuffer::DepthAttachment() const
Unexecuted instantiation: mozilla::WebGLFramebuffer::StencilAttachment() const
Unexecuted instantiation: mozilla::WebGLFramebuffer::DepthStencilAttachment() const
Unexecuted instantiation: mozilla::WebGLFramebuffer::ColorDrawBuffers() const
Unexecuted instantiation: mozilla::WebGLFramebuffer::ColorReadBuffer() const
Unexecuted instantiation: mozilla::WebGLFramebuffer::ResolvedCompleteData() const
251
252
    GETTER(DepthAttachment)
253
    GETTER(StencilAttachment)
254
    GETTER(DepthStencilAttachment)
255
    GETTER(ColorDrawBuffers)
256
    GETTER(ColorReadBuffer)
257
    GETTER(ResolvedCompleteData)
258
259
#undef GETTER
260
261
0
    const auto& ColorAttachment0() const {
262
0
        return mColorAttachments[0];
263
0
    }
264
265
0
    const auto& AnyDepthAttachment() const {
266
0
        if (mDepthStencilAttachment.IsDefined())
267
0
            return mDepthStencilAttachment;
268
0
        return mDepthAttachment;
269
0
    }
270
271
0
    const auto& AnyStencilAttachment() const {
272
0
        if (mDepthStencilAttachment.IsDefined())
273
0
            return mDepthStencilAttachment;
274
0
        return mStencilAttachment;
275
0
    }
276
277
    ////////////////
278
    // Invalidation
279
280
0
    bool IsResolvedComplete() const { return bool(mResolvedCompleteData); }
281
    void InvalidateFramebufferStatus();
282
    void RefreshResolvedData();
283
284
    ////////////////
285
    // WebGL funcs
286
287
0
    bool IsCheckFramebufferStatusComplete() const {
288
0
        return CheckFramebufferStatus() == LOCAL_GL_FRAMEBUFFER_COMPLETE;
289
0
    }
290
291
    FBStatus CheckFramebufferStatus() const;
292
    void FramebufferRenderbuffer(GLenum attachment, GLenum rbtarget,
293
                                 WebGLRenderbuffer* rb);
294
    void FramebufferTexture2D(GLenum attachment,
295
                              GLenum texImageTarget, WebGLTexture* tex, GLint level);
296
    void FramebufferTextureLayer(GLenum attachment,
297
                                 WebGLTexture* tex, GLint level, GLint layer);
298
    void DrawBuffers(const dom::Sequence<GLenum>& buffers);
299
    void ReadBuffer(GLenum attachPoint);
300
301
    JS::Value GetAttachmentParameter(JSContext* cx, GLenum target,
302
                                     GLenum attachment, GLenum pname,
303
                                     ErrorResult* const out_error);
304
305
    static void BlitFramebuffer(WebGLContext* webgl,
306
                                GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
307
                                GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
308
                                GLbitfield mask, GLenum filter);
309
};
310
311
} // namespace mozilla
312
313
#endif // WEBGL_FRAMEBUFFER_H_