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