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 WEBGLCONTEXT_H_
7 #define WEBGLCONTEXT_H_
13 #include "Colorspaces.h"
14 #include "GLContextTypes.h"
16 #include "GLScreenBuffer.h"
17 #include "js/ScalarType.h" // js::Scalar::Type
18 #include "mozilla/Attributes.h"
19 #include "mozilla/Atomics.h"
20 #include "mozilla/CheckedInt.h"
21 #include "mozilla/dom/ipc/IdType.h"
22 #include "mozilla/dom/BindingDeclarations.h"
23 #include "mozilla/dom/HTMLCanvasElement.h"
24 #include "mozilla/dom/Nullable.h"
25 #include "mozilla/dom/TypedArray.h"
26 #include "mozilla/EnumeratedArray.h"
27 #include "mozilla/gfx/2D.h"
28 #include "mozilla/Mutex.h"
29 #include "mozilla/StaticMutex.h"
30 #include "mozilla/StaticPrefs_webgl.h"
31 #include "mozilla/WeakPtr.h"
32 #include "nsICanvasRenderingContextInternal.h"
34 #include "SurfaceTypes.h"
35 #include "ScopedGLHelpers.h"
36 #include "TexUnpackBlob.h"
39 #include "CacheInvalidator.h"
40 #include "WebGLContextLossHandler.h"
41 #include "WebGLExtensions.h"
42 #include "WebGLObjectModel.h"
43 #include "WebGLStrongTypes.h"
44 #include "WebGLTypes.h"
47 #include "mozilla/dom/WebGLRenderingContextBinding.h"
48 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
56 #define LOCAL_GL_BROWSER_DEFAULT_WEBGL 0x9244
57 #define LOCAL_GL_CONTEXT_LOST_WEBGL 0x9242
58 #define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL 0x9247
59 #define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243
60 #define LOCAL_GL_UNPACK_FLIP_Y_WEBGL 0x9240
61 #define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
65 class HostWebGLContext
;
66 class ScopedCopyTexImageSource
;
67 class ScopedDrawCallWrapper
;
68 class ScopedResolveTexturesForDraw
;
70 class WebGLExtensionBase
;
71 class WebGLFramebuffer
;
74 class WebGLRenderbuffer
;
79 class WebGLTransformFeedback
;
80 class WebGLVertexArray
;
86 class OwningHTMLCanvasElementOrOffscreenCanvas
;
87 struct WebGLContextAttributes
;
104 class CompositableHost
;
105 class RemoteTextureOwnerClient
;
106 class SharedSurfacesHolder
;
107 class SurfaceDescriptor
;
108 } // namespace layers
111 class AvailabilityRunnable
;
112 struct CachedDrawFetchLimits
;
115 class FormatUsageAuthority
;
116 struct FormatUsageInfo
;
118 struct LinkedProgramInfo
;
119 struct SamplerUniformInfo
;
120 struct SamplingState
;
121 class ScopedPrepForResourceClear
;
122 class ShaderValidator
;
125 struct UniformBlockInfo
;
126 struct VertAttribPointerDesc
;
129 struct WebGLTexImageData
{
130 TexImageTarget mTarget
;
135 gfxAlphaType mSrcAlphaType
;
138 struct WebGLTexPboOffset
{
139 TexImageTarget mTarget
;
143 WebGLsizeiptr mPboOffset
;
144 bool mHasExpectedImageSize
;
145 GLsizei mExpectedImageSize
;
148 WebGLTexelFormat
GetWebGLTexelFormat(TexInternalFormat format
);
150 void AssertUintParamCorrect(gl::GLContext
* gl
, GLenum pname
, GLuint shadow
);
152 // From WebGLContextUtils
153 TexTarget
TexImageTargetToTexTarget(TexImageTarget texImageTarget
);
155 struct WebGLIntOrFloat
{
156 const enum { Int
, Float
, Uint
} mType
;
164 explicit WebGLIntOrFloat(GLint i
) : mType(Int
) { mValue
.i
= i
; }
165 explicit WebGLIntOrFloat(GLfloat f
) : mType(Float
) { mValue
.f
= f
; }
167 GLint
AsInt() const {
168 return (mType
== Int
) ? mValue
.i
: NS_lroundf(mValue
.f
);
170 GLfloat
AsFloat() const {
171 return (mType
== Float
) ? mValue
.f
: GLfloat(mValue
.i
);
175 ////////////////////////////////////
179 class AvailabilityRunnable final
: public DiscardableRunnable
{
181 const WeakPtr
<const ClientWebGLContext
> mWebGL
;
182 std::vector
<WeakPtr
<WebGLQueryJS
>> mQueries
;
183 std::vector
<WeakPtr
<WebGLSyncJS
>> mSyncs
;
185 explicit AvailabilityRunnable(const ClientWebGLContext
* webgl
);
186 ~AvailabilityRunnable();
188 NS_IMETHOD
Run() override
;
193 ////////////////////////////////////////////////////////////////////////////////
195 class WebGLContext
: public VRefCounted
, public SupportsWeakPtr
{
196 friend class ScopedDrawCallWrapper
;
197 friend class ScopedDrawWithTransformFeedback
;
198 friend class ScopedFakeVertexAttrib0
;
199 friend class ScopedFBRebinder
;
200 friend class WebGL2Context
;
201 friend class WebGLContextUserData
;
202 friend class WebGLExtensionCompressedTextureASTC
;
203 friend class WebGLExtensionCompressedTextureBPTC
;
204 friend class WebGLExtensionCompressedTextureES3
;
205 friend class WebGLExtensionCompressedTextureETC1
;
206 friend class WebGLExtensionCompressedTexturePVRTC
;
207 friend class WebGLExtensionCompressedTextureRGTC
;
208 friend class WebGLExtensionCompressedTextureS3TC
;
209 friend class WebGLExtensionCompressedTextureS3TC_SRGB
;
210 friend class WebGLExtensionDepthClamp
;
211 friend class WebGLExtensionDepthTexture
;
212 friend class WebGLExtensionDisjointTimerQuery
;
213 friend class WebGLExtensionDrawBuffers
;
214 friend class WebGLExtensionFragDepth
;
215 friend class WebGLExtensionLoseContext
;
216 friend class WebGLExtensionMOZDebug
;
217 friend class WebGLExtensionShaderTextureLod
;
218 friend class WebGLExtensionVertexArray
;
219 friend class WebGLMemoryTracker
;
220 friend class webgl::AvailabilityRunnable
;
221 friend struct webgl::LinkedProgramInfo
;
222 friend struct webgl::SamplerUniformInfo
;
223 friend class webgl::ScopedPrepForResourceClear
;
224 friend struct webgl::UniformBlockInfo
;
226 friend const webgl::CachedDrawFetchLimits
* ValidateDraw(WebGLContext
*, GLenum
,
228 friend RefPtr
<const webgl::LinkedProgramInfo
> QueryProgramInfo(
229 WebGLProgram
* prog
, gl::GLContext
* gl
);
231 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLContext
, override
)
234 UNPACK_FLIP_Y_WEBGL
= 0x9240,
235 UNPACK_PREMULTIPLY_ALPHA_WEBGL
= 0x9241,
236 // We throw InvalidOperation in TexImage if we fail to use GPU fast-path
237 // for texture copy when it is set to true, only for debug purpose.
238 UNPACK_REQUIRE_FASTPATH
= 0x10001,
239 CONTEXT_LOST_WEBGL
= 0x9242,
240 UNPACK_COLORSPACE_CONVERSION_WEBGL
= 0x9243,
241 BROWSER_DEFAULT_WEBGL
= 0x9244,
242 UNMASKED_VENDOR_WEBGL
= 0x9245,
243 UNMASKED_RENDERER_WEBGL
= 0x9246
247 class LruPosition final
{
248 std::list
<WebGLContext
*>::iterator mItr
;
250 LruPosition(const LruPosition
&) = delete;
251 LruPosition(LruPosition
&&) = delete;
252 LruPosition
& operator=(const LruPosition
&) = delete;
253 LruPosition
& operator=(LruPosition
&&) = delete;
256 void AssignLocked(WebGLContext
& aContext
) MOZ_REQUIRES(sLruMutex
);
258 void ResetLocked() MOZ_REQUIRES(sLruMutex
);
259 bool IsInsertedLocked() const MOZ_REQUIRES(sLruMutex
);
262 explicit LruPosition(WebGLContext
&);
264 ~LruPosition() { Reset(); }
267 mutable LruPosition mLruPosition
MOZ_GUARDED_BY(sLruMutex
);
269 void BumpLruLocked() MOZ_REQUIRES(sLruMutex
);
273 void LoseLruContextIfLimitExceeded();
277 // We've had issues in the past with nulling `gl` without actually releasing
278 // all of our resources. This construction ensures that we are aware that we
279 // should only null `gl` in DestroyResourcesAndContext.
280 RefPtr
<gl::GLContext
> mGL_OnlyClearInDestroyResourcesAndContext
;
283 // Grab a const reference so we can see changes, but can't make changes.
284 const decltype(mGL_OnlyClearInDestroyResourcesAndContext
)& gl
;
287 void CheckForInactivity();
290 const WeakPtr
<HostWebGLContext
> mHost
;
291 const bool mResistFingerprinting
;
292 WebGLContextOptions mOptions
;
293 const uint32_t mPrincipalKey
;
294 Maybe
<webgl::Limits
> mLimits
;
295 const uint32_t mMaxVertIdsPerDraw
=
296 StaticPrefs::webgl_max_vert_ids_per_draw();
298 bool mIsContextLost
= false;
299 Atomic
<bool> mPendingContextLoss
= Atomic
<bool>{false};
300 webgl::ContextLossReason mPendingContextLossReason
=
301 webgl::ContextLossReason::None
;
302 const uint32_t mMaxPerfWarnings
= StaticPrefs::webgl_perf_max_warnings();
303 mutable uint64_t mNumPerfWarnings
= 0;
304 const uint32_t mMaxAcceptableFBStatusInvals
=
305 StaticPrefs::webgl_perf_max_acceptable_fb_status_invals();
306 bool mWarnOnce_DepthTexCompareFilterable
= true;
307 mutable bool mRemapImplReadType_HalfFloatOes
= false;
309 mutable std::optional
<bool> mIsSupportedCache_DrawBuffers
;
310 mutable std::optional
<bool> mIsSupportedCache_FragDepth
;
311 mutable std::optional
<bool> mIsSupportedCache_ShaderTextureLod
;
315 uint64_t mNextFenceId
= 1;
316 uint64_t mCompletedFenceId
= 0;
318 mutable std::list
<WeakPtr
<WebGLSync
>> mPendingSyncs
;
319 mutable RefPtr
<nsIRunnable
> mPollPendingSyncs_Pending
;
320 static constexpr uint32_t kPollPendingSyncs_DelayMs
=
321 4; // Four times a frame.
323 void EnsurePollPendingSyncs_Pending() const;
324 void PollPendingSyncs() const;
327 std::unique_ptr
<gl::Texture
> mIncompleteTexOverride
;
333 mutable FuncScope
* mFuncScope
= nullptr;
336 static RefPtr
<WebGLContext
> Create(HostWebGLContext
*,
337 const webgl::InitContextDesc
&,
338 webgl::InitContextResult
* out
);
341 webgl::OptionalRenderableFormatBits mOptionalRenderableFormatBits
=
342 webgl::OptionalRenderableFormatBits
{0};
346 WebGLContext(HostWebGLContext
*, const webgl::InitContextDesc
&);
347 virtual ~WebGLContext();
349 RefPtr
<layers::CompositableHost
> mCompositableHost
;
351 layers::LayersBackend mBackend
= layers::LayersBackend::LAYERS_NONE
;
354 void Resize(uvec2 size
);
356 void SetCompositableHost(RefPtr
<layers::CompositableHost
>& aCompositableHost
);
359 * An abstract base class to be implemented by callers wanting to be notified
360 * that a refresh has occurred. Callers must ensure an observer is removed
361 * before it is destroyed.
363 virtual void DidRefresh();
365 void OnMemoryPressure();
371 Here are the bind calls that are supposed to be fully-validated client side,
372 so that client's binding state doesn't diverge:
382 * BindTransformFeedback
390 const auto& CurFuncScope() const { return *mFuncScope
; }
391 const char* FuncName() const;
393 class FuncScope final
{
395 const WebGLContext
& mWebGL
;
396 const char* const mFuncName
;
397 bool mBindFailureGuard
= false;
400 FuncScope(const WebGLContext
& webgl
, const char* funcName
);
404 void GenerateErrorImpl(const GLenum err
, const nsACString
& text
) const {
405 GenerateErrorImpl(err
, std::string(text
.BeginReading()));
407 void GenerateErrorImpl(const GLenum err
, const std::string
& text
) const;
409 void GenerateError(const webgl::ErrorInfo
& err
) {
410 GenerateError(err
.type
, "%s", err
.info
.c_str());
413 template <typename
... Args
>
414 void GenerateError(const GLenum err
, const char* const fmt
,
415 const Args
&... args
) const {
416 MOZ_ASSERT(FuncName());
419 text
.AppendPrintf("WebGL warning: %s: ", FuncName());
422 # pragma clang diagnostic push
423 # pragma clang diagnostic ignored "-Wformat-security"
424 #elif defined(__GNUC__)
425 # pragma GCC diagnostic push
426 # pragma GCC diagnostic ignored "-Wformat-security"
428 text
.AppendPrintf(fmt
, args
...);
430 # pragma clang diagnostic pop
431 #elif defined(__GNUC__)
432 # pragma GCC diagnostic pop
435 GenerateErrorImpl(err
, text
);
438 template <typename
... Args
>
439 void ErrorInvalidEnum(const char* const fmt
, const Args
&... args
) const {
440 GenerateError(LOCAL_GL_INVALID_ENUM
, fmt
, args
...);
442 template <typename
... Args
>
443 void ErrorInvalidOperation(const char* const fmt
, const Args
&... args
) const {
444 GenerateError(LOCAL_GL_INVALID_OPERATION
, fmt
, args
...);
446 template <typename
... Args
>
447 void ErrorInvalidValue(const char* const fmt
, const Args
&... args
) const {
448 GenerateError(LOCAL_GL_INVALID_VALUE
, fmt
, args
...);
450 template <typename
... Args
>
451 void ErrorInvalidFramebufferOperation(const char* const fmt
,
452 const Args
&... args
) const {
453 GenerateError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION
, fmt
, args
...);
455 template <typename
... Args
>
456 void ErrorOutOfMemory(const char* const fmt
, const Args
&... args
) const {
457 GenerateError(LOCAL_GL_OUT_OF_MEMORY
, fmt
, args
...);
460 template <typename
... Args
>
461 void ErrorImplementationBug(const char* const fmt
,
462 const Args
&... args
) const {
463 const nsPrintfCString
newFmt(
464 "Implementation bug, please file at %s! %s",
465 "https://bugzilla.mozilla.org/"
466 "enter_bug.cgi?product=Core&component=Canvas%3A+WebGL",
468 GenerateError(LOCAL_GL_OUT_OF_MEMORY
, newFmt
.BeginReading(), args
...);
469 MOZ_ASSERT(false, "WebGLContext::ErrorImplementationBug");
470 NS_ERROR("WebGLContext::ErrorImplementationBug");
473 void ErrorInvalidEnumInfo(const char* info
, GLenum enumValue
) const;
474 void ErrorInvalidEnumArg(const char* argName
, GLenum val
) const;
476 static const char* ErrorName(GLenum error
);
478 void JsWarning(const std::string
& text
) const;
481 * Return displayable name for GLenum.
482 * This version is like gl::GLenumToStr but with out the GL_ prefix to
483 * keep consistency with how errors are reported from WebGL.
484 * Returns hex formatted version of glenum if glenum is unknown.
486 static void EnumName(GLenum val
, nsCString
* out_name
);
488 void DummyReadFramebufferOperation();
490 layers::SharedSurfacesHolder
* GetSharedSurfacesHolder() const;
492 dom::ContentParentId
GetContentId() const;
494 WebGLTexture
* GetActiveTex(const GLenum texTarget
) const;
496 gl::GLContext
* GL() const { return gl
; }
498 bool IsPremultAlpha() const { return mOptions
.premultipliedAlpha
; }
500 bool IsPreservingDrawingBuffer() const {
501 return mOptions
.preserveDrawingBuffer
;
504 // Present to compositor
506 bool PresentInto(gl::SwapChain
& swapChain
);
507 bool PresentIntoXR(gl::SwapChain
& swapChain
, const gl::MozFramebuffer
& xrFb
);
510 // Present swaps the front and back buffers of the swap chain for compositing.
511 // This assumes the framebuffer may directly alias with the back buffer,
512 // dependent on remoting state or other concerns. Framebuffer and swap chain
513 // surface formats are assumed to be similar to enable this aliasing. As such,
514 // the back buffer may be invalidated by this swap with the front buffer,
515 // unless overriden by explicitly setting the preserveDrawingBuffer option,
516 // which may incur a further copy to preserve the back buffer.
518 WebGLFramebuffer
*, layers::TextureType
, const bool webvr
,
519 const webgl::SwapChainOptions
& options
= webgl::SwapChainOptions());
520 // CopyToSwapChain forces a copy from the supplied framebuffer into the back
521 // buffer before swapping the front and back buffers of the swap chain for
522 // compositing. The formats of the framebuffer and the swap chain buffers
523 // may differ subject to available format conversion options. Since this
524 // operation uses an explicit copy, it inherently preserves the framebuffer
525 // without need to set the preserveDrawingBuffer option.
526 bool CopyToSwapChain(
527 WebGLFramebuffer
*, layers::TextureType
,
528 const webgl::SwapChainOptions
& options
= webgl::SwapChainOptions(),
529 layers::RemoteTextureOwnerClient
* ownerClient
= nullptr);
530 // In use cases where a framebuffer is used as an offscreen framebuffer and
531 // does not need to be committed to the swap chain, it may still be useful
532 // for the implementation to delineate distinct frames, such as when sharing
533 // a single WebGLContext amongst many distinct users. EndOfFrame signals that
534 // frame rendering is complete so that any implementation side-effects such
535 // as resetting internal profile counters or resource queues may be handled
538 RefPtr
<gfx::DataSourceSurface
> GetFrontBufferSnapshot();
539 Maybe
<uvec2
> FrontBufferSnapshotInto(
540 const Maybe
<Range
<uint8_t>> dest
,
541 const Maybe
<size_t> destStride
= Nothing());
542 Maybe
<uvec2
> FrontBufferSnapshotInto(
543 const std::shared_ptr
<gl::SharedSurface
>& front
,
544 const Maybe
<Range
<uint8_t>> dest
,
545 const Maybe
<size_t> destStride
= Nothing());
546 Maybe
<uvec2
> SnapshotInto(GLuint srcFb
, const gfx::IntSize
& size
,
547 const Range
<uint8_t>& dest
,
548 const Maybe
<size_t> destStride
= Nothing());
549 gl::SwapChain
* GetSwapChain(WebGLFramebuffer
*, const bool webvr
);
550 Maybe
<layers::SurfaceDescriptor
> GetFrontBuffer(WebGLFramebuffer
*,
553 std::optional
<dom::PredefinedColorSpace
> mDrawingBufferColorSpace
;
554 std::optional
<dom::PredefinedColorSpace
> mUnpackColorSpace
;
555 std::optional
<color::ColorProfileDesc
> mDisplayProfile
;
557 void SetDrawingBufferColorSpace(const dom::PredefinedColorSpace val
) {
558 mDrawingBufferColorSpace
= val
;
561 void SetUnpackColorSpace(const dom::PredefinedColorSpace val
) {
562 mUnpackColorSpace
= val
;
565 void ClearVRSwapChain();
567 void RunContextLossTimer();
568 void CheckForContextLoss();
569 void HandlePendingContextLoss();
571 bool TryToRestoreContext();
573 void AssertCachedBindings() const;
574 void AssertCachedGlobalState() const;
576 // WebIDL WebGLRenderingContext API
579 uvec2
DrawingBufferSize();
582 void GetContextAttributes(dom::Nullable
<dom::WebGLContextAttributes
>& retval
);
584 // This is the entrypoint. Don't test against it directly.
585 bool IsContextLost() const {
586 auto* self
= const_cast<WebGLContext
*>(this);
587 if (self
->mPendingContextLoss
.exchange(false)) {
588 self
->HandlePendingContextLoss();
590 return mIsContextLost
;
595 RefPtr
<WebGLBuffer
> CreateBuffer();
596 RefPtr
<WebGLFramebuffer
> CreateFramebuffer();
597 RefPtr
<WebGLFramebuffer
> CreateOpaqueFramebuffer(
598 const webgl::OpaqueFramebufferOptions
& options
);
599 RefPtr
<WebGLProgram
> CreateProgram();
600 RefPtr
<WebGLQuery
> CreateQuery();
601 RefPtr
<WebGLRenderbuffer
> CreateRenderbuffer();
602 RefPtr
<WebGLShader
> CreateShader(GLenum type
);
603 RefPtr
<WebGLTexture
> CreateTexture();
604 RefPtr
<WebGLVertexArray
> CreateVertexArray();
608 void AttachShader(WebGLProgram
& prog
, WebGLShader
& shader
);
609 void BindAttribLocation(WebGLProgram
& prog
, GLuint location
,
610 const std::string
& name
) const;
611 void BindFramebuffer(GLenum target
, WebGLFramebuffer
* fb
);
612 void BindRenderbuffer(GLenum target
, WebGLRenderbuffer
* fb
);
613 void BindVertexArray(WebGLVertexArray
* vao
);
614 void BlendColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
);
615 void BlendEquationSeparate(Maybe
<GLuint
> i
, GLenum modeRGB
, GLenum modeAlpha
);
616 void BlendFuncSeparate(Maybe
<GLuint
> i
, GLenum srcRGB
, GLenum dstRGB
,
617 GLenum srcAlpha
, GLenum dstAlpha
);
618 GLenum
CheckFramebufferStatus(GLenum target
);
619 void Clear(GLbitfield mask
);
620 void ClearColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
);
621 void ClearDepth(GLclampf v
);
622 void ClearStencil(GLint v
);
623 void ColorMask(Maybe
<GLuint
> i
, uint8_t mask
);
624 void CompileShader(WebGLShader
& shader
);
627 void CompileShaderANGLE(WebGLShader
* shader
);
628 void CompileShaderBypass(WebGLShader
* shader
, const nsCString
& shaderSource
);
631 void CullFace(GLenum face
);
632 void DepthFunc(GLenum func
);
633 void DepthMask(WebGLboolean b
);
634 void DepthRange(GLclampf zNear
, GLclampf zFar
);
635 void DetachShader(WebGLProgram
& prog
, const WebGLShader
& shader
);
636 void DrawBuffers(const std::vector
<GLenum
>& buffers
);
640 void FramebufferAttach(GLenum target
, GLenum attachSlot
,
641 GLenum bindImageTarget
,
642 const webgl::FbAttachInfo
& toAttach
);
644 void FrontFace(GLenum mode
);
646 Maybe
<double> GetBufferParameter(GLenum target
, GLenum pname
);
647 webgl::CompileResult
GetCompileResult(const WebGLShader
&) const;
649 GLint
GetFragDataLocation(const WebGLProgram
&, const std::string
& name
) const;
651 Maybe
<double> GetFramebufferAttachmentParameter(WebGLFramebuffer
*,
655 Maybe
<double> GetRenderbufferParameter(const WebGLRenderbuffer
&,
657 webgl::LinkResult
GetLinkResult(const WebGLProgram
&) const;
659 Maybe
<webgl::ShaderPrecisionFormat
> GetShaderPrecisionFormat(
660 GLenum shadertype
, GLenum precisiontype
) const;
662 webgl::GetUniformData
GetUniform(const WebGLProgram
&, uint32_t loc
) const;
664 void Hint(GLenum target
, GLenum mode
);
666 void LineWidth(GLfloat width
);
667 void LinkProgram(WebGLProgram
& prog
);
668 void PolygonOffset(GLfloat factor
, GLfloat units
);
669 void ProvokingVertex(webgl::ProvokingVertex
) const;
673 webgl::PackingInfo
ValidImplementationColorReadPI(
674 const webgl::FormatUsageInfo
* usage
) const;
677 webgl::ReadPixelsResult
ReadPixelsImpl(const webgl::ReadPixelsDesc
&,
678 uintptr_t dest
, uint64_t availBytes
);
679 bool DoReadPixelsAndConvert(const webgl::FormatInfo
* srcFormat
,
680 const webgl::ReadPixelsDesc
&, uintptr_t dest
,
681 uint64_t dataLen
, uint32_t rowStride
);
684 void ReadPixelsPbo(const webgl::ReadPixelsDesc
&, uint64_t offset
);
685 webgl::ReadPixelsResult
ReadPixelsInto(const webgl::ReadPixelsDesc
&,
686 const Range
<uint8_t>& dest
);
690 void RenderbufferStorageMultisample(WebGLRenderbuffer
&, uint32_t samples
,
691 GLenum internalformat
, uint32_t width
,
692 uint32_t height
) const;
695 void SampleCoverage(GLclampf value
, WebGLboolean invert
);
696 void Scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
);
697 void ShaderSource(WebGLShader
& shader
, const std::string
& source
) const;
698 void StencilFuncSeparate(GLenum face
, GLenum func
, GLint ref
, GLuint mask
);
699 void StencilMaskSeparate(GLenum face
, GLuint mask
);
700 void StencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
703 //////////////////////////
705 void UniformData(uint32_t loc
, bool transpose
,
706 const Span
<const webgl::UniformDataVal
>& data
) const;
708 ////////////////////////////////////
710 void UseProgram(WebGLProgram
* prog
);
712 bool ValidateAttribArraySetter(uint32_t count
, uint32_t arrayLength
);
713 bool ValidateProgram(const WebGLProgram
& prog
) const;
714 void Viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
);
716 // -----------------------------------------------------------------------------
717 // Buffer Objects (WebGLContextBuffers.cpp)
718 void BindBuffer(GLenum target
, WebGLBuffer
* buffer
);
719 void BindBufferRange(GLenum target
, GLuint index
, WebGLBuffer
* buf
,
720 uint64_t offset
, uint64_t size
);
722 void BufferData(GLenum target
, uint64_t dataLen
, const uint8_t* data
,
724 void UninitializedBufferData_SizeOnly(GLenum target
, uint64_t dataLen
,
726 // The unsynchronized flag may allow for better performance when
727 // interleaving buffer updates with draw calls. However, care must
728 // be taken. This has similar semantics to glMapBufferRange's
729 // GL_MAP_UNSYNCHRONIZED_BIT: the results of any pending operations
730 // that reference the region of the buffer being updated are
732 void BufferSubData(GLenum target
, uint64_t dstByteOffset
, uint64_t srcDataLen
,
733 const uint8_t* srcData
, bool unsynchronized
= false) const;
736 // bound buffer state
737 RefPtr
<WebGLBuffer
> mBoundArrayBuffer
;
738 RefPtr
<WebGLBuffer
> mBoundCopyReadBuffer
;
739 RefPtr
<WebGLBuffer
> mBoundCopyWriteBuffer
;
740 RefPtr
<WebGLBuffer
> mBoundPixelPackBuffer
;
741 RefPtr
<WebGLBuffer
> mBoundPixelUnpackBuffer
;
742 RefPtr
<WebGLBuffer
> mBoundTransformFeedbackBuffer
;
743 RefPtr
<WebGLBuffer
> mBoundUniformBuffer
;
745 std::vector
<IndexedBufferBinding
> mIndexedUniformBufferBindings
;
747 RefPtr
<WebGLBuffer
>& GetBufferSlotByTarget(GLenum target
);
748 RefPtr
<WebGLBuffer
>& GetBufferSlotByTargetIndexed(GLenum target
,
753 void GenErrorIllegalUse(GLenum useTarget
, uint32_t useId
, GLenum boundTarget
,
754 uint32_t boundId
) const;
756 bool ValidateBufferForNonTf(const WebGLBuffer
&, GLenum nonTfTarget
,
757 uint32_t nonTfId
) const;
759 bool ValidateBufferForNonTf(const WebGLBuffer
* const nonTfBuffer
,
760 const GLenum nonTfTarget
,
761 const uint32_t nonTfId
= -1) const {
762 if (!nonTfBuffer
) return true;
763 return ValidateBufferForNonTf(*nonTfBuffer
, nonTfTarget
, nonTfId
);
766 bool ValidateBuffersForTf(const WebGLTransformFeedback
&,
767 const webgl::LinkedProgramInfo
&) const;
768 bool ValidateBuffersForTf(
769 const std::vector
<webgl::BufferAndIndex
>& tfBuffers
) const;
771 // -----------------------------------------------------------------------------
772 // Queries (WebGL2ContextQueries.cpp)
774 RefPtr
<WebGLQuery
> mQuerySlot_SamplesPassed
;
775 RefPtr
<WebGLQuery
> mQuerySlot_TFPrimsWritten
;
776 RefPtr
<WebGLQuery
> mQuerySlot_TimeElapsed
;
778 RefPtr
<WebGLQuery
>* ValidateQuerySlotByTarget(GLenum target
);
781 void BeginQuery(GLenum target
, WebGLQuery
& query
);
782 void EndQuery(GLenum target
);
783 Maybe
<double> GetQueryParameter(const WebGLQuery
& query
, GLenum pname
) const;
784 void QueryCounter(WebGLQuery
&) const;
786 // -----------------------------------------------------------------------------
787 // State and State Requests (WebGLContextState.cpp)
788 void SetEnabled(GLenum cap
, Maybe
<GLuint
> i
, bool enabled
);
789 bool GetStencilBits(GLint
* const out_stencilBits
) const;
791 virtual Maybe
<double> GetParameter(GLenum pname
);
792 Maybe
<std::string
> GetString(GLenum pname
) const;
795 static StaticMutex sLruMutex
;
796 static std::list
<WebGLContext
*> sLru
MOZ_GUARDED_BY(sLruMutex
);
798 // State tracking slots
799 bool mDitherEnabled
= true;
800 bool mRasterizerDiscardEnabled
= false;
801 bool mScissorTestEnabled
= false;
802 bool mDepthTestEnabled
= false;
803 bool mStencilTestEnabled
= false;
804 GLenum mGenerateMipmapHint
= LOCAL_GL_DONT_CARE
;
806 struct ScissorRect final
{
812 void Apply(gl::GLContext
&) const;
814 ScissorRect mScissorRect
= {};
816 bool* GetStateTrackingSlot(GLenum cap
);
818 // Allocation debugging variables
819 mutable uint64_t mDataAllocGLCallCount
= 0;
821 void OnDataAllocCall() const { mDataAllocGLCallCount
++; }
823 uint64_t GetNumGLDataAllocCalls() const { return mDataAllocGLCallCount
; }
827 // -----------------------------------------------------------------------------
828 // Texture funcions (WebGLContextTextures.cpp)
830 void ActiveTexture(uint32_t texUnit
);
831 void BindTexture(GLenum texTarget
, WebGLTexture
* tex
);
832 void GenerateMipmap(GLenum texTarget
);
834 Maybe
<double> GetTexParameter(const WebGLTexture
&, GLenum pname
) const;
835 void TexParameter_base(GLenum texTarget
, GLenum pname
,
836 const FloatOrInt
& param
);
838 virtual bool IsTexParamValid(GLenum pname
) const;
840 ////////////////////////////////////
843 // CompressedTexSubImage if `sub`
844 void CompressedTexImage(bool sub
, GLenum imageTarget
, uint32_t level
,
845 GLenum format
, uvec3 offset
, uvec3 size
,
846 const Range
<const uint8_t>& src
,
847 const uint32_t pboImageSize
,
848 const Maybe
<uint64_t>& pboOffset
) const;
850 // CopyTexSubImage if `!respectFormat`
851 void CopyTexImage(GLenum imageTarget
, uint32_t level
, GLenum respecFormat
,
852 uvec3 dstOffset
, const ivec2
& srcOffset
,
853 const uvec2
& size
) const;
855 // TexSubImage if `!respectFormat`
856 void TexImage(uint32_t level
, GLenum respecFormat
, uvec3 offset
,
857 const webgl::PackingInfo
& pi
,
858 const webgl::TexUnpackBlobDesc
&) const;
860 void TexStorage(GLenum texTarget
, uint32_t levels
, GLenum sizedFormat
,
863 std::unique_ptr
<webgl::TexUnpackBlob
> ToTexUnpackBytes(
864 const WebGLTexImageData
& imageData
);
866 std::unique_ptr
<webgl::TexUnpackBytes
> ToTexUnpackBytes(
867 WebGLTexPboOffset
& aPbo
);
869 ////////////////////////////////////
870 // WebGLTextureUpload.cpp
872 bool ValidateTexImageSpecification(uint8_t funcDims
, GLenum texImageTarget
,
873 GLint level
, GLsizei width
, GLsizei height
,
874 GLsizei depth
, GLint border
,
875 TexImageTarget
* const out_target
,
876 WebGLTexture
** const out_texture
,
877 webgl::ImageInfo
** const out_imageInfo
);
878 bool ValidateTexImageSelection(uint8_t funcDims
, GLenum texImageTarget
,
879 GLint level
, GLint xOffset
, GLint yOffset
,
880 GLint zOffset
, GLsizei width
, GLsizei height
,
882 TexImageTarget
* const out_target
,
883 WebGLTexture
** const out_texture
,
884 webgl::ImageInfo
** const out_imageInfo
);
885 bool ValidateUnpackInfo(bool usePBOs
, GLenum format
, GLenum type
,
886 webgl::PackingInfo
* const out
);
888 // -----------------------------------------------------------------------------
889 // Vertices Feature (WebGLContextVertices.cpp)
890 GLenum mPrimRestartTypeBytes
= 0;
893 void DrawArraysInstanced(GLenum mode
, GLint first
, GLsizei vertexCount
,
894 GLsizei instanceCount
);
895 void DrawElementsInstanced(GLenum mode
, GLsizei vertexCount
, GLenum type
,
896 WebGLintptr byteOffset
, GLsizei instanceCount
);
898 void EnableVertexAttribArray(GLuint index
);
899 void DisableVertexAttribArray(GLuint index
);
901 Maybe
<double> GetVertexAttrib(GLuint index
, GLenum pname
);
905 void VertexAttrib4T(GLuint index
, const webgl::TypedQuad
&);
909 void VertexAttribPointer(uint32_t index
, const webgl::VertAttribPointerDesc
&);
911 void VertexAttribDivisor(GLuint index
, GLuint divisor
);
914 WebGLBuffer
* DrawElements_check(GLsizei indexCount
, GLenum type
,
915 WebGLintptr byteOffset
,
916 GLsizei instanceCount
);
919 void VertexAttrib1fv_base(GLuint index
, uint32_t arrayLength
,
921 void VertexAttrib2fv_base(GLuint index
, uint32_t arrayLength
,
923 void VertexAttrib3fv_base(GLuint index
, uint32_t arrayLength
,
925 void VertexAttrib4fv_base(GLuint index
, uint32_t arrayLength
,
928 bool BindArrayAttribToLocation0(WebGLProgram
* prog
);
930 // -----------------------------------------------------------------------------
933 WebGLVertexAttrib0Status
WhatDoesVertexAttrib0Need() const;
934 bool DoFakeVertexAttrib0(uint64_t fakeVertexCount
,
935 WebGLVertexAttrib0Status whatDoesAttrib0Need
);
936 void UndoFakeVertexAttrib0();
938 bool mResetLayer
= true;
939 bool mOptionsFrozen
= false;
940 bool mIsMesa
= false;
941 bool mLoseContextOnMemoryPressure
= false;
942 bool mCanLoseContextInForeground
= true;
943 bool mShouldPresent
= false;
944 bool mDisableFragHighP
= false;
945 bool mForceResizeOnPresent
= false;
946 bool mVRReady
= false;
948 template <typename WebGLObjectType
>
949 void DeleteWebGLObjectsArray(nsTArray
<WebGLObjectType
>& array
);
951 GLuint mActiveTexture
= 0;
952 GLenum mDefaultFB_DrawBuffer0
= LOCAL_GL_BACK
;
953 GLenum mDefaultFB_ReadBuffer
= LOCAL_GL_BACK
;
955 mutable GLenum mWebGLError
= 0;
957 std::unique_ptr
<webgl::ShaderValidator
> CreateShaderValidator(
958 GLenum shaderType
) const;
961 uint32_t mGLMaxFragmentUniformVectors
= 0;
962 uint32_t mGLMaxVertexUniformVectors
= 0;
963 uint32_t mGLMaxVertexOutputVectors
= 0;
964 uint32_t mGLMaxFragmentInputVectors
= 0;
966 uint32_t mGLMaxVertexTextureImageUnits
= 0;
967 uint32_t mGLMaxFragmentTextureImageUnits
= 0;
968 uint32_t mGLMaxCombinedTextureImageUnits
= 0;
971 uint32_t mGLMinProgramTexelOffset
= 0;
972 uint32_t mGLMaxProgramTexelOffset
= 0;
975 auto GLMaxDrawBuffers() const { return mLimits
->maxColorDrawBuffers
; }
977 uint32_t MaxValidDrawBuffers() const {
979 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers
)) {
980 return GLMaxDrawBuffers();
985 GLenum
LastColorAttachmentEnum() const {
986 return LOCAL_GL_COLOR_ATTACHMENT0
+ MaxValidDrawBuffers() - 1;
989 const auto& Options() const { return mOptions
; }
992 uint32_t mGLMaxRenderbufferSize
= 0;
995 const auto& Limits() const { return *mLimits
; }
996 auto MaxVertexAttribs() const { return mLimits
->maxVertexAttribs
; }
997 auto GLMaxTextureUnits() const { return mLimits
->maxTexUnits
; }
999 bool IsFormatValidForFB(TexInternalFormat format
) const;
1002 // -------------------------------------------------------------------------
1003 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
1005 EnumeratedArray
<WebGLExtensionID
, std::unique_ptr
<WebGLExtensionBase
>,
1006 size_t(WebGLExtensionID::Max
)>
1010 void RequestExtension(WebGLExtensionID
, bool explicitly
= true);
1012 // returns true if the extension has been enabled by calling getExtension.
1013 bool IsExtensionEnabled(const WebGLExtensionID id
) const {
1014 return bool(mExtensions
[id
]);
1017 bool IsExtensionExplicit(WebGLExtensionID
) const;
1018 void WarnIfImplicit(WebGLExtensionID
) const;
1020 bool IsExtensionSupported(WebGLExtensionID
) const;
1022 // -------------------------------------------------------------------------
1023 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
1025 virtual bool IsWebGL2() const { return false; }
1027 struct FailureReason
{
1028 nsCString key
; // For reporting.
1031 FailureReason() = default;
1033 template <typename A
, typename B
>
1034 FailureReason(const A
& _key
, const B
& _info
)
1035 : key(nsCString(_key
)), info(nsCString(_info
)) {}
1039 bool InitWebGL2(FailureReason
* const out_failReason
);
1041 bool CreateAndInitGL(bool forceEnabled
,
1042 std::vector
<FailureReason
>* const out_failReasons
);
1044 // -------------------------------------------------------------------------
1045 // Validation functions (implemented in WebGLContextValidate.cpp)
1046 bool InitAndValidateGL(FailureReason
* const out_failReason
);
1048 bool ValidateBlendEquationEnum(GLenum cap
, const char* info
);
1049 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor
, GLenum dfactor
,
1051 bool ValidateStencilOpEnum(GLenum action
, const char* info
);
1052 bool ValidateFaceEnum(GLenum face
);
1053 bool ValidateTexInputData(GLenum type
, js::Scalar::Type jsArrayType
,
1054 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1055 bool ValidateAttribPointer(bool integerMode
, GLuint index
, GLint size
,
1056 GLenum type
, WebGLboolean normalized
,
1057 GLsizei stride
, WebGLintptr byteOffset
,
1059 bool ValidateStencilParamsForDrawCall() const;
1061 bool ValidateCopyTexImage(TexInternalFormat srcFormat
,
1062 TexInternalFormat dstformat
, WebGLTexImageFunc func
,
1063 WebGLTexDimensions dims
);
1065 bool ValidateTexImage(TexImageTarget texImageTarget
, GLint level
,
1066 GLenum internalFormat
, GLint xoffset
, GLint yoffset
,
1067 GLint zoffset
, GLint width
, GLint height
, GLint depth
,
1068 GLint border
, GLenum format
, GLenum type
,
1069 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1070 bool ValidateTexImageFormat(GLenum internalFormat
, WebGLTexImageFunc func
,
1071 WebGLTexDimensions dims
);
1072 bool ValidateTexImageType(GLenum type
, WebGLTexImageFunc func
,
1073 WebGLTexDimensions dims
);
1074 bool ValidateTexImageFormatAndType(GLenum format
, GLenum type
,
1075 WebGLTexImageFunc func
,
1076 WebGLTexDimensions dims
);
1077 bool ValidateCompTexImageInternalFormat(GLenum format
, WebGLTexImageFunc func
,
1078 WebGLTexDimensions dims
);
1079 bool ValidateCopyTexImageInternalFormat(GLenum format
, WebGLTexImageFunc func
,
1080 WebGLTexDimensions dims
);
1081 bool ValidateTexImageSize(TexImageTarget texImageTarget
, GLint level
,
1082 GLint width
, GLint height
, GLint depth
,
1083 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1084 bool ValidateTexSubImageSize(GLint x
, GLint y
, GLint z
, GLsizei width
,
1085 GLsizei height
, GLsizei depth
, GLsizei baseWidth
,
1086 GLsizei baseHeight
, GLsizei baseDepth
,
1087 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1088 bool ValidateCompTexImageSize(GLint level
, GLenum internalFormat
,
1089 GLint xoffset
, GLint yoffset
, GLsizei width
,
1090 GLsizei height
, GLsizei levelWidth
,
1091 GLsizei levelHeight
, WebGLTexImageFunc func
,
1092 WebGLTexDimensions dims
);
1093 bool ValidateCompTexImageDataSize(GLint level
, GLenum internalFormat
,
1094 GLsizei width
, GLsizei height
,
1095 uint32_t byteLength
, WebGLTexImageFunc func
,
1096 WebGLTexDimensions dims
);
1098 bool HasDrawBuffers() const {
1099 return IsWebGL2() ||
1100 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers
);
1103 RefPtr
<WebGLBuffer
>* ValidateBufferSlot(GLenum target
);
1106 WebGLBuffer
* ValidateBufferSelection(GLenum target
) const;
1109 IndexedBufferBinding
* ValidateIndexedBufferSlot(GLenum target
, GLuint index
);
1111 bool ValidateIndexedBufferBinding(
1112 GLenum target
, GLuint index
,
1113 RefPtr
<WebGLBuffer
>** const out_genericBinding
,
1114 IndexedBufferBinding
** const out_indexedBinding
);
1117 bool ValidateNonNegative(const char* argName
, int64_t val
) const {
1118 if (MOZ_UNLIKELY(val
< 0)) {
1119 ErrorInvalidValue("`%s` must be non-negative.", argName
);
1125 template <typename T
>
1126 bool ValidateNonNull(const char* const argName
,
1127 const dom::Nullable
<T
>& maybe
) const {
1128 if (maybe
.IsNull()) {
1129 ErrorInvalidValue("%s: Cannot be null.", argName
);
1138 void DestroyResourcesAndContext();
1142 bool ConvertImage(size_t width
, size_t height
, size_t srcStride
,
1143 size_t dstStride
, const uint8_t* src
, uint8_t* dst
,
1144 WebGLTexelFormat srcFormat
, bool srcPremultiplied
,
1145 WebGLTexelFormat dstFormat
, bool dstPremultiplied
,
1146 size_t dstTexelSize
);
1150 template <typename T
>
1151 bool ValidateObject(const char* const argName
, const T
& object
) const {
1152 // Todo: Remove all callers.
1156 template <typename T
>
1157 bool ValidateObject(const char* const argName
, const T
* const object
) const {
1158 // Todo: Remove most (all?) callers.
1160 ErrorInvalidOperation(
1161 "%s: Object argument cannot have been marked for"
1172 void LoseContextLruLocked(webgl::ContextLossReason reason
)
1173 MOZ_REQUIRES(sLruMutex
);
1177 webgl::ContextLossReason reason
= webgl::ContextLossReason::None
);
1180 nsTArray
<RefPtr
<WebGLTexture
>> mBound2DTextures
;
1181 nsTArray
<RefPtr
<WebGLTexture
>> mBoundCubeMapTextures
;
1182 nsTArray
<RefPtr
<WebGLTexture
>> mBound3DTextures
;
1183 nsTArray
<RefPtr
<WebGLTexture
>> mBound2DArrayTextures
;
1184 nsTArray
<RefPtr
<WebGLSampler
>> mBoundSamplers
;
1186 mutable std::unique_ptr
<gl::Sampler
> mSamplerLinear
;
1188 GLuint
SamplerLinear() const;
1190 void ResolveTexturesForDraw() const;
1192 RefPtr
<WebGLProgram
> mCurrentProgram
;
1193 RefPtr
<const webgl::LinkedProgramInfo
> mActiveProgramLinkInfo
;
1195 bool ValidateFramebufferTarget(GLenum target
) const;
1196 bool ValidateInvalidateFramebuffer(GLenum target
,
1197 const Span
<const GLenum
>& attachments
,
1198 std::vector
<GLenum
>* const scopedVector
,
1199 GLsizei
* const out_glNumAttachments
,
1200 const GLenum
** const out_glAttachments
);
1202 RefPtr
<WebGLFramebuffer
> mBoundDrawFramebuffer
;
1203 RefPtr
<WebGLFramebuffer
> mBoundReadFramebuffer
;
1204 RefPtr
<WebGLTransformFeedback
> mBoundTransformFeedback
;
1205 RefPtr
<WebGLVertexArray
> mBoundVertexArray
;
1208 const auto& BoundReadFb() const { return mBoundReadFramebuffer
; }
1211 RefPtr
<WebGLTransformFeedback
> mDefaultTransformFeedback
;
1212 RefPtr
<WebGLVertexArray
> mDefaultVertexArray
;
1214 ////////////////////////////////////
1217 GLuint mEmptyTFO
= 0;
1219 // Generic Vertex Attributes
1220 // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the
1221 // spec state tables, this isn't vertex shader /object/ state. This array is
1222 // merely state useful to vertex shaders, but is global state.
1223 std::vector
<webgl::AttribBaseType
> mGenericVertexAttribTypes
;
1224 CacheInvalidator mGenericVertexAttribTypeInvalidator
;
1226 GLuint mFakeVertexAttrib0BufferObject
= 0;
1227 intptr_t mFakeVertexAttrib0BufferObjectSize
= 0;
1228 bool mFakeVertexAttrib0DataDefined
= false;
1229 alignas(alignof(float)) uint8_t
1230 mGenericVertexAttrib0Data
[sizeof(float) * 4] = {};
1231 alignas(alignof(float)) uint8_t
1232 mFakeVertexAttrib0Data
[sizeof(float) * 4] = {};
1234 GLint mStencilRefFront
= 0;
1235 GLint mStencilRefBack
= 0;
1236 GLuint mStencilValueMaskFront
= 0;
1237 GLuint mStencilValueMaskBack
= 0;
1238 GLuint mStencilWriteMaskFront
= 0;
1239 GLuint mStencilWriteMaskBack
= 0;
1240 uint8_t mColorWriteMask0
= 0xf; // bitmask
1241 mutable uint8_t mDriverColorMask0
= 0xf;
1242 bool mDepthWriteMask
= true;
1243 GLfloat mColorClearValue
[4] = {0, 0, 0, 0};
1244 GLint mStencilClearValue
= 0;
1245 GLfloat mDepthClearValue
= 1.0f
;
1247 std::bitset
<webgl::kMaxDrawBuffers
> mColorWriteMaskNonzero
= -1;
1248 std::bitset
<webgl::kMaxDrawBuffers
> mBlendEnabled
= 0;
1250 std::unordered_set
<GLenum
> mIsEnabledMapKeys
;
1252 GLint mViewportX
= 0;
1253 GLint mViewportY
= 0;
1254 GLsizei mViewportWidth
= 0;
1255 GLsizei mViewportHeight
= 0;
1256 bool mAlreadyWarnedAboutViewportLargerThanDest
= false;
1258 GLfloat mLineWidth
= 1.0;
1260 WebGLContextLossHandler mContextLossHandler
;
1262 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1263 // be Flushed while doing hundreds of draw calls.
1264 mutable uint64_t mDrawCallsSinceLastFlush
= 0;
1266 mutable uint64_t mWarningCount
= 0;
1267 const uint64_t mMaxWarnings
= StaticPrefs::webgl_max_warnings_per_context();
1268 bool mAlreadyWarnedAboutFakeVertexAttrib0
= false;
1270 bool ShouldGenerateWarnings() const { return mWarningCount
< mMaxWarnings
; }
1272 bool ShouldGeneratePerfWarnings() const {
1273 return mNumPerfWarnings
< mMaxPerfWarnings
;
1276 bool mNeedsFakeNoAlpha
= false;
1277 bool mNeedsFakeNoDepth
= false;
1278 bool mNeedsFakeNoStencil
= false;
1280 bool mDriverDepthTest
= false;
1281 bool mDriverStencilTest
= false;
1283 bool mNeedsLegacyVertexAttrib0Handling
= false;
1284 bool mMaybeNeedsLegacyVertexAttrib0Handling
= false;
1285 bool mNeedsIndexValidation
= false;
1286 bool mBug_DrawArraysInstancedUserAttribFetchAffectedByFirst
= false;
1288 const bool mAllowFBInvalidation
= StaticPrefs::webgl_allow_fb_invalidation();
1290 bool Has64BitTimestamps() const;
1294 const uint8_t mMsaaSamples
=
1295 static_cast<uint8_t>(StaticPrefs::webgl_msaa_samples());
1296 mutable uvec2 mRequestedSize
;
1297 mutable UniquePtr
<gl::MozFramebuffer
> mDefaultFB
;
1298 mutable bool mDefaultFB_IsInvalid
= false;
1299 mutable UniquePtr
<gl::MozFramebuffer
> mResolvedDefaultFB
;
1301 mutable std::unordered_map
<std::tuple
<gfx::ColorSpace2
, gfx::ColorSpace2
>,
1302 std::shared_ptr
<gl::Texture
>>
1303 mLutTexByColorMapping
;
1305 gl::SwapChain mSwapChain
;
1306 gl::SwapChain mWebVRSwapChain
;
1308 RefPtr
<layers::RemoteTextureOwnerClient
> mRemoteTextureOwner
;
1310 bool PushRemoteTexture(
1311 WebGLFramebuffer
*, gl::SwapChain
&, std::shared_ptr
<gl::SharedSurface
>,
1312 const webgl::SwapChainOptions
& options
,
1313 layers::RemoteTextureOwnerClient
* ownerClient
= nullptr);
1315 void EnsureContextLostRemoteTextureOwner(
1316 const webgl::SwapChainOptions
& options
);
1319 void WaitForTxn(layers::RemoteTextureOwnerId ownerId
,
1320 layers::RemoteTextureTxnType txnType
,
1321 layers::RemoteTextureTxnId txnId
);
1326 bool EnsureDefaultFB();
1327 bool ValidateAndInitFB(
1328 const WebGLFramebuffer
* fb
,
1329 GLenum incompleteFbError
= LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION
);
1330 void DoBindFB(const WebGLFramebuffer
* fb
,
1331 GLenum target
= LOCAL_GL_FRAMEBUFFER
) const;
1333 bool BindCurFBForDraw();
1334 bool BindCurFBForColorRead(
1335 const webgl::FormatUsageInfo
** out_format
, uint32_t* out_width
,
1336 uint32_t* out_height
,
1337 GLenum incompleteFbError
= LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION
);
1338 void DoColorMask(Maybe
<GLuint
> i
, uint8_t bitmask
) const;
1339 void BlitBackbufferToCurDriverFB(
1340 WebGLFramebuffer
* const srcAsWebglFb
= nullptr,
1341 const gl::MozFramebuffer
* const srcAsMozFb
= nullptr,
1342 bool srcIsBGRA
= false) const;
1344 struct GetDefaultFBForReadDesc
{
1345 bool endOfFrame
= false;
1347 const gl::MozFramebuffer
* GetDefaultFBForRead(const GetDefaultFBForReadDesc
&);
1348 const gl::MozFramebuffer
* GetDefaultFBForRead() {
1349 return GetDefaultFBForRead({});
1352 bool BindDefaultFBForRead();
1357 // console logging helpers
1358 template <typename
... Args
>
1359 void GenerateWarning(const char* const fmt
, const Args
&... args
) const {
1360 GenerateError(0, fmt
, args
...);
1363 template <typename
... Args
>
1364 void GeneratePerfWarning(const char* const fmt
, const Args
&... args
) const {
1365 GenerateError(webgl::kErrorPerfWarning
, fmt
, args
...);
1369 std::unique_ptr
<webgl::FormatUsageAuthority
> mFormatUsage
;
1371 virtual std::unique_ptr
<webgl::FormatUsageAuthority
> CreateFormatUsage(
1372 gl::GLContext
* gl
) const;
1374 const decltype(mBound2DTextures
)* TexListForElemType(GLenum elemType
) const;
1377 friend class ScopedCopyTexImageSource
;
1378 friend class ScopedResolveTexturesForDraw
;
1379 friend class webgl::TexUnpackBlob
;
1380 friend class webgl::TexUnpackBytes
;
1381 friend class webgl::TexUnpackImage
;
1382 friend class webgl::TexUnpackSurface
;
1383 friend struct webgl::UniformInfo
;
1384 friend class WebGLTexture
;
1385 friend class WebGLFBAttachPoint
;
1386 friend class WebGLFramebuffer
;
1387 friend class WebGLRenderbuffer
;
1388 friend class WebGLProgram
;
1389 friend class WebGLQuery
;
1390 friend class WebGLBuffer
;
1391 friend class WebGLSampler
;
1392 friend class WebGLShader
;
1393 friend class WebGLSync
;
1394 friend class WebGLTransformFeedback
;
1395 friend class WebGLVertexArray
;
1396 friend class WebGLVertexArrayFake
;
1397 friend class WebGLVertexArrayGL
;
1400 // Returns `value` rounded to the next highest multiple of `multiple`.
1401 // AKA PadToAlignment, StrideForAlignment.
1402 template <typename V
, typename M
>
1403 V
RoundUpToMultipleOf(const V
& value
, const M
& multiple
) {
1404 return ((value
+ multiple
- 1) / multiple
) * multiple
;
1407 class ScopedFBRebinder final
{
1409 const WebGLContext
* const mWebGL
;
1412 explicit ScopedFBRebinder(const WebGLContext
* const webgl
) : mWebGL(webgl
) {}
1413 ~ScopedFBRebinder();
1418 constexpr inline bool IsBufferTargetLazilyBound(const GLenum target
) {
1419 return target
!= LOCAL_GL_ELEMENT_ARRAY_BUFFER
;
1422 void DoBindBuffer(gl::GLContext
&, GLenum target
, const WebGLBuffer
*);
1424 class ScopedLazyBind final
{
1427 const GLenum mTarget
;
1430 ScopedLazyBind(gl::GLContext
* const gl
, const GLenum target
,
1431 const WebGLBuffer
* const buf
)
1432 : mGL(*gl
), mTarget(IsBufferTargetLazilyBound(target
) ? target
: 0) {
1434 DoBindBuffer(mGL
, mTarget
, buf
);
1440 DoBindBuffer(mGL
, mTarget
, nullptr);
1447 bool Intersect(int32_t srcSize
, int32_t read0
, int32_t readSize
,
1448 int32_t* out_intRead0
, int32_t* out_intWrite0
,
1449 int32_t* out_intSize
);
1451 uint64_t AvailGroups(uint64_t totalAvailItems
, uint64_t firstItemOffset
,
1452 uint32_t groupSize
, uint32_t groupStride
);
1456 class ScopedDrawCallWrapper final
{
1458 WebGLContext
& mWebGL
;
1460 explicit ScopedDrawCallWrapper(WebGLContext
& webgl
);
1461 ~ScopedDrawCallWrapper();
1466 class ScopedPrepForResourceClear final
{
1467 const WebGLContext
& webgl
;
1470 explicit ScopedPrepForResourceClear(const WebGLContext
&);
1471 ~ScopedPrepForResourceClear();
1474 struct IndexedName final
{
1478 Maybe
<IndexedName
> ParseIndexed(const std::string
& str
);
1480 } // namespace webgl
1482 webgl::LinkActiveInfo
GetLinkActiveInfo(
1483 gl::GLContext
& gl
, const GLuint prog
, const bool webgl2
,
1484 const std::unordered_map
<std::string
, std::string
>& nameUnmap
);
1486 } // namespace mozilla