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_
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"
21 class WebGLFramebuffer
;
22 class WebGLRenderbuffer
;
34 struct FbAttachInfo final
{
35 WebGLRenderbuffer
* rb
= nullptr;
36 WebGLTexture
* tex
= nullptr;
37 uint32_t mipLevel
= 0;
39 uint32_t zLayerCount
= 1;
40 bool isMultiview
= false;
44 class WebGLFBAttachPoint final
{
45 friend class WebGLFramebuffer
;
48 const GLenum mAttachmentPoint
= 0;
49 const bool mDeferAttachment
= false;
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;
62 explicit WebGLFBAttachPoint(WebGLFBAttachPoint
&); // Make this private.
63 WebGLFBAttachPoint(const WebGLContext
* webgl
, GLenum attachmentPoint
);
66 ~WebGLFBAttachPoint();
70 bool HasAttachment() const {
71 return bool(mTexturePtr
) | bool(mRenderbufferPtr
);
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
,
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
));
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
)
131 class WebGLFramebuffer final
: public WebGLContextBoundObject
,
132 public SupportsWeakPtr
,
133 public CacheInvalidator
{
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;
144 mutable uint64_t mNumFBStatusInvals
= 0;
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
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
];
163 std::vector
<WebGLFBAttachPoint
*> mAttachments
; // Non-null.
165 std::vector
<const WebGLFBAttachPoint
*> mColorDrawBuffers
; // Non-null
166 const WebGLFBAttachPoint
* mColorReadBuffer
; // Null if NONE
170 struct CompletenessInfo final
{
171 const WebGLFramebuffer
* fb
= nullptr;
175 bool hasFloat32
= false;
176 uint8_t zLayerCount
= 1;
177 bool isMultiview
= false;
180 std::vector
<const WebGLFBAttachPoint
*> texAttachments
; // Non-null
184 friend struct CompletenessInfo
;
186 mutable CacheMaybe
<const CompletenessInfo
> mCompletenessInfo
;
191 WebGLFramebuffer(WebGLContext
* webgl
, GLuint fbo
);
192 WebGLFramebuffer(WebGLContext
* webgl
, UniquePtr
<gl::MozFramebuffer
> fbo
);
193 ~WebGLFramebuffer() override
;
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;
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;
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;
227 const decltype(m##X)& X() const { return m##X; }
229 GETTER(DepthAttachment
)
230 GETTER(StencilAttachment
)
231 GETTER(DepthStencilAttachment
)
233 GETTER(ColorDrawBuffers
)
234 GETTER(ColorReadBuffer
)
238 const auto& ColorAttachment0() const { return mColorAttachments
[0]; }
239 bool IsDrawBufferEnabled(uint32_t slotId
) const;
244 const auto* GetCompletenessInfo() const { return mCompletenessInfo
.get(); }
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_