Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / canvas / WebGLFramebuffer.h
blobbeab87d7afd5a1a49a9a5278b8cd6db7b7703822
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 <bitset>
10 #include <vector>
12 #include "mozilla/WeakPtr.h"
14 #include "GLScreenBuffer.h"
15 #include "WebGLObjectModel.h"
16 #include "WebGLStrongTypes.h"
17 #include "WebGLTexture.h"
18 #include "WebGLTypes.h"
20 namespace mozilla {
22 class WebGLFramebuffer;
23 class WebGLRenderbuffer;
24 class WebGLTexture;
26 template <typename T>
27 class PlacementArray;
29 namespace gl {
30 class GLContext;
31 class MozFramebuffer;
32 } // namespace gl
34 namespace webgl {
35 struct FbAttachInfo final {
36 WebGLRenderbuffer* rb = nullptr;
37 WebGLTexture* tex = nullptr;
38 uint32_t mipLevel = 0;
39 uint32_t zLayer = 0;
40 uint32_t zLayerCount = 1;
41 bool isMultiview = false;
43 } // namespace webgl
45 class WebGLFBAttachPoint final {
46 friend class WebGLFramebuffer;
48 public:
49 const GLenum mAttachmentPoint = 0;
50 const bool mDeferAttachment = false;
52 private:
53 RefPtr<WebGLTexture> mTexturePtr;
54 RefPtr<WebGLRenderbuffer> mRenderbufferPtr;
55 uint32_t mTexImageLayer = 0;
56 uint8_t mTexImageZLayerCount = 1;
57 uint8_t mTexImageLevel = 0;
58 bool mIsMultiview = false;
60 ////
62 WebGLFBAttachPoint();
63 explicit WebGLFBAttachPoint(WebGLFBAttachPoint&); // Make this private.
64 WebGLFBAttachPoint(const WebGLContext* webgl, GLenum attachmentPoint);
66 public:
67 ~WebGLFBAttachPoint();
69 ////
71 bool HasAttachment() const {
72 return bool(mTexturePtr) || bool(mRenderbufferPtr);
75 void Clear();
77 void Set(gl::GLContext* gl, const webgl::FbAttachInfo&);
79 WebGLTexture* Texture() const { return mTexturePtr; }
80 WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
82 Maybe<size_t> ColorAttachmentId() const {
83 const size_t id = mAttachmentPoint - LOCAL_GL_COLOR_ATTACHMENT0;
84 if (id >= webgl::kMaxDrawBuffers) return {};
85 return Some(id);
88 auto Layer() const { return mTexImageLayer; }
89 auto ZLayerCount() const { return mTexImageZLayerCount; }
90 auto MipLevel() const { return mTexImageLevel; }
91 const auto& IsMultiview() const { return mIsMultiview; }
93 void AttachmentName(nsCString* out) const;
95 const webgl::ImageInfo* GetImageInfo() const;
97 bool IsComplete(WebGLContext* webgl, nsCString* const out_info) const;
99 void DoAttachment(gl::GLContext* gl) const;
101 Maybe<double> GetParameter(WebGLContext* webgl, GLenum attachment,
102 GLenum pname) const;
104 bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
105 if (!HasAttachment() || !other.HasAttachment()) return false;
107 #define _(X) (X == other.X)
108 return (_(mRenderbufferPtr) && _(mTexturePtr) && _(mTexImageLevel) &&
109 _(mTexImageLayer) && _(mTexImageZLayerCount));
110 #undef _
113 ////
115 struct Ordered {
116 const WebGLFBAttachPoint& mRef;
118 explicit Ordered(const WebGLFBAttachPoint& ref) : mRef(ref) {}
120 bool operator<(const Ordered& other) const {
121 MOZ_ASSERT(mRef.HasAttachment() && other.mRef.HasAttachment());
123 #define ORDER_BY(X) \
124 if (X != other.X) return X < other.X;
126 ORDER_BY(mRef.mRenderbufferPtr)
127 ORDER_BY(mRef.mTexturePtr)
128 ORDER_BY(mRef.mTexImageLevel)
129 ORDER_BY(mRef.mTexImageLayer)
130 ORDER_BY(mRef.mTexImageZLayerCount)
132 #undef ORDER_BY
133 return false;
138 class WebGLFramebuffer final : public WebGLContextBoundObject,
139 public SupportsWeakPtr,
140 public CacheInvalidator {
141 public:
142 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLFramebuffer, override)
144 const GLuint mGLName;
145 bool mHasBeenBound = false;
146 const UniquePtr<gl::MozFramebuffer> mOpaque;
147 bool mInOpaqueRAF = false;
148 // Swap chain that may be used to present this framebuffer, for opaque
149 // framebuffers or other use cases. (e.g. DrawTargetWebgl)
150 gl::SwapChain mSwapChain;
152 private:
153 mutable uint64_t mNumFBStatusInvals = 0;
155 ////
157 protected:
158 WebGLFBAttachPoint mDepthAttachment;
159 WebGLFBAttachPoint mStencilAttachment;
160 WebGLFBAttachPoint mDepthStencilAttachment;
162 std::array<WebGLFBAttachPoint, webgl::kMaxDrawBuffers> mColorAttachments = {};
163 std::bitset<webgl::kMaxDrawBuffers> mDrawBufferEnabled = {1};
164 ////
166 std::vector<WebGLFBAttachPoint*> mAttachments; // Non-null.
168 std::vector<const WebGLFBAttachPoint*> mColorDrawBuffers; // Non-null
169 const WebGLFBAttachPoint* mColorReadBuffer; // Null if NONE
171 ////
173 struct CompletenessInfo final {
174 const WebGLFramebuffer* fb = nullptr;
176 uint32_t width = 0;
177 uint32_t height = 0;
178 std::bitset<webgl::kMaxDrawBuffers> hasAttachment = 0;
179 std::bitset<webgl::kMaxDrawBuffers> isAttachmentF32 = 0;
180 uint8_t zLayerCount = 1;
181 bool isMultiview = false;
183 // IsFeedback
184 std::vector<const WebGLFBAttachPoint*> texAttachments; // Non-null
186 ~CompletenessInfo();
188 friend struct CompletenessInfo;
190 mutable CacheMaybe<const CompletenessInfo> mCompletenessInfo;
192 ////
194 public:
195 WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
196 WebGLFramebuffer(WebGLContext* webgl, UniquePtr<gl::MozFramebuffer> fbo);
197 ~WebGLFramebuffer() override;
199 ////
201 bool HasDuplicateAttachments() const;
202 bool HasDefinedAttachments() const;
203 bool HasIncompleteAttachments(nsCString* const out_info) const;
204 bool AllImageRectsMatch() const;
205 bool AllImageSamplesMatch() const;
206 FBStatus PrecheckFramebufferStatus(nsCString* const out_info) const;
208 protected:
209 Maybe<WebGLFBAttachPoint*> GetAttachPoint(GLenum attachment); // Fallible
210 Maybe<WebGLFBAttachPoint*> GetColorAttachPoint(
211 GLenum attachment); // Fallible
212 void DoDeferredAttachments() const;
213 void RefreshDrawBuffers() const;
214 void RefreshReadBuffer() const;
215 void ResolveAttachmentData() const;
217 public:
218 void DetachTexture(const WebGLTexture* tex);
219 void DetachRenderbuffer(const WebGLRenderbuffer* rb);
220 bool ValidateAndInitAttachments(GLenum incompleteFbError) const;
221 bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
222 webgl::AttribBaseType funcType) const;
224 bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
225 uint32_t* out_width, uint32_t* out_height) const;
227 ////////////////
228 // Getters
230 #define GETTER(X) \
231 const decltype(m##X)& X() const { return m##X; }
233 GETTER(DepthAttachment)
234 GETTER(StencilAttachment)
235 GETTER(DepthStencilAttachment)
236 GETTER(Attachments)
237 GETTER(ColorDrawBuffers)
238 GETTER(ColorReadBuffer)
240 #undef GETTER
242 const auto& ColorAttachment0() const { return mColorAttachments[0]; }
243 const auto& DrawBufferEnabled() const { return mDrawBufferEnabled; }
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 bool FramebufferAttach(GLenum attachEnum,
259 const webgl::FbAttachInfo& toAttach);
260 void DrawBuffers(const std::vector<GLenum>& buffers);
261 void ReadBuffer(GLenum attachPoint);
263 Maybe<double> GetAttachmentParameter(GLenum attachment, GLenum pname);
265 static void BlitFramebuffer(WebGLContext* webgl, GLint srcX0, GLint srcY0,
266 GLint srcX1, GLint srcY1, GLint dstX0,
267 GLint dstY0, GLint dstX1, GLint dstY1,
268 GLbitfield mask, GLenum filter);
271 } // namespace mozilla
273 #endif // WEBGL_FRAMEBUFFER_H_