Bug 1895153 - Implement "Find in page..." menu functionality r=android-reviewers...
[gecko.git] / dom / canvas / WebGLContext.h
blob5b60ed19da7fbace478be842e29b925643858c05
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/UniquePtr.h"
32 #include "mozilla/WeakPtr.h"
33 #include "nsICanvasRenderingContextInternal.h"
34 #include "nsTArray.h"
35 #include "SurfaceTypes.h"
36 #include "ScopedGLHelpers.h"
37 #include "TexUnpackBlob.h"
39 // Local
40 #include "CacheInvalidator.h"
41 #include "WebGLContextLossHandler.h"
42 #include "WebGLExtensions.h"
43 #include "WebGLObjectModel.h"
44 #include "WebGLStrongTypes.h"
45 #include "WebGLTypes.h"
47 // Generated
48 #include "mozilla/dom/WebGLRenderingContextBinding.h"
49 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
51 #include <list>
53 class nsIDocShell;
55 // WebGL-only GLenums
56 // clang-format off
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
63 // clang-format on
65 namespace mozilla {
66 class HostWebGLContext;
67 class ScopedCopyTexImageSource;
68 class ScopedDrawCallWrapper;
69 class ScopedResolveTexturesForDraw;
70 class WebGLBuffer;
71 class WebGLExtensionBase;
72 class WebGLFramebuffer;
73 class WebGLProgram;
74 class WebGLQuery;
75 class WebGLRenderbuffer;
76 class WebGLSampler;
77 class WebGLShader;
78 class WebGLSync;
79 class WebGLTexture;
80 class WebGLTransformFeedback;
81 class WebGLVertexArray;
83 namespace dom {
84 class Document;
85 class Element;
86 class ImageData;
87 class OwningHTMLCanvasElementOrOffscreenCanvas;
88 struct WebGLContextAttributes;
89 } // namespace dom
91 namespace gfx {
92 class SourceSurface;
93 class VRLayerChild;
94 } // namespace gfx
96 namespace gl {
97 class GLScreenBuffer;
98 class MozFramebuffer;
99 class SharedSurface;
100 class Sampler;
101 class Texture;
102 } // namespace gl
104 namespace layers {
105 class CompositableHost;
106 class RemoteTextureOwnerClient;
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 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
503 private:
504 bool PresentInto(gl::SwapChain& swapChain);
505 bool PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& xrFb);
507 public:
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.
515 void Present(
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
534 // appropriately.
535 void EndOfFrame();
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*,
549 const bool webvr);
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
569 void Commit();
571 uvec2 DrawingBufferSize();
573 public:
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;
585 // -
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();
598 // -
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);
618 private:
619 void CompileShaderANGLE(WebGLShader* shader);
620 void CompileShaderBypass(WebGLShader* shader, const nsCString& shaderSource);
622 public:
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);
629 void Flush();
630 void Finish();
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;
640 GLenum GetError();
641 GLint GetFragDataLocation(const WebGLProgram&, const std::string& name) const;
643 Maybe<double> GetFramebufferAttachmentParameter(WebGLFramebuffer*,
644 GLenum attachment,
645 GLenum pname) const;
647 Maybe<double> GetRenderbufferParameter(const WebGLRenderbuffer&,
648 GLenum pname) const;
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;
663 ////
665 webgl::PackingInfo ValidImplementationColorReadPI(
666 const webgl::FormatUsageInfo* usage) const;
668 protected:
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);
675 public:
676 void ReadPixelsPbo(const webgl::ReadPixelsDesc&, uint64_t offset);
677 webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc&,
678 const Range<uint8_t>& dest);
680 ////
682 void RenderbufferStorageMultisample(WebGLRenderbuffer&, uint32_t samples,
683 GLenum internalformat, uint32_t width,
684 uint32_t height) const;
686 public:
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,
693 GLenum dppass);
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,
715 GLenum usage) const;
716 void UninitializedBufferData_SizeOnly(GLenum target, uint64_t dataLen,
717 GLenum usage) const;
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
723 // undefined.
724 void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t srcDataLen,
725 const uint8_t* srcData, bool unsynchronized = false) const;
727 protected:
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,
741 GLuint index);
743 // -
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)
765 protected:
766 RefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
767 RefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
768 RefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
770 RefPtr<WebGLQuery>* ValidateQuerySlotByTarget(GLenum target);
772 public:
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;
786 private:
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 {
799 GLint x;
800 GLint y;
801 GLsizei w;
802 GLsizei h;
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; }
817 void OnEndOfFrame();
819 // -----------------------------------------------------------------------------
820 // Texture funcions (WebGLContextTextures.cpp)
821 public:
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 ////////////////////////////////////
833 // Uploads
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,
853 uvec3 size) const;
855 UniquePtr<webgl::TexUnpackBlob> ToTexUnpackBytes(
856 const WebGLTexImageData& imageData);
858 UniquePtr<webgl::TexUnpackBytes> ToTexUnpackBytes(WebGLTexPboOffset& aPbo);
860 ////////////////////////////////////
861 // WebGLTextureUpload.cpp
862 protected:
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,
872 GLsizei depth,
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;
883 public:
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);
894 ////
896 void VertexAttrib4T(GLuint index, const webgl::TypedQuad&);
898 ////
900 void VertexAttribPointer(uint32_t index, const webgl::VertAttribPointerDesc&);
902 void VertexAttribDivisor(GLuint index, GLuint divisor);
904 private:
905 WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
906 WebGLintptr byteOffset,
907 GLsizei instanceCount);
908 void Draw_cleanup();
910 void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
911 const GLfloat* ptr);
912 void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
913 const GLfloat* ptr);
914 void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
915 const GLfloat* ptr);
916 void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
917 const GLfloat* ptr);
919 bool BindArrayAttribToLocation0(WebGLProgram* prog);
921 // -----------------------------------------------------------------------------
922 // PROTECTED
923 protected:
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;
951 // some GL constants
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;
961 // ES3:
962 uint32_t mGLMinProgramTexelOffset = 0;
963 uint32_t mGLMaxProgramTexelOffset = 0;
965 public:
966 auto GLMaxDrawBuffers() const { return mLimits->maxColorDrawBuffers; }
968 uint32_t MaxValidDrawBuffers() const {
969 if (IsWebGL2() ||
970 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
971 return GLMaxDrawBuffers();
973 return 1;
976 GLenum LastColorAttachmentEnum() const {
977 return LOCAL_GL_COLOR_ATTACHMENT0 + MaxValidDrawBuffers() - 1;
980 const auto& Options() const { return mOptions; }
982 protected:
983 uint32_t mGLMaxRenderbufferSize = 0;
985 public:
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;
992 protected:
993 // -------------------------------------------------------------------------
994 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
996 EnumeratedArray<WebGLExtensionID, std::unique_ptr<WebGLExtensionBase>,
997 size_t(WebGLExtensionID::Max)>
998 mExtensions;
1000 public:
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)
1015 public:
1016 virtual bool IsWebGL2() const { return false; }
1018 struct FailureReason {
1019 nsCString key; // For reporting.
1020 nsCString info;
1022 FailureReason() = default;
1024 template <typename A, typename B>
1025 FailureReason(const A& _key, const B& _info)
1026 : key(nsCString(_key)), info(nsCString(_info)) {}
1029 protected:
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,
1041 const char* info);
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,
1049 const char* info);
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);
1096 public:
1097 WebGLBuffer* ValidateBufferSelection(GLenum target) const;
1099 protected:
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);
1107 public:
1108 bool ValidateNonNegative(const char* argName, int64_t val) const {
1109 if (MOZ_UNLIKELY(val < 0)) {
1110 ErrorInvalidValue("`%s` must be non-negative.", argName);
1111 return false;
1113 return true;
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);
1121 return false;
1123 return true;
1126 ////
1128 protected:
1129 void DestroyResourcesAndContext();
1131 // helpers
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);
1139 //////
1140 public:
1141 template <typename T>
1142 bool ValidateObject(const char* const argName, const T& object) const {
1143 // Todo: Remove all callers.
1144 return true;
1147 template <typename T>
1148 bool ValidateObject(const char* const argName, const T* const object) const {
1149 // Todo: Remove most (all?) callers.
1150 if (!object) {
1151 ErrorInvalidOperation(
1152 "%s: Object argument cannot have been marked for"
1153 " deletion.",
1154 argName);
1155 return false;
1157 return true;
1160 ////
1162 private:
1163 void LoseContextLruLocked(webgl::ContextLossReason reason)
1164 MOZ_REQUIRES(sLruMutex);
1166 public:
1167 void LoseContext(
1168 webgl::ContextLossReason reason = webgl::ContextLossReason::None);
1170 protected:
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;
1198 public:
1199 const auto& BoundReadFb() const { return mBoundReadFramebuffer; }
1201 protected:
1202 RefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1203 RefPtr<WebGLVertexArray> mDefaultVertexArray;
1205 ////////////////////////////////////
1207 protected:
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;
1283 // --
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);
1309 public:
1310 void WaitForTxn(layers::RemoteTextureOwnerId ownerId,
1311 layers::RemoteTextureTxnType txnType,
1312 layers::RemoteTextureTxnId txnId);
1314 // --
1316 protected:
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();
1345 // --
1347 public:
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...);
1359 public:
1360 UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
1362 virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
1363 gl::GLContext* gl) const;
1365 const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
1367 // Friend list
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 {
1399 private:
1400 const WebGLContext* const mWebGL;
1402 public:
1403 explicit ScopedFBRebinder(const WebGLContext* const webgl) : mWebGL(webgl) {}
1404 ~ScopedFBRebinder();
1407 // -
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 {
1416 private:
1417 gl::GLContext& mGL;
1418 const GLenum mTarget;
1420 public:
1421 ScopedLazyBind(gl::GLContext* const gl, const GLenum target,
1422 const WebGLBuffer* const buf)
1423 : mGL(*gl), mTarget(IsBufferTargetLazilyBound(target) ? target : 0) {
1424 if (mTarget) {
1425 DoBindBuffer(mGL, mTarget, buf);
1429 ~ScopedLazyBind() {
1430 if (mTarget) {
1431 DoBindBuffer(mGL, mTarget, nullptr);
1436 ////
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);
1445 ////
1447 class ScopedDrawCallWrapper final {
1448 public:
1449 WebGLContext& mWebGL;
1451 explicit ScopedDrawCallWrapper(WebGLContext& webgl);
1452 ~ScopedDrawCallWrapper();
1455 namespace webgl {
1457 class ScopedPrepForResourceClear final {
1458 const WebGLContext& webgl;
1460 public:
1461 explicit ScopedPrepForResourceClear(const WebGLContext&);
1462 ~ScopedPrepForResourceClear();
1465 struct IndexedName final {
1466 std::string name;
1467 uint64_t index;
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
1479 #endif