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/UniquePtr.h"
32 #include "mozilla/WeakPtr.h"
33 #include "nsICanvasRenderingContextInternal.h"
35 #include "SurfaceTypes.h"
36 #include "ScopedGLHelpers.h"
37 #include "TexUnpackBlob.h"
40 #include "CacheInvalidator.h"
41 #include "WebGLContextLossHandler.h"
42 #include "WebGLExtensions.h"
43 #include "WebGLObjectModel.h"
44 #include "WebGLStrongTypes.h"
45 #include "WebGLTypes.h"
48 #include "mozilla/dom/WebGLRenderingContextBinding.h"
49 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
57 #define LOCAL_GL_BROWSER_DEFAULT_WEBGL 0x9244
58 #define LOCAL_GL_CONTEXT_LOST_WEBGL 0x9242
59 #define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL 0x9247
60 #define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243
61 #define LOCAL_GL_UNPACK_FLIP_Y_WEBGL 0x9240
62 #define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
66 class HostWebGLContext
;
67 class ScopedCopyTexImageSource
;
68 class ScopedDrawCallWrapper
;
69 class ScopedResolveTexturesForDraw
;
71 class WebGLExtensionBase
;
72 class WebGLFramebuffer
;
75 class WebGLRenderbuffer
;
80 class WebGLTransformFeedback
;
81 class WebGLVertexArray
;
87 class OwningHTMLCanvasElementOrOffscreenCanvas
;
88 struct WebGLContextAttributes
;
105 class CompositableHost
;
106 class RemoteTextureOwnerClient
;
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 dom::ContentParentId
GetContentId() const;
492 WebGLTexture
* GetActiveTex(const GLenum texTarget
) const;
494 gl::GLContext
* GL() const { return gl
; }
496 bool IsPremultAlpha() const { return mOptions
.premultipliedAlpha
; }
498 bool IsPreservingDrawingBuffer() const {
499 return mOptions
.preserveDrawingBuffer
;
502 // Present to compositor
504 bool PresentInto(gl::SwapChain
& swapChain
);
505 bool PresentIntoXR(gl::SwapChain
& swapChain
, const gl::MozFramebuffer
& xrFb
);
508 // Present swaps the front and back buffers of the swap chain for compositing.
509 // This assumes the framebuffer may directly alias with the back buffer,
510 // dependent on remoting state or other concerns. Framebuffer and swap chain
511 // surface formats are assumed to be similar to enable this aliasing. As such,
512 // the back buffer may be invalidated by this swap with the front buffer,
513 // unless overriden by explicitly setting the preserveDrawingBuffer option,
514 // which may incur a further copy to preserve the back buffer.
516 WebGLFramebuffer
*, layers::TextureType
, const bool webvr
,
517 const webgl::SwapChainOptions
& options
= webgl::SwapChainOptions());
518 // CopyToSwapChain forces a copy from the supplied framebuffer into the back
519 // buffer before swapping the front and back buffers of the swap chain for
520 // compositing. The formats of the framebuffer and the swap chain buffers
521 // may differ subject to available format conversion options. Since this
522 // operation uses an explicit copy, it inherently preserves the framebuffer
523 // without need to set the preserveDrawingBuffer option.
524 bool CopyToSwapChain(
525 WebGLFramebuffer
*, layers::TextureType
,
526 const webgl::SwapChainOptions
& options
= webgl::SwapChainOptions(),
527 layers::RemoteTextureOwnerClient
* ownerClient
= nullptr);
528 // In use cases where a framebuffer is used as an offscreen framebuffer and
529 // does not need to be committed to the swap chain, it may still be useful
530 // for the implementation to delineate distinct frames, such as when sharing
531 // a single WebGLContext amongst many distinct users. EndOfFrame signals that
532 // frame rendering is complete so that any implementation side-effects such
533 // as resetting internal profile counters or resource queues may be handled
536 RefPtr
<gfx::DataSourceSurface
> GetFrontBufferSnapshot();
537 Maybe
<uvec2
> FrontBufferSnapshotInto(
538 const Maybe
<Range
<uint8_t>> dest
,
539 const Maybe
<size_t> destStride
= Nothing());
540 Maybe
<uvec2
> FrontBufferSnapshotInto(
541 const std::shared_ptr
<gl::SharedSurface
>& front
,
542 const Maybe
<Range
<uint8_t>> dest
,
543 const Maybe
<size_t> destStride
= Nothing());
544 Maybe
<uvec2
> SnapshotInto(GLuint srcFb
, const gfx::IntSize
& size
,
545 const Range
<uint8_t>& dest
,
546 const Maybe
<size_t> destStride
= Nothing());
547 gl::SwapChain
* GetSwapChain(WebGLFramebuffer
*, const bool webvr
);
548 Maybe
<layers::SurfaceDescriptor
> GetFrontBuffer(WebGLFramebuffer
*,
551 std::optional
<color::ColorProfileDesc
> mDisplayProfile
;
553 void SetDrawingBufferColorSpace(const dom::PredefinedColorSpace val
) {
554 mOptions
.colorSpace
= val
;
557 void ClearVRSwapChain();
559 void RunContextLossTimer();
560 void CheckForContextLoss();
561 void HandlePendingContextLoss();
563 bool TryToRestoreContext();
565 void AssertCachedBindings() const;
566 void AssertCachedGlobalState() const;
568 // WebIDL WebGLRenderingContext API
571 uvec2
DrawingBufferSize();
574 void GetContextAttributes(dom::Nullable
<dom::WebGLContextAttributes
>& retval
);
576 // This is the entrypoint. Don't test against it directly.
577 bool IsContextLost() const {
578 auto* self
= const_cast<WebGLContext
*>(this);
579 if (self
->mPendingContextLoss
.exchange(false)) {
580 self
->HandlePendingContextLoss();
582 return mIsContextLost
;
587 RefPtr
<WebGLBuffer
> CreateBuffer();
588 RefPtr
<WebGLFramebuffer
> CreateFramebuffer();
589 RefPtr
<WebGLFramebuffer
> CreateOpaqueFramebuffer(
590 const webgl::OpaqueFramebufferOptions
& options
);
591 RefPtr
<WebGLProgram
> CreateProgram();
592 RefPtr
<WebGLQuery
> CreateQuery();
593 RefPtr
<WebGLRenderbuffer
> CreateRenderbuffer();
594 RefPtr
<WebGLShader
> CreateShader(GLenum type
);
595 RefPtr
<WebGLTexture
> CreateTexture();
596 RefPtr
<WebGLVertexArray
> CreateVertexArray();
600 void AttachShader(WebGLProgram
& prog
, WebGLShader
& shader
);
601 void BindAttribLocation(WebGLProgram
& prog
, GLuint location
,
602 const std::string
& name
) const;
603 void BindFramebuffer(GLenum target
, WebGLFramebuffer
* fb
);
604 void BindRenderbuffer(GLenum target
, WebGLRenderbuffer
* fb
);
605 void BindVertexArray(WebGLVertexArray
* vao
);
606 void BlendColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
);
607 void BlendEquationSeparate(Maybe
<GLuint
> i
, GLenum modeRGB
, GLenum modeAlpha
);
608 void BlendFuncSeparate(Maybe
<GLuint
> i
, GLenum srcRGB
, GLenum dstRGB
,
609 GLenum srcAlpha
, GLenum dstAlpha
);
610 GLenum
CheckFramebufferStatus(GLenum target
);
611 void Clear(GLbitfield mask
);
612 void ClearColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
);
613 void ClearDepth(GLclampf v
);
614 void ClearStencil(GLint v
);
615 void ColorMask(Maybe
<GLuint
> i
, uint8_t mask
);
616 void CompileShader(WebGLShader
& shader
);
619 void CompileShaderANGLE(WebGLShader
* shader
);
620 void CompileShaderBypass(WebGLShader
* shader
, const nsCString
& shaderSource
);
623 void CullFace(GLenum face
);
624 void DepthFunc(GLenum func
);
625 void DepthMask(WebGLboolean b
);
626 void DepthRange(GLclampf zNear
, GLclampf zFar
);
627 void DetachShader(WebGLProgram
& prog
, const WebGLShader
& shader
);
628 void DrawBuffers(const std::vector
<GLenum
>& buffers
);
632 void FramebufferAttach(GLenum target
, GLenum attachSlot
,
633 GLenum bindImageTarget
,
634 const webgl::FbAttachInfo
& toAttach
);
636 void FrontFace(GLenum mode
);
638 Maybe
<double> GetBufferParameter(GLenum target
, GLenum pname
);
639 webgl::CompileResult
GetCompileResult(const WebGLShader
&) const;
641 GLint
GetFragDataLocation(const WebGLProgram
&, const std::string
& name
) const;
643 Maybe
<double> GetFramebufferAttachmentParameter(WebGLFramebuffer
*,
647 Maybe
<double> GetRenderbufferParameter(const WebGLRenderbuffer
&,
649 webgl::LinkResult
GetLinkResult(const WebGLProgram
&) const;
651 Maybe
<webgl::ShaderPrecisionFormat
> GetShaderPrecisionFormat(
652 GLenum shadertype
, GLenum precisiontype
) const;
654 webgl::GetUniformData
GetUniform(const WebGLProgram
&, uint32_t loc
) const;
656 void Hint(GLenum target
, GLenum mode
);
658 void LineWidth(GLfloat width
);
659 void LinkProgram(WebGLProgram
& prog
);
660 void PolygonOffset(GLfloat factor
, GLfloat units
);
661 void ProvokingVertex(webgl::ProvokingVertex
) const;
665 webgl::PackingInfo
ValidImplementationColorReadPI(
666 const webgl::FormatUsageInfo
* usage
) const;
669 webgl::ReadPixelsResult
ReadPixelsImpl(const webgl::ReadPixelsDesc
&,
670 uintptr_t dest
, uint64_t availBytes
);
671 bool DoReadPixelsAndConvert(const webgl::FormatInfo
* srcFormat
,
672 const webgl::ReadPixelsDesc
&, uintptr_t dest
,
673 uint64_t dataLen
, uint32_t rowStride
);
676 void ReadPixelsPbo(const webgl::ReadPixelsDesc
&, uint64_t offset
);
677 webgl::ReadPixelsResult
ReadPixelsInto(const webgl::ReadPixelsDesc
&,
678 const Range
<uint8_t>& dest
);
682 void RenderbufferStorageMultisample(WebGLRenderbuffer
&, uint32_t samples
,
683 GLenum internalformat
, uint32_t width
,
684 uint32_t height
) const;
687 void SampleCoverage(GLclampf value
, WebGLboolean invert
);
688 void Scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
);
689 void ShaderSource(WebGLShader
& shader
, const std::string
& source
) const;
690 void StencilFuncSeparate(GLenum face
, GLenum func
, GLint ref
, GLuint mask
);
691 void StencilMaskSeparate(GLenum face
, GLuint mask
);
692 void StencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
695 //////////////////////////
697 void UniformData(uint32_t loc
, bool transpose
,
698 const Span
<const webgl::UniformDataVal
>& data
) const;
700 ////////////////////////////////////
702 void UseProgram(WebGLProgram
* prog
);
704 bool ValidateAttribArraySetter(uint32_t count
, uint32_t arrayLength
);
705 bool ValidateProgram(const WebGLProgram
& prog
) const;
706 void Viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
);
708 // -----------------------------------------------------------------------------
709 // Buffer Objects (WebGLContextBuffers.cpp)
710 void BindBuffer(GLenum target
, WebGLBuffer
* buffer
);
711 void BindBufferRange(GLenum target
, GLuint index
, WebGLBuffer
* buf
,
712 uint64_t offset
, uint64_t size
);
714 void BufferData(GLenum target
, uint64_t dataLen
, const uint8_t* data
,
716 void UninitializedBufferData_SizeOnly(GLenum target
, uint64_t dataLen
,
718 // The unsynchronized flag may allow for better performance when
719 // interleaving buffer updates with draw calls. However, care must
720 // be taken. This has similar semantics to glMapBufferRange's
721 // GL_MAP_UNSYNCHRONIZED_BIT: the results of any pending operations
722 // that reference the region of the buffer being updated are
724 void BufferSubData(GLenum target
, uint64_t dstByteOffset
, uint64_t srcDataLen
,
725 const uint8_t* srcData
, bool unsynchronized
= false) const;
728 // bound buffer state
729 RefPtr
<WebGLBuffer
> mBoundArrayBuffer
;
730 RefPtr
<WebGLBuffer
> mBoundCopyReadBuffer
;
731 RefPtr
<WebGLBuffer
> mBoundCopyWriteBuffer
;
732 RefPtr
<WebGLBuffer
> mBoundPixelPackBuffer
;
733 RefPtr
<WebGLBuffer
> mBoundPixelUnpackBuffer
;
734 RefPtr
<WebGLBuffer
> mBoundTransformFeedbackBuffer
;
735 RefPtr
<WebGLBuffer
> mBoundUniformBuffer
;
737 std::vector
<IndexedBufferBinding
> mIndexedUniformBufferBindings
;
739 RefPtr
<WebGLBuffer
>& GetBufferSlotByTarget(GLenum target
);
740 RefPtr
<WebGLBuffer
>& GetBufferSlotByTargetIndexed(GLenum target
,
745 void GenErrorIllegalUse(GLenum useTarget
, uint32_t useId
, GLenum boundTarget
,
746 uint32_t boundId
) const;
748 bool ValidateBufferForNonTf(const WebGLBuffer
&, GLenum nonTfTarget
,
749 uint32_t nonTfId
) const;
751 bool ValidateBufferForNonTf(const WebGLBuffer
* const nonTfBuffer
,
752 const GLenum nonTfTarget
,
753 const uint32_t nonTfId
= -1) const {
754 if (!nonTfBuffer
) return true;
755 return ValidateBufferForNonTf(*nonTfBuffer
, nonTfTarget
, nonTfId
);
758 bool ValidateBuffersForTf(const WebGLTransformFeedback
&,
759 const webgl::LinkedProgramInfo
&) const;
760 bool ValidateBuffersForTf(
761 const std::vector
<webgl::BufferAndIndex
>& tfBuffers
) const;
763 // -----------------------------------------------------------------------------
764 // Queries (WebGL2ContextQueries.cpp)
766 RefPtr
<WebGLQuery
> mQuerySlot_SamplesPassed
;
767 RefPtr
<WebGLQuery
> mQuerySlot_TFPrimsWritten
;
768 RefPtr
<WebGLQuery
> mQuerySlot_TimeElapsed
;
770 RefPtr
<WebGLQuery
>* ValidateQuerySlotByTarget(GLenum target
);
773 void BeginQuery(GLenum target
, WebGLQuery
& query
);
774 void EndQuery(GLenum target
);
775 Maybe
<double> GetQueryParameter(const WebGLQuery
& query
, GLenum pname
) const;
776 void QueryCounter(WebGLQuery
&) const;
778 // -----------------------------------------------------------------------------
779 // State and State Requests (WebGLContextState.cpp)
780 void SetEnabled(GLenum cap
, Maybe
<GLuint
> i
, bool enabled
);
781 bool GetStencilBits(GLint
* const out_stencilBits
) const;
783 virtual Maybe
<double> GetParameter(GLenum pname
);
784 Maybe
<std::string
> GetString(GLenum pname
) const;
787 static StaticMutex sLruMutex
;
788 static std::list
<WebGLContext
*> sLru
MOZ_GUARDED_BY(sLruMutex
);
790 // State tracking slots
791 bool mDitherEnabled
= true;
792 bool mRasterizerDiscardEnabled
= false;
793 bool mScissorTestEnabled
= false;
794 bool mDepthTestEnabled
= false;
795 bool mStencilTestEnabled
= false;
796 GLenum mGenerateMipmapHint
= LOCAL_GL_DONT_CARE
;
798 struct ScissorRect final
{
804 void Apply(gl::GLContext
&) const;
806 ScissorRect mScissorRect
= {};
808 bool* GetStateTrackingSlot(GLenum cap
);
810 // Allocation debugging variables
811 mutable uint64_t mDataAllocGLCallCount
= 0;
813 void OnDataAllocCall() const { mDataAllocGLCallCount
++; }
815 uint64_t GetNumGLDataAllocCalls() const { return mDataAllocGLCallCount
; }
819 // -----------------------------------------------------------------------------
820 // Texture funcions (WebGLContextTextures.cpp)
822 void ActiveTexture(uint32_t texUnit
);
823 void BindTexture(GLenum texTarget
, WebGLTexture
* tex
);
824 void GenerateMipmap(GLenum texTarget
);
826 Maybe
<double> GetTexParameter(const WebGLTexture
&, GLenum pname
) const;
827 void TexParameter_base(GLenum texTarget
, GLenum pname
,
828 const FloatOrInt
& param
);
830 virtual bool IsTexParamValid(GLenum pname
) const;
832 ////////////////////////////////////
835 // CompressedTexSubImage if `sub`
836 void CompressedTexImage(bool sub
, GLenum imageTarget
, uint32_t level
,
837 GLenum format
, uvec3 offset
, uvec3 size
,
838 const Range
<const uint8_t>& src
,
839 const uint32_t pboImageSize
,
840 const Maybe
<uint64_t>& pboOffset
) const;
842 // CopyTexSubImage if `!respectFormat`
843 void CopyTexImage(GLenum imageTarget
, uint32_t level
, GLenum respecFormat
,
844 uvec3 dstOffset
, const ivec2
& srcOffset
,
845 const uvec2
& size
) const;
847 // TexSubImage if `!respectFormat`
848 void TexImage(uint32_t level
, GLenum respecFormat
, uvec3 offset
,
849 const webgl::PackingInfo
& pi
,
850 const webgl::TexUnpackBlobDesc
&) const;
852 void TexStorage(GLenum texTarget
, uint32_t levels
, GLenum sizedFormat
,
855 UniquePtr
<webgl::TexUnpackBlob
> ToTexUnpackBytes(
856 const WebGLTexImageData
& imageData
);
858 UniquePtr
<webgl::TexUnpackBytes
> ToTexUnpackBytes(WebGLTexPboOffset
& aPbo
);
860 ////////////////////////////////////
861 // WebGLTextureUpload.cpp
863 bool ValidateTexImageSpecification(uint8_t funcDims
, GLenum texImageTarget
,
864 GLint level
, GLsizei width
, GLsizei height
,
865 GLsizei depth
, GLint border
,
866 TexImageTarget
* const out_target
,
867 WebGLTexture
** const out_texture
,
868 webgl::ImageInfo
** const out_imageInfo
);
869 bool ValidateTexImageSelection(uint8_t funcDims
, GLenum texImageTarget
,
870 GLint level
, GLint xOffset
, GLint yOffset
,
871 GLint zOffset
, GLsizei width
, GLsizei height
,
873 TexImageTarget
* const out_target
,
874 WebGLTexture
** const out_texture
,
875 webgl::ImageInfo
** const out_imageInfo
);
876 bool ValidateUnpackInfo(bool usePBOs
, GLenum format
, GLenum type
,
877 webgl::PackingInfo
* const out
);
879 // -----------------------------------------------------------------------------
880 // Vertices Feature (WebGLContextVertices.cpp)
881 GLenum mPrimRestartTypeBytes
= 0;
884 void DrawArraysInstanced(GLenum mode
, GLint first
, GLsizei vertexCount
,
885 GLsizei instanceCount
);
886 void DrawElementsInstanced(GLenum mode
, GLsizei vertexCount
, GLenum type
,
887 WebGLintptr byteOffset
, GLsizei instanceCount
);
889 void EnableVertexAttribArray(GLuint index
);
890 void DisableVertexAttribArray(GLuint index
);
892 Maybe
<double> GetVertexAttrib(GLuint index
, GLenum pname
);
896 void VertexAttrib4T(GLuint index
, const webgl::TypedQuad
&);
900 void VertexAttribPointer(uint32_t index
, const webgl::VertAttribPointerDesc
&);
902 void VertexAttribDivisor(GLuint index
, GLuint divisor
);
905 WebGLBuffer
* DrawElements_check(GLsizei indexCount
, GLenum type
,
906 WebGLintptr byteOffset
,
907 GLsizei instanceCount
);
910 void VertexAttrib1fv_base(GLuint index
, uint32_t arrayLength
,
912 void VertexAttrib2fv_base(GLuint index
, uint32_t arrayLength
,
914 void VertexAttrib3fv_base(GLuint index
, uint32_t arrayLength
,
916 void VertexAttrib4fv_base(GLuint index
, uint32_t arrayLength
,
919 bool BindArrayAttribToLocation0(WebGLProgram
* prog
);
921 // -----------------------------------------------------------------------------
924 WebGLVertexAttrib0Status
WhatDoesVertexAttrib0Need() const;
925 bool DoFakeVertexAttrib0(uint64_t fakeVertexCount
,
926 WebGLVertexAttrib0Status whatDoesAttrib0Need
);
927 void UndoFakeVertexAttrib0();
929 bool mResetLayer
= true;
930 bool mOptionsFrozen
= false;
931 bool mIsMesa
= false;
932 bool mLoseContextOnMemoryPressure
= false;
933 bool mCanLoseContextInForeground
= true;
934 bool mShouldPresent
= false;
935 bool mDisableFragHighP
= false;
936 bool mForceResizeOnPresent
= false;
937 bool mVRReady
= false;
939 template <typename WebGLObjectType
>
940 void DeleteWebGLObjectsArray(nsTArray
<WebGLObjectType
>& array
);
942 GLuint mActiveTexture
= 0;
943 GLenum mDefaultFB_DrawBuffer0
= LOCAL_GL_BACK
;
944 GLenum mDefaultFB_ReadBuffer
= LOCAL_GL_BACK
;
946 mutable GLenum mWebGLError
= 0;
948 std::unique_ptr
<webgl::ShaderValidator
> CreateShaderValidator(
949 GLenum shaderType
) const;
952 uint32_t mGLMaxFragmentUniformVectors
= 0;
953 uint32_t mGLMaxVertexUniformVectors
= 0;
954 uint32_t mGLMaxVertexOutputVectors
= 0;
955 uint32_t mGLMaxFragmentInputVectors
= 0;
957 uint32_t mGLMaxVertexTextureImageUnits
= 0;
958 uint32_t mGLMaxFragmentTextureImageUnits
= 0;
959 uint32_t mGLMaxCombinedTextureImageUnits
= 0;
962 uint32_t mGLMinProgramTexelOffset
= 0;
963 uint32_t mGLMaxProgramTexelOffset
= 0;
966 auto GLMaxDrawBuffers() const { return mLimits
->maxColorDrawBuffers
; }
968 uint32_t MaxValidDrawBuffers() const {
970 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers
)) {
971 return GLMaxDrawBuffers();
976 GLenum
LastColorAttachmentEnum() const {
977 return LOCAL_GL_COLOR_ATTACHMENT0
+ MaxValidDrawBuffers() - 1;
980 const auto& Options() const { return mOptions
; }
983 uint32_t mGLMaxRenderbufferSize
= 0;
986 const auto& Limits() const { return *mLimits
; }
987 auto MaxVertexAttribs() const { return mLimits
->maxVertexAttribs
; }
988 auto GLMaxTextureUnits() const { return mLimits
->maxTexUnits
; }
990 bool IsFormatValidForFB(TexInternalFormat format
) const;
993 // -------------------------------------------------------------------------
994 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
996 EnumeratedArray
<WebGLExtensionID
, std::unique_ptr
<WebGLExtensionBase
>,
997 size_t(WebGLExtensionID::Max
)>
1001 void RequestExtension(WebGLExtensionID
, bool explicitly
= true);
1003 // returns true if the extension has been enabled by calling getExtension.
1004 bool IsExtensionEnabled(const WebGLExtensionID id
) const {
1005 return bool(mExtensions
[id
]);
1008 bool IsExtensionExplicit(WebGLExtensionID
) const;
1009 void WarnIfImplicit(WebGLExtensionID
) const;
1011 bool IsExtensionSupported(WebGLExtensionID
) const;
1013 // -------------------------------------------------------------------------
1014 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
1016 virtual bool IsWebGL2() const { return false; }
1018 struct FailureReason
{
1019 nsCString key
; // For reporting.
1022 FailureReason() = default;
1024 template <typename A
, typename B
>
1025 FailureReason(const A
& _key
, const B
& _info
)
1026 : key(nsCString(_key
)), info(nsCString(_info
)) {}
1030 bool InitWebGL2(FailureReason
* const out_failReason
);
1032 bool CreateAndInitGL(bool forceEnabled
,
1033 std::vector
<FailureReason
>* const out_failReasons
);
1035 // -------------------------------------------------------------------------
1036 // Validation functions (implemented in WebGLContextValidate.cpp)
1037 bool InitAndValidateGL(FailureReason
* const out_failReason
);
1039 bool ValidateBlendEquationEnum(GLenum cap
, const char* info
);
1040 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor
, GLenum dfactor
,
1042 bool ValidateStencilOpEnum(GLenum action
, const char* info
);
1043 bool ValidateFaceEnum(GLenum face
);
1044 bool ValidateTexInputData(GLenum type
, js::Scalar::Type jsArrayType
,
1045 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1046 bool ValidateAttribPointer(bool integerMode
, GLuint index
, GLint size
,
1047 GLenum type
, WebGLboolean normalized
,
1048 GLsizei stride
, WebGLintptr byteOffset
,
1050 bool ValidateStencilParamsForDrawCall() const;
1052 bool ValidateCopyTexImage(TexInternalFormat srcFormat
,
1053 TexInternalFormat dstformat
, WebGLTexImageFunc func
,
1054 WebGLTexDimensions dims
);
1056 bool ValidateTexImage(TexImageTarget texImageTarget
, GLint level
,
1057 GLenum internalFormat
, GLint xoffset
, GLint yoffset
,
1058 GLint zoffset
, GLint width
, GLint height
, GLint depth
,
1059 GLint border
, GLenum format
, GLenum type
,
1060 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1061 bool ValidateTexImageFormat(GLenum internalFormat
, WebGLTexImageFunc func
,
1062 WebGLTexDimensions dims
);
1063 bool ValidateTexImageType(GLenum type
, WebGLTexImageFunc func
,
1064 WebGLTexDimensions dims
);
1065 bool ValidateTexImageFormatAndType(GLenum format
, GLenum type
,
1066 WebGLTexImageFunc func
,
1067 WebGLTexDimensions dims
);
1068 bool ValidateCompTexImageInternalFormat(GLenum format
, WebGLTexImageFunc func
,
1069 WebGLTexDimensions dims
);
1070 bool ValidateCopyTexImageInternalFormat(GLenum format
, WebGLTexImageFunc func
,
1071 WebGLTexDimensions dims
);
1072 bool ValidateTexImageSize(TexImageTarget texImageTarget
, GLint level
,
1073 GLint width
, GLint height
, GLint depth
,
1074 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1075 bool ValidateTexSubImageSize(GLint x
, GLint y
, GLint z
, GLsizei width
,
1076 GLsizei height
, GLsizei depth
, GLsizei baseWidth
,
1077 GLsizei baseHeight
, GLsizei baseDepth
,
1078 WebGLTexImageFunc func
, WebGLTexDimensions dims
);
1079 bool ValidateCompTexImageSize(GLint level
, GLenum internalFormat
,
1080 GLint xoffset
, GLint yoffset
, GLsizei width
,
1081 GLsizei height
, GLsizei levelWidth
,
1082 GLsizei levelHeight
, WebGLTexImageFunc func
,
1083 WebGLTexDimensions dims
);
1084 bool ValidateCompTexImageDataSize(GLint level
, GLenum internalFormat
,
1085 GLsizei width
, GLsizei height
,
1086 uint32_t byteLength
, WebGLTexImageFunc func
,
1087 WebGLTexDimensions dims
);
1089 bool HasDrawBuffers() const {
1090 return IsWebGL2() ||
1091 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers
);
1094 RefPtr
<WebGLBuffer
>* ValidateBufferSlot(GLenum target
);
1097 WebGLBuffer
* ValidateBufferSelection(GLenum target
) const;
1100 IndexedBufferBinding
* ValidateIndexedBufferSlot(GLenum target
, GLuint index
);
1102 bool ValidateIndexedBufferBinding(
1103 GLenum target
, GLuint index
,
1104 RefPtr
<WebGLBuffer
>** const out_genericBinding
,
1105 IndexedBufferBinding
** const out_indexedBinding
);
1108 bool ValidateNonNegative(const char* argName
, int64_t val
) const {
1109 if (MOZ_UNLIKELY(val
< 0)) {
1110 ErrorInvalidValue("`%s` must be non-negative.", argName
);
1116 template <typename T
>
1117 bool ValidateNonNull(const char* const argName
,
1118 const dom::Nullable
<T
>& maybe
) const {
1119 if (maybe
.IsNull()) {
1120 ErrorInvalidValue("%s: Cannot be null.", argName
);
1129 void DestroyResourcesAndContext();
1133 bool ConvertImage(size_t width
, size_t height
, size_t srcStride
,
1134 size_t dstStride
, const uint8_t* src
, uint8_t* dst
,
1135 WebGLTexelFormat srcFormat
, bool srcPremultiplied
,
1136 WebGLTexelFormat dstFormat
, bool dstPremultiplied
,
1137 size_t dstTexelSize
);
1141 template <typename T
>
1142 bool ValidateObject(const char* const argName
, const T
& object
) const {
1143 // Todo: Remove all callers.
1147 template <typename T
>
1148 bool ValidateObject(const char* const argName
, const T
* const object
) const {
1149 // Todo: Remove most (all?) callers.
1151 ErrorInvalidOperation(
1152 "%s: Object argument cannot have been marked for"
1163 void LoseContextLruLocked(webgl::ContextLossReason reason
)
1164 MOZ_REQUIRES(sLruMutex
);
1168 webgl::ContextLossReason reason
= webgl::ContextLossReason::None
);
1171 nsTArray
<RefPtr
<WebGLTexture
>> mBound2DTextures
;
1172 nsTArray
<RefPtr
<WebGLTexture
>> mBoundCubeMapTextures
;
1173 nsTArray
<RefPtr
<WebGLTexture
>> mBound3DTextures
;
1174 nsTArray
<RefPtr
<WebGLTexture
>> mBound2DArrayTextures
;
1175 nsTArray
<RefPtr
<WebGLSampler
>> mBoundSamplers
;
1177 mutable std::unique_ptr
<gl::Sampler
> mSamplerLinear
;
1179 GLuint
SamplerLinear() const;
1181 void ResolveTexturesForDraw() const;
1183 RefPtr
<WebGLProgram
> mCurrentProgram
;
1184 RefPtr
<const webgl::LinkedProgramInfo
> mActiveProgramLinkInfo
;
1186 bool ValidateFramebufferTarget(GLenum target
) const;
1187 bool ValidateInvalidateFramebuffer(GLenum target
,
1188 const Span
<const GLenum
>& attachments
,
1189 std::vector
<GLenum
>* const scopedVector
,
1190 GLsizei
* const out_glNumAttachments
,
1191 const GLenum
** const out_glAttachments
);
1193 RefPtr
<WebGLFramebuffer
> mBoundDrawFramebuffer
;
1194 RefPtr
<WebGLFramebuffer
> mBoundReadFramebuffer
;
1195 RefPtr
<WebGLTransformFeedback
> mBoundTransformFeedback
;
1196 RefPtr
<WebGLVertexArray
> mBoundVertexArray
;
1199 const auto& BoundReadFb() const { return mBoundReadFramebuffer
; }
1202 RefPtr
<WebGLTransformFeedback
> mDefaultTransformFeedback
;
1203 RefPtr
<WebGLVertexArray
> mDefaultVertexArray
;
1205 ////////////////////////////////////
1208 GLuint mEmptyTFO
= 0;
1210 // Generic Vertex Attributes
1211 // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the
1212 // spec state tables, this isn't vertex shader /object/ state. This array is
1213 // merely state useful to vertex shaders, but is global state.
1214 std::vector
<webgl::AttribBaseType
> mGenericVertexAttribTypes
;
1215 CacheInvalidator mGenericVertexAttribTypeInvalidator
;
1217 GLuint mFakeVertexAttrib0BufferObject
= 0;
1218 intptr_t mFakeVertexAttrib0BufferObjectSize
= 0;
1219 bool mFakeVertexAttrib0DataDefined
= false;
1220 alignas(alignof(float)) uint8_t
1221 mGenericVertexAttrib0Data
[sizeof(float) * 4] = {};
1222 alignas(alignof(float)) uint8_t
1223 mFakeVertexAttrib0Data
[sizeof(float) * 4] = {};
1225 GLint mStencilRefFront
= 0;
1226 GLint mStencilRefBack
= 0;
1227 GLuint mStencilValueMaskFront
= 0;
1228 GLuint mStencilValueMaskBack
= 0;
1229 GLuint mStencilWriteMaskFront
= 0;
1230 GLuint mStencilWriteMaskBack
= 0;
1231 uint8_t mColorWriteMask0
= 0xf; // bitmask
1232 mutable uint8_t mDriverColorMask0
= 0xf;
1233 bool mDepthWriteMask
= true;
1234 GLfloat mColorClearValue
[4] = {0, 0, 0, 0};
1235 GLint mStencilClearValue
= 0;
1236 GLfloat mDepthClearValue
= 1.0f
;
1238 std::bitset
<webgl::kMaxDrawBuffers
> mColorWriteMaskNonzero
= -1;
1239 std::bitset
<webgl::kMaxDrawBuffers
> mBlendEnabled
= 0;
1241 std::unordered_set
<GLenum
> mIsEnabledMapKeys
;
1243 GLint mViewportX
= 0;
1244 GLint mViewportY
= 0;
1245 GLsizei mViewportWidth
= 0;
1246 GLsizei mViewportHeight
= 0;
1247 bool mAlreadyWarnedAboutViewportLargerThanDest
= false;
1249 GLfloat mLineWidth
= 1.0;
1251 WebGLContextLossHandler mContextLossHandler
;
1253 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1254 // be Flushed while doing hundreds of draw calls.
1255 mutable uint64_t mDrawCallsSinceLastFlush
= 0;
1257 mutable uint64_t mWarningCount
= 0;
1258 const uint64_t mMaxWarnings
= StaticPrefs::webgl_max_warnings_per_context();
1259 bool mAlreadyWarnedAboutFakeVertexAttrib0
= false;
1261 bool ShouldGenerateWarnings() const { return mWarningCount
< mMaxWarnings
; }
1263 bool ShouldGeneratePerfWarnings() const {
1264 return mNumPerfWarnings
< mMaxPerfWarnings
;
1267 bool mNeedsFakeNoAlpha
= false;
1268 bool mNeedsFakeNoDepth
= false;
1269 bool mNeedsFakeNoStencil
= false;
1271 bool mDriverDepthTest
= false;
1272 bool mDriverStencilTest
= false;
1274 bool mNeedsLegacyVertexAttrib0Handling
= false;
1275 bool mMaybeNeedsLegacyVertexAttrib0Handling
= false;
1276 bool mNeedsIndexValidation
= false;
1277 bool mBug_DrawArraysInstancedUserAttribFetchAffectedByFirst
= false;
1279 const bool mAllowFBInvalidation
= StaticPrefs::webgl_allow_fb_invalidation();
1281 bool Has64BitTimestamps() const;
1285 const uint8_t mMsaaSamples
=
1286 static_cast<uint8_t>(StaticPrefs::webgl_msaa_samples());
1287 mutable uvec2 mRequestedSize
;
1288 mutable UniquePtr
<gl::MozFramebuffer
> mDefaultFB
;
1289 mutable bool mDefaultFB_IsInvalid
= false;
1290 mutable UniquePtr
<gl::MozFramebuffer
> mResolvedDefaultFB
;
1292 mutable std::unordered_map
<std::tuple
<gfx::ColorSpace2
, gfx::ColorSpace2
>,
1293 std::shared_ptr
<gl::Texture
>>
1294 mLutTexByColorMapping
;
1296 gl::SwapChain mSwapChain
;
1297 gl::SwapChain mWebVRSwapChain
;
1299 RefPtr
<layers::RemoteTextureOwnerClient
> mRemoteTextureOwner
;
1301 bool PushRemoteTexture(
1302 WebGLFramebuffer
*, gl::SwapChain
&, std::shared_ptr
<gl::SharedSurface
>,
1303 const webgl::SwapChainOptions
& options
,
1304 layers::RemoteTextureOwnerClient
* ownerClient
= nullptr);
1306 void EnsureContextLostRemoteTextureOwner(
1307 const webgl::SwapChainOptions
& options
);
1310 void WaitForTxn(layers::RemoteTextureOwnerId ownerId
,
1311 layers::RemoteTextureTxnType txnType
,
1312 layers::RemoteTextureTxnId txnId
);
1317 bool EnsureDefaultFB();
1318 bool ValidateAndInitFB(
1319 const WebGLFramebuffer
* fb
,
1320 GLenum incompleteFbError
= LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION
);
1321 void DoBindFB(const WebGLFramebuffer
* fb
,
1322 GLenum target
= LOCAL_GL_FRAMEBUFFER
) const;
1324 bool BindCurFBForDraw();
1325 bool BindCurFBForColorRead(
1326 const webgl::FormatUsageInfo
** out_format
, uint32_t* out_width
,
1327 uint32_t* out_height
,
1328 GLenum incompleteFbError
= LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION
);
1329 void DoColorMask(Maybe
<GLuint
> i
, uint8_t bitmask
) const;
1330 void BlitBackbufferToCurDriverFB(
1331 WebGLFramebuffer
* const srcAsWebglFb
= nullptr,
1332 const gl::MozFramebuffer
* const srcAsMozFb
= nullptr,
1333 bool srcIsBGRA
= false) const;
1335 struct GetDefaultFBForReadDesc
{
1336 bool endOfFrame
= false;
1338 const gl::MozFramebuffer
* GetDefaultFBForRead(const GetDefaultFBForReadDesc
&);
1339 const gl::MozFramebuffer
* GetDefaultFBForRead() {
1340 return GetDefaultFBForRead({});
1343 bool BindDefaultFBForRead();
1348 // console logging helpers
1349 template <typename
... Args
>
1350 void GenerateWarning(const char* const fmt
, const Args
&... args
) const {
1351 GenerateError(0, fmt
, args
...);
1354 template <typename
... Args
>
1355 void GeneratePerfWarning(const char* const fmt
, const Args
&... args
) const {
1356 GenerateError(webgl::kErrorPerfWarning
, fmt
, args
...);
1360 UniquePtr
<webgl::FormatUsageAuthority
> mFormatUsage
;
1362 virtual UniquePtr
<webgl::FormatUsageAuthority
> CreateFormatUsage(
1363 gl::GLContext
* gl
) const;
1365 const decltype(mBound2DTextures
)* TexListForElemType(GLenum elemType
) const;
1368 friend class ScopedCopyTexImageSource
;
1369 friend class ScopedResolveTexturesForDraw
;
1370 friend class webgl::TexUnpackBlob
;
1371 friend class webgl::TexUnpackBytes
;
1372 friend class webgl::TexUnpackImage
;
1373 friend class webgl::TexUnpackSurface
;
1374 friend struct webgl::UniformInfo
;
1375 friend class WebGLTexture
;
1376 friend class WebGLFBAttachPoint
;
1377 friend class WebGLFramebuffer
;
1378 friend class WebGLRenderbuffer
;
1379 friend class WebGLProgram
;
1380 friend class WebGLQuery
;
1381 friend class WebGLBuffer
;
1382 friend class WebGLSampler
;
1383 friend class WebGLShader
;
1384 friend class WebGLSync
;
1385 friend class WebGLTransformFeedback
;
1386 friend class WebGLVertexArray
;
1387 friend class WebGLVertexArrayFake
;
1388 friend class WebGLVertexArrayGL
;
1391 // Returns `value` rounded to the next highest multiple of `multiple`.
1392 // AKA PadToAlignment, StrideForAlignment.
1393 template <typename V
, typename M
>
1394 V
RoundUpToMultipleOf(const V
& value
, const M
& multiple
) {
1395 return ((value
+ multiple
- 1) / multiple
) * multiple
;
1398 class ScopedFBRebinder final
{
1400 const WebGLContext
* const mWebGL
;
1403 explicit ScopedFBRebinder(const WebGLContext
* const webgl
) : mWebGL(webgl
) {}
1404 ~ScopedFBRebinder();
1409 constexpr inline bool IsBufferTargetLazilyBound(const GLenum target
) {
1410 return target
!= LOCAL_GL_ELEMENT_ARRAY_BUFFER
;
1413 void DoBindBuffer(gl::GLContext
&, GLenum target
, const WebGLBuffer
*);
1415 class ScopedLazyBind final
{
1418 const GLenum mTarget
;
1421 ScopedLazyBind(gl::GLContext
* const gl
, const GLenum target
,
1422 const WebGLBuffer
* const buf
)
1423 : mGL(*gl
), mTarget(IsBufferTargetLazilyBound(target
) ? target
: 0) {
1425 DoBindBuffer(mGL
, mTarget
, buf
);
1431 DoBindBuffer(mGL
, mTarget
, nullptr);
1438 bool Intersect(int32_t srcSize
, int32_t read0
, int32_t readSize
,
1439 int32_t* out_intRead0
, int32_t* out_intWrite0
,
1440 int32_t* out_intSize
);
1442 uint64_t AvailGroups(uint64_t totalAvailItems
, uint64_t firstItemOffset
,
1443 uint32_t groupSize
, uint32_t groupStride
);
1447 class ScopedDrawCallWrapper final
{
1449 WebGLContext
& mWebGL
;
1451 explicit ScopedDrawCallWrapper(WebGLContext
& webgl
);
1452 ~ScopedDrawCallWrapper();
1457 class ScopedPrepForResourceClear final
{
1458 const WebGLContext
& webgl
;
1461 explicit ScopedPrepForResourceClear(const WebGLContext
&);
1462 ~ScopedPrepForResourceClear();
1465 struct IndexedName final
{
1469 Maybe
<IndexedName
> ParseIndexed(const std::string
& str
);
1471 } // namespace webgl
1473 webgl::LinkActiveInfo
GetLinkActiveInfo(
1474 gl::GLContext
& gl
, const GLuint prog
, const bool webgl2
,
1475 const std::unordered_map
<std::string
, std::string
>& nameUnmap
);
1477 } // namespace mozilla