Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / canvas / WebGLContext.h
blobcaa5eeec4d9f5998cb0da91411d1cd5e3af2eaf9
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_
9 #include <bitset>
10 #include <memory>
11 #include <stdarg.h>
13 #include "Colorspaces.h"
14 #include "GLContextTypes.h"
15 #include "GLDefs.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"
33 #include "nsTArray.h"
34 #include "SurfaceTypes.h"
35 #include "ScopedGLHelpers.h"
36 #include "TexUnpackBlob.h"
38 // Local
39 #include "CacheInvalidator.h"
40 #include "WebGLContextLossHandler.h"
41 #include "WebGLExtensions.h"
42 #include "WebGLObjectModel.h"
43 #include "WebGLStrongTypes.h"
44 #include "WebGLTypes.h"
46 // Generated
47 #include "mozilla/dom/WebGLRenderingContextBinding.h"
48 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
50 #include <list>
52 class nsIDocShell;
54 // WebGL-only GLenums
55 // clang-format off
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
62 // clang-format on
64 namespace mozilla {
65 class HostWebGLContext;
66 class ScopedCopyTexImageSource;
67 class ScopedDrawCallWrapper;
68 class ScopedResolveTexturesForDraw;
69 class WebGLBuffer;
70 class WebGLExtensionBase;
71 class WebGLFramebuffer;
72 class WebGLProgram;
73 class WebGLQuery;
74 class WebGLRenderbuffer;
75 class WebGLSampler;
76 class WebGLShader;
77 class WebGLSync;
78 class WebGLTexture;
79 class WebGLTransformFeedback;
80 class WebGLVertexArray;
82 namespace dom {
83 class Document;
84 class Element;
85 class ImageData;
86 class OwningHTMLCanvasElementOrOffscreenCanvas;
87 struct WebGLContextAttributes;
88 } // namespace dom
90 namespace gfx {
91 class SourceSurface;
92 class VRLayerChild;
93 } // namespace gfx
95 namespace gl {
96 class GLScreenBuffer;
97 class MozFramebuffer;
98 class SharedSurface;
99 class Sampler;
100 class Texture;
101 } // namespace gl
103 namespace layers {
104 class CompositableHost;
105 class RemoteTextureOwnerClient;
106 class SharedSurfacesHolder;
107 class SurfaceDescriptor;
108 } // namespace layers
110 namespace webgl {
111 class AvailabilityRunnable;
112 struct CachedDrawFetchLimits;
113 struct FbAttachInfo;
114 struct FormatInfo;
115 class FormatUsageAuthority;
116 struct FormatUsageInfo;
117 struct ImageInfo;
118 struct LinkedProgramInfo;
119 struct SamplerUniformInfo;
120 struct SamplingState;
121 class ScopedPrepForResourceClear;
122 class ShaderValidator;
123 class TexUnpackBlob;
124 struct UniformInfo;
125 struct UniformBlockInfo;
126 struct VertAttribPointerDesc;
127 } // namespace webgl
129 struct WebGLTexImageData {
130 TexImageTarget mTarget;
131 int32_t mRowLength;
132 uint32_t mWidth;
133 uint32_t mHeight;
134 uint32_t mDepth;
135 gfxAlphaType mSrcAlphaType;
138 struct WebGLTexPboOffset {
139 TexImageTarget mTarget;
140 uint32_t mWidth;
141 uint32_t mHeight;
142 uint32_t mDepth;
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;
158 union {
159 GLint i;
160 GLfloat f;
161 GLuint u;
162 } mValue;
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 ////////////////////////////////////
177 namespace webgl {
179 class AvailabilityRunnable final : public DiscardableRunnable {
180 public:
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;
191 } // namespace webgl
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,
227 uint32_t);
228 friend RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
229 WebGLProgram* prog, gl::GLContext* gl);
231 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLContext, override)
233 enum {
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
246 private:
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;
255 public:
256 void AssignLocked(WebGLContext& aContext) MOZ_REQUIRES(sLruMutex);
257 void Reset();
258 void ResetLocked() MOZ_REQUIRES(sLruMutex);
259 bool IsInsertedLocked() const MOZ_REQUIRES(sLruMutex);
261 LruPosition();
262 explicit LruPosition(WebGLContext&);
264 ~LruPosition() { Reset(); }
267 mutable LruPosition mLruPosition MOZ_GUARDED_BY(sLruMutex);
269 void BumpLruLocked() MOZ_REQUIRES(sLruMutex);
271 public:
272 void BumpLru();
273 void LoseLruContextIfLimitExceeded();
275 // -
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;
282 public:
283 // Grab a const reference so we can see changes, but can't make changes.
284 const decltype(mGL_OnlyClearInDestroyResourcesAndContext)& gl;
286 public:
287 void CheckForInactivity();
289 protected:
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;
313 // -
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.
322 public:
323 void EnsurePollPendingSyncs_Pending() const;
324 void PollPendingSyncs() const;
326 protected:
327 std::unique_ptr<gl::Texture> mIncompleteTexOverride;
329 public:
330 class FuncScope;
332 private:
333 mutable FuncScope* mFuncScope = nullptr;
335 public:
336 static RefPtr<WebGLContext> Create(HostWebGLContext*,
337 const webgl::InitContextDesc&,
338 webgl::InitContextResult* out);
340 private:
341 webgl::OptionalRenderableFormatBits mOptionalRenderableFormatBits =
342 webgl::OptionalRenderableFormatBits{0};
343 void FinishInit();
345 protected:
346 WebGLContext(HostWebGLContext*, const webgl::InitContextDesc&);
347 virtual ~WebGLContext();
349 RefPtr<layers::CompositableHost> mCompositableHost;
351 layers::LayersBackend mBackend = layers::LayersBackend::LAYERS_NONE;
353 public:
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();
367 // -
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:
373 * AttachShader
374 * DetachShader
375 * BindFramebuffer
376 * FramebufferAttach
377 * BindBuffer
378 * BindBufferRange
379 * BindTexture
380 * UseProgram
381 * BindSampler
382 * BindTransformFeedback
383 * BindVertexArray
384 * BeginQuery
385 * EndQuery
386 * ActiveTexture
390 const auto& CurFuncScope() const { return *mFuncScope; }
391 const char* FuncName() const;
393 class FuncScope final {
394 public:
395 const WebGLContext& mWebGL;
396 const char* const mFuncName;
397 bool mBindFailureGuard = false;
399 public:
400 FuncScope(const WebGLContext& webgl, const char* funcName);
401 ~FuncScope();
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());
418 nsCString text;
419 text.AppendPrintf("WebGL warning: %s: ", FuncName());
421 #ifdef __clang__
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"
427 #endif
428 text.AppendPrintf(fmt, args...);
429 #ifdef __clang__
430 # pragma clang diagnostic pop
431 #elif defined(__GNUC__)
432 # pragma GCC diagnostic pop
433 #endif
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",
467 fmt);
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
505 private:
506 bool PresentInto(gl::SwapChain& swapChain);
507 bool PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& xrFb);
509 public:
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.
517 void Present(
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
536 // appropriately.
537 void EndOfFrame();
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*,
551 const bool webvr);
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
577 void Commit();
579 uvec2 DrawingBufferSize();
581 public:
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;
593 // -
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();
606 // -
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);
626 private:
627 void CompileShaderANGLE(WebGLShader* shader);
628 void CompileShaderBypass(WebGLShader* shader, const nsCString& shaderSource);
630 public:
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);
637 void Flush();
638 void Finish();
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;
648 GLenum GetError();
649 GLint GetFragDataLocation(const WebGLProgram&, const std::string& name) const;
651 Maybe<double> GetFramebufferAttachmentParameter(WebGLFramebuffer*,
652 GLenum attachment,
653 GLenum pname) const;
655 Maybe<double> GetRenderbufferParameter(const WebGLRenderbuffer&,
656 GLenum pname) const;
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;
671 ////
673 webgl::PackingInfo ValidImplementationColorReadPI(
674 const webgl::FormatUsageInfo* usage) const;
676 protected:
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);
683 public:
684 void ReadPixelsPbo(const webgl::ReadPixelsDesc&, uint64_t offset);
685 webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc&,
686 const Range<uint8_t>& dest);
688 ////
690 void RenderbufferStorageMultisample(WebGLRenderbuffer&, uint32_t samples,
691 GLenum internalformat, uint32_t width,
692 uint32_t height) const;
694 public:
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,
701 GLenum dppass);
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,
723 GLenum usage) const;
724 void UninitializedBufferData_SizeOnly(GLenum target, uint64_t dataLen,
725 GLenum usage) const;
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
731 // undefined.
732 void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t srcDataLen,
733 const uint8_t* srcData, bool unsynchronized = false) const;
735 protected:
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,
749 GLuint index);
751 // -
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)
773 protected:
774 RefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
775 RefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
776 RefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
778 RefPtr<WebGLQuery>* ValidateQuerySlotByTarget(GLenum target);
780 public:
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;
794 private:
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 {
807 GLint x;
808 GLint y;
809 GLsizei w;
810 GLsizei h;
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; }
825 void OnEndOfFrame();
827 // -----------------------------------------------------------------------------
828 // Texture funcions (WebGLContextTextures.cpp)
829 public:
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 ////////////////////////////////////
841 // Uploads
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,
861 uvec3 size) const;
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
871 protected:
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,
881 GLsizei depth,
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;
892 public:
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);
903 ////
905 void VertexAttrib4T(GLuint index, const webgl::TypedQuad&);
907 ////
909 void VertexAttribPointer(uint32_t index, const webgl::VertAttribPointerDesc&);
911 void VertexAttribDivisor(GLuint index, GLuint divisor);
913 private:
914 WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
915 WebGLintptr byteOffset,
916 GLsizei instanceCount);
917 void Draw_cleanup();
919 void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
920 const GLfloat* ptr);
921 void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
922 const GLfloat* ptr);
923 void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
924 const GLfloat* ptr);
925 void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
926 const GLfloat* ptr);
928 bool BindArrayAttribToLocation0(WebGLProgram* prog);
930 // -----------------------------------------------------------------------------
931 // PROTECTED
932 protected:
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;
960 // some GL constants
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;
970 // ES3:
971 uint32_t mGLMinProgramTexelOffset = 0;
972 uint32_t mGLMaxProgramTexelOffset = 0;
974 public:
975 auto GLMaxDrawBuffers() const { return mLimits->maxColorDrawBuffers; }
977 uint32_t MaxValidDrawBuffers() const {
978 if (IsWebGL2() ||
979 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
980 return GLMaxDrawBuffers();
982 return 1;
985 GLenum LastColorAttachmentEnum() const {
986 return LOCAL_GL_COLOR_ATTACHMENT0 + MaxValidDrawBuffers() - 1;
989 const auto& Options() const { return mOptions; }
991 protected:
992 uint32_t mGLMaxRenderbufferSize = 0;
994 public:
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;
1001 protected:
1002 // -------------------------------------------------------------------------
1003 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
1005 EnumeratedArray<WebGLExtensionID, std::unique_ptr<WebGLExtensionBase>,
1006 size_t(WebGLExtensionID::Max)>
1007 mExtensions;
1009 public:
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)
1024 public:
1025 virtual bool IsWebGL2() const { return false; }
1027 struct FailureReason {
1028 nsCString key; // For reporting.
1029 nsCString info;
1031 FailureReason() = default;
1033 template <typename A, typename B>
1034 FailureReason(const A& _key, const B& _info)
1035 : key(nsCString(_key)), info(nsCString(_info)) {}
1038 protected:
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,
1050 const char* info);
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,
1058 const char* info);
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);
1105 public:
1106 WebGLBuffer* ValidateBufferSelection(GLenum target) const;
1108 protected:
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);
1116 public:
1117 bool ValidateNonNegative(const char* argName, int64_t val) const {
1118 if (MOZ_UNLIKELY(val < 0)) {
1119 ErrorInvalidValue("`%s` must be non-negative.", argName);
1120 return false;
1122 return true;
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);
1130 return false;
1132 return true;
1135 ////
1137 protected:
1138 void DestroyResourcesAndContext();
1140 // helpers
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);
1148 //////
1149 public:
1150 template <typename T>
1151 bool ValidateObject(const char* const argName, const T& object) const {
1152 // Todo: Remove all callers.
1153 return true;
1156 template <typename T>
1157 bool ValidateObject(const char* const argName, const T* const object) const {
1158 // Todo: Remove most (all?) callers.
1159 if (!object) {
1160 ErrorInvalidOperation(
1161 "%s: Object argument cannot have been marked for"
1162 " deletion.",
1163 argName);
1164 return false;
1166 return true;
1169 ////
1171 private:
1172 void LoseContextLruLocked(webgl::ContextLossReason reason)
1173 MOZ_REQUIRES(sLruMutex);
1175 public:
1176 void LoseContext(
1177 webgl::ContextLossReason reason = webgl::ContextLossReason::None);
1179 protected:
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;
1207 public:
1208 const auto& BoundReadFb() const { return mBoundReadFramebuffer; }
1210 protected:
1211 RefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1212 RefPtr<WebGLVertexArray> mDefaultVertexArray;
1214 ////////////////////////////////////
1216 protected:
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;
1292 // --
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);
1318 public:
1319 void WaitForTxn(layers::RemoteTextureOwnerId ownerId,
1320 layers::RemoteTextureTxnType txnType,
1321 layers::RemoteTextureTxnId txnId);
1323 // --
1325 protected:
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();
1354 // --
1356 public:
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...);
1368 public:
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;
1376 // Friend list
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 {
1408 private:
1409 const WebGLContext* const mWebGL;
1411 public:
1412 explicit ScopedFBRebinder(const WebGLContext* const webgl) : mWebGL(webgl) {}
1413 ~ScopedFBRebinder();
1416 // -
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 {
1425 private:
1426 gl::GLContext& mGL;
1427 const GLenum mTarget;
1429 public:
1430 ScopedLazyBind(gl::GLContext* const gl, const GLenum target,
1431 const WebGLBuffer* const buf)
1432 : mGL(*gl), mTarget(IsBufferTargetLazilyBound(target) ? target : 0) {
1433 if (mTarget) {
1434 DoBindBuffer(mGL, mTarget, buf);
1438 ~ScopedLazyBind() {
1439 if (mTarget) {
1440 DoBindBuffer(mGL, mTarget, nullptr);
1445 ////
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);
1454 ////
1456 class ScopedDrawCallWrapper final {
1457 public:
1458 WebGLContext& mWebGL;
1460 explicit ScopedDrawCallWrapper(WebGLContext& webgl);
1461 ~ScopedDrawCallWrapper();
1464 namespace webgl {
1466 class ScopedPrepForResourceClear final {
1467 const WebGLContext& webgl;
1469 public:
1470 explicit ScopedPrepForResourceClear(const WebGLContext&);
1471 ~ScopedPrepForResourceClear();
1474 struct IndexedName final {
1475 std::string name;
1476 uint64_t index;
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
1488 #endif