Bug 1521243 - Show a warning for invalid declarations and filter icon for overridden...
[gecko.git] / dom / canvas / WebGLContext.h
blob59b19f3c3835fe81c4258a6e0c145d00a247b356
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 <stdarg.h>
11 #include "GLContextTypes.h"
12 #include "GLDefs.h"
13 #include "mozilla/Attributes.h"
14 #include "mozilla/CheckedInt.h"
15 #include "mozilla/dom/BindingDeclarations.h"
16 #include "mozilla/dom/HTMLCanvasElement.h"
17 #include "mozilla/dom/Nullable.h"
18 #include "mozilla/dom/TypedArray.h"
19 #include "mozilla/EnumeratedArray.h"
20 #include "mozilla/ErrorResult.h"
21 #include "mozilla/gfx/2D.h"
22 #include "mozilla/LinkedList.h"
23 #include "mozilla/UniquePtr.h"
24 #include "nsCycleCollectionNoteChild.h"
25 #include "nsICanvasRenderingContextInternal.h"
26 #include "nsLayoutUtils.h"
27 #include "nsTArray.h"
28 #include "nsWrapperCache.h"
29 #include "SurfaceTypes.h"
30 #include "ScopedGLHelpers.h"
31 #include "TexUnpackBlob.h"
33 // Local
34 #include "CacheInvalidator.h"
35 #include "WebGLContextLossHandler.h"
36 #include "WebGLObjectModel.h"
37 #include "WebGLStrongTypes.h"
39 // Generated
40 #include "nsIDOMEventListener.h"
41 #include "nsICanvasRenderingContextInternal.h"
42 #include "nsIObserver.h"
43 #include "mozilla/dom/HTMLCanvasElement.h"
44 #include "nsWrapperCache.h"
45 #include "nsLayoutUtils.h"
46 #include "mozilla/dom/WebGLRenderingContextBinding.h"
47 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
49 class nsIDocShell;
51 // WebGL-only GLenums
52 // clang-format off
53 #define LOCAL_GL_BROWSER_DEFAULT_WEBGL 0x9244
54 #define LOCAL_GL_CONTEXT_LOST_WEBGL 0x9242
55 #define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL 0x9247
56 #define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL 0x9243
57 #define LOCAL_GL_UNPACK_FLIP_Y_WEBGL 0x9240
58 #define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL 0x9241
59 // clang-format on
61 namespace mozilla {
62 class ScopedCopyTexImageSource;
63 class ScopedDrawCallWrapper;
64 class ScopedResolveTexturesForDraw;
65 class ScopedUnpackReset;
66 class WebGLActiveInfo;
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 WebGLShaderPrecisionFormat;
76 class WebGLSync;
77 class WebGLTexture;
78 class WebGLTransformFeedback;
79 class WebGLUniformLocation;
80 class WebGLVertexArray;
82 namespace dom {
83 class Element;
84 class ImageData;
85 class OwningHTMLCanvasElementOrOffscreenCanvas;
86 struct WebGLContextAttributes;
87 } // namespace dom
89 namespace gfx {
90 class SourceSurface;
91 class VRLayerChild;
92 } // namespace gfx
94 namespace gl {
95 class GLScreenBuffer;
96 class MozFramebuffer;
97 } // namespace gl
99 namespace webgl {
100 class AvailabilityRunnable;
101 struct CachedDrawFetchLimits;
102 struct FormatInfo;
103 class FormatUsageAuthority;
104 struct FormatUsageInfo;
105 struct ImageInfo;
106 struct LinkedProgramInfo;
107 struct SamplingState;
108 class ScopedPrepForResourceClear;
109 class ShaderValidator;
110 class TexUnpackBlob;
111 struct UniformInfo;
112 struct UniformBlockInfo;
113 } // namespace webgl
115 WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
117 void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
119 struct WebGLContextOptions {
120 bool alpha = true;
121 bool depth = true;
122 bool stencil = false;
123 bool premultipliedAlpha = true;
124 bool antialias = true;
125 bool preserveDrawingBuffer = false;
126 bool failIfMajorPerformanceCaveat = false;
127 dom::WebGLPowerPreference powerPreference =
128 dom::WebGLPowerPreference::Default;
130 WebGLContextOptions();
131 bool operator==(const WebGLContextOptions&) const;
134 // From WebGLContextUtils
135 TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
137 struct WebGLIntOrFloat {
138 const enum { Int, Float, Uint } mType;
140 union {
141 GLint i;
142 GLfloat f;
143 GLuint u;
144 } mValue;
146 explicit WebGLIntOrFloat(GLint i) : mType(Int) { mValue.i = i; }
147 explicit WebGLIntOrFloat(GLfloat f) : mType(Float) { mValue.f = f; }
149 GLint AsInt() const {
150 return (mType == Int) ? mValue.i : NS_lroundf(mValue.f);
152 GLfloat AsFloat() const {
153 return (mType == Float) ? mValue.f : GLfloat(mValue.i);
157 struct IndexedBufferBinding {
158 WebGLRefPtr<WebGLBuffer> mBufferBinding;
159 uint64_t mRangeStart;
160 uint64_t mRangeSize;
162 IndexedBufferBinding();
164 uint64_t ByteCount() const;
167 ////
169 struct FloatOrInt final // For TexParameter[fi] and friends.
171 const bool isFloat;
172 const GLfloat f;
173 const GLint i;
175 explicit FloatOrInt(GLint x) : isFloat(false), f(x), i(x) {}
177 explicit FloatOrInt(GLfloat x) : isFloat(true), f(x), i(roundf(x)) {}
179 FloatOrInt& operator=(const FloatOrInt& x) {
180 memcpy(this, &x, sizeof(x));
181 return *this;
185 ////////////////////////////////////
187 struct TexImageSource {
188 const dom::ArrayBufferView* mView;
189 GLuint mViewElemOffset;
190 GLuint mViewElemLengthOverride;
192 const WebGLsizeiptr* mPboOffset;
194 const dom::ImageBitmap* mImageBitmap;
195 const dom::ImageData* mImageData;
197 const dom::Element* mDomElem;
198 ErrorResult* mOut_error;
200 protected:
201 TexImageSource() { memset(this, 0, sizeof(*this)); }
204 ////
206 struct TexImageSourceAdapter final : public TexImageSource {
207 TexImageSourceAdapter(const dom::Nullable<dom::ArrayBufferView>* maybeView,
208 ErrorResult*) {
209 if (!maybeView->IsNull()) {
210 mView = &(maybeView->Value());
214 TexImageSourceAdapter(const dom::ArrayBufferView* view, ErrorResult*) {
215 mView = view;
218 TexImageSourceAdapter(const dom::ArrayBufferView* view, GLuint viewElemOffset,
219 GLuint viewElemLengthOverride = 0) {
220 mView = view;
221 mViewElemOffset = viewElemOffset;
222 mViewElemLengthOverride = viewElemLengthOverride;
225 TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, GLuint ignored1,
226 GLuint ignored2 = 0) {
227 mPboOffset = pboOffset;
230 TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, ErrorResult* ignored) {
231 mPboOffset = pboOffset;
234 TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap,
235 ErrorResult* out_error) {
236 mImageBitmap = imageBitmap;
237 mOut_error = out_error;
240 TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {
241 mImageData = imageData;
244 TexImageSourceAdapter(const dom::Element* domElem,
245 ErrorResult* const out_error) {
246 mDomElem = domElem;
247 mOut_error = out_error;
251 // --
253 namespace webgl {
254 class AvailabilityRunnable final : public Runnable {
255 public:
256 const RefPtr<WebGLContext> mWebGL; // Prevent CC
257 std::vector<RefPtr<WebGLQuery>> mQueries;
258 std::vector<RefPtr<WebGLSync>> mSyncs;
260 explicit AvailabilityRunnable(WebGLContext* webgl);
261 ~AvailabilityRunnable();
263 NS_IMETHOD Run() override;
265 } // namespace webgl
267 ////////////////////////////////////////////////////////////////////////////////
269 class WebGLContext : public nsICanvasRenderingContextInternal,
270 public nsSupportsWeakReference,
271 public nsWrapperCache {
272 friend class ScopedDrawCallWrapper;
273 friend class ScopedDrawWithTransformFeedback;
274 friend class ScopedFakeVertexAttrib0;
275 friend class ScopedFBRebinder;
276 friend class WebGL2Context;
277 friend class WebGLContextUserData;
278 friend class WebGLExtensionCompressedTextureASTC;
279 friend class WebGLExtensionCompressedTextureBPTC;
280 friend class WebGLExtensionCompressedTextureES3;
281 friend class WebGLExtensionCompressedTextureETC1;
282 friend class WebGLExtensionCompressedTexturePVRTC;
283 friend class WebGLExtensionCompressedTextureRGTC;
284 friend class WebGLExtensionCompressedTextureS3TC;
285 friend class WebGLExtensionCompressedTextureS3TC_SRGB;
286 friend class WebGLExtensionDepthTexture;
287 friend class WebGLExtensionDisjointTimerQuery;
288 friend class WebGLExtensionDrawBuffers;
289 friend class WebGLExtensionLoseContext;
290 friend class WebGLExtensionMOZDebug;
291 friend class WebGLExtensionVertexArray;
292 friend class WebGLMemoryTracker;
293 friend class webgl::AvailabilityRunnable;
294 friend struct webgl::LinkedProgramInfo;
295 friend class webgl::ScopedPrepForResourceClear;
296 friend struct webgl::UniformBlockInfo;
298 friend const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext*, GLenum,
299 uint32_t);
301 enum {
302 UNPACK_FLIP_Y_WEBGL = 0x9240,
303 UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
304 // We throw InvalidOperation in TexImage if we fail to use GPU fast-path
305 // for texture copy when it is set to true, only for debug purpose.
306 UNPACK_REQUIRE_FASTPATH = 0x10001,
307 CONTEXT_LOST_WEBGL = 0x9242,
308 UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243,
309 BROWSER_DEFAULT_WEBGL = 0x9244,
310 UNMASKED_VENDOR_WEBGL = 0x9245,
311 UNMASKED_RENDERER_WEBGL = 0x9246
314 private:
315 // We've had issues in the past with nulling `gl` without actually releasing
316 // all of our resources. This construction ensures that we are aware that we
317 // should only null `gl` in DestroyResourcesAndContext.
318 RefPtr<gl::GLContext> mGL_OnlyClearInDestroyResourcesAndContext;
320 public:
321 // Grab a const reference so we can see changes, but can't make changes.
322 const decltype(mGL_OnlyClearInDestroyResourcesAndContext)& gl;
324 protected:
325 const uint32_t mMaxPerfWarnings;
326 mutable uint64_t mNumPerfWarnings;
327 const uint32_t mMaxAcceptableFBStatusInvals;
329 uint64_t mNextFenceId = 1;
330 uint64_t mCompletedFenceId = 0;
332 public:
333 class FuncScope;
335 private:
336 mutable FuncScope* mFuncScope = nullptr;
338 public:
339 WebGLContext();
341 protected:
342 virtual ~WebGLContext();
344 public:
345 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
347 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
348 WebGLContext, nsICanvasRenderingContextInternal)
350 virtual JSObject* WrapObject(JSContext* cx,
351 JS::Handle<JSObject*> givenProto) override = 0;
353 virtual void OnMemoryPressure() override;
355 // nsICanvasRenderingContextInternal
356 virtual int32_t GetWidth() override { return DrawingBufferWidth(); }
357 virtual int32_t GetHeight() override { return DrawingBufferHeight(); }
359 NS_IMETHOD SetDimensions(int32_t width, int32_t height) override;
360 NS_IMETHOD InitializeWithDrawTarget(nsIDocShell*,
361 NotNull<gfx::DrawTarget*>) override {
362 return NS_ERROR_NOT_IMPLEMENTED;
365 NS_IMETHOD Reset() override {
366 /* (InitializeWithSurface) */
367 return NS_ERROR_NOT_IMPLEMENTED;
370 virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* out_format) override;
371 NS_IMETHOD GetInputStream(const char* mimeType,
372 const char16_t* encoderOptions,
373 nsIInputStream** out_stream) override;
375 virtual already_AddRefed<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(
376 gfxAlphaType* out_alphaType) override;
378 virtual void SetOpaqueValueFromOpaqueAttr(bool) override{};
379 bool GetIsOpaque() override { return !mOptions.alpha; }
380 NS_IMETHOD SetContextOptions(JSContext* cx, JS::Handle<JS::Value> options,
381 ErrorResult& aRvForDictionaryInit) override;
383 NS_IMETHOD SetIsIPC(bool) override { return NS_ERROR_NOT_IMPLEMENTED; }
386 * An abstract base class to be implemented by callers wanting to be notified
387 * that a refresh has occurred. Callers must ensure an observer is removed
388 * before it is destroyed.
390 virtual void DidRefresh() override;
392 NS_IMETHOD Redraw(const gfxRect&) override {
393 return NS_ERROR_NOT_IMPLEMENTED;
396 // -
398 const auto& CurFuncScope() const { return *mFuncScope; }
399 const char* FuncName() const;
401 class FuncScope final {
402 public:
403 const WebGLContext& mWebGL;
404 const char* const mFuncName;
406 private:
407 #ifdef DEBUG
408 mutable bool mStillNeedsToCheckContextLost = true;
409 #endif
411 public:
412 FuncScope(const WebGLContext& webgl, const char* funcName);
413 ~FuncScope();
415 void OnCheckContextLost() const {
416 #ifdef DEBUG
417 mStillNeedsToCheckContextLost = false;
418 #endif
422 void SynthesizeGLError(GLenum err) const;
423 void SynthesizeGLError(GLenum err, const char* fmt, ...) const
424 MOZ_FORMAT_PRINTF(3, 4);
426 void ErrorInvalidEnum(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
427 void ErrorInvalidOperation(const char* fmt = 0, ...) const
428 MOZ_FORMAT_PRINTF(2, 3);
429 void ErrorInvalidValue(const char* fmt = 0, ...) const
430 MOZ_FORMAT_PRINTF(2, 3);
431 void ErrorInvalidFramebufferOperation(const char* fmt = 0, ...) const
432 MOZ_FORMAT_PRINTF(2, 3);
433 void ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const;
434 void ErrorOutOfMemory(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
435 void ErrorImplementationBug(const char* fmt = 0, ...) const
436 MOZ_FORMAT_PRINTF(2, 3);
438 void ErrorInvalidEnumArg(const char* argName, GLenum val) const;
440 static const char* ErrorName(GLenum error);
443 * Return displayable name for GLenum.
444 * This version is like gl::GLenumToStr but with out the GL_ prefix to
445 * keep consistency with how errors are reported from WebGL.
446 * Returns hex formatted version of glenum if glenum is unknown.
448 static void EnumName(GLenum val, nsCString* out_name);
450 void DummyReadFramebufferOperation();
452 WebGLTexture* ActiveBoundTextureForTarget(const TexTarget texTarget) const {
453 switch (texTarget.get()) {
454 case LOCAL_GL_TEXTURE_2D:
455 return mBound2DTextures[mActiveTexture];
456 case LOCAL_GL_TEXTURE_CUBE_MAP:
457 return mBoundCubeMapTextures[mActiveTexture];
458 case LOCAL_GL_TEXTURE_3D:
459 return mBound3DTextures[mActiveTexture];
460 case LOCAL_GL_TEXTURE_2D_ARRAY:
461 return mBound2DArrayTextures[mActiveTexture];
462 default:
463 MOZ_CRASH("GFX: bad target");
467 /* Use this function when you have the texture image target, for example:
468 * GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_[POSITIVE|NEGATIVE]_[X|Y|Z], and
469 * not the actual texture binding target: GL_TEXTURE_2D or
470 * GL_TEXTURE_CUBE_MAP.
472 WebGLTexture* ActiveBoundTextureForTexImageTarget(
473 const TexImageTarget texImgTarget) const {
474 const TexTarget texTarget = TexImageTargetToTexTarget(texImgTarget);
475 return ActiveBoundTextureForTarget(texTarget);
478 already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* builder,
479 Layer* oldLayer,
480 LayerManager* manager) override;
482 bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
483 WebRenderCanvasData* aCanvasData) override;
485 bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
486 CanvasRenderer* aRenderer) override;
488 // Note that 'clean' here refers to its invalidation state, not the
489 // contents of the buffer.
490 void MarkContextClean() override { mInvalidated = false; }
492 void MarkContextCleanForFrameCapture() override {
493 mCapturedFrameInvalidated = false;
496 bool IsContextCleanForFrameCapture() override {
497 return !mCapturedFrameInvalidated;
500 gl::GLContext* GL() const { return gl; }
502 bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
504 bool IsPreservingDrawingBuffer() const {
505 return mOptions.preserveDrawingBuffer;
508 bool PresentScreenBuffer(gl::GLScreenBuffer* const screen = nullptr);
510 // Prepare the context for capture before compositing
511 void BeginComposition(gl::GLScreenBuffer* const screen = nullptr);
512 // Clean up the context after captured for compositing
513 void EndComposition();
515 // a number that increments every time we have an event that causes
516 // all context resources to be lost.
517 uint32_t Generation() const { return mGeneration.value(); }
519 void RunContextLossTimer();
520 void UpdateContextLossStatus();
521 void EnqueueUpdateContextLossStatus();
523 bool TryToRestoreContext();
525 void AssertCachedBindings() const;
526 void AssertCachedGlobalState() const;
528 dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
529 dom::Document* GetOwnerDoc() const;
531 // WebIDL WebGLRenderingContext API
532 void Commit();
533 void GetCanvas(
534 dom::Nullable<dom::OwningHTMLCanvasElementOrOffscreenCanvas>& retval);
536 private:
537 gfx::IntSize DrawingBufferSize();
539 public:
540 GLsizei DrawingBufferWidth() {
541 const FuncScope funcScope(*this, "drawingBufferWidth");
542 return DrawingBufferSize().width;
544 GLsizei DrawingBufferHeight() {
545 const FuncScope funcScope(*this, "drawingBufferHeight");
546 return DrawingBufferSize().height;
549 layers::LayersBackend GetCompositorBackendType() const;
551 void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
553 // This is the entrypoint. Don't test against it directly.
554 bool IsContextLost() const;
556 void GetSupportedExtensions(dom::Nullable<nsTArray<nsString>>& retval,
557 dom::CallerType callerType);
558 void GetExtension(JSContext* cx, const nsAString& name,
559 JS::MutableHandle<JSObject*> retval,
560 dom::CallerType callerType, ErrorResult& rv);
561 void AttachShader(WebGLProgram& prog, WebGLShader& shader);
562 void BindAttribLocation(WebGLProgram& prog, GLuint location,
563 const nsAString& name);
564 void BindFramebuffer(GLenum target, WebGLFramebuffer* fb);
565 void BindRenderbuffer(GLenum target, WebGLRenderbuffer* fb);
566 void BindVertexArray(WebGLVertexArray* vao);
567 void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
568 void BlendEquation(GLenum mode);
569 void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
570 void BlendFunc(GLenum sfactor, GLenum dfactor);
571 void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
572 GLenum dstAlpha);
573 GLenum CheckFramebufferStatus(GLenum target);
574 void Clear(GLbitfield mask);
575 void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
576 void ClearDepth(GLclampf v);
577 void ClearStencil(GLint v);
578 void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b,
579 WebGLboolean a);
580 void CompileShader(WebGLShader& shader);
581 void CompileShaderANGLE(WebGLShader* shader);
582 void CompileShaderBypass(WebGLShader* shader, const nsCString& shaderSource);
583 already_AddRefed<WebGLFramebuffer> CreateFramebuffer();
584 already_AddRefed<WebGLProgram> CreateProgram();
585 already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer();
586 already_AddRefed<WebGLShader> CreateShader(GLenum type);
587 already_AddRefed<WebGLVertexArray> CreateVertexArray();
588 void CullFace(GLenum face);
589 void DeleteFramebuffer(WebGLFramebuffer* fb);
590 void DeleteProgram(WebGLProgram* prog);
591 void DeleteRenderbuffer(WebGLRenderbuffer* rb);
592 void DeleteShader(WebGLShader* shader);
593 void DeleteVertexArray(WebGLVertexArray* vao);
594 void DepthFunc(GLenum func);
595 void DepthMask(WebGLboolean b);
596 void DepthRange(GLclampf zNear, GLclampf zFar);
597 void DetachShader(WebGLProgram& prog, const WebGLShader& shader);
598 void DrawBuffers(const dom::Sequence<GLenum>& buffers);
599 void Flush();
600 void Finish();
601 void FramebufferRenderbuffer(GLenum target, GLenum attachment,
602 GLenum rbTarget, WebGLRenderbuffer* rb);
603 void FramebufferTexture2D(GLenum target, GLenum attachment,
604 GLenum texImageTarget, WebGLTexture* tex,
605 GLint level);
607 void FrontFace(GLenum mode);
608 already_AddRefed<WebGLActiveInfo> GetActiveAttrib(const WebGLProgram& prog,
609 GLuint index);
610 already_AddRefed<WebGLActiveInfo> GetActiveUniform(const WebGLProgram& prog,
611 GLuint index);
613 void GetAttachedShaders(const WebGLProgram& prog,
614 dom::Nullable<nsTArray<RefPtr<WebGLShader>>>& retval);
616 GLint GetAttribLocation(const WebGLProgram& prog, const nsAString& name);
617 JS::Value GetBufferParameter(GLenum target, GLenum pname);
619 void GetBufferParameter(JSContext*, GLenum target, GLenum pname,
620 JS::MutableHandle<JS::Value> retval) {
621 retval.set(GetBufferParameter(target, pname));
624 GLenum GetError();
625 virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
626 GLenum target,
627 GLenum attachment,
628 GLenum pname,
629 ErrorResult& rv);
631 void GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
632 GLenum attachment, GLenum pname,
633 JS::MutableHandle<JS::Value> retval,
634 ErrorResult& rv) {
635 retval.set(
636 GetFramebufferAttachmentParameter(cx, target, attachment, pname, rv));
639 JS::Value GetProgramParameter(const WebGLProgram& prog, GLenum pname);
641 void GetProgramParameter(JSContext*, const WebGLProgram& prog, GLenum pname,
642 JS::MutableHandle<JS::Value> retval) {
643 retval.set(GetProgramParameter(prog, pname));
646 void GetProgramInfoLog(const WebGLProgram& prog, nsACString& retval);
647 void GetProgramInfoLog(const WebGLProgram& prog, nsAString& retval);
648 JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
650 void GetRenderbufferParameter(JSContext*, GLenum target, GLenum pname,
651 JS::MutableHandle<JS::Value> retval) {
652 retval.set(GetRenderbufferParameter(target, pname));
655 JS::Value GetShaderParameter(const WebGLShader& shader, GLenum pname);
657 void GetShaderParameter(JSContext*, const WebGLShader& shader, GLenum pname,
658 JS::MutableHandle<JS::Value> retval) {
659 retval.set(GetShaderParameter(shader, pname));
662 already_AddRefed<WebGLShaderPrecisionFormat> GetShaderPrecisionFormat(
663 GLenum shadertype, GLenum precisiontype);
665 void GetShaderInfoLog(const WebGLShader& shader, nsACString& retval);
666 void GetShaderInfoLog(const WebGLShader& shader, nsAString& retval);
667 void GetShaderSource(const WebGLShader& shader, nsAString& retval);
669 JS::Value GetUniform(JSContext* cx, const WebGLProgram& prog,
670 const WebGLUniformLocation& loc);
672 void GetUniform(JSContext* cx, const WebGLProgram& prog,
673 const WebGLUniformLocation& loc,
674 JS::MutableHandle<JS::Value> retval) {
675 retval.set(GetUniform(cx, prog, loc));
678 already_AddRefed<WebGLUniformLocation> GetUniformLocation(
679 const WebGLProgram& prog, const nsAString& name);
681 void Hint(GLenum target, GLenum mode);
683 bool IsBuffer(const WebGLBuffer* obj);
684 bool IsFramebuffer(const WebGLFramebuffer* obj);
685 bool IsProgram(const WebGLProgram* obj);
686 bool IsRenderbuffer(const WebGLRenderbuffer* obj);
687 bool IsShader(const WebGLShader* obj);
688 bool IsTexture(const WebGLTexture* obj);
689 bool IsVertexArray(const WebGLVertexArray* obj);
691 void LineWidth(GLfloat width);
692 void LinkProgram(WebGLProgram& prog);
693 void PixelStorei(GLenum pname, GLint param);
694 void PolygonOffset(GLfloat factor, GLfloat units);
696 already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
697 void EnsureVRReady();
699 ////
701 webgl::PackingInfo ValidImplementationColorReadPI(
702 const webgl::FormatUsageInfo* usage) const;
704 protected:
705 bool ReadPixels_SharedPrecheck(dom::CallerType aCallerType,
706 ErrorResult& out_error);
707 void ReadPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height,
708 GLenum format, GLenum type, void* data, uint32_t dataLen);
709 bool DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat, GLint x,
710 GLint y, GLsizei width, GLsizei height,
711 GLenum format, GLenum destType, void* dest,
712 uint32_t dataLen, uint32_t rowStride);
714 public:
715 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
716 GLenum format, GLenum type,
717 const dom::Nullable<dom::ArrayBufferView>& maybeView,
718 dom::CallerType aCallerType, ErrorResult& rv) {
719 const FuncScope funcScope(*this, "readPixels");
720 if (!ValidateNonNull("pixels", maybeView)) return;
721 ReadPixels(x, y, width, height, format, type, maybeView.Value(), 0,
722 aCallerType, rv);
725 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
726 GLenum format, GLenum type, WebGLsizeiptr offset,
727 dom::CallerType, ErrorResult& out_error);
729 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
730 GLenum format, GLenum type,
731 const dom::ArrayBufferView& dstData, GLuint dstOffset,
732 dom::CallerType, ErrorResult& out_error);
734 ////
736 void RenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width,
737 GLsizei height) {
738 const FuncScope funcScope(*this, "renderbufferStorage");
739 RenderbufferStorage_base(target, 0, internalFormat, width, height);
742 protected:
743 void RenderbufferStorage_base(GLenum target, GLsizei samples,
744 GLenum internalformat, GLsizei width,
745 GLsizei height);
747 public:
748 void SampleCoverage(GLclampf value, WebGLboolean invert);
749 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
750 void ShaderSource(WebGLShader& shader, const nsAString& source);
751 void StencilFunc(GLenum func, GLint ref, GLuint mask);
752 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
753 void StencilMask(GLuint mask);
754 void StencilMaskSeparate(GLenum face, GLuint mask);
755 void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
756 void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
757 GLenum dppass);
759 //////
761 void Uniform1f(WebGLUniformLocation* loc, GLfloat x);
762 void Uniform2f(WebGLUniformLocation* loc, GLfloat x, GLfloat y);
763 void Uniform3f(WebGLUniformLocation* loc, GLfloat x, GLfloat y, GLfloat z);
764 void Uniform4f(WebGLUniformLocation* loc, GLfloat x, GLfloat y, GLfloat z,
765 GLfloat w);
767 void Uniform1i(WebGLUniformLocation* loc, GLint x);
768 void Uniform2i(WebGLUniformLocation* loc, GLint x, GLint y);
769 void Uniform3i(WebGLUniformLocation* loc, GLint x, GLint y, GLint z);
770 void Uniform4i(WebGLUniformLocation* loc, GLint x, GLint y, GLint z, GLint w);
772 void Uniform1ui(WebGLUniformLocation* loc, GLuint v0);
773 void Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1);
774 void Uniform3ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2);
775 void Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2,
776 GLuint v3);
778 //////////////////////////
780 typedef dom::Float32ArrayOrUnrestrictedFloatSequence Float32ListU;
781 typedef dom::Int32ArrayOrLongSequence Int32ListU;
782 typedef dom::Uint32ArrayOrUnsignedLongSequence Uint32ListU;
784 protected:
785 template <typename elemT, typename viewT>
786 struct Arr {
787 const size_t elemCount;
788 const elemT* const elemBytes;
790 private:
791 static size_t ComputeAndReturnLength(const viewT& view) {
792 view.ComputeLengthAndData();
793 return view.LengthAllowShared();
796 public:
797 explicit Arr(const viewT& view)
798 : elemCount(ComputeAndReturnLength(view)),
799 elemBytes(view.DataAllowShared()) {}
801 explicit Arr(const dom::Sequence<elemT>& seq)
802 : elemCount(seq.Length()), elemBytes(seq.Elements()) {}
804 Arr(size_t _elemCount, const elemT* _elemBytes)
805 : elemCount(_elemCount), elemBytes(_elemBytes) {}
807 ////
809 static Arr From(const Float32ListU& list) {
810 if (list.IsFloat32Array()) return Arr(list.GetAsFloat32Array());
812 return Arr(list.GetAsUnrestrictedFloatSequence());
815 static Arr From(const Int32ListU& list) {
816 if (list.IsInt32Array()) return Arr(list.GetAsInt32Array());
818 return Arr(list.GetAsLongSequence());
821 static Arr From(const Uint32ListU& list) {
822 if (list.IsUint32Array()) return Arr(list.GetAsUint32Array());
824 return Arr(list.GetAsUnsignedLongSequence());
828 typedef Arr<GLfloat, dom::Float32Array> Float32Arr;
829 typedef Arr<GLint, dom::Int32Array> Int32Arr;
830 typedef Arr<GLuint, dom::Uint32Array> Uint32Arr;
832 ////////////////
834 void UniformNfv(const char* funcName, uint8_t N, WebGLUniformLocation* loc,
835 const Float32Arr& arr, GLuint elemOffset,
836 GLuint elemCountOverride);
837 void UniformNiv(const char* funcName, uint8_t N, WebGLUniformLocation* loc,
838 const Int32Arr& arr, GLuint elemOffset,
839 GLuint elemCountOverride);
840 void UniformNuiv(const char* funcName, uint8_t N, WebGLUniformLocation* loc,
841 const Uint32Arr& arr, GLuint elemOffset,
842 GLuint elemCountOverride);
844 void UniformMatrixAxBfv(const char* funcName, uint8_t A, uint8_t B,
845 WebGLUniformLocation* loc, bool transpose,
846 const Float32Arr& arr, GLuint elemOffset,
847 GLuint elemCountOverride);
849 ////////////////
851 public:
852 #define FOO(N) \
853 void Uniform##N##fv(WebGLUniformLocation* loc, const Float32ListU& list, \
854 GLuint elemOffset = 0, GLuint elemCountOverride = 0) { \
855 UniformNfv("uniform" #N "fv", N, loc, Float32Arr::From(list), elemOffset, \
856 elemCountOverride); \
859 FOO(1)
860 FOO(2)
861 FOO(3)
862 FOO(4)
864 #undef FOO
866 //////
868 #define FOO(N) \
869 void Uniform##N##iv(WebGLUniformLocation* loc, const Int32ListU& list, \
870 GLuint elemOffset = 0, GLuint elemCountOverride = 0) { \
871 UniformNiv("uniform" #N "iv", N, loc, Int32Arr::From(list), elemOffset, \
872 elemCountOverride); \
875 FOO(1)
876 FOO(2)
877 FOO(3)
878 FOO(4)
880 #undef FOO
882 //////
884 #define FOO(N) \
885 void Uniform##N##uiv(WebGLUniformLocation* loc, const Uint32ListU& list, \
886 GLuint elemOffset = 0, GLuint elemCountOverride = 0) { \
887 UniformNuiv("uniform" #N "uiv", N, loc, Uint32Arr::From(list), elemOffset, \
888 elemCountOverride); \
891 FOO(1)
892 FOO(2)
893 FOO(3)
894 FOO(4)
896 #undef FOO
898 //////
900 #define FOO(X, A, B) \
901 void UniformMatrix##X##fv(WebGLUniformLocation* loc, bool transpose, \
902 const Float32ListU& list, GLuint elemOffset = 0, \
903 GLuint elemCountOverride = 0) { \
904 UniformMatrixAxBfv("uniformMatrix" #X "fv", A, B, loc, transpose, \
905 Float32Arr::From(list), elemOffset, elemCountOverride); \
908 FOO(2, 2, 2)
909 FOO(2x3, 2, 3)
910 FOO(2x4, 2, 4)
912 FOO(3x2, 3, 2)
913 FOO(3, 3, 3)
914 FOO(3x4, 3, 4)
916 FOO(4x2, 4, 2)
917 FOO(4x3, 4, 3)
918 FOO(4, 4, 4)
920 #undef FOO
922 ////////////////////////////////////
924 void UseProgram(WebGLProgram* prog);
926 bool ValidateAttribArraySetter(uint32_t count, uint32_t arrayLength);
927 bool ValidateUniformLocation(const WebGLUniformLocation* loc);
928 bool ValidateUniformSetter(const WebGLUniformLocation* loc,
929 uint8_t setterElemSize,
930 webgl::AttribBaseType setterType);
931 bool ValidateUniformArraySetter(const WebGLUniformLocation* loc,
932 uint8_t setterElemSize,
933 webgl::AttribBaseType setterType,
934 uint32_t setterArraySize,
935 uint32_t* out_numElementsToUpload);
936 bool ValidateUniformMatrixArraySetter(const WebGLUniformLocation* loc,
937 uint8_t setterCols, uint8_t setterRows,
938 webgl::AttribBaseType setterType,
939 uint32_t setterArraySize,
940 bool setterTranspose,
941 uint32_t* out_numElementsToUpload);
942 void ValidateProgram(const WebGLProgram& prog);
943 bool ValidateUniformLocation(const char* info, WebGLUniformLocation* loc);
944 bool ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation* loc,
945 GLint value);
946 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
947 // -----------------------------------------------------------------------------
948 // WEBGL_lose_context
949 public:
950 void LoseContext();
951 void RestoreContext();
953 // -----------------------------------------------------------------------------
954 // Buffer Objects (WebGLContextBuffers.cpp)
955 void BindBuffer(GLenum target, WebGLBuffer* buffer);
956 void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buf);
957 void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
958 WebGLintptr offset, WebGLsizeiptr size);
960 private:
961 void BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data,
962 GLenum usage);
964 public:
965 void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
966 void BufferData(GLenum target,
967 const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
968 GLenum usage);
969 void BufferData(GLenum target, const dom::ArrayBufferView& srcData,
970 GLenum usage, GLuint srcElemOffset = 0,
971 GLuint srcElemCountOverride = 0);
973 private:
974 void BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
975 size_t srcDataLen, const uint8_t* srcData);
977 public:
978 void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
979 const dom::ArrayBufferView& src, GLuint srcElemOffset = 0,
980 GLuint srcElemCountOverride = 0);
981 void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
982 const dom::ArrayBuffer& src);
983 void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
984 const dom::SharedArrayBuffer& src);
986 already_AddRefed<WebGLBuffer> CreateBuffer();
987 void DeleteBuffer(WebGLBuffer* buf);
989 protected:
990 // bound buffer state
991 WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
992 WebGLRefPtr<WebGLBuffer> mBoundCopyReadBuffer;
993 WebGLRefPtr<WebGLBuffer> mBoundCopyWriteBuffer;
994 WebGLRefPtr<WebGLBuffer> mBoundPixelPackBuffer;
995 WebGLRefPtr<WebGLBuffer> mBoundPixelUnpackBuffer;
996 WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
997 WebGLRefPtr<WebGLBuffer> mBoundUniformBuffer;
999 std::vector<IndexedBufferBinding> mIndexedUniformBufferBindings;
1001 WebGLRefPtr<WebGLBuffer>& GetBufferSlotByTarget(GLenum target);
1002 WebGLRefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
1003 GLuint index);
1005 // -----------------------------------------------------------------------------
1006 // Queries (WebGL2ContextQueries.cpp)
1007 protected:
1008 WebGLRefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
1009 WebGLRefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
1010 WebGLRefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
1012 WebGLRefPtr<WebGLQuery>* ValidateQuerySlotByTarget(GLenum target);
1014 public:
1015 already_AddRefed<WebGLQuery> CreateQuery();
1016 void DeleteQuery(WebGLQuery* query);
1017 bool IsQuery(const WebGLQuery* query);
1018 void BeginQuery(GLenum target, WebGLQuery& query);
1019 void EndQuery(GLenum target);
1020 void GetQuery(JSContext* cx, GLenum target, GLenum pname,
1021 JS::MutableHandleValue retval);
1022 void GetQueryParameter(JSContext* cx, const WebGLQuery& query, GLenum pname,
1023 JS::MutableHandleValue retval);
1025 // -----------------------------------------------------------------------------
1026 // State and State Requests (WebGLContextState.cpp)
1027 private:
1028 void SetEnabled(const char* funcName, GLenum cap, bool enabled);
1030 public:
1031 void Disable(GLenum cap) { SetEnabled("disabled", cap, false); }
1032 void Enable(GLenum cap) { SetEnabled("enabled", cap, true); }
1033 bool GetStencilBits(GLint* const out_stencilBits) const;
1034 virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
1036 void GetParameter(JSContext* cx, GLenum pname,
1037 JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
1038 retval.set(GetParameter(cx, pname, rv));
1041 bool IsEnabled(GLenum cap);
1043 private:
1044 // State tracking slots
1045 realGLboolean mDitherEnabled;
1046 realGLboolean mRasterizerDiscardEnabled;
1047 realGLboolean mScissorTestEnabled;
1048 realGLboolean mDepthTestEnabled = 0;
1049 realGLboolean mStencilTestEnabled;
1050 GLenum mGenerateMipmapHint = 0;
1052 bool ValidateCapabilityEnum(GLenum cap);
1053 realGLboolean* GetStateTrackingSlot(GLenum cap);
1055 // Allocation debugging variables
1056 mutable uint64_t mDataAllocGLCallCount;
1058 void OnDataAllocCall() const { mDataAllocGLCallCount++; }
1060 uint64_t GetNumGLDataAllocCalls() const { return mDataAllocGLCallCount; }
1062 void OnEndOfFrame() const;
1064 // -----------------------------------------------------------------------------
1065 // Texture funcions (WebGLContextTextures.cpp)
1066 public:
1067 void ActiveTexture(GLenum texUnit);
1068 void BindTexture(GLenum texTarget, WebGLTexture* tex);
1069 already_AddRefed<WebGLTexture> CreateTexture();
1070 void DeleteTexture(WebGLTexture* tex);
1071 void GenerateMipmap(GLenum texTarget);
1073 void GetTexParameter(JSContext*, GLenum texTarget, GLenum pname,
1074 JS::MutableHandle<JS::Value> retval) {
1075 retval.set(GetTexParameter(texTarget, pname));
1078 void TexParameterf(GLenum texTarget, GLenum pname, GLfloat param) {
1079 TexParameter_base(texTarget, pname, FloatOrInt(param));
1082 void TexParameteri(GLenum texTarget, GLenum pname, GLint param) {
1083 TexParameter_base(texTarget, pname, FloatOrInt(param));
1086 protected:
1087 JS::Value GetTexParameter(GLenum texTarget, GLenum pname);
1088 void TexParameter_base(GLenum texTarget, GLenum pname,
1089 const FloatOrInt& param);
1091 virtual bool IsTexParamValid(GLenum pname) const;
1093 ////////////////////////////////////
1095 public:
1096 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
1097 GLsizei width, GLsizei height, GLint border,
1098 GLsizei imageSize, WebGLsizeiptr offset) {
1099 const FuncScope funcScope(*this, "compressedTexImage2D");
1100 const uint8_t funcDims = 2;
1101 const GLsizei depth = 1;
1102 const TexImageSourceAdapter src(&offset, 0, 0);
1103 CompressedTexImage(funcDims, target, level, internalFormat, width, height,
1104 depth, border, src, Some(imageSize));
1107 template <typename T>
1108 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
1109 GLsizei width, GLsizei height, GLint border,
1110 const T& anySrc, GLuint viewElemOffset = 0,
1111 GLuint viewElemLengthOverride = 0) {
1112 const FuncScope funcScope(*this, "compressedTexImage2D");
1113 const uint8_t funcDims = 2;
1114 const GLsizei depth = 1;
1115 const TexImageSourceAdapter src(&anySrc, viewElemOffset,
1116 viewElemLengthOverride);
1117 CompressedTexImage(funcDims, target, level, internalFormat, width, height,
1118 depth, border, src, Nothing());
1121 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset,
1122 GLint yOffset, GLsizei width, GLsizei height,
1123 GLenum unpackFormat, GLsizei imageSize,
1124 WebGLsizeiptr offset) {
1125 const FuncScope funcScope(*this, "compressedTexSubImage2D");
1126 const uint8_t funcDims = 2;
1127 const GLint zOffset = 0;
1128 const GLsizei depth = 1;
1129 const TexImageSourceAdapter src(&offset, 0, 0);
1130 CompressedTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset,
1131 width, height, depth, unpackFormat, src,
1132 Some(imageSize));
1135 template <typename T>
1136 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset,
1137 GLint yOffset, GLsizei width, GLsizei height,
1138 GLenum unpackFormat, const T& anySrc,
1139 GLuint viewElemOffset = 0,
1140 GLuint viewElemLengthOverride = 0) {
1141 const FuncScope funcScope(*this, "compressedTexSubImage2D");
1142 const uint8_t funcDims = 2;
1143 const GLint zOffset = 0;
1144 const GLsizei depth = 1;
1145 const TexImageSourceAdapter src(&anySrc, viewElemOffset,
1146 viewElemLengthOverride);
1147 CompressedTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset,
1148 width, height, depth, unpackFormat, src, Nothing());
1151 protected:
1152 void CompressedTexImage(uint8_t funcDims, GLenum target, GLint level,
1153 GLenum internalFormat, GLsizei width, GLsizei height,
1154 GLsizei depth, GLint border,
1155 const TexImageSource& src,
1156 const Maybe<GLsizei>& expectedImageSize);
1157 void CompressedTexSubImage(uint8_t funcDims, GLenum target, GLint level,
1158 GLint xOffset, GLint yOffset, GLint zOffset,
1159 GLsizei width, GLsizei height, GLsizei depth,
1160 GLenum unpackFormat, const TexImageSource& src,
1161 const Maybe<GLsizei>& expectedImageSize);
1163 ////////////////////////////////////
1165 public:
1166 void CopyTexImage2D(GLenum target, GLint level, GLenum internalFormat,
1167 GLint x, GLint y, GLsizei width, GLsizei height,
1168 GLint border);
1170 void CopyTexSubImage2D(GLenum target, GLint level, GLint xOffset,
1171 GLint yOffset, GLint x, GLint y, GLsizei width,
1172 GLsizei height) {
1173 const FuncScope funcScope(*this, "copyTexSubImage2D");
1174 const uint8_t funcDims = 2;
1175 const GLint zOffset = 0;
1176 CopyTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset, x, y,
1177 width, height);
1180 protected:
1181 void CopyTexSubImage(uint8_t funcDims, GLenum target, GLint level,
1182 GLint xOffset, GLint yOffset, GLint zOffset, GLint x,
1183 GLint y, GLsizei width, GLsizei height);
1185 ////////////////////////////////////
1186 // TexImage
1188 // Implicit width/height uploads
1190 public:
1191 template <typename T>
1192 void TexImage2D(GLenum target, GLint level, GLenum internalFormat,
1193 GLenum unpackFormat, GLenum unpackType, const T& src,
1194 ErrorResult& out_error) {
1195 GLsizei width = 0;
1196 GLsizei height = 0;
1197 GLint border = 0;
1198 TexImage2D(target, level, internalFormat, width, height, border,
1199 unpackFormat, unpackType, src, out_error);
1202 template <typename T>
1203 void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1204 GLenum unpackFormat, GLenum unpackType, const T& src,
1205 ErrorResult& out_error) {
1206 GLsizei width = 0;
1207 GLsizei height = 0;
1208 TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
1209 unpackType, src, out_error);
1212 ////
1214 template <typename T>
1215 void TexImage2D(GLenum target, GLint level, GLenum internalFormat,
1216 GLsizei width, GLsizei height, GLint border,
1217 GLenum unpackFormat, GLenum unpackType, const T& anySrc,
1218 ErrorResult& out_error) {
1219 const TexImageSourceAdapter src(&anySrc, &out_error);
1220 TexImage2D(target, level, internalFormat, width, height, border,
1221 unpackFormat, unpackType, src);
1224 void TexImage2D(GLenum target, GLint level, GLenum internalFormat,
1225 GLsizei width, GLsizei height, GLint border,
1226 GLenum unpackFormat, GLenum unpackType,
1227 const dom::ArrayBufferView& view, GLuint viewElemOffset,
1228 ErrorResult&) {
1229 const TexImageSourceAdapter src(&view, viewElemOffset);
1230 TexImage2D(target, level, internalFormat, width, height, border,
1231 unpackFormat, unpackType, src);
1234 protected:
1235 void TexImage2D(GLenum target, GLint level, GLenum internalFormat,
1236 GLsizei width, GLsizei height, GLint border,
1237 GLenum unpackFormat, GLenum unpackType,
1238 const TexImageSource& src) {
1239 const FuncScope funcScope(*this, "texImage2D");
1240 const uint8_t funcDims = 2;
1241 const GLsizei depth = 1;
1242 TexImage(funcDims, target, level, internalFormat, width, height, depth,
1243 border, unpackFormat, unpackType, src);
1246 void TexImage(uint8_t funcDims, GLenum target, GLint level,
1247 GLenum internalFormat, GLsizei width, GLsizei height,
1248 GLsizei depth, GLint border, GLenum unpackFormat,
1249 GLenum unpackType, const TexImageSource& src);
1251 ////
1253 public:
1254 template <typename T>
1255 void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1256 GLsizei width, GLsizei height, GLenum unpackFormat,
1257 GLenum unpackType, const T& anySrc,
1258 ErrorResult& out_error) {
1259 const TexImageSourceAdapter src(&anySrc, &out_error);
1260 TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
1261 unpackType, src);
1264 void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1265 GLsizei width, GLsizei height, GLenum unpackFormat,
1266 GLenum unpackType, const dom::ArrayBufferView& view,
1267 GLuint viewElemOffset, ErrorResult&) {
1268 const TexImageSourceAdapter src(&view, viewElemOffset);
1269 TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
1270 unpackType, src);
1273 protected:
1274 void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1275 GLsizei width, GLsizei height, GLenum unpackFormat,
1276 GLenum unpackType, const TexImageSource& src) {
1277 const FuncScope funcScope(*this, "texSubImage2D");
1278 const uint8_t funcDims = 2;
1279 const GLint zOffset = 0;
1280 const GLsizei depth = 1;
1281 TexSubImage(funcDims, target, level, xOffset, yOffset, zOffset, width,
1282 height, depth, unpackFormat, unpackType, src);
1285 void TexSubImage(uint8_t funcDims, GLenum target, GLint level, GLint xOffset,
1286 GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
1287 GLsizei depth, GLenum unpackFormat, GLenum unpackType,
1288 const TexImageSource& src);
1290 ////////////////////////////////////
1291 // WebGLTextureUpload.cpp
1292 public:
1293 UniquePtr<webgl::TexUnpackBlob> From(TexImageTarget target, GLsizei rawWidth,
1294 GLsizei rawHeight, GLsizei rawDepth,
1295 GLint border, const TexImageSource& src,
1296 dom::Uint8ClampedArray* const scopedArr);
1298 protected:
1299 bool ValidateTexImageSpecification(uint8_t funcDims, GLenum texImageTarget,
1300 GLint level, GLsizei width, GLsizei height,
1301 GLsizei depth, GLint border,
1302 TexImageTarget* const out_target,
1303 WebGLTexture** const out_texture,
1304 webgl::ImageInfo** const out_imageInfo);
1305 bool ValidateTexImageSelection(uint8_t funcDims, GLenum texImageTarget,
1306 GLint level, GLint xOffset, GLint yOffset,
1307 GLint zOffset, GLsizei width, GLsizei height,
1308 GLsizei depth,
1309 TexImageTarget* const out_target,
1310 WebGLTexture** const out_texture,
1311 webgl::ImageInfo** const out_imageInfo);
1312 bool ValidateUnpackInfo(bool usePBOs, GLenum format, GLenum type,
1313 webgl::PackingInfo* const out);
1315 UniquePtr<webgl::TexUnpackBlob> FromDomElem(TexImageTarget target,
1316 uint32_t width, uint32_t height,
1317 uint32_t depth,
1318 const dom::Element& elem,
1319 ErrorResult* const out_error);
1321 UniquePtr<webgl::TexUnpackBytes> FromCompressed(
1322 TexImageTarget target, GLsizei rawWidth, GLsizei rawHeight,
1323 GLsizei rawDepth, GLint border, const TexImageSource& src,
1324 const Maybe<GLsizei>& expectedImageSize);
1326 // -----------------------------------------------------------------------------
1327 // Vertices Feature (WebGLContextVertices.cpp)
1328 GLenum mPrimRestartTypeBytes = 0;
1330 public:
1331 void DrawArrays(GLenum mode, GLint first, GLsizei count) {
1332 const FuncScope funcScope(*this, "drawArrays");
1333 DrawArraysInstanced(mode, first, count, 1);
1336 void DrawElements(GLenum mode, GLsizei count, GLenum type,
1337 WebGLintptr byteOffset) {
1338 const FuncScope funcScope(*this, "drawElements");
1339 DrawElementsInstanced(mode, count, type, byteOffset, 1);
1342 void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertexCount,
1343 GLsizei instanceCount);
1344 void DrawElementsInstanced(GLenum mode, GLsizei vertexCount, GLenum type,
1345 WebGLintptr byteOffset, GLsizei instanceCount);
1347 void EnableVertexAttribArray(GLuint index);
1348 void DisableVertexAttribArray(GLuint index);
1350 JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
1351 ErrorResult& rv);
1353 void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
1354 JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
1355 retval.set(GetVertexAttrib(cx, index, pname, rv));
1358 WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
1360 ////
1362 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
1364 ////
1366 void VertexAttrib1f(GLuint index, GLfloat x) {
1367 const FuncScope funcScope(*this, "vertexAttrib1f");
1368 VertexAttrib4f(index, x, 0, 0, 1);
1370 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1371 const FuncScope funcScope(*this, "vertexAttrib2f");
1372 VertexAttrib4f(index, x, y, 0, 1);
1374 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1375 const FuncScope funcScope(*this, "vertexAttrib3f");
1376 VertexAttrib4f(index, x, y, z, 1);
1379 ////
1381 void VertexAttrib1fv(GLuint index, const Float32ListU& list) {
1382 const FuncScope funcScope(*this, "vertexAttrib1fv");
1383 const auto& arr = Float32Arr::From(list);
1384 if (!ValidateAttribArraySetter(1, arr.elemCount)) return;
1386 VertexAttrib4f(index, arr.elemBytes[0], 0, 0, 1);
1389 void VertexAttrib2fv(GLuint index, const Float32ListU& list) {
1390 const FuncScope funcScope(*this, "vertexAttrib2fv");
1391 const auto& arr = Float32Arr::From(list);
1392 if (!ValidateAttribArraySetter(2, arr.elemCount)) return;
1394 VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], 0, 1);
1397 void VertexAttrib3fv(GLuint index, const Float32ListU& list) {
1398 const FuncScope funcScope(*this, "vertexAttrib3fv");
1399 const auto& arr = Float32Arr::From(list);
1400 if (!ValidateAttribArraySetter(3, arr.elemCount)) return;
1402 VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2],
1406 void VertexAttrib4fv(GLuint index, const Float32ListU& list) {
1407 const FuncScope funcScope(*this, "vertexAttrib4fv");
1408 const auto& arr = Float32Arr::From(list);
1409 if (!ValidateAttribArraySetter(4, arr.elemCount)) return;
1411 VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2],
1412 arr.elemBytes[3]);
1415 ////
1417 protected:
1418 void VertexAttribAnyPointer(bool isFuncInt, GLuint index, GLint size,
1419 GLenum type, bool normalized, GLsizei stride,
1420 WebGLintptr byteOffset);
1422 public:
1423 void VertexAttribPointer(GLuint index, GLint size, GLenum type,
1424 WebGLboolean normalized, GLsizei stride,
1425 WebGLintptr byteOffset) {
1426 const FuncScope funcScope(*this, "vertexAttribPointer");
1427 const bool isFuncInt = false;
1428 VertexAttribAnyPointer(isFuncInt, index, size, type, normalized, stride,
1429 byteOffset);
1432 void VertexAttribDivisor(GLuint index, GLuint divisor);
1434 private:
1435 WebGLBuffer* DrawElements_check(GLsizei indexCount, GLenum type,
1436 WebGLintptr byteOffset,
1437 GLsizei instanceCount);
1438 void Draw_cleanup();
1440 void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
1441 const GLfloat* ptr);
1442 void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
1443 const GLfloat* ptr);
1444 void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
1445 const GLfloat* ptr);
1446 void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
1447 const GLfloat* ptr);
1449 bool BindArrayAttribToLocation0(WebGLProgram* prog);
1451 // -----------------------------------------------------------------------------
1452 // PROTECTED
1453 protected:
1454 WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
1455 bool DoFakeVertexAttrib0(uint64_t vertexCount);
1456 void UndoFakeVertexAttrib0();
1458 CheckedUint32 mGeneration;
1460 WebGLContextOptions mOptions;
1462 bool mInvalidated;
1463 bool mCapturedFrameInvalidated;
1464 bool mResetLayer;
1465 bool mOptionsFrozen;
1466 bool mDisableExtensions;
1467 bool mIsMesa;
1468 bool mLoseContextOnMemoryPressure;
1469 bool mCanLoseContextInForeground;
1470 bool mShouldPresent;
1471 bool mDisableFragHighP;
1472 bool mVRReady;
1474 template <typename WebGLObjectType>
1475 void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
1477 GLuint mActiveTexture = 0;
1478 GLenum mDefaultFB_DrawBuffer0 = 0;
1479 GLenum mDefaultFB_ReadBuffer = 0;
1481 mutable GLenum mWebGLError;
1483 bool mBypassShaderValidation;
1485 webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
1487 // some GL constants
1488 uint32_t mGLMaxTextureUnits = 0;
1490 uint32_t mGLMaxVertexAttribs = 0;
1491 uint32_t mGLMaxFragmentUniformVectors = 0;
1492 uint32_t mGLMaxVertexUniformVectors = 0;
1493 uint32_t mGLMaxVaryingVectors = 0;
1495 uint32_t mGLMaxTransformFeedbackSeparateAttribs = 0;
1496 uint32_t mGLMaxUniformBufferBindings = 0;
1498 uint32_t mGLMaxVertexTextureImageUnits = 0;
1499 uint32_t mGLMaxFragmentTextureImageUnits = 0;
1500 uint32_t mGLMaxCombinedTextureImageUnits = 0;
1502 uint32_t mGLMaxColorAttachments = 0;
1503 uint32_t mGLMaxDrawBuffers = 0;
1505 uint32_t mGLMaxViewportDims[2];
1507 public:
1508 GLenum LastColorAttachmentEnum() const {
1509 return LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments - 1;
1512 const decltype(mOptions)& Options() const { return mOptions; }
1514 protected:
1515 // Texture sizes are often not actually the GL values. Let's be explicit that
1516 // these are implementation limits.
1517 uint32_t mGLMaxTextureSize = 0;
1518 uint32_t mGLMaxCubeMapTextureSize = 0;
1519 uint32_t mGLMax3DTextureSize = 0;
1520 uint32_t mGLMaxArrayTextureLayers = 0;
1521 uint32_t mGLMaxRenderbufferSize = 0;
1523 public:
1524 GLuint MaxVertexAttribs() const { return mGLMaxVertexAttribs; }
1526 GLuint GLMaxTextureUnits() const { return mGLMaxTextureUnits; }
1528 float mGLAliasedLineWidthRange[2];
1529 float mGLAliasedPointSizeRange[2];
1531 bool IsFormatValidForFB(TexInternalFormat format) const;
1533 protected:
1534 // Represents current status of the context with respect to context loss.
1535 // That is, whether the context is lost, and what part of the context loss
1536 // process we currently are at.
1537 // This is used to support the WebGL spec's asyncronous nature in handling
1538 // context loss.
1539 enum class ContextStatus {
1540 // The context is stable; there either are none or we don't know of any.
1541 NotLost,
1542 // The context has been lost, but we have not yet sent an event to the
1543 // script informing it of this.
1544 LostAwaitingEvent,
1545 // The context has been lost, and we have sent the script an event
1546 // informing it of this.
1547 Lost,
1548 // The context is lost, an event has been sent to the script, and the
1549 // script correctly handled the event. We are waiting for the context to
1550 // be restored.
1551 LostAwaitingRestore
1554 // -------------------------------------------------------------------------
1555 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
1556 typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max,
1557 RefPtr<WebGLExtensionBase>>
1558 ExtensionsArrayType;
1560 ExtensionsArrayType mExtensions;
1562 // enable an extension. the extension should not be enabled before.
1563 void EnableExtension(WebGLExtensionID ext);
1565 // Enable an extension if it's supported. Return the extension on success.
1566 WebGLExtensionBase* EnableSupportedExtension(dom::CallerType callerType,
1567 WebGLExtensionID ext);
1569 public:
1570 // returns true if the extension has been enabled by calling getExtension.
1571 bool IsExtensionEnabled(WebGLExtensionID ext) const;
1573 protected:
1574 // returns true if the extension is supported for this caller type (this
1575 // decides what getSupportedExtensions exposes)
1576 bool IsExtensionSupported(dom::CallerType callerType,
1577 WebGLExtensionID ext) const;
1578 bool IsExtensionSupported(WebGLExtensionID ext) const;
1580 static const char* GetExtensionString(WebGLExtensionID ext);
1582 nsTArray<GLenum> mCompressedTextureFormats;
1584 // -------------------------------------------------------------------------
1585 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
1586 public:
1587 virtual bool IsWebGL2() const = 0;
1589 struct FailureReason {
1590 nsCString key; // For reporting.
1591 nsCString info;
1593 FailureReason() {}
1595 template <typename A, typename B>
1596 FailureReason(const A& _key, const B& _info)
1597 : key(nsCString(_key)), info(nsCString(_info)) {}
1600 protected:
1601 bool InitWebGL2(FailureReason* const out_failReason);
1603 bool CreateAndInitGL(bool forceEnabled,
1604 std::vector<FailureReason>* const out_failReasons);
1606 void ThrowEvent_WebGLContextCreationError(const nsACString& text);
1608 // -------------------------------------------------------------------------
1609 // Validation functions (implemented in WebGLContextValidate.cpp)
1610 bool InitAndValidateGL(FailureReason* const out_failReason);
1612 bool ValidateBlendEquationEnum(GLenum cap, const char* info);
1613 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor,
1614 const char* info);
1615 bool ValidateStencilOpEnum(GLenum action, const char* info);
1616 bool ValidateFaceEnum(GLenum face);
1617 bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
1618 WebGLTexImageFunc func, WebGLTexDimensions dims);
1619 bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size,
1620 GLenum type, WebGLboolean normalized,
1621 GLsizei stride, WebGLintptr byteOffset,
1622 const char* info);
1623 bool ValidateStencilParamsForDrawCall() const;
1625 bool ValidateCopyTexImage(TexInternalFormat srcFormat,
1626 TexInternalFormat dstformat, WebGLTexImageFunc func,
1627 WebGLTexDimensions dims);
1629 bool ValidateTexImage(TexImageTarget texImageTarget, GLint level,
1630 GLenum internalFormat, GLint xoffset, GLint yoffset,
1631 GLint zoffset, GLint width, GLint height, GLint depth,
1632 GLint border, GLenum format, GLenum type,
1633 WebGLTexImageFunc func, WebGLTexDimensions dims);
1634 bool ValidateTexImageFormat(GLenum internalFormat, WebGLTexImageFunc func,
1635 WebGLTexDimensions dims);
1636 bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func,
1637 WebGLTexDimensions dims);
1638 bool ValidateTexImageFormatAndType(GLenum format, GLenum type,
1639 WebGLTexImageFunc func,
1640 WebGLTexDimensions dims);
1641 bool ValidateCompTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1642 WebGLTexDimensions dims);
1643 bool ValidateCopyTexImageInternalFormat(GLenum format, WebGLTexImageFunc func,
1644 WebGLTexDimensions dims);
1645 bool ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
1646 GLint width, GLint height, GLint depth,
1647 WebGLTexImageFunc func, WebGLTexDimensions dims);
1648 bool ValidateTexSubImageSize(GLint x, GLint y, GLint z, GLsizei width,
1649 GLsizei height, GLsizei depth, GLsizei baseWidth,
1650 GLsizei baseHeight, GLsizei baseDepth,
1651 WebGLTexImageFunc func, WebGLTexDimensions dims);
1652 bool ValidateCompTexImageSize(GLint level, GLenum internalFormat,
1653 GLint xoffset, GLint yoffset, GLsizei width,
1654 GLsizei height, GLsizei levelWidth,
1655 GLsizei levelHeight, WebGLTexImageFunc func,
1656 WebGLTexDimensions dims);
1657 bool ValidateCompTexImageDataSize(GLint level, GLenum internalFormat,
1658 GLsizei width, GLsizei height,
1659 uint32_t byteLength, WebGLTexImageFunc func,
1660 WebGLTexDimensions dims);
1662 bool ValidateUniformLocationForProgram(WebGLUniformLocation* location,
1663 WebGLProgram* program);
1665 bool HasDrawBuffers() const {
1666 return IsWebGL2() ||
1667 IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
1670 WebGLRefPtr<WebGLBuffer>* ValidateBufferSlot(GLenum target);
1672 public:
1673 WebGLBuffer* ValidateBufferSelection(GLenum target);
1675 protected:
1676 IndexedBufferBinding* ValidateIndexedBufferSlot(GLenum target, GLuint index);
1678 bool ValidateIndexedBufferBinding(
1679 GLenum target, GLuint index,
1680 WebGLRefPtr<WebGLBuffer>** const out_genericBinding,
1681 IndexedBufferBinding** const out_indexedBinding);
1683 bool ValidateNonNegative(const char* argName, int64_t val) {
1684 if (MOZ_UNLIKELY(val < 0)) {
1685 ErrorInvalidValue("`%s` must be non-negative.", argName);
1686 return false;
1688 return true;
1691 public:
1692 template <typename T>
1693 bool ValidateNonNull(const char* const argName,
1694 const dom::Nullable<T>& maybe) {
1695 if (maybe.IsNull()) {
1696 ErrorInvalidValue("%s: Cannot be null.", argName);
1697 return false;
1699 return true;
1702 bool ValidateArrayBufferView(const dom::ArrayBufferView& view,
1703 GLuint elemOffset, GLuint elemCountOverride,
1704 uint8_t** const out_bytes,
1705 size_t* const out_byteLen);
1707 protected:
1708 ////
1710 void Invalidate();
1711 void DestroyResourcesAndContext();
1713 // helpers
1715 bool ConvertImage(size_t width, size_t height, size_t srcStride,
1716 size_t dstStride, const uint8_t* src, uint8_t* dst,
1717 WebGLTexelFormat srcFormat, bool srcPremultiplied,
1718 WebGLTexelFormat dstFormat, bool dstPremultiplied,
1719 size_t dstTexelSize);
1721 //////
1722 public:
1723 bool ValidateObjectAllowDeleted(const char* const argName,
1724 const WebGLContextBoundObject& object) {
1725 if (!object.IsCompatibleWithContext(this)) {
1726 ErrorInvalidOperation(
1727 "%s: Object from different WebGL context (or older"
1728 " generation of this one) passed as argument.",
1729 argName);
1730 return false;
1733 return true;
1736 bool ValidateObject(const char* const argName,
1737 const WebGLDeletableObject& object,
1738 const bool isShaderOrProgram = false) {
1739 if (!ValidateObjectAllowDeleted(argName, object)) return false;
1741 if (isShaderOrProgram) {
1742 /* GLES 3.0.5 p45:
1743 * "Commands that accept shader or program object names will generate the
1744 * error INVALID_VALUE if the provided name is not the name of either a
1745 * shader or program object[.]"
1746 * Further, shaders and programs appear to be different from other
1747 * objects, in that their lifetimes are better defined. However, they also
1748 * appear to allow use of objects marked for deletion, and only reject
1749 * actually-destroyed objects.
1751 if (object.IsDeleted()) {
1752 ErrorInvalidValue(
1753 "%s: Shader or program object argument cannot have been"
1754 " deleted.",
1755 argName);
1756 return false;
1758 } else {
1759 if (object.IsDeleteRequested()) {
1760 ErrorInvalidOperation(
1761 "%s: Object argument cannot have been marked for"
1762 " deletion.",
1763 argName);
1764 return false;
1768 return true;
1771 ////
1773 // Program and Shader are incomplete, so we can't inline the conversion to
1774 // WebGLDeletableObject here.
1775 bool ValidateObject(const char* const argName, const WebGLProgram& object);
1776 bool ValidateObject(const char* const argName, const WebGLShader& object);
1778 ////
1780 bool ValidateIsObject(const WebGLDeletableObject* object) const;
1781 bool ValidateDeleteObject(const WebGLDeletableObject* object);
1783 ////
1785 private:
1786 // -------------------------------------------------------------------------
1787 // Context customization points
1788 virtual WebGLVertexArray* CreateVertexArrayImpl();
1790 public:
1791 void ForceLoseContext(bool simulateLoss = false);
1793 protected:
1794 void ForceRestoreContext();
1796 nsTArray<WebGLRefPtr<WebGLTexture>> mBound2DTextures;
1797 nsTArray<WebGLRefPtr<WebGLTexture>> mBoundCubeMapTextures;
1798 nsTArray<WebGLRefPtr<WebGLTexture>> mBound3DTextures;
1799 nsTArray<WebGLRefPtr<WebGLTexture>> mBound2DArrayTextures;
1800 nsTArray<WebGLRefPtr<WebGLSampler>> mBoundSamplers;
1802 void ResolveTexturesForDraw() const;
1804 WebGLRefPtr<WebGLProgram> mCurrentProgram;
1805 RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
1807 bool ValidateFramebufferTarget(GLenum target);
1808 bool ValidateInvalidateFramebuffer(GLenum target,
1809 const dom::Sequence<GLenum>& attachments,
1810 ErrorResult* const out_rv,
1811 std::vector<GLenum>* const scopedVector,
1812 GLsizei* const out_glNumAttachments,
1813 const GLenum** const out_glAttachments);
1815 WebGLRefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
1816 WebGLRefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
1817 WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
1818 WebGLRefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
1819 WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
1821 LinkedList<WebGLBuffer> mBuffers;
1822 LinkedList<WebGLFramebuffer> mFramebuffers;
1823 LinkedList<WebGLProgram> mPrograms;
1824 LinkedList<WebGLQuery> mQueries;
1825 LinkedList<WebGLRenderbuffer> mRenderbuffers;
1826 LinkedList<WebGLSampler> mSamplers;
1827 LinkedList<WebGLShader> mShaders;
1828 LinkedList<WebGLSync> mSyncs;
1829 LinkedList<WebGLTexture> mTextures;
1830 LinkedList<WebGLTransformFeedback> mTransformFeedbacks;
1831 LinkedList<WebGLVertexArray> mVertexArrays;
1833 WebGLRefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1834 WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
1836 // PixelStore parameters
1837 uint32_t mPixelStore_UnpackImageHeight = 0;
1838 uint32_t mPixelStore_UnpackSkipImages = 0;
1839 uint32_t mPixelStore_UnpackRowLength = 0;
1840 uint32_t mPixelStore_UnpackSkipRows = 0;
1841 uint32_t mPixelStore_UnpackSkipPixels = 0;
1842 uint32_t mPixelStore_UnpackAlignment = 0;
1843 uint32_t mPixelStore_PackRowLength = 0;
1844 uint32_t mPixelStore_PackSkipRows = 0;
1845 uint32_t mPixelStore_PackSkipPixels = 0;
1846 uint32_t mPixelStore_PackAlignment = 0;
1848 CheckedUint32 GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
1849 uint32_t depth, uint8_t bytesPerPixel);
1851 bool ValidatePackSize(uint32_t width, uint32_t height, uint8_t bytesPerPixel,
1852 uint32_t* const out_rowStride,
1853 uint32_t* const out_endOffset);
1855 GLenum mPixelStore_ColorspaceConversion = 0;
1856 bool mPixelStore_FlipY = false;
1857 bool mPixelStore_PremultiplyAlpha = false;
1858 bool mPixelStore_RequireFastPath = false;
1860 ////////////////////////////////////
1862 protected:
1863 GLuint mEmptyTFO;
1865 // Generic Vertex Attributes
1866 // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the
1867 // spec state tables, this isn't vertex shader /object/ state. This array is
1868 // merely state useful to vertex shaders, but is global state.
1869 std::vector<webgl::AttribBaseType> mGenericVertexAttribTypes;
1870 uint8_t mGenericVertexAttrib0Data[sizeof(float) * 4];
1871 CacheInvalidator mGenericVertexAttribTypeInvalidator;
1873 GLuint mFakeVertexAttrib0BufferObject = 0;
1874 size_t mFakeVertexAttrib0BufferObjectSize = 0;
1875 bool mFakeVertexAttrib0DataDefined = false;
1876 uint8_t mFakeVertexAttrib0Data[sizeof(float) * 4];
1878 JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
1879 JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
1880 JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);
1882 GLint mStencilRefFront = 0;
1883 GLint mStencilRefBack = 0;
1884 GLuint mStencilValueMaskFront = 0;
1885 GLuint mStencilValueMaskBack = 0;
1886 GLuint mStencilWriteMaskFront = 0;
1887 GLuint mStencilWriteMaskBack = 0;
1888 uint8_t mColorWriteMask = 0; // bitmask
1889 realGLboolean mDepthWriteMask = 0;
1890 GLfloat mColorClearValue[4];
1891 GLint mStencilClearValue = 0;
1892 GLfloat mDepthClearValue = 0.0;
1894 GLint mViewportX;
1895 GLint mViewportY;
1896 GLsizei mViewportWidth;
1897 GLsizei mViewportHeight;
1898 bool mAlreadyWarnedAboutViewportLargerThanDest;
1900 GLfloat mLineWidth = 0.0;
1902 WebGLContextLossHandler mContextLossHandler;
1903 bool mAllowContextRestore;
1904 bool mLastLossWasSimulated;
1905 ContextStatus mContextStatus = ContextStatus::NotLost;
1907 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1908 // be Flushed while doing hundreds of draw calls.
1909 int mDrawCallsSinceLastFlush;
1911 mutable int mAlreadyGeneratedWarnings;
1912 int mMaxWarnings;
1913 bool mAlreadyWarnedAboutFakeVertexAttrib0;
1915 bool ShouldGenerateWarnings() const;
1917 bool ShouldGeneratePerfWarnings() const {
1918 return mNumPerfWarnings < mMaxPerfWarnings;
1921 uint64_t mLastUseIndex;
1923 bool mNeedsFakeNoAlpha;
1924 bool mNeedsFakeNoDepth;
1925 bool mNeedsFakeNoStencil;
1926 bool mNeedsFakeNoStencil_UserFBs = false;
1928 mutable uint8_t mDriverColorMask = 0;
1929 bool mDriverDepthTest = false;
1930 bool mDriverStencilTest = false;
1932 bool mNeedsIndexValidation = false;
1934 const bool mAllowFBInvalidation;
1935 #if defined(MOZ_WIDGET_ANDROID)
1936 UniquePtr<gl::GLScreenBuffer> mVRScreen;
1937 #endif
1939 bool Has64BitTimestamps() const;
1941 // --
1943 const uint8_t mMsaaSamples;
1944 mutable gfx::IntSize mRequestedSize;
1945 mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
1946 mutable bool mDefaultFB_IsInvalid = false;
1947 mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
1949 // --
1951 bool EnsureDefaultFB();
1952 bool ValidateAndInitFB(const WebGLFramebuffer* fb);
1953 void DoBindFB(const WebGLFramebuffer* fb,
1954 GLenum target = LOCAL_GL_FRAMEBUFFER) const;
1956 bool BindCurFBForDraw();
1957 bool BindCurFBForColorRead(const webgl::FormatUsageInfo** out_format,
1958 uint32_t* out_width, uint32_t* out_height);
1959 void DoColorMask(uint8_t bitmask) const;
1960 void BlitBackbufferToCurDriverFB() const;
1961 bool BindDefaultFBForRead();
1963 // --
1965 public:
1966 void LoseOldestWebGLContextIfLimitExceeded();
1967 void UpdateLastUseIndex();
1969 template <typename WebGLObjectType>
1970 JS::Value WebGLObjectAsJSValue(JSContext* cx, const WebGLObjectType*,
1971 ErrorResult& rv) const;
1972 template <typename WebGLObjectType>
1973 JSObject* WebGLObjectAsJSObject(JSContext* cx, const WebGLObjectType*,
1974 ErrorResult& rv) const;
1976 public:
1977 // console logging helpers
1978 void GenerateWarning(const char* fmt, ...) const MOZ_FORMAT_PRINTF(2, 3);
1979 void GenerateWarning(const char* fmt, va_list ap) const
1980 MOZ_FORMAT_PRINTF(2, 0);
1982 void GeneratePerfWarning(const char* fmt, ...) const MOZ_FORMAT_PRINTF(2, 3);
1984 public:
1985 UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
1987 virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
1988 gl::GLContext* gl) const = 0;
1990 const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
1992 void UpdateMaxDrawBuffers();
1994 // --
1995 private:
1996 webgl::AvailabilityRunnable* mAvailabilityRunnable = nullptr;
1998 public:
1999 webgl::AvailabilityRunnable* EnsureAvailabilityRunnable();
2001 // -
2003 // Friend list
2004 friend class ScopedCopyTexImageSource;
2005 friend class ScopedResolveTexturesForDraw;
2006 friend class ScopedUnpackReset;
2007 friend class webgl::TexUnpackBlob;
2008 friend class webgl::TexUnpackBytes;
2009 friend class webgl::TexUnpackImage;
2010 friend class webgl::TexUnpackSurface;
2011 friend struct webgl::UniformInfo;
2012 friend class WebGLTexture;
2013 friend class WebGLFBAttachPoint;
2014 friend class WebGLFramebuffer;
2015 friend class WebGLRenderbuffer;
2016 friend class WebGLProgram;
2017 friend class WebGLQuery;
2018 friend class WebGLBuffer;
2019 friend class WebGLSampler;
2020 friend class WebGLShader;
2021 friend class WebGLSync;
2022 friend class WebGLTransformFeedback;
2023 friend class WebGLUniformLocation;
2024 friend class WebGLVertexArray;
2025 friend class WebGLVertexArrayFake;
2026 friend class WebGLVertexArrayGL;
2029 // used by DOM bindings in conjunction with GetParentObject
2030 inline nsISupports* ToSupports(WebGLContext* webgl) {
2031 return static_cast<nsICanvasRenderingContextInternal*>(webgl);
2034 // Returns `value` rounded to the next highest multiple of `multiple`.
2035 // AKA PadToAlignment, StrideForAlignment.
2036 template <typename V, typename M>
2037 V RoundUpToMultipleOf(const V& value, const M& multiple) {
2038 return ((value + multiple - 1) / multiple) * multiple;
2041 const char* GetEnumName(GLenum val, const char* defaultRet = "<unknown>");
2042 std::string EnumString(GLenum val);
2044 bool ValidateTexTarget(WebGLContext* webgl, uint8_t funcDims,
2045 GLenum rawTexTarget, TexTarget* const out_texTarget,
2046 WebGLTexture** const out_tex);
2047 bool ValidateTexImageTarget(WebGLContext* webgl, uint8_t funcDims,
2048 GLenum rawTexImageTarget,
2049 TexImageTarget* const out_texImageTarget,
2050 WebGLTexture** const out_tex);
2052 class ScopedUnpackReset final : public gl::ScopedGLWrapper<ScopedUnpackReset> {
2053 friend struct gl::ScopedGLWrapper<ScopedUnpackReset>;
2055 private:
2056 const WebGLContext* const mWebGL;
2058 public:
2059 explicit ScopedUnpackReset(const WebGLContext* webgl);
2061 private:
2062 void UnwrapImpl();
2065 class ScopedFBRebinder final : public gl::ScopedGLWrapper<ScopedFBRebinder> {
2066 friend struct gl::ScopedGLWrapper<ScopedFBRebinder>;
2068 private:
2069 const WebGLContext* const mWebGL;
2071 public:
2072 explicit ScopedFBRebinder(const WebGLContext* const webgl)
2073 : ScopedGLWrapper<ScopedFBRebinder>(webgl->gl), mWebGL(webgl) {}
2075 private:
2076 void UnwrapImpl();
2079 class ScopedLazyBind final : public gl::ScopedGLWrapper<ScopedLazyBind> {
2080 friend struct gl::ScopedGLWrapper<ScopedLazyBind>;
2082 const GLenum mTarget;
2083 const WebGLBuffer* const mBuf;
2085 public:
2086 ScopedLazyBind(gl::GLContext* gl, GLenum target, const WebGLBuffer* buf);
2088 private:
2089 void UnwrapImpl();
2092 ////
2094 bool Intersect(int32_t srcSize, int32_t read0, int32_t readSize,
2095 int32_t* out_intRead0, int32_t* out_intWrite0,
2096 int32_t* out_intSize);
2098 uint64_t AvailGroups(uint64_t totalAvailItems, uint64_t firstItemOffset,
2099 uint32_t groupSize, uint32_t groupStride);
2101 ////
2103 class ScopedDrawCallWrapper final {
2104 public:
2105 WebGLContext& mWebGL;
2107 explicit ScopedDrawCallWrapper(WebGLContext& webgl);
2108 ~ScopedDrawCallWrapper();
2111 namespace webgl {
2112 class ScopedPrepForResourceClear final {
2113 const WebGLContext& webgl;
2115 public:
2116 explicit ScopedPrepForResourceClear(const WebGLContext&);
2117 ~ScopedPrepForResourceClear();
2119 } // namespace webgl
2121 ////
2123 void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
2124 const std::vector<IndexedBufferBinding>& field,
2125 const char* name, uint32_t flags = 0);
2127 void ImplCycleCollectionUnlink(std::vector<IndexedBufferBinding>& field);
2129 } // namespace mozilla
2131 #endif