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_
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"
22 class WebGLFramebuffer
;
23 class WebGLRenderbuffer
;
35 struct FbAttachInfo final
{
36 WebGLRenderbuffer
* rb
= nullptr;
37 WebGLTexture
* tex
= nullptr;
38 uint32_t mipLevel
= 0;
40 uint32_t zLayerCount
= 1;
41 bool isMultiview
= false;
45 class WebGLFBAttachPoint final
{
46 friend class WebGLFramebuffer
;
49 const GLenum mAttachmentPoint
= 0;
50 const bool mDeferAttachment
= false;
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;
63 explicit WebGLFBAttachPoint(WebGLFBAttachPoint
&); // Make this private.
64 WebGLFBAttachPoint(const WebGLContext
* webgl
, GLenum attachmentPoint
);
67 ~WebGLFBAttachPoint();
71 bool HasAttachment() const {
72 return bool(mTexturePtr
) || bool(mRenderbufferPtr
);
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 {};
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
,
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
));
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
)
138 class WebGLFramebuffer final
: public WebGLContextBoundObject
,
139 public SupportsWeakPtr
,
140 public CacheInvalidator
{
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
;
153 mutable uint64_t mNumFBStatusInvals
= 0;
158 WebGLFBAttachPoint mDepthAttachment
;
159 WebGLFBAttachPoint mStencilAttachment
;
160 WebGLFBAttachPoint mDepthStencilAttachment
;
162 std::array
<WebGLFBAttachPoint
, webgl::kMaxDrawBuffers
> mColorAttachments
= {};
163 std::bitset
<webgl::kMaxDrawBuffers
> mDrawBufferEnabled
= {1};
166 std::vector
<WebGLFBAttachPoint
*> mAttachments
; // Non-null.
168 std::vector
<const WebGLFBAttachPoint
*> mColorDrawBuffers
; // Non-null
169 const WebGLFBAttachPoint
* mColorReadBuffer
; // Null if NONE
173 struct CompletenessInfo final
{
174 const WebGLFramebuffer
* fb
= nullptr;
178 std::bitset
<webgl::kMaxDrawBuffers
> hasAttachment
= 0;
179 std::bitset
<webgl::kMaxDrawBuffers
> isAttachmentF32
= 0;
180 uint8_t zLayerCount
= 1;
181 bool isMultiview
= false;
184 std::vector
<const WebGLFBAttachPoint
*> texAttachments
; // Non-null
188 friend struct CompletenessInfo
;
190 mutable CacheMaybe
<const CompletenessInfo
> mCompletenessInfo
;
195 WebGLFramebuffer(WebGLContext
* webgl
, GLuint fbo
);
196 WebGLFramebuffer(WebGLContext
* webgl
, UniquePtr
<gl::MozFramebuffer
> fbo
);
197 ~WebGLFramebuffer() override
;
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;
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;
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;
231 const decltype(m##X)& X() const { return m##X; }
233 GETTER(DepthAttachment
)
234 GETTER(StencilAttachment
)
235 GETTER(DepthStencilAttachment
)
237 GETTER(ColorDrawBuffers
)
238 GETTER(ColorReadBuffer
)
242 const auto& ColorAttachment0() const { return mColorAttachments
[0]; }
243 const auto& DrawBufferEnabled() const { return mDrawBufferEnabled
; }
248 const auto* GetCompletenessInfo() const { return mCompletenessInfo
.get(); }
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_