Bug 1521243 - Show a warning for invalid declarations and filter icon for overridden...
[gecko.git] / dom / canvas / WebGLFramebuffer.h
blob7d9c928164bece2df9d49749248ed40476a43870
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 #ifndef WEBGL_FRAMEBUFFER_H_
7 #define WEBGL_FRAMEBUFFER_H_
9 #include <vector>
11 #include "mozilla/LinkedList.h"
12 #include "mozilla/WeakPtr.h"
13 #include "nsWrapperCache.h"
15 #include "WebGLObjectModel.h"
16 #include "WebGLRenderbuffer.h"
17 #include "WebGLStrongTypes.h"
18 #include "WebGLTexture.h"
19 #include "WebGLTypes.h"
21 namespace mozilla {
23 class WebGLFramebuffer;
24 class WebGLRenderbuffer;
25 class WebGLTexture;
27 template <typename T>
28 class PlacementArray;
30 namespace gl {
31 class GLContext;
32 } // namespace gl
34 class WebGLFBAttachPoint final {
35 friend class WebGLFramebuffer;
37 public:
38 const GLenum mAttachmentPoint = 0;
39 const bool mDeferAttachment = false;
41 private:
42 WebGLRefPtr<WebGLTexture> mTexturePtr;
43 WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
44 TexImageTarget mTexImageTarget = 0;
45 GLint mTexImageLayer = 0;
46 uint32_t mTexImageLevel = 0;
48 ////
50 WebGLFBAttachPoint() = default;
51 WebGLFBAttachPoint(const WebGLContext* webgl, GLenum attachmentPoint);
53 explicit WebGLFBAttachPoint(WebGLFBAttachPoint&) =
54 default; // Make this private.
56 public:
57 ~WebGLFBAttachPoint();
59 ////
61 void Unlink() { Clear(); }
63 bool HasAttachment() const {
64 return bool(mTexturePtr) | bool(mRenderbufferPtr);
66 bool IsDeleteRequested() const;
68 void Clear();
70 void SetTexImage(gl::GLContext* gl, WebGLTexture* tex, TexImageTarget target,
71 GLint level, GLint layer = 0);
72 void SetRenderbuffer(gl::GLContext* gl, WebGLRenderbuffer* rb);
74 WebGLTexture* Texture() const { return mTexturePtr; }
75 WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
77 TexImageTarget ImageTarget() const { return mTexImageTarget; }
78 GLint Layer() const { return mTexImageLayer; }
79 uint32_t MipLevel() const { return mTexImageLevel; }
80 void AttachmentName(nsCString* out) const;
82 const webgl::ImageInfo* GetImageInfo() const;
84 bool IsComplete(WebGLContext* webgl, nsCString* const out_info) const;
86 void DoAttachment(gl::GLContext* gl) const;
88 JS::Value GetParameter(WebGLContext* webgl, JSContext* cx, GLenum target,
89 GLenum attachment, GLenum pname,
90 ErrorResult* const out_error) const;
92 bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
93 if (!HasAttachment() | !other.HasAttachment()) return false;
95 #define _(X) (X == other.X)
96 return (_(mRenderbufferPtr) & _(mTexturePtr) & _(mTexImageTarget.get()) &
97 _(mTexImageLevel) & _(mTexImageLayer));
98 #undef _
101 ////
103 struct Ordered {
104 const WebGLFBAttachPoint& mRef;
106 explicit Ordered(const WebGLFBAttachPoint& ref) : mRef(ref) {}
108 bool operator<(const Ordered& other) const {
109 MOZ_ASSERT(mRef.HasAttachment() && other.mRef.HasAttachment());
111 #define ORDER_BY(X) \
112 if (X != other.X) return X < other.X;
114 ORDER_BY(mRef.mRenderbufferPtr)
115 ORDER_BY(mRef.mTexturePtr)
116 ORDER_BY(mRef.mTexImageTarget.get())
117 ORDER_BY(mRef.mTexImageLevel)
118 ORDER_BY(mRef.mTexImageLayer)
120 #undef ORDER_BY
121 return false;
126 class WebGLFramebuffer final : public nsWrapperCache,
127 public WebGLRefCountedObject<WebGLFramebuffer>,
128 public LinkedListElement<WebGLFramebuffer>,
129 public SupportsWeakPtr<WebGLFramebuffer>,
130 public CacheInvalidator {
131 public:
132 MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
134 const GLuint mGLName;
135 bool mHasBeenBound = false;
137 private:
138 mutable uint64_t mNumFBStatusInvals = 0;
140 ////
142 protected:
143 WebGLFBAttachPoint mDepthAttachment;
144 WebGLFBAttachPoint mStencilAttachment;
145 WebGLFBAttachPoint mDepthStencilAttachment;
147 // In theory, this number can be unbounded based on the driver. However, no
148 // driver appears to expose more than 8. We might as well stop there too, for
149 // now.
150 // (http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COLOR_ATTACHMENTS)
151 static const size_t kMaxColorAttachments =
152 8; // jgilbert's MacBook Pro exposes 8.
153 WebGLFBAttachPoint mColorAttachments[kMaxColorAttachments];
155 ////
157 std::vector<WebGLFBAttachPoint*> mAttachments; // Non-null.
159 std::vector<const WebGLFBAttachPoint*> mColorDrawBuffers; // Non-null
160 const WebGLFBAttachPoint* mColorReadBuffer; // Null if NONE
162 ////
164 struct CompletenessInfo final {
165 const WebGLFramebuffer& fb;
167 uint32_t width = 0;
168 uint32_t height = 0;
170 // IsFeedback
171 std::vector<const WebGLFBAttachPoint*> texAttachments; // Non-null
173 ~CompletenessInfo();
175 friend struct CompletenessInfo;
177 mutable CacheMaybe<const CompletenessInfo> mCompletenessInfo;
179 ////
181 public:
182 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
183 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
185 WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
187 WebGLContext* GetParentObject() const { return mContext; }
188 virtual JSObject* WrapObject(JSContext* cx,
189 JS::Handle<JSObject*> givenProto) override;
191 private:
192 ~WebGLFramebuffer() {
193 DeleteOnce();
194 InvalidateCaches();
197 public:
198 void Delete();
200 ////
202 bool HasDuplicateAttachments() const;
203 bool HasDefinedAttachments() const;
204 bool HasIncompleteAttachments(nsCString* const out_info) const;
205 bool AllImageRectsMatch() const;
206 bool AllImageSamplesMatch() const;
207 FBStatus PrecheckFramebufferStatus(nsCString* const out_info) const;
209 protected:
210 Maybe<WebGLFBAttachPoint*> GetAttachPoint(GLenum attachment); // Fallible
211 Maybe<WebGLFBAttachPoint*> GetColorAttachPoint(
212 GLenum attachment); // Fallible
213 void DoDeferredAttachments() const;
214 void RefreshDrawBuffers() const;
215 void RefreshReadBuffer() const;
216 void ResolveAttachmentData() const;
218 public:
219 void DetachTexture(const WebGLTexture* tex);
220 void DetachRenderbuffer(const WebGLRenderbuffer* rb);
221 bool ValidateAndInitAttachments() const;
222 bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
223 GLenum funcType) const;
225 bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
226 uint32_t* out_width, uint32_t* out_height) const;
228 ////////////////
229 // Getters
231 #define GETTER(X) \
232 const decltype(m##X)& X() const { return m##X; }
234 GETTER(DepthAttachment)
235 GETTER(StencilAttachment)
236 GETTER(DepthStencilAttachment)
237 GETTER(Attachments)
238 GETTER(ColorDrawBuffers)
239 GETTER(ColorReadBuffer)
241 #undef GETTER
243 const auto& ColorAttachment0() const { return mColorAttachments[0]; }
245 ////////////////
246 // Invalidation
248 const auto* GetCompletenessInfo() const { return mCompletenessInfo.get(); }
250 ////////////////
251 // WebGL funcs
253 bool IsCheckFramebufferStatusComplete() const {
254 return CheckFramebufferStatus() == LOCAL_GL_FRAMEBUFFER_COMPLETE;
257 FBStatus CheckFramebufferStatus() const;
258 void FramebufferRenderbuffer(GLenum attachment, GLenum rbtarget,
259 WebGLRenderbuffer* rb);
260 void FramebufferTexture2D(GLenum attachment, GLenum texImageTarget,
261 WebGLTexture* tex, GLint level);
262 void FramebufferTextureLayer(GLenum attachment, WebGLTexture* tex,
263 GLint level, GLint layer);
264 void DrawBuffers(const dom::Sequence<GLenum>& buffers);
265 void ReadBuffer(GLenum attachPoint);
267 JS::Value GetAttachmentParameter(JSContext* cx, GLenum target,
268 GLenum attachment, GLenum pname,
269 ErrorResult* const out_error);
271 static void BlitFramebuffer(WebGLContext* webgl, GLint srcX0, GLint srcY0,
272 GLint srcX1, GLint srcY1, GLint dstX0,
273 GLint dstY0, GLint dstX1, GLint dstY1,
274 GLbitfield mask, GLenum filter);
277 } // namespace mozilla
279 #endif // WEBGL_FRAMEBUFFER_H_