Bug 1798929 - Reuse samplerByTexUnit capacity to avoid (de)allocs. r=gfx-reviewers...
[gecko.git] / dom / canvas / WebGLContext.h
blobb191a2f133a17394c7fd3fe67d415e18251b15d1
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 // Reuse, to avoid reallocing data for this, as this is showing up in
319 // profiles.
320 std::unordered_map<uint32_t, const webgl::SamplerUniformInfo*>
321 mReuseable_ScopedResolveTexturesForDraw_samplerByTexUnit;
323 public:
324 class FuncScope;
326 private:
327 mutable FuncScope* mFuncScope = nullptr;
329 public:
330 static RefPtr<WebGLContext> Create(HostWebGLContext&,
331 const webgl::InitContextDesc&,
332 webgl::InitContextResult* out);
334 private:
335 void FinishInit();
337 protected:
338 WebGLContext(HostWebGLContext&, const webgl::InitContextDesc&);
339 virtual ~WebGLContext();
341 RefPtr<layers::CompositableHost> mCompositableHost;
343 layers::LayersBackend mBackend = layers::LayersBackend::LAYERS_NONE;
345 public:
346 void Resize(uvec2 size);
348 void SetCompositableHost(RefPtr<layers::CompositableHost>& aCompositableHost);
351 * An abstract base class to be implemented by callers wanting to be notified
352 * that a refresh has occurred. Callers must ensure an observer is removed
353 * before it is destroyed.
355 virtual void DidRefresh();
357 void OnMemoryPressure();
359 // -
363 Here are the bind calls that are supposed to be fully-validated client side,
364 so that client's binding state doesn't diverge:
365 * AttachShader
366 * DetachShader
367 * BindFramebuffer
368 * FramebufferAttach
369 * BindBuffer
370 * BindBufferRange
371 * BindTexture
372 * UseProgram
373 * BindSampler
374 * BindTransformFeedback
375 * BindVertexArray
376 * BeginQuery
377 * EndQuery
378 * ActiveTexture
382 const auto& CurFuncScope() const { return *mFuncScope; }
383 const char* FuncName() const;
385 class FuncScope final {
386 public:
387 const WebGLContext& mWebGL;
388 const char* const mFuncName;
389 bool mBindFailureGuard = false;
391 public:
392 FuncScope(const WebGLContext& webgl, const char* funcName);
393 ~FuncScope();
396 void GenerateErrorImpl(const GLenum err, const nsACString& text) const {
397 GenerateErrorImpl(err, std::string(text.BeginReading()));
399 void GenerateErrorImpl(const GLenum err, const std::string& text) const;
401 void GenerateError(const webgl::ErrorInfo& err) {
402 GenerateError(err.type, "%s", err.info.c_str());
405 template <typename... Args>
406 void GenerateError(const GLenum err, const char* const fmt,
407 const Args&... args) const {
408 MOZ_ASSERT(FuncName());
410 nsCString text;
411 text.AppendPrintf("WebGL warning: %s: ", FuncName());
413 #ifdef __clang__
414 # pragma clang diagnostic push
415 # pragma clang diagnostic ignored "-Wformat-security"
416 #elif defined(__GNUC__)
417 # pragma GCC diagnostic push
418 # pragma GCC diagnostic ignored "-Wformat-security"
419 #endif
420 text.AppendPrintf(fmt, args...);
421 #ifdef __clang__
422 # pragma clang diagnostic pop
423 #elif defined(__GNUC__)
424 # pragma GCC diagnostic pop
425 #endif
427 GenerateErrorImpl(err, text);
430 template <typename... Args>
431 void ErrorInvalidEnum(const char* const fmt, const Args&... args) const {
432 GenerateError(LOCAL_GL_INVALID_ENUM, fmt, args...);
434 template <typename... Args>
435 void ErrorInvalidOperation(const char* const fmt, const Args&... args) const {
436 GenerateError(LOCAL_GL_INVALID_OPERATION, fmt, args...);
438 template <typename... Args>
439 void ErrorInvalidValue(const char* const fmt, const Args&... args) const {
440 GenerateError(LOCAL_GL_INVALID_VALUE, fmt, args...);
442 template <typename... Args>
443 void ErrorInvalidFramebufferOperation(const char* const fmt,
444 const Args&... args) const {
445 GenerateError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION, fmt, args...);
447 template <typename... Args>
448 void ErrorOutOfMemory(const char* const fmt, const Args&... args) const {
449 GenerateError(LOCAL_GL_OUT_OF_MEMORY, fmt, args...);
452 template <typename... Args>
453 void ErrorImplementationBug(const char* const fmt,
454 const Args&... args) const {
455 const nsPrintfCString newFmt(
456 "Implementation bug, please file at %s! %s",
457 "https://bugzilla.mozilla.org/"
458 "enter_bug.cgi?product=Core&component=Canvas%3A+WebGL",
459 fmt);
460 GenerateError(LOCAL_GL_OUT_OF_MEMORY, newFmt.BeginReading(), args...);
461 MOZ_ASSERT(false, "WebGLContext::ErrorImplementationBug");
462 NS_ERROR("WebGLContext::ErrorImplementationBug");
465 void ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const;
466 void ErrorInvalidEnumArg(const char* argName, GLenum val) const;
468 static const char* ErrorName(GLenum error);
471 * Return displayable name for GLenum.
472 * This version is like gl::GLenumToStr but with out the GL_ prefix to
473 * keep consistency with how errors are reported from WebGL.
474 * Returns hex formatted version of glenum if glenum is unknown.
476 static void EnumName(GLenum val, nsCString* out_name);
478 void DummyReadFramebufferOperation();
480 WebGLTexture* GetActiveTex(const GLenum texTarget) const;
482 gl::GLContext* GL() const { return gl; }
484 bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
486 bool IsPreservingDrawingBuffer() const {
487 return mOptions.preserveDrawingBuffer;
490 // Present to compositor
491 private:
492 bool PresentInto(gl::SwapChain& swapChain);
493 bool PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& xrFb);
495 public:
496 // Present swaps the front and back buffers of the swap chain for compositing.
497 // This assumes the framebuffer may directly alias with the back buffer,
498 // dependent on remoting state or other concerns. Framebuffer and swap chain
499 // surface formats are assumed to be similar to enable this aliasing. As such,
500 // the back buffer may be invalidated by this swap with the front buffer,
501 // unless overriden by explicitly setting the preserveDrawingBuffer option,
502 // which may incur a further copy to preserve the back buffer.
503 void Present(
504 WebGLFramebuffer*, layers::TextureType, const bool webvr,
505 const webgl::SwapChainOptions& options = webgl::SwapChainOptions());
506 // CopyToSwapChain forces a copy from the supplied framebuffer into the back
507 // buffer before swapping the front and back buffers of the swap chain for
508 // compositing. The formats of the framebuffer and the swap chain buffers
509 // may differ subject to available format conversion options. Since this
510 // operation uses an explicit copy, it inherently preserves the framebuffer
511 // without need to set the preserveDrawingBuffer option.
512 void CopyToSwapChain(
513 WebGLFramebuffer*, layers::TextureType,
514 const webgl::SwapChainOptions& options = webgl::SwapChainOptions());
515 // In use cases where a framebuffer is used as an offscreen framebuffer and
516 // does not need to be committed to the swap chain, it may still be useful
517 // for the implementation to delineate distinct frames, such as when sharing
518 // a single WebGLContext amongst many distinct users. EndOfFrame signals that
519 // frame rendering is complete so that any implementation side-effects such
520 // as resetting internal profile counters or resource queues may be handled
521 // appropriately.
522 void EndOfFrame();
523 RefPtr<gfx::DataSourceSurface> GetFrontBufferSnapshot();
524 Maybe<uvec2> FrontBufferSnapshotInto(
525 const Maybe<Range<uint8_t>> dest,
526 const Maybe<size_t> destStride = Nothing());
527 Maybe<uvec2> FrontBufferSnapshotInto(
528 const std::shared_ptr<gl::SharedSurface>& front,
529 const Maybe<Range<uint8_t>> dest,
530 const Maybe<size_t> destStride = Nothing());
531 Maybe<uvec2> SnapshotInto(GLuint srcFb, const gfx::IntSize& size,
532 const Range<uint8_t>& dest,
533 const Maybe<size_t> destStride = Nothing());
534 gl::SwapChain* GetSwapChain(WebGLFramebuffer*, const bool webvr);
535 Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebuffer*,
536 const bool webvr);
538 void ClearVRSwapChain();
540 void RunContextLossTimer();
541 void CheckForContextLoss();
542 void HandlePendingContextLoss();
544 bool TryToRestoreContext();
546 void AssertCachedBindings() const;
547 void AssertCachedGlobalState() const;
549 // WebIDL WebGLRenderingContext API
550 void Commit();
552 uvec2 DrawingBufferSize();
554 public:
555 void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
557 // This is the entrypoint. Don't test against it directly.
558 bool IsContextLost() const {
559 auto* self = const_cast<WebGLContext*>(this);
560 if (self->mPendingContextLoss.exchange(false)) {
561 self->HandlePendingContextLoss();
563 return mIsContextLost;
566 // -
568 RefPtr<WebGLBuffer> CreateBuffer();
569 RefPtr<WebGLFramebuffer> CreateFramebuffer();
570 RefPtr<WebGLFramebuffer> CreateOpaqueFramebuffer(
571 const webgl::OpaqueFramebufferOptions& options);
572 RefPtr<WebGLProgram> CreateProgram();
573 RefPtr<WebGLQuery> CreateQuery();
574 RefPtr<WebGLRenderbuffer> CreateRenderbuffer();
575 RefPtr<WebGLShader> CreateShader(GLenum type);
576 RefPtr<WebGLTexture> CreateTexture();
577 RefPtr<WebGLVertexArray> CreateVertexArray();
579 // -
581 void AttachShader(WebGLProgram& prog, WebGLShader& shader);
582 void BindAttribLocation(WebGLProgram& prog, GLuint location,
583 const std::string& name) const;
584 void BindFramebuffer(GLenum target, WebGLFramebuffer* fb);
585 void BindRenderbuffer(GLenum target, WebGLRenderbuffer* fb);
586 void BindVertexArray(WebGLVertexArray* vao);
587 void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
588 void BlendEquationSeparate(Maybe<GLuint> i, GLenum modeRGB, GLenum modeAlpha);
589 void BlendFuncSeparate(Maybe<GLuint> i, GLenum srcRGB, GLenum dstRGB,
590 GLenum srcAlpha, GLenum dstAlpha);
591 GLenum CheckFramebufferStatus(GLenum target);
592 void Clear(GLbitfield mask);
593 void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
594 void ClearDepth(GLclampf v);
595 void ClearStencil(GLint v);
596 void ColorMask(Maybe<GLuint> i, uint8_t mask);
597 void CompileShader(WebGLShader& shader);
599 private:
600 void CompileShaderANGLE(WebGLShader* shader);
601 void CompileShaderBypass(WebGLShader* shader, const nsCString& shaderSource);
603 public:
604 void CullFace(GLenum face);
605 void DepthFunc(GLenum func);
606 void DepthMask(WebGLboolean b);
607 void DepthRange(GLclampf zNear, GLclampf zFar);
608 void DetachShader(WebGLProgram& prog, const WebGLShader& shader);
609 void DrawBuffers(const std::vector<GLenum>& buffers);
610 void Flush();
611 void Finish();
613 void FramebufferAttach(GLenum target, GLenum attachSlot,
614 GLenum bindImageTarget,
615 const webgl::FbAttachInfo& toAttach);
617 void FrontFace(GLenum mode);
619 Maybe<double> GetBufferParameter(GLenum target, GLenum pname);
620 webgl::CompileResult GetCompileResult(const WebGLShader&) const;
621 GLenum GetError();
622 GLint GetFragDataLocation(const WebGLProgram&, const std::string& name) const;
624 Maybe<double> GetFramebufferAttachmentParameter(WebGLFramebuffer*,
625 GLenum attachment,
626 GLenum pname) const;
628 Maybe<double> GetRenderbufferParameter(const WebGLRenderbuffer&,
629 GLenum pname) const;
630 webgl::LinkResult GetLinkResult(const WebGLProgram&) const;
632 Maybe<webgl::ShaderPrecisionFormat> GetShaderPrecisionFormat(
633 GLenum shadertype, GLenum precisiontype) const;
635 webgl::GetUniformData GetUniform(const WebGLProgram&, uint32_t loc) const;
637 void Hint(GLenum target, GLenum mode);
639 void LineWidth(GLfloat width);
640 void LinkProgram(WebGLProgram& prog);
641 void PolygonOffset(GLfloat factor, GLfloat units);
643 ////
645 webgl::PackingInfo ValidImplementationColorReadPI(
646 const webgl::FormatUsageInfo* usage) const;
648 protected:
649 webgl::ReadPixelsResult ReadPixelsImpl(const webgl::ReadPixelsDesc&,
650 uintptr_t dest, uint64_t availBytes);
651 bool DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat,
652 const webgl::ReadPixelsDesc&, uintptr_t dest,
653 uint64_t dataLen, uint32_t rowStride);
655 public:
656 void ReadPixelsPbo(const webgl::ReadPixelsDesc&, uint64_t offset);
657 webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc&,
658 const Range<uint8_t>& dest);
660 ////
662 void RenderbufferStorageMultisample(WebGLRenderbuffer&, uint32_t samples,
663 GLenum internalformat, uint32_t width,
664 uint32_t height) const;
666 public:
667 void SampleCoverage(GLclampf value, WebGLboolean invert);
668 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
669 void ShaderSource(WebGLShader& shader, const std::string& source) const;
670 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
671 void StencilMaskSeparate(GLenum face, GLuint mask);
672 void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
673 GLenum dppass);
675 //////////////////////////
677 void UniformData(uint32_t loc, bool transpose,
678 const Range<const webgl::UniformDataVal>& data) const;
680 ////////////////////////////////////
682 void UseProgram(WebGLProgram* prog);
684 bool ValidateAttribArraySetter(uint32_t count, uint32_t arrayLength);
685 bool ValidateProgram(const WebGLProgram& prog) const;
686 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
688 // -----------------------------------------------------------------------------
689 // Buffer Objects (WebGLContextBuffers.cpp)
690 void BindBuffer(GLenum target, WebGLBuffer* buffer);
691 void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
692 uint64_t offset, uint64_t size);
694 void BufferData(GLenum target, uint64_t dataLen, const uint8_t* data,
695 GLenum usage) const;
696 void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t srcDataLen,
697 const uint8_t* srcData) const;
699 protected:
700 // bound buffer state
701 RefPtr<WebGLBuffer> mBoundArrayBuffer;
702 RefPtr<WebGLBuffer> mBoundCopyReadBuffer;
703 RefPtr<WebGLBuffer> mBoundCopyWriteBuffer;
704 RefPtr<WebGLBuffer> mBoundPixelPackBuffer;
705 RefPtr<WebGLBuffer> mBoundPixelUnpackBuffer;
706 RefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
707 RefPtr<WebGLBuffer> mBoundUniformBuffer;
709 std::vector<IndexedBufferBinding> mIndexedUniformBufferBindings;
711 RefPtr<WebGLBuffer>& GetBufferSlotByTarget(GLenum target);
712 RefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
713 GLuint index);
715 // -
717 void GenErrorIllegalUse(GLenum useTarget, uint32_t useId, GLenum boundTarget,
718 uint32_t boundId) const;
720 bool ValidateBufferForNonTf(const WebGLBuffer&, GLenum nonTfTarget,
721 uint32_t nonTfId) const;
723 bool ValidateBufferForNonTf(const WebGLBuffer* const nonTfBuffer,
724 const GLenum nonTfTarget,
725 const uint32_t nonTfId = -1) const {
726 if (!nonTfBuffer) return true;
727 return ValidateBufferForNonTf(*nonTfBuffer, nonTfTarget, nonTfId);
730 bool ValidateBuffersForTf(const WebGLTransformFeedback&,
731 const webgl::LinkedProgramInfo&) const;
732 bool ValidateBuffersForTf(
733 const std::vector<webgl::BufferAndIndex>& tfBuffers) const;
735 // -----------------------------------------------------------------------------
736 // Queries (WebGL2ContextQueries.cpp)
737 protected:
738 RefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
739 RefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
740 RefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
742 RefPtr<WebGLQuery>* ValidateQuerySlotByTarget(GLenum target);
744 public:
745 void BeginQuery(GLenum target, WebGLQuery& query);
746 void EndQuery(GLenum target);
747 Maybe<double> GetQueryParameter(const WebGLQuery& query, GLenum pname) const;
748 void QueryCounter(WebGLQuery&) const;
750 // -----------------------------------------------------------------------------
751 // State and State Requests (WebGLContextState.cpp)
752 void SetEnabled(GLenum cap, Maybe<GLuint> i, bool enabled);
753 bool GetStencilBits(GLint* const out_stencilBits) const;
755 virtual Maybe<double> GetParameter(GLenum pname);
756 Maybe<std::string> GetString(GLenum pname) const;
758 bool IsEnabled(GLenum cap);
760 private:
761 static StaticMutex sLruMutex;
762 static std::list<WebGLContext*> sLru MOZ_GUARDED_BY(sLruMutex);
764 // State tracking slots
765 bool mDitherEnabled = true;
766 bool mRasterizerDiscardEnabled = false;
767 bool mScissorTestEnabled = false;
768 bool mDepthTestEnabled = false;
769 bool mStencilTestEnabled = false;
770 GLenum mGenerateMipmapHint = LOCAL_GL_DONT_CARE;
772 struct ScissorRect final {
773 GLint x;
774 GLint y;
775 GLsizei w;
776 GLsizei h;
778 void Apply(gl::GLContext&) const;
780 ScissorRect mScissorRect = {};
782 bool ValidateCapabilityEnum(GLenum cap);
783 bool* GetStateTrackingSlot(GLenum cap, GLuint i);
785 // Allocation debugging variables
786 mutable uint64_t mDataAllocGLCallCount = 0;
788 void OnDataAllocCall() const { mDataAllocGLCallCount++; }
790 uint64_t GetNumGLDataAllocCalls() const { return mDataAllocGLCallCount; }
792 void OnEndOfFrame();
794 // -----------------------------------------------------------------------------
795 // Texture funcions (WebGLContextTextures.cpp)
796 public:
797 void ActiveTexture(uint32_t texUnit);
798 void BindTexture(GLenum texTarget, WebGLTexture* tex);
799 void GenerateMipmap(GLenum texTarget);
801 Maybe<double> GetTexParameter(const WebGLTexture&, GLenum pname) const;
802 void TexParameter_base(GLenum texTarget, GLenum pname,
803 const FloatOrInt& param);
805 virtual bool IsTexParamValid(GLenum pname) const;
807 ////////////////////////////////////
808 // Uploads
810 // CompressedTexSubImage if `sub`
811 void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level,
812 GLenum format, uvec3 offset, uvec3 size,
813 const Range<const uint8_t>& src,
814 const uint32_t pboImageSize,
815 const Maybe<uint64_t>& pboOffset) const;
817 // CopyTexSubImage if `!respectFormat`
818 void CopyTexImage(GLenum imageTarget, uint32_t level, GLenum respecFormat,
819 uvec3 dstOffset, const ivec2& srcOffset,
820 const uvec2& size) const;
822 // TexSubImage if `!respectFormat`
823 void TexImage(uint32_t level, GLenum respecFormat, uvec3 offset,
824 const webgl::PackingInfo& pi,
825 const webgl::TexUnpackBlobDesc&) const;
827 void TexStorage(GLenum texTarget, uint32_t levels, GLenum sizedFormat,
828 uvec3 size) const;
830 UniquePtr<webgl::TexUnpackBlob> ToTexUnpackBytes(
831 const WebGLTexImageData& imageData);
833 UniquePtr<webgl::TexUnpackBytes> ToTexUnpackBytes(WebGLTexPboOffset& aPbo);
835 ////////////////////////////////////
836 // WebGLTextureUpload.cpp
837 protected:
838 bool ValidateTexImageSpecification(uint8_t funcDims, GLenum texImageTarget,
839 GLint level, GLsizei width, GLsizei height,
840 GLsizei depth, GLint border,
841 TexImageTarget* const out_target,
842 WebGLTexture** const out_texture,
843 webgl::ImageInfo** const out_imageInfo);
844 bool ValidateTexImageSelection(uint8_t funcDims, GLenum texImageTarget,
845 GLint level, GLint xOffset, GLint yOffset,
846 GLint zOffset, GLsizei width, GLsizei height,
847 GLsizei depth,
848 TexImageTarget* const out_target,
849 WebGLTexture** const out_texture,
850 webgl::ImageInfo** const out_imageInfo);
851 bool ValidateUnpackInfo(bool usePBOs, GLenum format, GLenum type,
852 webgl::PackingInfo* const out);
854 // -----------------------------------------------------------------------------
855 // Vertices Feature (WebGLContextVertices.cpp)
856 GLenum mPrimRestartTypeBytes = 0;
858 public:
859 void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount,
860 GLsizei instanceCount);
861 void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type,
862 WebGLintptr byteOffset, GLsizei instanceCount);
864 void EnableVertexAttribArray(GLuint index);
865 void DisableVertexAttribArray(GLuint index);
867 Maybe<double> GetVertexAttrib(GLuint index, GLenum pname);
869 ////
871 void VertexAttrib4T(GLuint index, const webgl::TypedQuad&);
873 ////
875 void VertexAttribPointer(uint32_t index, const webgl::VertAttribPointerDesc&);
877 void VertexAttribDivisor(GLuint index, GLuint divisor);
879 private:
880 WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
881 WebGLintptr byteOffset,
882 GLsizei instanceCount);
883 void Draw_cleanup();
885 void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
886 const GLfloat* ptr);
887 void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
888 const GLfloat* ptr);
889 void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
890 const GLfloat* ptr);
891 void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
892 const GLfloat* ptr);
894 bool BindArrayAttribToLocation0(WebGLProgram* prog);
896 // -----------------------------------------------------------------------------
897 // PROTECTED
898 protected:
899 WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
900 bool DoFakeVertexAttrib0(uint64_t fakeVertexCount,
901 WebGLVertexAttrib0Status whatDoesAttrib0Need);
902 void UndoFakeVertexAttrib0();
904 bool mResetLayer = true;
905 bool mOptionsFrozen = false;
906 bool mIsMesa = false;
907 bool mLoseContextOnMemoryPressure = false;
908 bool mCanLoseContextInForeground = true;
909 bool mShouldPresent = false;
910 bool mDisableFragHighP = false;
911 bool mForceResizeOnPresent = false;
912 bool mVRReady = false;
914 template <typename WebGLObjectType>
915 void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
917 GLuint mActiveTexture = 0;
918 GLenum mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
919 GLenum mDefaultFB_ReadBuffer = LOCAL_GL_BACK;
921 mutable GLenum mWebGLError = 0;
923 std::unique_ptr<webgl::ShaderValidator> CreateShaderValidator(
924 GLenum shaderType) const;
926 // some GL constants
927 uint32_t mGLMaxFragmentUniformVectors = 0;
928 uint32_t mGLMaxVertexUniformVectors = 0;
929 uint32_t mGLMaxVertexOutputVectors = 0;
930 uint32_t mGLMaxFragmentInputVectors = 0;
932 uint32_t mGLMaxVertexTextureImageUnits = 0;
933 uint32_t mGLMaxFragmentTextureImageUnits = 0;
934 uint32_t mGLMaxCombinedTextureImageUnits = 0;
936 // ES3:
937 uint32_t mGLMinProgramTexelOffset = 0;
938 uint32_t mGLMaxProgramTexelOffset = 0;
940 public:
941 auto GLMaxDrawBuffers() const { return mLimits->maxColorDrawBuffers; }
943 uint32_t MaxValidDrawBuffers() const {
944 if (IsWebGL2() ||
945 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
946 return GLMaxDrawBuffers();
948 return 1;
951 GLenum LastColorAttachmentEnum() const {
952 return LOCAL_GL_COLOR_ATTACHMENT0 + MaxValidDrawBuffers() - 1;
955 const auto& Options() const { return mOptions; }
957 protected:
958 uint32_t mGLMaxRenderbufferSize = 0;
960 public:
961 const auto& Limits() const { return *mLimits; }
962 auto MaxVertexAttribs() const { return mLimits->maxVertexAttribs; }
963 auto GLMaxTextureUnits() const { return mLimits->maxTexUnits; }
965 bool IsFormatValidForFB(TexInternalFormat format) const;
967 protected:
968 // -------------------------------------------------------------------------
969 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
971 EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max,
972 std::unique_ptr<WebGLExtensionBase>>
973 mExtensions;
975 public:
976 void RequestExtension(WebGLExtensionID, bool explicitly = true);
978 // returns true if the extension has been enabled by calling getExtension.
979 bool IsExtensionEnabled(const WebGLExtensionID id) const {
980 return bool(mExtensions[id]);
983 bool IsExtensionExplicit(WebGLExtensionID) const;
984 void WarnIfImplicit(WebGLExtensionID) const;
986 bool IsExtensionSupported(WebGLExtensionID) const;
988 // -------------------------------------------------------------------------
989 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
990 public:
991 virtual bool IsWebGL2() const { return false; }
993 struct FailureReason {
994 nsCString key; // For reporting.
995 nsCString info;
997 FailureReason() = default;
999 template <typename A, typename B>
1000 FailureReason(const A& _key, const B& _info)
1001 : key(nsCString(_key)), info(nsCString(_info)) {}
1004 protected:
1005 bool InitWebGL2(FailureReason* const out_failReason);
1007 bool CreateAndInitGL(bool forceEnabled,
1008 std::vector<FailureReason>* const out_failReasons);
1010 // -------------------------------------------------------------------------
1011 // Validation functions (implemented in WebGLContextValidate.cpp)
1012 bool InitAndValidateGL(FailureReason* const out_failReason);
1014 bool ValidateBlendEquationEnum(GLenum cap, const char* info);
1015 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor,
1016 const char* info);
1017 bool ValidateStencilOpEnum(GLenum action, const char* info);
1018 bool ValidateFaceEnum(GLenum face);
1019 bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
1020 WebGLTexImageFunc func, WebGLTexDimensions dims);
1021 bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size,
1022 GLenum type, WebGLboolean normalized,
1023 GLsizei stride, WebGLintptr byteOffset,
1024 const char* info);
1025 bool ValidateStencilParamsForDrawCall() const;
1027 bool ValidateCopyTexImage(TexInternalFormat srcFormat,
1028 TexInternalFormat dstformat, WebGLTexImageFunc func,
1029 WebGLTexDimensions dims);
1031 bool ValidateTexImage(TexImageTarget texImageTarget, GLint level,
1032 GLenum internalFormat, GLint xoffset, GLint yoffset,
1033 GLint zoffset, GLint width, GLint height, GLint depth,
1034 GLint border, GLenum format, GLenum type,
1035 WebGLTexImageFunc func, WebGLTexDimensions dims);
1036 bool ValidateTexImageFormat(GLenum internalFormat, WebGLTexImageFunc func,
1037 WebGLTexDimensions dims);
1038 bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func,
1039 WebGLTexDimensions dims);
1040 bool ValidateTexImageFormatAndType(GLenum format, GLenum type,
1041 WebGLTexImageFunc func,
1042 WebGLTexDimensions dims);
1043 bool ValidateCompTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1044 WebGLTexDimensions dims);
1045 bool ValidateCopyTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1046 WebGLTexDimensions dims);
1047 bool ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
1048 GLint width, GLint height, GLint depth,
1049 WebGLTexImageFunc func, WebGLTexDimensions dims);
1050 bool ValidateTexSubImageSize(GLint x, GLint y, GLint z, GLsizei width,
1051 GLsizei height, GLsizei depth, GLsizei baseWidth,
1052 GLsizei baseHeight, GLsizei baseDepth,
1053 WebGLTexImageFunc func, WebGLTexDimensions dims);
1054 bool ValidateCompTexImageSize(GLint level, GLenum internalFormat,
1055 GLint xoffset, GLint yoffset, GLsizei width,
1056 GLsizei height, GLsizei levelWidth,
1057 GLsizei levelHeight, WebGLTexImageFunc func,
1058 WebGLTexDimensions dims);
1059 bool ValidateCompTexImageDataSize(GLint level, GLenum internalFormat,
1060 GLsizei width, GLsizei height,
1061 uint32_t byteLength, WebGLTexImageFunc func,
1062 WebGLTexDimensions dims);
1064 bool HasDrawBuffers() const {
1065 return IsWebGL2() ||
1066 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
1069 RefPtr<WebGLBuffer>* ValidateBufferSlot(GLenum target);
1071 public:
1072 WebGLBuffer* ValidateBufferSelection(GLenum target) const;
1074 protected:
1075 IndexedBufferBinding* ValidateIndexedBufferSlot(GLenum target, GLuint index);
1077 bool ValidateIndexedBufferBinding(
1078 GLenum target, GLuint index,
1079 RefPtr<WebGLBuffer>** const out_genericBinding,
1080 IndexedBufferBinding** const out_indexedBinding);
1082 public:
1083 bool ValidateNonNegative(const char* argName, int64_t val) const {
1084 if (MOZ_UNLIKELY(val < 0)) {
1085 ErrorInvalidValue("`%s` must be non-negative.", argName);
1086 return false;
1088 return true;
1091 template <typename T>
1092 bool ValidateNonNull(const char* const argName,
1093 const dom::Nullable<T>& maybe) const {
1094 if (maybe.IsNull()) {
1095 ErrorInvalidValue("%s: Cannot be null.", argName);
1096 return false;
1098 return true;
1101 ////
1103 protected:
1104 void DestroyResourcesAndContext();
1106 // helpers
1108 bool ConvertImage(size_t width, size_t height, size_t srcStride,
1109 size_t dstStride, const uint8_t* src, uint8_t* dst,
1110 WebGLTexelFormat srcFormat, bool srcPremultiplied,
1111 WebGLTexelFormat dstFormat, bool dstPremultiplied,
1112 size_t dstTexelSize);
1114 //////
1115 public:
1116 template <typename T>
1117 bool ValidateObject(const char* const argName, const T& object) const {
1118 // Todo: Remove all callers.
1119 return true;
1122 template <typename T>
1123 bool ValidateObject(const char* const argName, const T* const object) const {
1124 // Todo: Remove most (all?) callers.
1125 if (!object) {
1126 ErrorInvalidOperation(
1127 "%s: Object argument cannot have been marked for"
1128 " deletion.",
1129 argName);
1130 return false;
1132 return true;
1135 ////
1137 private:
1138 void LoseContextLruLocked(webgl::ContextLossReason reason)
1139 MOZ_REQUIRES(sLruMutex);
1141 public:
1142 void LoseContext(
1143 webgl::ContextLossReason reason = webgl::ContextLossReason::None);
1145 protected:
1146 nsTArray<RefPtr<WebGLTexture>> mBound2DTextures;
1147 nsTArray<RefPtr<WebGLTexture>> mBoundCubeMapTextures;
1148 nsTArray<RefPtr<WebGLTexture>> mBound3DTextures;
1149 nsTArray<RefPtr<WebGLTexture>> mBound2DArrayTextures;
1150 nsTArray<RefPtr<WebGLSampler>> mBoundSamplers;
1152 void ResolveTexturesForDraw() const;
1154 RefPtr<WebGLProgram> mCurrentProgram;
1155 RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
1157 bool ValidateFramebufferTarget(GLenum target) const;
1158 bool ValidateInvalidateFramebuffer(GLenum target,
1159 const Range<const GLenum>& attachments,
1160 std::vector<GLenum>* const scopedVector,
1161 GLsizei* const out_glNumAttachments,
1162 const GLenum** const out_glAttachments);
1164 RefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
1165 RefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
1166 RefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
1167 RefPtr<WebGLVertexArray> mBoundVertexArray;
1169 public:
1170 const auto& BoundReadFb() const { return mBoundReadFramebuffer; }
1172 protected:
1173 RefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1174 RefPtr<WebGLVertexArray> mDefaultVertexArray;
1176 ////////////////////////////////////
1178 protected:
1179 GLuint mEmptyTFO = 0;
1181 // Generic Vertex Attributes
1182 // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the
1183 // spec state tables, this isn't vertex shader /object/ state. This array is
1184 // merely state useful to vertex shaders, but is global state.
1185 std::vector<webgl::AttribBaseType> mGenericVertexAttribTypes;
1186 CacheInvalidator mGenericVertexAttribTypeInvalidator;
1188 GLuint mFakeVertexAttrib0BufferObject = 0;
1189 intptr_t mFakeVertexAttrib0BufferObjectSize = 0;
1190 bool mFakeVertexAttrib0DataDefined = false;
1191 alignas(alignof(float)) uint8_t
1192 mGenericVertexAttrib0Data[sizeof(float) * 4] = {};
1193 alignas(alignof(float)) uint8_t
1194 mFakeVertexAttrib0Data[sizeof(float) * 4] = {};
1196 GLint mStencilRefFront = 0;
1197 GLint mStencilRefBack = 0;
1198 GLuint mStencilValueMaskFront = 0;
1199 GLuint mStencilValueMaskBack = 0;
1200 GLuint mStencilWriteMaskFront = 0;
1201 GLuint mStencilWriteMaskBack = 0;
1202 uint8_t mColorWriteMask0 = 0xf; // bitmask
1203 mutable uint8_t mDriverColorMask0 = 0xf;
1204 bool mDepthWriteMask = true;
1205 GLfloat mColorClearValue[4] = {0, 0, 0, 0};
1206 GLint mStencilClearValue = 0;
1207 GLfloat mDepthClearValue = 1.0f;
1209 std::bitset<webgl::kMaxDrawBuffers> mColorWriteMaskNonzero = -1;
1210 std::bitset<webgl::kMaxDrawBuffers> mBlendEnabled = 0;
1212 GLint mViewportX = 0;
1213 GLint mViewportY = 0;
1214 GLsizei mViewportWidth = 0;
1215 GLsizei mViewportHeight = 0;
1216 bool mAlreadyWarnedAboutViewportLargerThanDest = false;
1218 GLfloat mLineWidth = 1.0;
1220 WebGLContextLossHandler mContextLossHandler;
1222 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1223 // be Flushed while doing hundreds of draw calls.
1224 mutable uint64_t mDrawCallsSinceLastFlush = 0;
1226 mutable uint64_t mWarningCount = 0;
1227 const uint64_t mMaxWarnings;
1228 bool mAlreadyWarnedAboutFakeVertexAttrib0 = false;
1230 bool ShouldGenerateWarnings() const { return mWarningCount < mMaxWarnings; }
1232 bool ShouldGeneratePerfWarnings() const {
1233 return mNumPerfWarnings < mMaxPerfWarnings;
1236 bool mNeedsFakeNoAlpha = false;
1237 bool mNeedsFakeNoDepth = false;
1238 bool mNeedsFakeNoStencil = false;
1239 bool mNeedsFakeNoStencil_UserFBs = false;
1241 bool mDriverDepthTest = false;
1242 bool mDriverStencilTest = false;
1244 bool mNeedsLegacyVertexAttrib0Handling = false;
1245 bool mMaybeNeedsLegacyVertexAttrib0Handling = false;
1246 bool mNeedsIndexValidation = false;
1247 bool mBug_DrawArraysInstancedUserAttribFetchAffectedByFirst = false;
1249 const bool mAllowFBInvalidation;
1251 bool Has64BitTimestamps() const;
1253 // --
1255 const uint8_t mMsaaSamples;
1256 mutable uvec2 mRequestedSize;
1257 mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
1258 mutable bool mDefaultFB_IsInvalid = false;
1259 mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
1261 gl::SwapChain mSwapChain;
1262 gl::SwapChain mWebVRSwapChain;
1264 RefPtr<layers::RemoteTextureOwnerClient> mRemoteTextureOwner;
1266 bool PushRemoteTexture(WebGLFramebuffer*, gl::SwapChain&,
1267 std::shared_ptr<gl::SharedSurface>,
1268 const webgl::SwapChainOptions& options);
1270 // --
1272 bool EnsureDefaultFB();
1273 bool ValidateAndInitFB(
1274 const WebGLFramebuffer* fb,
1275 GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
1276 void DoBindFB(const WebGLFramebuffer* fb,
1277 GLenum target = LOCAL_GL_FRAMEBUFFER) const;
1279 bool BindCurFBForDraw();
1280 bool BindCurFBForColorRead(
1281 const webgl::FormatUsageInfo** out_format, uint32_t* out_width,
1282 uint32_t* out_height,
1283 GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
1284 void DoColorMask(Maybe<GLuint> i, uint8_t bitmask) const;
1285 void BlitBackbufferToCurDriverFB(
1286 WebGLFramebuffer* const srcAsWebglFb = nullptr,
1287 const gl::MozFramebuffer* const srcAsMozFb = nullptr,
1288 bool srcIsBGRA = false) const;
1289 bool BindDefaultFBForRead();
1291 // --
1293 public:
1294 // console logging helpers
1295 template <typename... Args>
1296 void GenerateWarning(const char* const fmt, const Args&... args) const {
1297 GenerateError(0, fmt, args...);
1300 template <typename... Args>
1301 void GeneratePerfWarning(const char* const fmt, const Args&... args) const {
1302 GenerateError(webgl::kErrorPerfWarning, fmt, args...);
1305 public:
1306 UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
1308 virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
1309 gl::GLContext* gl) const;
1311 const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
1313 // Friend list
1314 friend class ScopedCopyTexImageSource;
1315 friend class ScopedResolveTexturesForDraw;
1316 friend class webgl::TexUnpackBlob;
1317 friend class webgl::TexUnpackBytes;
1318 friend class webgl::TexUnpackImage;
1319 friend class webgl::TexUnpackSurface;
1320 friend struct webgl::UniformInfo;
1321 friend class WebGLTexture;
1322 friend class WebGLFBAttachPoint;
1323 friend class WebGLFramebuffer;
1324 friend class WebGLRenderbuffer;
1325 friend class WebGLProgram;
1326 friend class WebGLQuery;
1327 friend class WebGLBuffer;
1328 friend class WebGLSampler;
1329 friend class WebGLShader;
1330 friend class WebGLSync;
1331 friend class WebGLTransformFeedback;
1332 friend class WebGLVertexArray;
1333 friend class WebGLVertexArrayFake;
1334 friend class WebGLVertexArrayGL;
1337 // Returns `value` rounded to the next highest multiple of `multiple`.
1338 // AKA PadToAlignment, StrideForAlignment.
1339 template <typename V, typename M>
1340 V RoundUpToMultipleOf(const V& value, const M& multiple) {
1341 return ((value + multiple - 1) / multiple) * multiple;
1344 class ScopedFBRebinder final {
1345 private:
1346 const WebGLContext* const mWebGL;
1348 public:
1349 explicit ScopedFBRebinder(const WebGLContext* const webgl) : mWebGL(webgl) {}
1350 ~ScopedFBRebinder();
1353 // -
1355 constexpr inline bool IsBufferTargetLazilyBound(const GLenum target) {
1356 return target != LOCAL_GL_ELEMENT_ARRAY_BUFFER;
1359 void DoBindBuffer(gl::GLContext&, GLenum target, const WebGLBuffer*);
1361 class ScopedLazyBind final {
1362 private:
1363 gl::GLContext& mGL;
1364 const GLenum mTarget;
1366 public:
1367 ScopedLazyBind(gl::GLContext* const gl, const GLenum target,
1368 const WebGLBuffer* const buf)
1369 : mGL(*gl), mTarget(IsBufferTargetLazilyBound(target) ? target : 0) {
1370 if (mTarget) {
1371 DoBindBuffer(mGL, mTarget, buf);
1375 ~ScopedLazyBind() {
1376 if (mTarget) {
1377 DoBindBuffer(mGL, mTarget, nullptr);
1382 ////
1384 bool Intersect(int32_t srcSize, int32_t read0, int32_t readSize,
1385 int32_t* out_intRead0, int32_t* out_intWrite0,
1386 int32_t* out_intSize);
1388 uint64_t AvailGroups(uint64_t totalAvailItems, uint64_t firstItemOffset,
1389 uint32_t groupSize, uint32_t groupStride);
1391 ////
1393 class ScopedDrawCallWrapper final {
1394 public:
1395 WebGLContext& mWebGL;
1397 explicit ScopedDrawCallWrapper(WebGLContext& webgl);
1398 ~ScopedDrawCallWrapper();
1401 namespace webgl {
1403 class ScopedPrepForResourceClear final {
1404 const WebGLContext& webgl;
1406 public:
1407 explicit ScopedPrepForResourceClear(const WebGLContext&);
1408 ~ScopedPrepForResourceClear();
1411 struct IndexedName final {
1412 std::string name;
1413 uint64_t index;
1415 Maybe<IndexedName> ParseIndexed(const std::string& str);
1417 } // namespace webgl
1419 webgl::LinkActiveInfo GetLinkActiveInfo(
1420 gl::GLContext& gl, const GLuint prog, const bool webgl2,
1421 const std::unordered_map<std::string, std::string>& nameUnmap);
1423 } // namespace mozilla
1425 #endif