Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / dom / canvas / WebGLContext.h
blob96d1fe468feb4f5a812b99b9c1ce94bb015a59a5
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);
637 void ProvokingVertex(webgl::ProvokingVertex) const;
639 ////
641 webgl::PackingInfo ValidImplementationColorReadPI(
642 const webgl::FormatUsageInfo* usage) const;
644 protected:
645 webgl::ReadPixelsResult ReadPixelsImpl(const webgl::ReadPixelsDesc&,
646 uintptr_t dest, uint64_t availBytes);
647 bool DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat,
648 const webgl::ReadPixelsDesc&, uintptr_t dest,
649 uint64_t dataLen, uint32_t rowStride);
651 public:
652 void ReadPixelsPbo(const webgl::ReadPixelsDesc&, uint64_t offset);
653 webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc&,
654 const Range<uint8_t>& dest);
656 ////
658 void RenderbufferStorageMultisample(WebGLRenderbuffer&, uint32_t samples,
659 GLenum internalformat, uint32_t width,
660 uint32_t height) const;
662 public:
663 void SampleCoverage(GLclampf value, WebGLboolean invert);
664 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
665 void ShaderSource(WebGLShader& shader, const std::string& source) const;
666 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
667 void StencilMaskSeparate(GLenum face, GLuint mask);
668 void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
669 GLenum dppass);
671 //////////////////////////
673 void UniformData(uint32_t loc, bool transpose,
674 const Range<const webgl::UniformDataVal>& data) const;
676 ////////////////////////////////////
678 void UseProgram(WebGLProgram* prog);
680 bool ValidateAttribArraySetter(uint32_t count, uint32_t arrayLength);
681 bool ValidateProgram(const WebGLProgram& prog) const;
682 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
684 // -----------------------------------------------------------------------------
685 // Buffer Objects (WebGLContextBuffers.cpp)
686 void BindBuffer(GLenum target, WebGLBuffer* buffer);
687 void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
688 uint64_t offset, uint64_t size);
690 void BufferData(GLenum target, uint64_t dataLen, const uint8_t* data,
691 GLenum usage) const;
692 // The unsynchronized flag may allow for better performance when
693 // interleaving buffer updates with draw calls. However, care must
694 // be taken. This has similar semantics to glMapBufferRange's
695 // GL_MAP_UNSYNCHRONIZED_BIT: the results of any pending operations
696 // that reference the region of the buffer being updated are
697 // undefined.
698 void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t srcDataLen,
699 const uint8_t* srcData, bool unsynchronized = false) const;
701 protected:
702 // bound buffer state
703 RefPtr<WebGLBuffer> mBoundArrayBuffer;
704 RefPtr<WebGLBuffer> mBoundCopyReadBuffer;
705 RefPtr<WebGLBuffer> mBoundCopyWriteBuffer;
706 RefPtr<WebGLBuffer> mBoundPixelPackBuffer;
707 RefPtr<WebGLBuffer> mBoundPixelUnpackBuffer;
708 RefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
709 RefPtr<WebGLBuffer> mBoundUniformBuffer;
711 std::vector<IndexedBufferBinding> mIndexedUniformBufferBindings;
713 RefPtr<WebGLBuffer>& GetBufferSlotByTarget(GLenum target);
714 RefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
715 GLuint index);
717 // -
719 void GenErrorIllegalUse(GLenum useTarget, uint32_t useId, GLenum boundTarget,
720 uint32_t boundId) const;
722 bool ValidateBufferForNonTf(const WebGLBuffer&, GLenum nonTfTarget,
723 uint32_t nonTfId) const;
725 bool ValidateBufferForNonTf(const WebGLBuffer* const nonTfBuffer,
726 const GLenum nonTfTarget,
727 const uint32_t nonTfId = -1) const {
728 if (!nonTfBuffer) return true;
729 return ValidateBufferForNonTf(*nonTfBuffer, nonTfTarget, nonTfId);
732 bool ValidateBuffersForTf(const WebGLTransformFeedback&,
733 const webgl::LinkedProgramInfo&) const;
734 bool ValidateBuffersForTf(
735 const std::vector<webgl::BufferAndIndex>& tfBuffers) const;
737 // -----------------------------------------------------------------------------
738 // Queries (WebGL2ContextQueries.cpp)
739 protected:
740 RefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
741 RefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
742 RefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
744 RefPtr<WebGLQuery>* ValidateQuerySlotByTarget(GLenum target);
746 public:
747 void BeginQuery(GLenum target, WebGLQuery& query);
748 void EndQuery(GLenum target);
749 Maybe<double> GetQueryParameter(const WebGLQuery& query, GLenum pname) const;
750 void QueryCounter(WebGLQuery&) const;
752 // -----------------------------------------------------------------------------
753 // State and State Requests (WebGLContextState.cpp)
754 void SetEnabled(GLenum cap, Maybe<GLuint> i, bool enabled);
755 bool GetStencilBits(GLint* const out_stencilBits) const;
757 virtual Maybe<double> GetParameter(GLenum pname);
758 Maybe<std::string> GetString(GLenum pname) const;
760 bool IsEnabled(GLenum cap);
762 private:
763 static StaticMutex sLruMutex;
764 static std::list<WebGLContext*> sLru MOZ_GUARDED_BY(sLruMutex);
766 // State tracking slots
767 bool mDitherEnabled = true;
768 bool mRasterizerDiscardEnabled = false;
769 bool mScissorTestEnabled = false;
770 bool mDepthTestEnabled = false;
771 bool mStencilTestEnabled = false;
772 GLenum mGenerateMipmapHint = LOCAL_GL_DONT_CARE;
774 struct ScissorRect final {
775 GLint x;
776 GLint y;
777 GLsizei w;
778 GLsizei h;
780 void Apply(gl::GLContext&) const;
782 ScissorRect mScissorRect = {};
784 bool ValidateCapabilityEnum(GLenum cap);
785 bool* GetStateTrackingSlot(GLenum cap, GLuint i);
787 // Allocation debugging variables
788 mutable uint64_t mDataAllocGLCallCount = 0;
790 void OnDataAllocCall() const { mDataAllocGLCallCount++; }
792 uint64_t GetNumGLDataAllocCalls() const { return mDataAllocGLCallCount; }
794 void OnEndOfFrame();
796 // -----------------------------------------------------------------------------
797 // Texture funcions (WebGLContextTextures.cpp)
798 public:
799 void ActiveTexture(uint32_t texUnit);
800 void BindTexture(GLenum texTarget, WebGLTexture* tex);
801 void GenerateMipmap(GLenum texTarget);
803 Maybe<double> GetTexParameter(const WebGLTexture&, GLenum pname) const;
804 void TexParameter_base(GLenum texTarget, GLenum pname,
805 const FloatOrInt& param);
807 virtual bool IsTexParamValid(GLenum pname) const;
809 ////////////////////////////////////
810 // Uploads
812 // CompressedTexSubImage if `sub`
813 void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level,
814 GLenum format, uvec3 offset, uvec3 size,
815 const Range<const uint8_t>& src,
816 const uint32_t pboImageSize,
817 const Maybe<uint64_t>& pboOffset) const;
819 // CopyTexSubImage if `!respectFormat`
820 void CopyTexImage(GLenum imageTarget, uint32_t level, GLenum respecFormat,
821 uvec3 dstOffset, const ivec2& srcOffset,
822 const uvec2& size) const;
824 // TexSubImage if `!respectFormat`
825 void TexImage(uint32_t level, GLenum respecFormat, uvec3 offset,
826 const webgl::PackingInfo& pi,
827 const webgl::TexUnpackBlobDesc&) const;
829 void TexStorage(GLenum texTarget, uint32_t levels, GLenum sizedFormat,
830 uvec3 size) const;
832 UniquePtr<webgl::TexUnpackBlob> ToTexUnpackBytes(
833 const WebGLTexImageData& imageData);
835 UniquePtr<webgl::TexUnpackBytes> ToTexUnpackBytes(WebGLTexPboOffset& aPbo);
837 ////////////////////////////////////
838 // WebGLTextureUpload.cpp
839 protected:
840 bool ValidateTexImageSpecification(uint8_t funcDims, GLenum texImageTarget,
841 GLint level, GLsizei width, GLsizei height,
842 GLsizei depth, GLint border,
843 TexImageTarget* const out_target,
844 WebGLTexture** const out_texture,
845 webgl::ImageInfo** const out_imageInfo);
846 bool ValidateTexImageSelection(uint8_t funcDims, GLenum texImageTarget,
847 GLint level, GLint xOffset, GLint yOffset,
848 GLint zOffset, GLsizei width, GLsizei height,
849 GLsizei depth,
850 TexImageTarget* const out_target,
851 WebGLTexture** const out_texture,
852 webgl::ImageInfo** const out_imageInfo);
853 bool ValidateUnpackInfo(bool usePBOs, GLenum format, GLenum type,
854 webgl::PackingInfo* const out);
856 // -----------------------------------------------------------------------------
857 // Vertices Feature (WebGLContextVertices.cpp)
858 GLenum mPrimRestartTypeBytes = 0;
860 public:
861 void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount,
862 GLsizei instanceCount);
863 void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type,
864 WebGLintptr byteOffset, GLsizei instanceCount);
866 void EnableVertexAttribArray(GLuint index);
867 void DisableVertexAttribArray(GLuint index);
869 Maybe<double> GetVertexAttrib(GLuint index, GLenum pname);
871 ////
873 void VertexAttrib4T(GLuint index, const webgl::TypedQuad&);
875 ////
877 void VertexAttribPointer(uint32_t index, const webgl::VertAttribPointerDesc&);
879 void VertexAttribDivisor(GLuint index, GLuint divisor);
881 private:
882 WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
883 WebGLintptr byteOffset,
884 GLsizei instanceCount);
885 void Draw_cleanup();
887 void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
888 const GLfloat* ptr);
889 void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
890 const GLfloat* ptr);
891 void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
892 const GLfloat* ptr);
893 void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
894 const GLfloat* ptr);
896 bool BindArrayAttribToLocation0(WebGLProgram* prog);
898 // -----------------------------------------------------------------------------
899 // PROTECTED
900 protected:
901 WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
902 bool DoFakeVertexAttrib0(uint64_t fakeVertexCount,
903 WebGLVertexAttrib0Status whatDoesAttrib0Need);
904 void UndoFakeVertexAttrib0();
906 bool mResetLayer = true;
907 bool mOptionsFrozen = false;
908 bool mIsMesa = false;
909 bool mLoseContextOnMemoryPressure = false;
910 bool mCanLoseContextInForeground = true;
911 bool mShouldPresent = false;
912 bool mDisableFragHighP = false;
913 bool mForceResizeOnPresent = false;
914 bool mVRReady = false;
916 template <typename WebGLObjectType>
917 void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
919 GLuint mActiveTexture = 0;
920 GLenum mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
921 GLenum mDefaultFB_ReadBuffer = LOCAL_GL_BACK;
923 mutable GLenum mWebGLError = 0;
925 std::unique_ptr<webgl::ShaderValidator> CreateShaderValidator(
926 GLenum shaderType) const;
928 // some GL constants
929 uint32_t mGLMaxFragmentUniformVectors = 0;
930 uint32_t mGLMaxVertexUniformVectors = 0;
931 uint32_t mGLMaxVertexOutputVectors = 0;
932 uint32_t mGLMaxFragmentInputVectors = 0;
934 uint32_t mGLMaxVertexTextureImageUnits = 0;
935 uint32_t mGLMaxFragmentTextureImageUnits = 0;
936 uint32_t mGLMaxCombinedTextureImageUnits = 0;
938 // ES3:
939 uint32_t mGLMinProgramTexelOffset = 0;
940 uint32_t mGLMaxProgramTexelOffset = 0;
942 public:
943 auto GLMaxDrawBuffers() const { return mLimits->maxColorDrawBuffers; }
945 uint32_t MaxValidDrawBuffers() const {
946 if (IsWebGL2() ||
947 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
948 return GLMaxDrawBuffers();
950 return 1;
953 GLenum LastColorAttachmentEnum() const {
954 return LOCAL_GL_COLOR_ATTACHMENT0 + MaxValidDrawBuffers() - 1;
957 const auto& Options() const { return mOptions; }
959 protected:
960 uint32_t mGLMaxRenderbufferSize = 0;
962 public:
963 const auto& Limits() const { return *mLimits; }
964 auto MaxVertexAttribs() const { return mLimits->maxVertexAttribs; }
965 auto GLMaxTextureUnits() const { return mLimits->maxTexUnits; }
967 bool IsFormatValidForFB(TexInternalFormat format) const;
969 protected:
970 // -------------------------------------------------------------------------
971 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
973 EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max,
974 std::unique_ptr<WebGLExtensionBase>>
975 mExtensions;
977 public:
978 void RequestExtension(WebGLExtensionID, bool explicitly = true);
980 // returns true if the extension has been enabled by calling getExtension.
981 bool IsExtensionEnabled(const WebGLExtensionID id) const {
982 return bool(mExtensions[id]);
985 bool IsExtensionExplicit(WebGLExtensionID) const;
986 void WarnIfImplicit(WebGLExtensionID) const;
988 bool IsExtensionSupported(WebGLExtensionID) const;
990 // -------------------------------------------------------------------------
991 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
992 public:
993 virtual bool IsWebGL2() const { return false; }
995 struct FailureReason {
996 nsCString key; // For reporting.
997 nsCString info;
999 FailureReason() = default;
1001 template <typename A, typename B>
1002 FailureReason(const A& _key, const B& _info)
1003 : key(nsCString(_key)), info(nsCString(_info)) {}
1006 protected:
1007 bool InitWebGL2(FailureReason* const out_failReason);
1009 bool CreateAndInitGL(bool forceEnabled,
1010 std::vector<FailureReason>* const out_failReasons);
1012 // -------------------------------------------------------------------------
1013 // Validation functions (implemented in WebGLContextValidate.cpp)
1014 bool InitAndValidateGL(FailureReason* const out_failReason);
1016 bool ValidateBlendEquationEnum(GLenum cap, const char* info);
1017 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor,
1018 const char* info);
1019 bool ValidateStencilOpEnum(GLenum action, const char* info);
1020 bool ValidateFaceEnum(GLenum face);
1021 bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
1022 WebGLTexImageFunc func, WebGLTexDimensions dims);
1023 bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size,
1024 GLenum type, WebGLboolean normalized,
1025 GLsizei stride, WebGLintptr byteOffset,
1026 const char* info);
1027 bool ValidateStencilParamsForDrawCall() const;
1029 bool ValidateCopyTexImage(TexInternalFormat srcFormat,
1030 TexInternalFormat dstformat, WebGLTexImageFunc func,
1031 WebGLTexDimensions dims);
1033 bool ValidateTexImage(TexImageTarget texImageTarget, GLint level,
1034 GLenum internalFormat, GLint xoffset, GLint yoffset,
1035 GLint zoffset, GLint width, GLint height, GLint depth,
1036 GLint border, GLenum format, GLenum type,
1037 WebGLTexImageFunc func, WebGLTexDimensions dims);
1038 bool ValidateTexImageFormat(GLenum internalFormat, WebGLTexImageFunc func,
1039 WebGLTexDimensions dims);
1040 bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func,
1041 WebGLTexDimensions dims);
1042 bool ValidateTexImageFormatAndType(GLenum format, GLenum type,
1043 WebGLTexImageFunc func,
1044 WebGLTexDimensions dims);
1045 bool ValidateCompTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1046 WebGLTexDimensions dims);
1047 bool ValidateCopyTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1048 WebGLTexDimensions dims);
1049 bool ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
1050 GLint width, GLint height, GLint depth,
1051 WebGLTexImageFunc func, WebGLTexDimensions dims);
1052 bool ValidateTexSubImageSize(GLint x, GLint y, GLint z, GLsizei width,
1053 GLsizei height, GLsizei depth, GLsizei baseWidth,
1054 GLsizei baseHeight, GLsizei baseDepth,
1055 WebGLTexImageFunc func, WebGLTexDimensions dims);
1056 bool ValidateCompTexImageSize(GLint level, GLenum internalFormat,
1057 GLint xoffset, GLint yoffset, GLsizei width,
1058 GLsizei height, GLsizei levelWidth,
1059 GLsizei levelHeight, WebGLTexImageFunc func,
1060 WebGLTexDimensions dims);
1061 bool ValidateCompTexImageDataSize(GLint level, GLenum internalFormat,
1062 GLsizei width, GLsizei height,
1063 uint32_t byteLength, WebGLTexImageFunc func,
1064 WebGLTexDimensions dims);
1066 bool HasDrawBuffers() const {
1067 return IsWebGL2() ||
1068 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
1071 RefPtr<WebGLBuffer>* ValidateBufferSlot(GLenum target);
1073 public:
1074 WebGLBuffer* ValidateBufferSelection(GLenum target) const;
1076 protected:
1077 IndexedBufferBinding* ValidateIndexedBufferSlot(GLenum target, GLuint index);
1079 bool ValidateIndexedBufferBinding(
1080 GLenum target, GLuint index,
1081 RefPtr<WebGLBuffer>** const out_genericBinding,
1082 IndexedBufferBinding** const out_indexedBinding);
1084 public:
1085 bool ValidateNonNegative(const char* argName, int64_t val) const {
1086 if (MOZ_UNLIKELY(val < 0)) {
1087 ErrorInvalidValue("`%s` must be non-negative.", argName);
1088 return false;
1090 return true;
1093 template <typename T>
1094 bool ValidateNonNull(const char* const argName,
1095 const dom::Nullable<T>& maybe) const {
1096 if (maybe.IsNull()) {
1097 ErrorInvalidValue("%s: Cannot be null.", argName);
1098 return false;
1100 return true;
1103 ////
1105 protected:
1106 void DestroyResourcesAndContext();
1108 // helpers
1110 bool ConvertImage(size_t width, size_t height, size_t srcStride,
1111 size_t dstStride, const uint8_t* src, uint8_t* dst,
1112 WebGLTexelFormat srcFormat, bool srcPremultiplied,
1113 WebGLTexelFormat dstFormat, bool dstPremultiplied,
1114 size_t dstTexelSize);
1116 //////
1117 public:
1118 template <typename T>
1119 bool ValidateObject(const char* const argName, const T& object) const {
1120 // Todo: Remove all callers.
1121 return true;
1124 template <typename T>
1125 bool ValidateObject(const char* const argName, const T* const object) const {
1126 // Todo: Remove most (all?) callers.
1127 if (!object) {
1128 ErrorInvalidOperation(
1129 "%s: Object argument cannot have been marked for"
1130 " deletion.",
1131 argName);
1132 return false;
1134 return true;
1137 ////
1139 private:
1140 void LoseContextLruLocked(webgl::ContextLossReason reason)
1141 MOZ_REQUIRES(sLruMutex);
1143 public:
1144 void LoseContext(
1145 webgl::ContextLossReason reason = webgl::ContextLossReason::None);
1147 protected:
1148 nsTArray<RefPtr<WebGLTexture>> mBound2DTextures;
1149 nsTArray<RefPtr<WebGLTexture>> mBoundCubeMapTextures;
1150 nsTArray<RefPtr<WebGLTexture>> mBound3DTextures;
1151 nsTArray<RefPtr<WebGLTexture>> mBound2DArrayTextures;
1152 nsTArray<RefPtr<WebGLSampler>> mBoundSamplers;
1154 void ResolveTexturesForDraw() const;
1156 RefPtr<WebGLProgram> mCurrentProgram;
1157 RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
1159 bool ValidateFramebufferTarget(GLenum target) const;
1160 bool ValidateInvalidateFramebuffer(GLenum target,
1161 const Range<const GLenum>& attachments,
1162 std::vector<GLenum>* const scopedVector,
1163 GLsizei* const out_glNumAttachments,
1164 const GLenum** const out_glAttachments);
1166 RefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
1167 RefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
1168 RefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
1169 RefPtr<WebGLVertexArray> mBoundVertexArray;
1171 public:
1172 const auto& BoundReadFb() const { return mBoundReadFramebuffer; }
1174 protected:
1175 RefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1176 RefPtr<WebGLVertexArray> mDefaultVertexArray;
1178 ////////////////////////////////////
1180 protected:
1181 GLuint mEmptyTFO = 0;
1183 // Generic Vertex Attributes
1184 // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the
1185 // spec state tables, this isn't vertex shader /object/ state. This array is
1186 // merely state useful to vertex shaders, but is global state.
1187 std::vector<webgl::AttribBaseType> mGenericVertexAttribTypes;
1188 CacheInvalidator mGenericVertexAttribTypeInvalidator;
1190 GLuint mFakeVertexAttrib0BufferObject = 0;
1191 intptr_t mFakeVertexAttrib0BufferObjectSize = 0;
1192 bool mFakeVertexAttrib0DataDefined = false;
1193 alignas(alignof(float)) uint8_t
1194 mGenericVertexAttrib0Data[sizeof(float) * 4] = {};
1195 alignas(alignof(float)) uint8_t
1196 mFakeVertexAttrib0Data[sizeof(float) * 4] = {};
1198 GLint mStencilRefFront = 0;
1199 GLint mStencilRefBack = 0;
1200 GLuint mStencilValueMaskFront = 0;
1201 GLuint mStencilValueMaskBack = 0;
1202 GLuint mStencilWriteMaskFront = 0;
1203 GLuint mStencilWriteMaskBack = 0;
1204 uint8_t mColorWriteMask0 = 0xf; // bitmask
1205 mutable uint8_t mDriverColorMask0 = 0xf;
1206 bool mDepthWriteMask = true;
1207 GLfloat mColorClearValue[4] = {0, 0, 0, 0};
1208 GLint mStencilClearValue = 0;
1209 GLfloat mDepthClearValue = 1.0f;
1211 std::bitset<webgl::kMaxDrawBuffers> mColorWriteMaskNonzero = -1;
1212 std::bitset<webgl::kMaxDrawBuffers> mBlendEnabled = 0;
1214 GLint mViewportX = 0;
1215 GLint mViewportY = 0;
1216 GLsizei mViewportWidth = 0;
1217 GLsizei mViewportHeight = 0;
1218 bool mAlreadyWarnedAboutViewportLargerThanDest = false;
1220 GLfloat mLineWidth = 1.0;
1222 WebGLContextLossHandler mContextLossHandler;
1224 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1225 // be Flushed while doing hundreds of draw calls.
1226 mutable uint64_t mDrawCallsSinceLastFlush = 0;
1228 mutable uint64_t mWarningCount = 0;
1229 const uint64_t mMaxWarnings;
1230 bool mAlreadyWarnedAboutFakeVertexAttrib0 = false;
1232 bool ShouldGenerateWarnings() const { return mWarningCount < mMaxWarnings; }
1234 bool ShouldGeneratePerfWarnings() const {
1235 return mNumPerfWarnings < mMaxPerfWarnings;
1238 bool mNeedsFakeNoAlpha = false;
1239 bool mNeedsFakeNoDepth = false;
1240 bool mNeedsFakeNoStencil = false;
1241 bool mNeedsFakeNoStencil_UserFBs = false;
1243 bool mDriverDepthTest = false;
1244 bool mDriverStencilTest = false;
1246 bool mNeedsLegacyVertexAttrib0Handling = false;
1247 bool mMaybeNeedsLegacyVertexAttrib0Handling = false;
1248 bool mNeedsIndexValidation = false;
1249 bool mBug_DrawArraysInstancedUserAttribFetchAffectedByFirst = false;
1251 const bool mAllowFBInvalidation;
1253 bool Has64BitTimestamps() const;
1255 // --
1257 const uint8_t mMsaaSamples;
1258 mutable uvec2 mRequestedSize;
1259 mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
1260 mutable bool mDefaultFB_IsInvalid = false;
1261 mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
1263 gl::SwapChain mSwapChain;
1264 gl::SwapChain mWebVRSwapChain;
1266 RefPtr<layers::RemoteTextureOwnerClient> mRemoteTextureOwner;
1268 bool PushRemoteTexture(WebGLFramebuffer*, gl::SwapChain&,
1269 std::shared_ptr<gl::SharedSurface>,
1270 const webgl::SwapChainOptions& options);
1272 // --
1274 bool EnsureDefaultFB();
1275 bool ValidateAndInitFB(
1276 const WebGLFramebuffer* fb,
1277 GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
1278 void DoBindFB(const WebGLFramebuffer* fb,
1279 GLenum target = LOCAL_GL_FRAMEBUFFER) const;
1281 bool BindCurFBForDraw();
1282 bool BindCurFBForColorRead(
1283 const webgl::FormatUsageInfo** out_format, uint32_t* out_width,
1284 uint32_t* out_height,
1285 GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
1286 void DoColorMask(Maybe<GLuint> i, uint8_t bitmask) const;
1287 void BlitBackbufferToCurDriverFB(
1288 WebGLFramebuffer* const srcAsWebglFb = nullptr,
1289 const gl::MozFramebuffer* const srcAsMozFb = nullptr,
1290 bool srcIsBGRA = false) const;
1291 bool BindDefaultFBForRead();
1293 // --
1295 public:
1296 // console logging helpers
1297 template <typename... Args>
1298 void GenerateWarning(const char* const fmt, const Args&... args) const {
1299 GenerateError(0, fmt, args...);
1302 template <typename... Args>
1303 void GeneratePerfWarning(const char* const fmt, const Args&... args) const {
1304 GenerateError(webgl::kErrorPerfWarning, fmt, args...);
1307 public:
1308 UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
1310 virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
1311 gl::GLContext* gl) const;
1313 const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
1315 // Friend list
1316 friend class ScopedCopyTexImageSource;
1317 friend class ScopedResolveTexturesForDraw;
1318 friend class webgl::TexUnpackBlob;
1319 friend class webgl::TexUnpackBytes;
1320 friend class webgl::TexUnpackImage;
1321 friend class webgl::TexUnpackSurface;
1322 friend struct webgl::UniformInfo;
1323 friend class WebGLTexture;
1324 friend class WebGLFBAttachPoint;
1325 friend class WebGLFramebuffer;
1326 friend class WebGLRenderbuffer;
1327 friend class WebGLProgram;
1328 friend class WebGLQuery;
1329 friend class WebGLBuffer;
1330 friend class WebGLSampler;
1331 friend class WebGLShader;
1332 friend class WebGLSync;
1333 friend class WebGLTransformFeedback;
1334 friend class WebGLVertexArray;
1335 friend class WebGLVertexArrayFake;
1336 friend class WebGLVertexArrayGL;
1339 // Returns `value` rounded to the next highest multiple of `multiple`.
1340 // AKA PadToAlignment, StrideForAlignment.
1341 template <typename V, typename M>
1342 V RoundUpToMultipleOf(const V& value, const M& multiple) {
1343 return ((value + multiple - 1) / multiple) * multiple;
1346 class ScopedFBRebinder final {
1347 private:
1348 const WebGLContext* const mWebGL;
1350 public:
1351 explicit ScopedFBRebinder(const WebGLContext* const webgl) : mWebGL(webgl) {}
1352 ~ScopedFBRebinder();
1355 // -
1357 constexpr inline bool IsBufferTargetLazilyBound(const GLenum target) {
1358 return target != LOCAL_GL_ELEMENT_ARRAY_BUFFER;
1361 void DoBindBuffer(gl::GLContext&, GLenum target, const WebGLBuffer*);
1363 class ScopedLazyBind final {
1364 private:
1365 gl::GLContext& mGL;
1366 const GLenum mTarget;
1368 public:
1369 ScopedLazyBind(gl::GLContext* const gl, const GLenum target,
1370 const WebGLBuffer* const buf)
1371 : mGL(*gl), mTarget(IsBufferTargetLazilyBound(target) ? target : 0) {
1372 if (mTarget) {
1373 DoBindBuffer(mGL, mTarget, buf);
1377 ~ScopedLazyBind() {
1378 if (mTarget) {
1379 DoBindBuffer(mGL, mTarget, nullptr);
1384 ////
1386 bool Intersect(int32_t srcSize, int32_t read0, int32_t readSize,
1387 int32_t* out_intRead0, int32_t* out_intWrite0,
1388 int32_t* out_intSize);
1390 uint64_t AvailGroups(uint64_t totalAvailItems, uint64_t firstItemOffset,
1391 uint32_t groupSize, uint32_t groupStride);
1393 ////
1395 class ScopedDrawCallWrapper final {
1396 public:
1397 WebGLContext& mWebGL;
1399 explicit ScopedDrawCallWrapper(WebGLContext& webgl);
1400 ~ScopedDrawCallWrapper();
1403 namespace webgl {
1405 class ScopedPrepForResourceClear final {
1406 const WebGLContext& webgl;
1408 public:
1409 explicit ScopedPrepForResourceClear(const WebGLContext&);
1410 ~ScopedPrepForResourceClear();
1413 struct IndexedName final {
1414 std::string name;
1415 uint64_t index;
1417 Maybe<IndexedName> ParseIndexed(const std::string& str);
1419 } // namespace webgl
1421 webgl::LinkActiveInfo GetLinkActiveInfo(
1422 gl::GLContext& gl, const GLuint prog, const bool webgl2,
1423 const std::unordered_map<std::string, std::string>& nameUnmap);
1425 } // namespace mozilla
1427 #endif