Bug 1800301 - Reduce allocs and ptr-chasing in ScopedResolveTexturesForDraw. r=gfx...
[gecko.git] / dom / canvas / WebGLContext.h
blob77b9270941b14d9ea05d26e10497999cb7228b2c
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 "GLContextTypes.h"
14 #include "GLDefs.h"
15 #include "GLScreenBuffer.h"
16 #include "js/ScalarType.h" // js::Scalar::Type
17 #include "mozilla/Attributes.h"
18 #include "mozilla/Atomics.h"
19 #include "mozilla/CheckedInt.h"
20 #include "mozilla/dom/BindingDeclarations.h"
21 #include "mozilla/dom/HTMLCanvasElement.h"
22 #include "mozilla/dom/Nullable.h"
23 #include "mozilla/dom/TypedArray.h"
24 #include "mozilla/EnumeratedArray.h"
25 #include "mozilla/gfx/2D.h"
26 #include "mozilla/Mutex.h"
27 #include "mozilla/StaticMutex.h"
28 #include "mozilla/UniquePtr.h"
29 #include "mozilla/WeakPtr.h"
30 #include "nsICanvasRenderingContextInternal.h"
31 #include "nsTArray.h"
32 #include "SurfaceTypes.h"
33 #include "ScopedGLHelpers.h"
34 #include "TexUnpackBlob.h"
36 // Local
37 #include "CacheInvalidator.h"
38 #include "WebGLContextLossHandler.h"
39 #include "WebGLExtensions.h"
40 #include "WebGLObjectModel.h"
41 #include "WebGLStrongTypes.h"
42 #include "WebGLTypes.h"
44 // Generated
45 #include "mozilla/dom/WebGLRenderingContextBinding.h"
46 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
48 #include <list>
50 class nsIDocShell;
52 // WebGL-only GLenums
53 // clang-format off
54 #define LOCAL_GL_BROWSER_DEFAULT_WEBGL 0x9244
55 #define LOCAL_GL_CONTEXT_LOST_WEBGL 0x9242
56 #define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL 0x9247
57 #define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243
58 #define LOCAL_GL_UNPACK_FLIP_Y_WEBGL 0x9240
59 #define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
60 // clang-format on
62 namespace mozilla {
63 class HostWebGLContext;
64 class ScopedCopyTexImageSource;
65 class ScopedDrawCallWrapper;
66 class ScopedResolveTexturesForDraw;
67 class WebGLBuffer;
68 class WebGLExtensionBase;
69 class WebGLFramebuffer;
70 class WebGLProgram;
71 class WebGLQuery;
72 class WebGLRenderbuffer;
73 class WebGLSampler;
74 class WebGLShader;
75 class WebGLSync;
76 class WebGLTexture;
77 class WebGLTransformFeedback;
78 class WebGLVertexArray;
80 namespace dom {
81 class Document;
82 class Element;
83 class ImageData;
84 class OwningHTMLCanvasElementOrOffscreenCanvas;
85 struct WebGLContextAttributes;
86 } // namespace dom
88 namespace gfx {
89 class SourceSurface;
90 class VRLayerChild;
91 } // namespace gfx
93 namespace gl {
94 class GLScreenBuffer;
95 class MozFramebuffer;
96 class SharedSurface;
97 class Texture;
98 } // namespace gl
100 namespace layers {
101 class CompositableHost;
102 class RemoteTextureOwnerClient;
103 class SurfaceDescriptor;
104 } // namespace layers
106 namespace webgl {
107 class AvailabilityRunnable;
108 struct CachedDrawFetchLimits;
109 struct FbAttachInfo;
110 struct FormatInfo;
111 class FormatUsageAuthority;
112 struct FormatUsageInfo;
113 struct ImageInfo;
114 struct LinkedProgramInfo;
115 struct SamplerUniformInfo;
116 struct SamplingState;
117 class ScopedPrepForResourceClear;
118 class ShaderValidator;
119 class TexUnpackBlob;
120 struct UniformInfo;
121 struct UniformBlockInfo;
122 struct VertAttribPointerDesc;
123 } // namespace webgl
125 struct WebGLTexImageData {
126 TexImageTarget mTarget;
127 int32_t mRowLength;
128 uint32_t mWidth;
129 uint32_t mHeight;
130 uint32_t mDepth;
131 gfxAlphaType mSrcAlphaType;
134 struct WebGLTexPboOffset {
135 TexImageTarget mTarget;
136 uint32_t mWidth;
137 uint32_t mHeight;
138 uint32_t mDepth;
139 WebGLsizeiptr mPboOffset;
140 bool mHasExpectedImageSize;
141 GLsizei mExpectedImageSize;
144 WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
146 void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
148 // From WebGLContextUtils
149 TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
151 struct WebGLIntOrFloat {
152 const enum { Int, Float, Uint } mType;
154 union {
155 GLint i;
156 GLfloat f;
157 GLuint u;
158 } mValue;
160 explicit WebGLIntOrFloat(GLint i) : mType(Int) { mValue.i = i; }
161 explicit WebGLIntOrFloat(GLfloat f) : mType(Float) { mValue.f = f; }
163 GLint AsInt() const {
164 return (mType == Int) ? mValue.i : NS_lroundf(mValue.f);
166 GLfloat AsFloat() const {
167 return (mType == Float) ? mValue.f : GLfloat(mValue.i);
171 struct IndexedBufferBinding {
172 RefPtr<WebGLBuffer> mBufferBinding;
173 uint64_t mRangeStart;
174 uint64_t mRangeSize;
176 IndexedBufferBinding();
178 uint64_t ByteCount() const;
181 ////////////////////////////////////
183 namespace webgl {
185 class AvailabilityRunnable final : public DiscardableRunnable {
186 public:
187 const WeakPtr<const ClientWebGLContext> mWebGL;
188 std::vector<WeakPtr<WebGLQueryJS>> mQueries;
189 std::vector<WeakPtr<WebGLSyncJS>> mSyncs;
191 explicit AvailabilityRunnable(const ClientWebGLContext* webgl);
192 ~AvailabilityRunnable();
194 NS_IMETHOD Run() override;
197 struct BufferAndIndex final {
198 const WebGLBuffer* buffer = nullptr;
199 uint32_t id = -1;
202 } // namespace webgl
204 ////////////////////////////////////////////////////////////////////////////////
206 class WebGLContext : public VRefCounted, public SupportsWeakPtr {
207 friend class ScopedDrawCallWrapper;
208 friend class ScopedDrawWithTransformFeedback;
209 friend class ScopedFakeVertexAttrib0;
210 friend class ScopedFBRebinder;
211 friend class WebGL2Context;
212 friend class WebGLContextUserData;
213 friend class WebGLExtensionCompressedTextureASTC;
214 friend class WebGLExtensionCompressedTextureBPTC;
215 friend class WebGLExtensionCompressedTextureES3;
216 friend class WebGLExtensionCompressedTextureETC1;
217 friend class WebGLExtensionCompressedTexturePVRTC;
218 friend class WebGLExtensionCompressedTextureRGTC;
219 friend class WebGLExtensionCompressedTextureS3TC;
220 friend class WebGLExtensionCompressedTextureS3TC_SRGB;
221 friend class WebGLExtensionDepthTexture;
222 friend class WebGLExtensionDisjointTimerQuery;
223 friend class WebGLExtensionDrawBuffers;
224 friend class WebGLExtensionLoseContext;
225 friend class WebGLExtensionMOZDebug;
226 friend class WebGLExtensionVertexArray;
227 friend class WebGLMemoryTracker;
228 friend class webgl::AvailabilityRunnable;
229 friend struct webgl::LinkedProgramInfo;
230 friend struct webgl::SamplerUniformInfo;
231 friend class webgl::ScopedPrepForResourceClear;
232 friend struct webgl::UniformBlockInfo;
234 friend const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext*, GLenum,
235 uint32_t);
236 friend RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
237 WebGLProgram* prog, gl::GLContext* gl);
239 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLContext, override)
241 enum {
242 UNPACK_FLIP_Y_WEBGL = 0x9240,
243 UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
244 // We throw InvalidOperation in TexImage if we fail to use GPU fast-path
245 // for texture copy when it is set to true, only for debug purpose.
246 UNPACK_REQUIRE_FASTPATH = 0x10001,
247 CONTEXT_LOST_WEBGL = 0x9242,
248 UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243,
249 BROWSER_DEFAULT_WEBGL = 0x9244,
250 UNMASKED_VENDOR_WEBGL = 0x9245,
251 UNMASKED_RENDERER_WEBGL = 0x9246
254 private:
255 class LruPosition final {
256 std::list<WebGLContext*>::iterator mItr;
258 LruPosition(const LruPosition&) = delete;
259 LruPosition(LruPosition&&) = delete;
260 LruPosition& operator=(const LruPosition&) = delete;
261 LruPosition& operator=(LruPosition&&) = delete;
263 public:
264 void AssignLocked(WebGLContext& aContext) MOZ_REQUIRES(sLruMutex);
265 void Reset();
266 void ResetLocked() MOZ_REQUIRES(sLruMutex);
267 bool IsInsertedLocked() const MOZ_REQUIRES(sLruMutex);
269 LruPosition();
270 explicit LruPosition(WebGLContext&);
272 ~LruPosition() { Reset(); }
275 mutable LruPosition mLruPosition MOZ_GUARDED_BY(sLruMutex);
277 void BumpLruLocked() MOZ_REQUIRES(sLruMutex);
279 public:
280 void BumpLru();
281 void LoseLruContextIfLimitExceeded();
283 // -
285 // We've had issues in the past with nulling `gl` without actually releasing
286 // all of our resources. This construction ensures that we are aware that we
287 // should only null `gl` in DestroyResourcesAndContext.
288 RefPtr<gl::GLContext> mGL_OnlyClearInDestroyResourcesAndContext;
290 public:
291 // Grab a const reference so we can see changes, but can't make changes.
292 const decltype(mGL_OnlyClearInDestroyResourcesAndContext)& gl;
294 public:
295 void CheckForInactivity();
297 protected:
298 const WeakPtr<HostWebGLContext> mHost;
299 const bool mResistFingerprinting;
300 WebGLContextOptions mOptions;
301 const uint32_t mPrincipalKey;
302 Maybe<webgl::Limits> mLimits;
304 bool mIsContextLost = false;
305 Atomic<bool> mPendingContextLoss;
306 webgl::ContextLossReason mPendingContextLossReason =
307 webgl::ContextLossReason::None;
308 const uint32_t mMaxPerfWarnings;
309 mutable uint64_t mNumPerfWarnings = 0;
310 const uint32_t mMaxAcceptableFBStatusInvals;
311 bool mWarnOnce_DepthTexCompareFilterable = true;
313 uint64_t mNextFenceId = 1;
314 uint64_t mCompletedFenceId = 0;
316 std::unique_ptr<gl::Texture> mIncompleteTexOverride;
318 public:
319 class FuncScope;
321 private:
322 mutable FuncScope* mFuncScope = nullptr;
324 public:
325 static RefPtr<WebGLContext> Create(HostWebGLContext&,
326 const webgl::InitContextDesc&,
327 webgl::InitContextResult* out);
329 private:
330 void FinishInit();
332 protected:
333 WebGLContext(HostWebGLContext&, const webgl::InitContextDesc&);
334 virtual ~WebGLContext();
336 RefPtr<layers::CompositableHost> mCompositableHost;
338 layers::LayersBackend mBackend = layers::LayersBackend::LAYERS_NONE;
340 public:
341 void Resize(uvec2 size);
343 void SetCompositableHost(RefPtr<layers::CompositableHost>& aCompositableHost);
346 * An abstract base class to be implemented by callers wanting to be notified
347 * that a refresh has occurred. Callers must ensure an observer is removed
348 * before it is destroyed.
350 virtual void DidRefresh();
352 void OnMemoryPressure();
354 // -
358 Here are the bind calls that are supposed to be fully-validated client side,
359 so that client's binding state doesn't diverge:
360 * AttachShader
361 * DetachShader
362 * BindFramebuffer
363 * FramebufferAttach
364 * BindBuffer
365 * BindBufferRange
366 * BindTexture
367 * UseProgram
368 * BindSampler
369 * BindTransformFeedback
370 * BindVertexArray
371 * BeginQuery
372 * EndQuery
373 * ActiveTexture
377 const auto& CurFuncScope() const { return *mFuncScope; }
378 const char* FuncName() const;
380 class FuncScope final {
381 public:
382 const WebGLContext& mWebGL;
383 const char* const mFuncName;
384 bool mBindFailureGuard = false;
386 public:
387 FuncScope(const WebGLContext& webgl, const char* funcName);
388 ~FuncScope();
391 void GenerateErrorImpl(const GLenum err, const nsACString& text) const {
392 GenerateErrorImpl(err, std::string(text.BeginReading()));
394 void GenerateErrorImpl(const GLenum err, const std::string& text) const;
396 void GenerateError(const webgl::ErrorInfo& err) {
397 GenerateError(err.type, "%s", err.info.c_str());
400 template <typename... Args>
401 void GenerateError(const GLenum err, const char* const fmt,
402 const Args&... args) const {
403 MOZ_ASSERT(FuncName());
405 nsCString text;
406 text.AppendPrintf("WebGL warning: %s: ", FuncName());
408 #ifdef __clang__
409 # pragma clang diagnostic push
410 # pragma clang diagnostic ignored "-Wformat-security"
411 #elif defined(__GNUC__)
412 # pragma GCC diagnostic push
413 # pragma GCC diagnostic ignored "-Wformat-security"
414 #endif
415 text.AppendPrintf(fmt, args...);
416 #ifdef __clang__
417 # pragma clang diagnostic pop
418 #elif defined(__GNUC__)
419 # pragma GCC diagnostic pop
420 #endif
422 GenerateErrorImpl(err, text);
425 template <typename... Args>
426 void ErrorInvalidEnum(const char* const fmt, const Args&... args) const {
427 GenerateError(LOCAL_GL_INVALID_ENUM, fmt, args...);
429 template <typename... Args>
430 void ErrorInvalidOperation(const char* const fmt, const Args&... args) const {
431 GenerateError(LOCAL_GL_INVALID_OPERATION, fmt, args...);
433 template <typename... Args>
434 void ErrorInvalidValue(const char* const fmt, const Args&... args) const {
435 GenerateError(LOCAL_GL_INVALID_VALUE, fmt, args...);
437 template <typename... Args>
438 void ErrorInvalidFramebufferOperation(const char* const fmt,
439 const Args&... args) const {
440 GenerateError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION, fmt, args...);
442 template <typename... Args>
443 void ErrorOutOfMemory(const char* const fmt, const Args&... args) const {
444 GenerateError(LOCAL_GL_OUT_OF_MEMORY, fmt, args...);
447 template <typename... Args>
448 void ErrorImplementationBug(const char* const fmt,
449 const Args&... args) const {
450 const nsPrintfCString newFmt(
451 "Implementation bug, please file at %s! %s",
452 "https://bugzilla.mozilla.org/"
453 "enter_bug.cgi?product=Core&component=Canvas%3A+WebGL",
454 fmt);
455 GenerateError(LOCAL_GL_OUT_OF_MEMORY, newFmt.BeginReading(), args...);
456 MOZ_ASSERT(false, "WebGLContext::ErrorImplementationBug");
457 NS_ERROR("WebGLContext::ErrorImplementationBug");
460 void ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const;
461 void ErrorInvalidEnumArg(const char* argName, GLenum val) const;
463 static const char* ErrorName(GLenum error);
466 * Return displayable name for GLenum.
467 * This version is like gl::GLenumToStr but with out the GL_ prefix to
468 * keep consistency with how errors are reported from WebGL.
469 * Returns hex formatted version of glenum if glenum is unknown.
471 static void EnumName(GLenum val, nsCString* out_name);
473 void DummyReadFramebufferOperation();
475 WebGLTexture* GetActiveTex(const GLenum texTarget) const;
477 gl::GLContext* GL() const { return gl; }
479 bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
481 bool IsPreservingDrawingBuffer() const {
482 return mOptions.preserveDrawingBuffer;
485 // Present to compositor
486 private:
487 bool PresentInto(gl::SwapChain& swapChain);
488 bool PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& xrFb);
490 public:
491 // Present swaps the front and back buffers of the swap chain for compositing.
492 // This assumes the framebuffer may directly alias with the back buffer,
493 // dependent on remoting state or other concerns. Framebuffer and swap chain
494 // surface formats are assumed to be similar to enable this aliasing. As such,
495 // the back buffer may be invalidated by this swap with the front buffer,
496 // unless overriden by explicitly setting the preserveDrawingBuffer option,
497 // which may incur a further copy to preserve the back buffer.
498 void Present(
499 WebGLFramebuffer*, layers::TextureType, const bool webvr,
500 const webgl::SwapChainOptions& options = webgl::SwapChainOptions());
501 // CopyToSwapChain forces a copy from the supplied framebuffer into the back
502 // buffer before swapping the front and back buffers of the swap chain for
503 // compositing. The formats of the framebuffer and the swap chain buffers
504 // may differ subject to available format conversion options. Since this
505 // operation uses an explicit copy, it inherently preserves the framebuffer
506 // without need to set the preserveDrawingBuffer option.
507 void CopyToSwapChain(
508 WebGLFramebuffer*, layers::TextureType,
509 const webgl::SwapChainOptions& options = webgl::SwapChainOptions());
510 // In use cases where a framebuffer is used as an offscreen framebuffer and
511 // does not need to be committed to the swap chain, it may still be useful
512 // for the implementation to delineate distinct frames, such as when sharing
513 // a single WebGLContext amongst many distinct users. EndOfFrame signals that
514 // frame rendering is complete so that any implementation side-effects such
515 // as resetting internal profile counters or resource queues may be handled
516 // appropriately.
517 void EndOfFrame();
518 RefPtr<gfx::DataSourceSurface> GetFrontBufferSnapshot();
519 Maybe<uvec2> FrontBufferSnapshotInto(
520 const Maybe<Range<uint8_t>> dest,
521 const Maybe<size_t> destStride = Nothing());
522 Maybe<uvec2> FrontBufferSnapshotInto(
523 const std::shared_ptr<gl::SharedSurface>& front,
524 const Maybe<Range<uint8_t>> dest,
525 const Maybe<size_t> destStride = Nothing());
526 Maybe<uvec2> SnapshotInto(GLuint srcFb, const gfx::IntSize& size,
527 const Range<uint8_t>& dest,
528 const Maybe<size_t> destStride = Nothing());
529 gl::SwapChain* GetSwapChain(WebGLFramebuffer*, const bool webvr);
530 Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebuffer*,
531 const bool webvr);
533 void ClearVRSwapChain();
535 void RunContextLossTimer();
536 void CheckForContextLoss();
537 void HandlePendingContextLoss();
539 bool TryToRestoreContext();
541 void AssertCachedBindings() const;
542 void AssertCachedGlobalState() const;
544 // WebIDL WebGLRenderingContext API
545 void Commit();
547 uvec2 DrawingBufferSize();
549 public:
550 void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
552 // This is the entrypoint. Don't test against it directly.
553 bool IsContextLost() const {
554 auto* self = const_cast<WebGLContext*>(this);
555 if (self->mPendingContextLoss.exchange(false)) {
556 self->HandlePendingContextLoss();
558 return mIsContextLost;
561 // -
563 RefPtr<WebGLBuffer> CreateBuffer();
564 RefPtr<WebGLFramebuffer> CreateFramebuffer();
565 RefPtr<WebGLFramebuffer> CreateOpaqueFramebuffer(
566 const webgl::OpaqueFramebufferOptions& options);
567 RefPtr<WebGLProgram> CreateProgram();
568 RefPtr<WebGLQuery> CreateQuery();
569 RefPtr<WebGLRenderbuffer> CreateRenderbuffer();
570 RefPtr<WebGLShader> CreateShader(GLenum type);
571 RefPtr<WebGLTexture> CreateTexture();
572 RefPtr<WebGLVertexArray> CreateVertexArray();
574 // -
576 void AttachShader(WebGLProgram& prog, WebGLShader& shader);
577 void BindAttribLocation(WebGLProgram& prog, GLuint location,
578 const std::string& name) const;
579 void BindFramebuffer(GLenum target, WebGLFramebuffer* fb);
580 void BindRenderbuffer(GLenum target, WebGLRenderbuffer* fb);
581 void BindVertexArray(WebGLVertexArray* vao);
582 void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
583 void BlendEquationSeparate(Maybe<GLuint> i, GLenum modeRGB, GLenum modeAlpha);
584 void BlendFuncSeparate(Maybe<GLuint> i, GLenum srcRGB, GLenum dstRGB,
585 GLenum srcAlpha, GLenum dstAlpha);
586 GLenum CheckFramebufferStatus(GLenum target);
587 void Clear(GLbitfield mask);
588 void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
589 void ClearDepth(GLclampf v);
590 void ClearStencil(GLint v);
591 void ColorMask(Maybe<GLuint> i, uint8_t mask);
592 void CompileShader(WebGLShader& shader);
594 private:
595 void CompileShaderANGLE(WebGLShader* shader);
596 void CompileShaderBypass(WebGLShader* shader, const nsCString& shaderSource);
598 public:
599 void CullFace(GLenum face);
600 void DepthFunc(GLenum func);
601 void DepthMask(WebGLboolean b);
602 void DepthRange(GLclampf zNear, GLclampf zFar);
603 void DetachShader(WebGLProgram& prog, const WebGLShader& shader);
604 void DrawBuffers(const std::vector<GLenum>& buffers);
605 void Flush();
606 void Finish();
608 void FramebufferAttach(GLenum target, GLenum attachSlot,
609 GLenum bindImageTarget,
610 const webgl::FbAttachInfo& toAttach);
612 void FrontFace(GLenum mode);
614 Maybe<double> GetBufferParameter(GLenum target, GLenum pname);
615 webgl::CompileResult GetCompileResult(const WebGLShader&) const;
616 GLenum GetError();
617 GLint GetFragDataLocation(const WebGLProgram&, const std::string& name) const;
619 Maybe<double> GetFramebufferAttachmentParameter(WebGLFramebuffer*,
620 GLenum attachment,
621 GLenum pname) const;
623 Maybe<double> GetRenderbufferParameter(const WebGLRenderbuffer&,
624 GLenum pname) const;
625 webgl::LinkResult GetLinkResult(const WebGLProgram&) const;
627 Maybe<webgl::ShaderPrecisionFormat> GetShaderPrecisionFormat(
628 GLenum shadertype, GLenum precisiontype) const;
630 webgl::GetUniformData GetUniform(const WebGLProgram&, uint32_t loc) const;
632 void Hint(GLenum target, GLenum mode);
634 void LineWidth(GLfloat width);
635 void LinkProgram(WebGLProgram& prog);
636 void PolygonOffset(GLfloat factor, GLfloat units);
638 ////
640 webgl::PackingInfo ValidImplementationColorReadPI(
641 const webgl::FormatUsageInfo* usage) const;
643 protected:
644 webgl::ReadPixelsResult ReadPixelsImpl(const webgl::ReadPixelsDesc&,
645 uintptr_t dest, uint64_t availBytes);
646 bool DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat,
647 const webgl::ReadPixelsDesc&, uintptr_t dest,
648 uint64_t dataLen, uint32_t rowStride);
650 public:
651 void ReadPixelsPbo(const webgl::ReadPixelsDesc&, uint64_t offset);
652 webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc&,
653 const Range<uint8_t>& dest);
655 ////
657 void RenderbufferStorageMultisample(WebGLRenderbuffer&, uint32_t samples,
658 GLenum internalformat, uint32_t width,
659 uint32_t height) const;
661 public:
662 void SampleCoverage(GLclampf value, WebGLboolean invert);
663 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
664 void ShaderSource(WebGLShader& shader, const std::string& source) const;
665 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
666 void StencilMaskSeparate(GLenum face, GLuint mask);
667 void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
668 GLenum dppass);
670 //////////////////////////
672 void UniformData(uint32_t loc, bool transpose,
673 const Range<const webgl::UniformDataVal>& data) const;
675 ////////////////////////////////////
677 void UseProgram(WebGLProgram* prog);
679 bool ValidateAttribArraySetter(uint32_t count, uint32_t arrayLength);
680 bool ValidateProgram(const WebGLProgram& prog) const;
681 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
683 // -----------------------------------------------------------------------------
684 // Buffer Objects (WebGLContextBuffers.cpp)
685 void BindBuffer(GLenum target, WebGLBuffer* buffer);
686 void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
687 uint64_t offset, uint64_t size);
689 void BufferData(GLenum target, uint64_t dataLen, const uint8_t* data,
690 GLenum usage) const;
691 void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t srcDataLen,
692 const uint8_t* srcData) const;
694 protected:
695 // bound buffer state
696 RefPtr<WebGLBuffer> mBoundArrayBuffer;
697 RefPtr<WebGLBuffer> mBoundCopyReadBuffer;
698 RefPtr<WebGLBuffer> mBoundCopyWriteBuffer;
699 RefPtr<WebGLBuffer> mBoundPixelPackBuffer;
700 RefPtr<WebGLBuffer> mBoundPixelUnpackBuffer;
701 RefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
702 RefPtr<WebGLBuffer> mBoundUniformBuffer;
704 std::vector<IndexedBufferBinding> mIndexedUniformBufferBindings;
706 RefPtr<WebGLBuffer>& GetBufferSlotByTarget(GLenum target);
707 RefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
708 GLuint index);
710 // -
712 void GenErrorIllegalUse(GLenum useTarget, uint32_t useId, GLenum boundTarget,
713 uint32_t boundId) const;
715 bool ValidateBufferForNonTf(const WebGLBuffer&, GLenum nonTfTarget,
716 uint32_t nonTfId) const;
718 bool ValidateBufferForNonTf(const WebGLBuffer* const nonTfBuffer,
719 const GLenum nonTfTarget,
720 const uint32_t nonTfId = -1) const {
721 if (!nonTfBuffer) return true;
722 return ValidateBufferForNonTf(*nonTfBuffer, nonTfTarget, nonTfId);
725 bool ValidateBuffersForTf(const WebGLTransformFeedback&,
726 const webgl::LinkedProgramInfo&) const;
727 bool ValidateBuffersForTf(
728 const std::vector<webgl::BufferAndIndex>& tfBuffers) const;
730 // -----------------------------------------------------------------------------
731 // Queries (WebGL2ContextQueries.cpp)
732 protected:
733 RefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
734 RefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
735 RefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
737 RefPtr<WebGLQuery>* ValidateQuerySlotByTarget(GLenum target);
739 public:
740 void BeginQuery(GLenum target, WebGLQuery& query);
741 void EndQuery(GLenum target);
742 Maybe<double> GetQueryParameter(const WebGLQuery& query, GLenum pname) const;
743 void QueryCounter(WebGLQuery&) const;
745 // -----------------------------------------------------------------------------
746 // State and State Requests (WebGLContextState.cpp)
747 void SetEnabled(GLenum cap, Maybe<GLuint> i, bool enabled);
748 bool GetStencilBits(GLint* const out_stencilBits) const;
750 virtual Maybe<double> GetParameter(GLenum pname);
751 Maybe<std::string> GetString(GLenum pname) const;
753 bool IsEnabled(GLenum cap);
755 private:
756 static StaticMutex sLruMutex;
757 static std::list<WebGLContext*> sLru MOZ_GUARDED_BY(sLruMutex);
759 // State tracking slots
760 bool mDitherEnabled = true;
761 bool mRasterizerDiscardEnabled = false;
762 bool mScissorTestEnabled = false;
763 bool mDepthTestEnabled = false;
764 bool mStencilTestEnabled = false;
765 GLenum mGenerateMipmapHint = LOCAL_GL_DONT_CARE;
767 struct ScissorRect final {
768 GLint x;
769 GLint y;
770 GLsizei w;
771 GLsizei h;
773 void Apply(gl::GLContext&) const;
775 ScissorRect mScissorRect = {};
777 bool ValidateCapabilityEnum(GLenum cap);
778 bool* GetStateTrackingSlot(GLenum cap, GLuint i);
780 // Allocation debugging variables
781 mutable uint64_t mDataAllocGLCallCount = 0;
783 void OnDataAllocCall() const { mDataAllocGLCallCount++; }
785 uint64_t GetNumGLDataAllocCalls() const { return mDataAllocGLCallCount; }
787 void OnEndOfFrame();
789 // -----------------------------------------------------------------------------
790 // Texture funcions (WebGLContextTextures.cpp)
791 public:
792 void ActiveTexture(uint32_t texUnit);
793 void BindTexture(GLenum texTarget, WebGLTexture* tex);
794 void GenerateMipmap(GLenum texTarget);
796 Maybe<double> GetTexParameter(const WebGLTexture&, GLenum pname) const;
797 void TexParameter_base(GLenum texTarget, GLenum pname,
798 const FloatOrInt& param);
800 virtual bool IsTexParamValid(GLenum pname) const;
802 ////////////////////////////////////
803 // Uploads
805 // CompressedTexSubImage if `sub`
806 void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level,
807 GLenum format, uvec3 offset, uvec3 size,
808 const Range<const uint8_t>& src,
809 const uint32_t pboImageSize,
810 const Maybe<uint64_t>& pboOffset) const;
812 // CopyTexSubImage if `!respectFormat`
813 void CopyTexImage(GLenum imageTarget, uint32_t level, GLenum respecFormat,
814 uvec3 dstOffset, const ivec2& srcOffset,
815 const uvec2& size) const;
817 // TexSubImage if `!respectFormat`
818 void TexImage(uint32_t level, GLenum respecFormat, uvec3 offset,
819 const webgl::PackingInfo& pi,
820 const webgl::TexUnpackBlobDesc&) const;
822 void TexStorage(GLenum texTarget, uint32_t levels, GLenum sizedFormat,
823 uvec3 size) const;
825 UniquePtr<webgl::TexUnpackBlob> ToTexUnpackBytes(
826 const WebGLTexImageData& imageData);
828 UniquePtr<webgl::TexUnpackBytes> ToTexUnpackBytes(WebGLTexPboOffset& aPbo);
830 ////////////////////////////////////
831 // WebGLTextureUpload.cpp
832 protected:
833 bool ValidateTexImageSpecification(uint8_t funcDims, GLenum texImageTarget,
834 GLint level, GLsizei width, GLsizei height,
835 GLsizei depth, GLint border,
836 TexImageTarget* const out_target,
837 WebGLTexture** const out_texture,
838 webgl::ImageInfo** const out_imageInfo);
839 bool ValidateTexImageSelection(uint8_t funcDims, GLenum texImageTarget,
840 GLint level, GLint xOffset, GLint yOffset,
841 GLint zOffset, GLsizei width, GLsizei height,
842 GLsizei depth,
843 TexImageTarget* const out_target,
844 WebGLTexture** const out_texture,
845 webgl::ImageInfo** const out_imageInfo);
846 bool ValidateUnpackInfo(bool usePBOs, GLenum format, GLenum type,
847 webgl::PackingInfo* const out);
849 // -----------------------------------------------------------------------------
850 // Vertices Feature (WebGLContextVertices.cpp)
851 GLenum mPrimRestartTypeBytes = 0;
853 public:
854 void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount,
855 GLsizei instanceCount);
856 void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type,
857 WebGLintptr byteOffset, GLsizei instanceCount);
859 void EnableVertexAttribArray(GLuint index);
860 void DisableVertexAttribArray(GLuint index);
862 Maybe<double> GetVertexAttrib(GLuint index, GLenum pname);
864 ////
866 void VertexAttrib4T(GLuint index, const webgl::TypedQuad&);
868 ////
870 void VertexAttribPointer(uint32_t index, const webgl::VertAttribPointerDesc&);
872 void VertexAttribDivisor(GLuint index, GLuint divisor);
874 private:
875 WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
876 WebGLintptr byteOffset,
877 GLsizei instanceCount);
878 void Draw_cleanup();
880 void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
881 const GLfloat* ptr);
882 void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
883 const GLfloat* ptr);
884 void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
885 const GLfloat* ptr);
886 void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
887 const GLfloat* ptr);
889 bool BindArrayAttribToLocation0(WebGLProgram* prog);
891 // -----------------------------------------------------------------------------
892 // PROTECTED
893 protected:
894 WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
895 bool DoFakeVertexAttrib0(uint64_t fakeVertexCount,
896 WebGLVertexAttrib0Status whatDoesAttrib0Need);
897 void UndoFakeVertexAttrib0();
899 bool mResetLayer = true;
900 bool mOptionsFrozen = false;
901 bool mIsMesa = false;
902 bool mLoseContextOnMemoryPressure = false;
903 bool mCanLoseContextInForeground = true;
904 bool mShouldPresent = false;
905 bool mDisableFragHighP = false;
906 bool mForceResizeOnPresent = false;
907 bool mVRReady = false;
909 template <typename WebGLObjectType>
910 void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
912 GLuint mActiveTexture = 0;
913 GLenum mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
914 GLenum mDefaultFB_ReadBuffer = LOCAL_GL_BACK;
916 mutable GLenum mWebGLError = 0;
918 std::unique_ptr<webgl::ShaderValidator> CreateShaderValidator(
919 GLenum shaderType) const;
921 // some GL constants
922 uint32_t mGLMaxFragmentUniformVectors = 0;
923 uint32_t mGLMaxVertexUniformVectors = 0;
924 uint32_t mGLMaxVertexOutputVectors = 0;
925 uint32_t mGLMaxFragmentInputVectors = 0;
927 uint32_t mGLMaxVertexTextureImageUnits = 0;
928 uint32_t mGLMaxFragmentTextureImageUnits = 0;
929 uint32_t mGLMaxCombinedTextureImageUnits = 0;
931 // ES3:
932 uint32_t mGLMinProgramTexelOffset = 0;
933 uint32_t mGLMaxProgramTexelOffset = 0;
935 public:
936 auto GLMaxDrawBuffers() const { return mLimits->maxColorDrawBuffers; }
938 uint32_t MaxValidDrawBuffers() const {
939 if (IsWebGL2() ||
940 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
941 return GLMaxDrawBuffers();
943 return 1;
946 GLenum LastColorAttachmentEnum() const {
947 return LOCAL_GL_COLOR_ATTACHMENT0 + MaxValidDrawBuffers() - 1;
950 const auto& Options() const { return mOptions; }
952 protected:
953 uint32_t mGLMaxRenderbufferSize = 0;
955 public:
956 const auto& Limits() const { return *mLimits; }
957 auto MaxVertexAttribs() const { return mLimits->maxVertexAttribs; }
958 auto GLMaxTextureUnits() const { return mLimits->maxTexUnits; }
960 bool IsFormatValidForFB(TexInternalFormat format) const;
962 protected:
963 // -------------------------------------------------------------------------
964 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
966 EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max,
967 std::unique_ptr<WebGLExtensionBase>>
968 mExtensions;
970 public:
971 void RequestExtension(WebGLExtensionID, bool explicitly = true);
973 // returns true if the extension has been enabled by calling getExtension.
974 bool IsExtensionEnabled(const WebGLExtensionID id) const {
975 return bool(mExtensions[id]);
978 bool IsExtensionExplicit(WebGLExtensionID) const;
979 void WarnIfImplicit(WebGLExtensionID) const;
981 bool IsExtensionSupported(WebGLExtensionID) const;
983 // -------------------------------------------------------------------------
984 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
985 public:
986 virtual bool IsWebGL2() const { return false; }
988 struct FailureReason {
989 nsCString key; // For reporting.
990 nsCString info;
992 FailureReason() = default;
994 template <typename A, typename B>
995 FailureReason(const A& _key, const B& _info)
996 : key(nsCString(_key)), info(nsCString(_info)) {}
999 protected:
1000 bool InitWebGL2(FailureReason* const out_failReason);
1002 bool CreateAndInitGL(bool forceEnabled,
1003 std::vector<FailureReason>* const out_failReasons);
1005 // -------------------------------------------------------------------------
1006 // Validation functions (implemented in WebGLContextValidate.cpp)
1007 bool InitAndValidateGL(FailureReason* const out_failReason);
1009 bool ValidateBlendEquationEnum(GLenum cap, const char* info);
1010 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor,
1011 const char* info);
1012 bool ValidateStencilOpEnum(GLenum action, const char* info);
1013 bool ValidateFaceEnum(GLenum face);
1014 bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
1015 WebGLTexImageFunc func, WebGLTexDimensions dims);
1016 bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size,
1017 GLenum type, WebGLboolean normalized,
1018 GLsizei stride, WebGLintptr byteOffset,
1019 const char* info);
1020 bool ValidateStencilParamsForDrawCall() const;
1022 bool ValidateCopyTexImage(TexInternalFormat srcFormat,
1023 TexInternalFormat dstformat, WebGLTexImageFunc func,
1024 WebGLTexDimensions dims);
1026 bool ValidateTexImage(TexImageTarget texImageTarget, GLint level,
1027 GLenum internalFormat, GLint xoffset, GLint yoffset,
1028 GLint zoffset, GLint width, GLint height, GLint depth,
1029 GLint border, GLenum format, GLenum type,
1030 WebGLTexImageFunc func, WebGLTexDimensions dims);
1031 bool ValidateTexImageFormat(GLenum internalFormat, WebGLTexImageFunc func,
1032 WebGLTexDimensions dims);
1033 bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func,
1034 WebGLTexDimensions dims);
1035 bool ValidateTexImageFormatAndType(GLenum format, GLenum type,
1036 WebGLTexImageFunc func,
1037 WebGLTexDimensions dims);
1038 bool ValidateCompTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1039 WebGLTexDimensions dims);
1040 bool ValidateCopyTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1041 WebGLTexDimensions dims);
1042 bool ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
1043 GLint width, GLint height, GLint depth,
1044 WebGLTexImageFunc func, WebGLTexDimensions dims);
1045 bool ValidateTexSubImageSize(GLint x, GLint y, GLint z, GLsizei width,
1046 GLsizei height, GLsizei depth, GLsizei baseWidth,
1047 GLsizei baseHeight, GLsizei baseDepth,
1048 WebGLTexImageFunc func, WebGLTexDimensions dims);
1049 bool ValidateCompTexImageSize(GLint level, GLenum internalFormat,
1050 GLint xoffset, GLint yoffset, GLsizei width,
1051 GLsizei height, GLsizei levelWidth,
1052 GLsizei levelHeight, WebGLTexImageFunc func,
1053 WebGLTexDimensions dims);
1054 bool ValidateCompTexImageDataSize(GLint level, GLenum internalFormat,
1055 GLsizei width, GLsizei height,
1056 uint32_t byteLength, WebGLTexImageFunc func,
1057 WebGLTexDimensions dims);
1059 bool HasDrawBuffers() const {
1060 return IsWebGL2() ||
1061 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
1064 RefPtr<WebGLBuffer>* ValidateBufferSlot(GLenum target);
1066 public:
1067 WebGLBuffer* ValidateBufferSelection(GLenum target) const;
1069 protected:
1070 IndexedBufferBinding* ValidateIndexedBufferSlot(GLenum target, GLuint index);
1072 bool ValidateIndexedBufferBinding(
1073 GLenum target, GLuint index,
1074 RefPtr<WebGLBuffer>** const out_genericBinding,
1075 IndexedBufferBinding** const out_indexedBinding);
1077 public:
1078 bool ValidateNonNegative(const char* argName, int64_t val) const {
1079 if (MOZ_UNLIKELY(val < 0)) {
1080 ErrorInvalidValue("`%s` must be non-negative.", argName);
1081 return false;
1083 return true;
1086 template <typename T>
1087 bool ValidateNonNull(const char* const argName,
1088 const dom::Nullable<T>& maybe) const {
1089 if (maybe.IsNull()) {
1090 ErrorInvalidValue("%s: Cannot be null.", argName);
1091 return false;
1093 return true;
1096 ////
1098 protected:
1099 void DestroyResourcesAndContext();
1101 // helpers
1103 bool ConvertImage(size_t width, size_t height, size_t srcStride,
1104 size_t dstStride, const uint8_t* src, uint8_t* dst,
1105 WebGLTexelFormat srcFormat, bool srcPremultiplied,
1106 WebGLTexelFormat dstFormat, bool dstPremultiplied,
1107 size_t dstTexelSize);
1109 //////
1110 public:
1111 template <typename T>
1112 bool ValidateObject(const char* const argName, const T& object) const {
1113 // Todo: Remove all callers.
1114 return true;
1117 template <typename T>
1118 bool ValidateObject(const char* const argName, const T* const object) const {
1119 // Todo: Remove most (all?) callers.
1120 if (!object) {
1121 ErrorInvalidOperation(
1122 "%s: Object argument cannot have been marked for"
1123 " deletion.",
1124 argName);
1125 return false;
1127 return true;
1130 ////
1132 private:
1133 void LoseContextLruLocked(webgl::ContextLossReason reason)
1134 MOZ_REQUIRES(sLruMutex);
1136 public:
1137 void LoseContext(
1138 webgl::ContextLossReason reason = webgl::ContextLossReason::None);
1140 protected:
1141 nsTArray<RefPtr<WebGLTexture>> mBound2DTextures;
1142 nsTArray<RefPtr<WebGLTexture>> mBoundCubeMapTextures;
1143 nsTArray<RefPtr<WebGLTexture>> mBound3DTextures;
1144 nsTArray<RefPtr<WebGLTexture>> mBound2DArrayTextures;
1145 nsTArray<RefPtr<WebGLSampler>> mBoundSamplers;
1147 void ResolveTexturesForDraw() const;
1149 RefPtr<WebGLProgram> mCurrentProgram;
1150 RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
1152 bool ValidateFramebufferTarget(GLenum target) const;
1153 bool ValidateInvalidateFramebuffer(GLenum target,
1154 const Range<const GLenum>& attachments,
1155 std::vector<GLenum>* const scopedVector,
1156 GLsizei* const out_glNumAttachments,
1157 const GLenum** const out_glAttachments);
1159 RefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
1160 RefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
1161 RefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
1162 RefPtr<WebGLVertexArray> mBoundVertexArray;
1164 public:
1165 const auto& BoundReadFb() const { return mBoundReadFramebuffer; }
1167 protected:
1168 RefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1169 RefPtr<WebGLVertexArray> mDefaultVertexArray;
1171 ////////////////////////////////////
1173 protected:
1174 GLuint mEmptyTFO = 0;
1176 // Generic Vertex Attributes
1177 // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the
1178 // spec state tables, this isn't vertex shader /object/ state. This array is
1179 // merely state useful to vertex shaders, but is global state.
1180 std::vector<webgl::AttribBaseType> mGenericVertexAttribTypes;
1181 CacheInvalidator mGenericVertexAttribTypeInvalidator;
1183 GLuint mFakeVertexAttrib0BufferObject = 0;
1184 intptr_t mFakeVertexAttrib0BufferObjectSize = 0;
1185 bool mFakeVertexAttrib0DataDefined = false;
1186 alignas(alignof(float)) uint8_t
1187 mGenericVertexAttrib0Data[sizeof(float) * 4] = {};
1188 alignas(alignof(float)) uint8_t
1189 mFakeVertexAttrib0Data[sizeof(float) * 4] = {};
1191 GLint mStencilRefFront = 0;
1192 GLint mStencilRefBack = 0;
1193 GLuint mStencilValueMaskFront = 0;
1194 GLuint mStencilValueMaskBack = 0;
1195 GLuint mStencilWriteMaskFront = 0;
1196 GLuint mStencilWriteMaskBack = 0;
1197 uint8_t mColorWriteMask0 = 0xf; // bitmask
1198 mutable uint8_t mDriverColorMask0 = 0xf;
1199 bool mDepthWriteMask = true;
1200 GLfloat mColorClearValue[4] = {0, 0, 0, 0};
1201 GLint mStencilClearValue = 0;
1202 GLfloat mDepthClearValue = 1.0f;
1204 std::bitset<webgl::kMaxDrawBuffers> mColorWriteMaskNonzero = -1;
1205 std::bitset<webgl::kMaxDrawBuffers> mBlendEnabled = 0;
1207 GLint mViewportX = 0;
1208 GLint mViewportY = 0;
1209 GLsizei mViewportWidth = 0;
1210 GLsizei mViewportHeight = 0;
1211 bool mAlreadyWarnedAboutViewportLargerThanDest = false;
1213 GLfloat mLineWidth = 1.0;
1215 WebGLContextLossHandler mContextLossHandler;
1217 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1218 // be Flushed while doing hundreds of draw calls.
1219 mutable uint64_t mDrawCallsSinceLastFlush = 0;
1221 mutable uint64_t mWarningCount = 0;
1222 const uint64_t mMaxWarnings;
1223 bool mAlreadyWarnedAboutFakeVertexAttrib0 = false;
1225 bool ShouldGenerateWarnings() const { return mWarningCount < mMaxWarnings; }
1227 bool ShouldGeneratePerfWarnings() const {
1228 return mNumPerfWarnings < mMaxPerfWarnings;
1231 bool mNeedsFakeNoAlpha = false;
1232 bool mNeedsFakeNoDepth = false;
1233 bool mNeedsFakeNoStencil = false;
1234 bool mNeedsFakeNoStencil_UserFBs = false;
1236 bool mDriverDepthTest = false;
1237 bool mDriverStencilTest = false;
1239 bool mNeedsLegacyVertexAttrib0Handling = false;
1240 bool mMaybeNeedsLegacyVertexAttrib0Handling = false;
1241 bool mNeedsIndexValidation = false;
1242 bool mBug_DrawArraysInstancedUserAttribFetchAffectedByFirst = false;
1244 const bool mAllowFBInvalidation;
1246 bool Has64BitTimestamps() const;
1248 // --
1250 const uint8_t mMsaaSamples;
1251 mutable uvec2 mRequestedSize;
1252 mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
1253 mutable bool mDefaultFB_IsInvalid = false;
1254 mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
1256 gl::SwapChain mSwapChain;
1257 gl::SwapChain mWebVRSwapChain;
1259 RefPtr<layers::RemoteTextureOwnerClient> mRemoteTextureOwner;
1261 bool PushRemoteTexture(WebGLFramebuffer*, gl::SwapChain&,
1262 std::shared_ptr<gl::SharedSurface>,
1263 const webgl::SwapChainOptions& options);
1265 // --
1267 bool EnsureDefaultFB();
1268 bool ValidateAndInitFB(
1269 const WebGLFramebuffer* fb,
1270 GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
1271 void DoBindFB(const WebGLFramebuffer* fb,
1272 GLenum target = LOCAL_GL_FRAMEBUFFER) const;
1274 bool BindCurFBForDraw();
1275 bool BindCurFBForColorRead(
1276 const webgl::FormatUsageInfo** out_format, uint32_t* out_width,
1277 uint32_t* out_height,
1278 GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
1279 void DoColorMask(Maybe<GLuint> i, uint8_t bitmask) const;
1280 void BlitBackbufferToCurDriverFB(
1281 WebGLFramebuffer* const srcAsWebglFb = nullptr,
1282 const gl::MozFramebuffer* const srcAsMozFb = nullptr,
1283 bool srcIsBGRA = false) const;
1284 bool BindDefaultFBForRead();
1286 // --
1288 public:
1289 // console logging helpers
1290 template <typename... Args>
1291 void GenerateWarning(const char* const fmt, const Args&... args) const {
1292 GenerateError(0, fmt, args...);
1295 template <typename... Args>
1296 void GeneratePerfWarning(const char* const fmt, const Args&... args) const {
1297 GenerateError(webgl::kErrorPerfWarning, fmt, args...);
1300 public:
1301 UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
1303 virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
1304 gl::GLContext* gl) const;
1306 const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
1308 // Friend list
1309 friend class ScopedCopyTexImageSource;
1310 friend class ScopedResolveTexturesForDraw;
1311 friend class webgl::TexUnpackBlob;
1312 friend class webgl::TexUnpackBytes;
1313 friend class webgl::TexUnpackImage;
1314 friend class webgl::TexUnpackSurface;
1315 friend struct webgl::UniformInfo;
1316 friend class WebGLTexture;
1317 friend class WebGLFBAttachPoint;
1318 friend class WebGLFramebuffer;
1319 friend class WebGLRenderbuffer;
1320 friend class WebGLProgram;
1321 friend class WebGLQuery;
1322 friend class WebGLBuffer;
1323 friend class WebGLSampler;
1324 friend class WebGLShader;
1325 friend class WebGLSync;
1326 friend class WebGLTransformFeedback;
1327 friend class WebGLVertexArray;
1328 friend class WebGLVertexArrayFake;
1329 friend class WebGLVertexArrayGL;
1332 // Returns `value` rounded to the next highest multiple of `multiple`.
1333 // AKA PadToAlignment, StrideForAlignment.
1334 template <typename V, typename M>
1335 V RoundUpToMultipleOf(const V& value, const M& multiple) {
1336 return ((value + multiple - 1) / multiple) * multiple;
1339 class ScopedFBRebinder final {
1340 private:
1341 const WebGLContext* const mWebGL;
1343 public:
1344 explicit ScopedFBRebinder(const WebGLContext* const webgl) : mWebGL(webgl) {}
1345 ~ScopedFBRebinder();
1348 // -
1350 constexpr inline bool IsBufferTargetLazilyBound(const GLenum target) {
1351 return target != LOCAL_GL_ELEMENT_ARRAY_BUFFER;
1354 void DoBindBuffer(gl::GLContext&, GLenum target, const WebGLBuffer*);
1356 class ScopedLazyBind final {
1357 private:
1358 gl::GLContext& mGL;
1359 const GLenum mTarget;
1361 public:
1362 ScopedLazyBind(gl::GLContext* const gl, const GLenum target,
1363 const WebGLBuffer* const buf)
1364 : mGL(*gl), mTarget(IsBufferTargetLazilyBound(target) ? target : 0) {
1365 if (mTarget) {
1366 DoBindBuffer(mGL, mTarget, buf);
1370 ~ScopedLazyBind() {
1371 if (mTarget) {
1372 DoBindBuffer(mGL, mTarget, nullptr);
1377 ////
1379 bool Intersect(int32_t srcSize, int32_t read0, int32_t readSize,
1380 int32_t* out_intRead0, int32_t* out_intWrite0,
1381 int32_t* out_intSize);
1383 uint64_t AvailGroups(uint64_t totalAvailItems, uint64_t firstItemOffset,
1384 uint32_t groupSize, uint32_t groupStride);
1386 ////
1388 class ScopedDrawCallWrapper final {
1389 public:
1390 WebGLContext& mWebGL;
1392 explicit ScopedDrawCallWrapper(WebGLContext& webgl);
1393 ~ScopedDrawCallWrapper();
1396 namespace webgl {
1398 class ScopedPrepForResourceClear final {
1399 const WebGLContext& webgl;
1401 public:
1402 explicit ScopedPrepForResourceClear(const WebGLContext&);
1403 ~ScopedPrepForResourceClear();
1406 struct IndexedName final {
1407 std::string name;
1408 uint64_t index;
1410 Maybe<IndexedName> ParseIndexed(const std::string& str);
1412 } // namespace webgl
1414 webgl::LinkActiveInfo GetLinkActiveInfo(
1415 gl::GLContext& gl, const GLuint prog, const bool webgl2,
1416 const std::unordered_map<std::string, std::string>& nameUnmap);
1418 } // namespace mozilla
1420 #endif