Bug 1685822 [wpt PR 27117] - [Import Maps] Add tests for rejecting multiple import...
[gecko.git] / dom / canvas / WebGLFramebuffer.h
blob9928198a646da9fa68396340f8abcd2b7819c56a
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/WeakPtr.h"
13 #include "GLScreenBuffer.h"
14 #include "WebGLObjectModel.h"
15 #include "WebGLStrongTypes.h"
16 #include "WebGLTexture.h"
17 #include "WebGLTypes.h"
19 namespace mozilla {
21 class WebGLFramebuffer;
22 class WebGLRenderbuffer;
23 class WebGLTexture;
25 template <typename T>
26 class PlacementArray;
28 namespace gl {
29 class GLContext;
30 class MozFramebuffer;
31 } // namespace gl
33 namespace webgl {
34 struct FbAttachInfo final {
35 WebGLRenderbuffer* rb = nullptr;
36 WebGLTexture* tex = nullptr;
37 uint32_t mipLevel = 0;
38 uint32_t zLayer = 0;
39 uint32_t zLayerCount = 1;
40 bool isMultiview = false;
42 } // namespace webgl
44 class WebGLFBAttachPoint final {
45 friend class WebGLFramebuffer;
47 public:
48 const GLenum mAttachmentPoint = 0;
49 const bool mDeferAttachment = false;
51 private:
52 RefPtr<WebGLTexture> mTexturePtr;
53 RefPtr<WebGLRenderbuffer> mRenderbufferPtr;
54 uint32_t mTexImageLayer = 0;
55 uint8_t mTexImageZLayerCount = 1;
56 uint8_t mTexImageLevel = 0;
57 bool mIsMultiview = false;
59 ////
61 WebGLFBAttachPoint();
62 explicit WebGLFBAttachPoint(WebGLFBAttachPoint&); // Make this private.
63 WebGLFBAttachPoint(const WebGLContext* webgl, GLenum attachmentPoint);
65 public:
66 ~WebGLFBAttachPoint();
68 ////
70 bool HasAttachment() const {
71 return bool(mTexturePtr) | bool(mRenderbufferPtr);
74 void Clear();
76 void Set(gl::GLContext* gl, const webgl::FbAttachInfo&);
78 WebGLTexture* Texture() const { return mTexturePtr; }
79 WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
81 auto Layer() const { return mTexImageLayer; }
82 auto ZLayerCount() const { return mTexImageZLayerCount; }
83 auto MipLevel() const { return mTexImageLevel; }
84 const auto& IsMultiview() const { return mIsMultiview; }
86 void AttachmentName(nsCString* out) const;
88 const webgl::ImageInfo* GetImageInfo() const;
90 bool IsComplete(WebGLContext* webgl, nsCString* const out_info) const;
92 void DoAttachment(gl::GLContext* gl) const;
94 Maybe<double> GetParameter(WebGLContext* webgl, GLenum attachment,
95 GLenum pname) const;
97 bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
98 if (!HasAttachment() | !other.HasAttachment()) return false;
100 #define _(X) (X == other.X)
101 return (_(mRenderbufferPtr) && _(mTexturePtr) && _(mTexImageLevel) &&
102 _(mTexImageLayer) && _(mTexImageZLayerCount));
103 #undef _
106 ////
108 struct Ordered {
109 const WebGLFBAttachPoint& mRef;
111 explicit Ordered(const WebGLFBAttachPoint& ref) : mRef(ref) {}
113 bool operator<(const Ordered& other) const {
114 MOZ_ASSERT(mRef.HasAttachment() && other.mRef.HasAttachment());
116 #define ORDER_BY(X) \
117 if (X != other.X) return X < other.X;
119 ORDER_BY(mRef.mRenderbufferPtr)
120 ORDER_BY(mRef.mTexturePtr)
121 ORDER_BY(mRef.mTexImageLevel)
122 ORDER_BY(mRef.mTexImageLayer)
123 ORDER_BY(mRef.mTexImageZLayerCount)
125 #undef ORDER_BY
126 return false;
131 class WebGLFramebuffer final : public WebGLContextBoundObject,
132 public SupportsWeakPtr,
133 public CacheInvalidator {
134 public:
135 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLFramebuffer, override)
137 const GLuint mGLName;
138 bool mHasBeenBound = false;
139 const UniquePtr<gl::MozFramebuffer> mOpaque;
140 gl::SwapChain mOpaqueSwapChain;
141 bool mInOpaqueRAF = false;
143 private:
144 mutable uint64_t mNumFBStatusInvals = 0;
146 ////
148 protected:
149 WebGLFBAttachPoint mDepthAttachment;
150 WebGLFBAttachPoint mStencilAttachment;
151 WebGLFBAttachPoint mDepthStencilAttachment;
153 // In theory, this number can be unbounded based on the driver. However, no
154 // driver appears to expose more than 8. We might as well stop there too, for
155 // now.
156 // (http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COLOR_ATTACHMENTS)
157 static const size_t kMaxColorAttachments =
158 8; // jgilbert's MacBook Pro exposes 8.
159 WebGLFBAttachPoint mColorAttachments[kMaxColorAttachments];
161 ////
163 std::vector<WebGLFBAttachPoint*> mAttachments; // Non-null.
165 std::vector<const WebGLFBAttachPoint*> mColorDrawBuffers; // Non-null
166 const WebGLFBAttachPoint* mColorReadBuffer; // Null if NONE
168 ////
170 struct CompletenessInfo final {
171 const WebGLFramebuffer* fb = nullptr;
173 uint32_t width = 0;
174 uint32_t height = 0;
175 bool hasFloat32 = false;
176 uint8_t zLayerCount = 1;
177 bool isMultiview = false;
179 // IsFeedback
180 std::vector<const WebGLFBAttachPoint*> texAttachments; // Non-null
182 ~CompletenessInfo();
184 friend struct CompletenessInfo;
186 mutable CacheMaybe<const CompletenessInfo> mCompletenessInfo;
188 ////
190 public:
191 WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
192 WebGLFramebuffer(WebGLContext* webgl, UniquePtr<gl::MozFramebuffer> fbo);
193 ~WebGLFramebuffer() override;
195 ////
197 bool HasDuplicateAttachments() const;
198 bool HasDefinedAttachments() const;
199 bool HasIncompleteAttachments(nsCString* const out_info) const;
200 bool AllImageRectsMatch() const;
201 bool AllImageSamplesMatch() const;
202 FBStatus PrecheckFramebufferStatus(nsCString* const out_info) const;
204 protected:
205 Maybe<WebGLFBAttachPoint*> GetAttachPoint(GLenum attachment); // Fallible
206 Maybe<WebGLFBAttachPoint*> GetColorAttachPoint(
207 GLenum attachment); // Fallible
208 void DoDeferredAttachments() const;
209 void RefreshDrawBuffers() const;
210 void RefreshReadBuffer() const;
211 void ResolveAttachmentData() const;
213 public:
214 void DetachTexture(const WebGLTexture* tex);
215 void DetachRenderbuffer(const WebGLRenderbuffer* rb);
216 bool ValidateAndInitAttachments(GLenum incompleteFbError) const;
217 bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
218 webgl::AttribBaseType funcType) const;
220 bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
221 uint32_t* out_width, uint32_t* out_height) const;
223 ////////////////
224 // Getters
226 #define GETTER(X) \
227 const decltype(m##X)& X() const { return m##X; }
229 GETTER(DepthAttachment)
230 GETTER(StencilAttachment)
231 GETTER(DepthStencilAttachment)
232 GETTER(Attachments)
233 GETTER(ColorDrawBuffers)
234 GETTER(ColorReadBuffer)
236 #undef GETTER
238 const auto& ColorAttachment0() const { return mColorAttachments[0]; }
239 bool IsDrawBufferEnabled(uint32_t slotId) const;
241 ////////////////
242 // Invalidation
244 const auto* GetCompletenessInfo() const { return mCompletenessInfo.get(); }
246 ////////////////
247 // WebGL funcs
249 bool IsCheckFramebufferStatusComplete() const {
250 return CheckFramebufferStatus() == LOCAL_GL_FRAMEBUFFER_COMPLETE;
253 FBStatus CheckFramebufferStatus() const;
254 bool FramebufferAttach(GLenum attachEnum,
255 const webgl::FbAttachInfo& toAttach);
256 void DrawBuffers(const std::vector<GLenum>& buffers);
257 void ReadBuffer(GLenum attachPoint);
259 Maybe<double> GetAttachmentParameter(GLenum attachment, GLenum pname);
261 static void BlitFramebuffer(WebGLContext* webgl, GLint srcX0, GLint srcY0,
262 GLint srcX1, GLint srcY1, GLint dstX0,
263 GLint dstY0, GLint dstX1, GLint dstY1,
264 GLbitfield mask, GLenum filter);
267 } // namespace mozilla
269 #endif // WEBGL_FRAMEBUFFER_H_