1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
5 
6 #ifndef WEBGLCONTEXT_H_
7 #define WEBGLCONTEXT_H_
8 
9 #include <stdarg.h>
10 
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/TypedArray.h"
18 #include "mozilla/EnumeratedArray.h"
19 #include "mozilla/ErrorResult.h"
20 #include "mozilla/gfx/2D.h"
21 #include "mozilla/LinkedList.h"
22 #include "mozilla/UniquePtr.h"
23 #include "nsCycleCollectionNoteChild.h"
24 #include "nsICanvasRenderingContextInternal.h"
25 #include "nsLayoutUtils.h"
26 #include "nsTArray.h"
27 #include "nsWrapperCache.h"
28 #include "SurfaceTypes.h"
29 #include "ScopedGLHelpers.h"
30 #include "TexUnpackBlob.h"
31 
32 #ifdef XP_MACOSX
33 #include "ForceDiscreteGPUHelperCGL.h"
34 #endif
35 
36 // Local
37 #include "WebGLContextLossHandler.h"
38 #include "WebGLContextUnchecked.h"
39 #include "WebGLFormats.h"
40 #include "WebGLObjectModel.h"
41 #include "WebGLStrongTypes.h"
42 #include "WebGLTexture.h"
43 
44 // Generated
45 #include "nsIDOMEventListener.h"
46 #include "nsIDOMWebGLRenderingContext.h"
47 #include "nsICanvasRenderingContextInternal.h"
48 #include "nsIObserver.h"
49 #include "mozilla/dom/HTMLCanvasElement.h"
50 #include "nsWrapperCache.h"
51 #include "nsLayoutUtils.h"
52 #include "mozilla/dom/WebGLRenderingContextBinding.h"
53 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
54 
55 class nsIDocShell;
56 
57 /*
58  * Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
59  *   https://bugzilla.mozilla.org/show_bug.cgi?id=686732
60  *
61  * Exceptions: some of the following values are set to higher values than in the spec because
62  * the values in the spec are ridiculously low. They are explicitly marked below
63  */
64 #define MINVALUE_GL_MAX_TEXTURE_SIZE                  1024  // Different from the spec, which sets it to 64 on page 162
65 #define MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE         512   // Different from the spec, which sets it to 16 on page 162
66 #define MINVALUE_GL_MAX_VERTEX_ATTRIBS                8     // Page 164
67 #define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS      16    // Page 164
68 #define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS        128   // Page 164
69 #define MINVALUE_GL_MAX_VARYING_VECTORS               8     // Page 164
70 #define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS           8     // Page 164
71 #define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS    0     // Page 164
72 #define MINVALUE_GL_MAX_RENDERBUFFER_SIZE             1024  // Different from the spec, which sets it to 1 on page 164
73 #define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS  8     // Page 164
74 
75 /*
76  * Minimum value constants define in 6.2 State Tables of OpenGL ES - 3.0.4
77  */
78 #define MINVALUE_GL_MAX_3D_TEXTURE_SIZE             256
79 #define MINVALUE_GL_MAX_ARRAY_TEXTURE_LAYERS        256
80 
81 /*
82  * WebGL-only GLenums
83  */
84 #define LOCAL_GL_BROWSER_DEFAULT_WEBGL                       0x9244
85 #define LOCAL_GL_CONTEXT_LOST_WEBGL                          0x9242
86 #define LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL               0x9247
87 #define LOCAL_GL_UNPACK_COLORSPACE_CONVERSION_WEBGL          0x9243
88 #define LOCAL_GL_UNPACK_FLIP_Y_WEBGL                         0x9240
89 #define LOCAL_GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL              0x9241
90 
91 namespace mozilla {
92 class ScopedCopyTexImageSource;
93 class ScopedResolveTexturesForDraw;
94 class ScopedUnpackReset;
95 class WebGLActiveInfo;
96 class WebGLBuffer;
97 class WebGLExtensionBase;
98 class WebGLFramebuffer;
99 class WebGLProgram;
100 class WebGLQuery;
101 class WebGLRenderbuffer;
102 class WebGLSampler;
103 class WebGLShader;
104 class WebGLShaderPrecisionFormat;
105 class WebGLSync;
106 class WebGLTexture;
107 class WebGLTransformFeedback;
108 class WebGLUniformLocation;
109 class WebGLVertexArray;
110 
111 namespace dom {
112 class Element;
113 class ImageData;
114 class OwningHTMLCanvasElementOrOffscreenCanvas;
115 struct WebGLContextAttributes;
116 template<typename> struct Nullable;
117 } // namespace dom
118 
119 namespace gfx {
120 class SourceSurface;
121 class VRLayerChild;
122 } // namespace gfx
123 
124 namespace webgl {
125 struct LinkedProgramInfo;
126 class ShaderValidator;
127 class TexUnpackBlob;
128 struct UniformInfo;
129 struct UniformBlockInfo;
130 } // namespace webgl
131 
132 WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
133 
134 void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
135 
136 struct WebGLContextOptions
137 {
138     // these are defaults
139     WebGLContextOptions();
140 
141     bool operator==(const WebGLContextOptions& other) const {
142         return
143             alpha == other.alpha &&
144             depth == other.depth &&
145             stencil == other.stencil &&
146             premultipliedAlpha == other.premultipliedAlpha &&
147             antialias == other.antialias &&
148             preserveDrawingBuffer == other.preserveDrawingBuffer;
149     }
150 
151     bool operator!=(const WebGLContextOptions& other) const {
152         return !operator==(other);
153     }
154 
155     bool alpha;
156     bool depth;
157     bool stencil;
158     bool premultipliedAlpha;
159     bool antialias;
160     bool preserveDrawingBuffer;
161     bool failIfMajorPerformanceCaveat;
162 };
163 
164 // From WebGLContextUtils
165 TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
166 
167 struct WebGLIntOrFloat {
168     const enum {
169         Int,
170         Float,
171         Uint
172     } mType;
173 
174     union {
175         GLint i;
176         GLfloat f;
177         GLuint u;
178     } mValue;
179 
WebGLIntOrFloatWebGLIntOrFloat180     explicit WebGLIntOrFloat(GLint i) : mType(Int) { mValue.i = i; }
WebGLIntOrFloatWebGLIntOrFloat181     explicit WebGLIntOrFloat(GLfloat f) : mType(Float) { mValue.f = f; }
182 
AsIntWebGLIntOrFloat183     GLint AsInt() const { return (mType == Int) ? mValue.i : NS_lroundf(mValue.f); }
AsFloatWebGLIntOrFloat184     GLfloat AsFloat() const { return (mType == Float) ? mValue.f : GLfloat(mValue.i); }
185 };
186 
187 struct IndexedBufferBinding
188 {
189     WebGLRefPtr<WebGLBuffer> mBufferBinding;
190     uint64_t mRangeStart;
191     uint64_t mRangeSize;
192 
193     IndexedBufferBinding();
194 
195     uint64_t ByteCount() const;
196 };
197 
198 ////
199 
200 struct FloatOrInt final // For TexParameter[fi] and friends.
201 {
202     const bool isFloat;
203     const GLfloat f;
204     const GLint i;
205 
FloatOrIntfinal206     explicit FloatOrInt(GLint x)
207         : isFloat(false)
208         , f(x)
209         , i(x)
210     { }
211 
FloatOrIntfinal212     explicit FloatOrInt(GLfloat x)
213         : isFloat(true)
214         , f(x)
215         , i(roundf(x))
216     { }
217 
218     FloatOrInt& operator =(const FloatOrInt& x) {
219         memcpy(this, &x, sizeof(x));
220         return *this;
221     }
222 };
223 
224 ////////////////////////////////////
225 
226 struct TexImageSource
227 {
228     const dom::ArrayBufferView* mView;
229     GLuint mViewElemOffset;
230     GLuint mViewElemLengthOverride;
231 
232     const WebGLsizeiptr* mPboOffset;
233 
234     const dom::ImageBitmap* mImageBitmap;
235     const dom::ImageData* mImageData;
236 
237     const dom::Element* mDomElem;
238     ErrorResult* mOut_error;
239 
240 protected:
TexImageSourceTexImageSource241     TexImageSource() {
242         memset(this, 0, sizeof(*this));
243     }
244 };
245 
246 ////
247 
248 struct TexImageSourceAdapter final : public TexImageSource
249 {
TexImageSourceAdapterfinal250     TexImageSourceAdapter(const dom::Nullable<dom::ArrayBufferView>* maybeView,
251                           ErrorResult*)
252     {
253         if (!maybeView->IsNull()) {
254             mView = &(maybeView->Value());
255         }
256     }
257 
TexImageSourceAdapterfinal258     TexImageSourceAdapter(const dom::ArrayBufferView* view, ErrorResult*) {
259         mView = view;
260     }
261 
262     TexImageSourceAdapter(const dom::ArrayBufferView* view, GLuint viewElemOffset,
263                           GLuint viewElemLengthOverride = 0)
264     {
265         mView = view;
266         mViewElemOffset = viewElemOffset;
267         mViewElemLengthOverride = viewElemLengthOverride;
268     }
269 
270     TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, GLuint ignored1, GLuint ignored2 = 0) {
271         mPboOffset = pboOffset;
272     }
273 
TexImageSourceAdapterfinal274     TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, ErrorResult* ignored) {
275         mPboOffset = pboOffset;
276     }
277 
TexImageSourceAdapterfinal278     TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult*) {
279         mImageBitmap = imageBitmap;
280     }
281 
TexImageSourceAdapterfinal282     TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {
283         mImageData = imageData;
284     }
285 
TexImageSourceAdapterfinal286     TexImageSourceAdapter(const dom::Element* domElem, ErrorResult* const out_error) {
287         mDomElem = domElem;
288         mOut_error = out_error;
289     }
290 };
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 
294 class WebGLContext
295     : public nsIDOMWebGLRenderingContext
296     , public nsICanvasRenderingContextInternal
297     , public nsSupportsWeakReference
298     , public WebGLContextUnchecked
299     , public WebGLRectangleObject
300     , public nsWrapperCache
301 {
302     friend class ScopedDrawHelper;
303     friend class ScopedDrawWithTransformFeedback;
304     friend class ScopedFBRebinder;
305     friend class WebGL2Context;
306     friend class WebGLContextUserData;
307     friend class WebGLExtensionCompressedTextureATC;
308     friend class WebGLExtensionCompressedTextureES3;
309     friend class WebGLExtensionCompressedTextureETC1;
310     friend class WebGLExtensionCompressedTexturePVRTC;
311     friend class WebGLExtensionCompressedTextureS3TC;
312     friend class WebGLExtensionDepthTexture;
313     friend class WebGLExtensionDisjointTimerQuery;
314     friend class WebGLExtensionDrawBuffers;
315     friend class WebGLExtensionLoseContext;
316     friend class WebGLExtensionVertexArray;
317     friend class WebGLMemoryTracker;
318     friend struct webgl::UniformBlockInfo;
319 
320     enum {
321         UNPACK_FLIP_Y_WEBGL = 0x9240,
322         UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
323         CONTEXT_LOST_WEBGL = 0x9242,
324         UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243,
325         BROWSER_DEFAULT_WEBGL = 0x9244,
326         UNMASKED_VENDOR_WEBGL = 0x9245,
327         UNMASKED_RENDERER_WEBGL = 0x9246
328     };
329 
330     static const uint32_t kMinMaxColorAttachments;
331     static const uint32_t kMinMaxDrawBuffers;
332 
333 public:
334     WebGLContext();
335 
336 protected:
337     virtual ~WebGLContext();
338 
339 public:
340     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
341 
342     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
343                                                            nsIDOMWebGLRenderingContext)
344 
345     virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override = 0;
346 
347     NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
348 
349     virtual void OnVisibilityChange() override;
350     virtual void OnMemoryPressure() override;
351 
352     // nsICanvasRenderingContextInternal
353     virtual int32_t GetWidth() const override;
354     virtual int32_t GetHeight() const override;
355 
356     NS_IMETHOD SetDimensions(int32_t width, int32_t height) override;
InitializeWithDrawTarget(nsIDocShell *,NotNull<gfx::DrawTarget * >)357     NS_IMETHOD InitializeWithDrawTarget(nsIDocShell*,
358                                         NotNull<gfx::DrawTarget*>) override
359     {
360         return NS_ERROR_NOT_IMPLEMENTED;
361     }
362 
Reset()363     NS_IMETHOD Reset() override {
364         /* (InitializeWithSurface) */
365         return NS_ERROR_NOT_IMPLEMENTED;
366     }
367 
368     virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* out_format) override;
369     NS_IMETHOD GetInputStream(const char* mimeType,
370                               const char16_t* encoderOptions,
371                               nsIInputStream** out_stream) override;
372 
373     already_AddRefed<mozilla::gfx::SourceSurface>
374     GetSurfaceSnapshot(bool* out_premultAlpha) override;
375 
SetIsOpaque(bool)376     NS_IMETHOD SetIsOpaque(bool) override { return NS_OK; };
GetIsOpaque()377     bool GetIsOpaque() override { return false; }
378     NS_IMETHOD SetContextOptions(JSContext* cx,
379                                  JS::Handle<JS::Value> options,
380                                  ErrorResult& aRvForDictionaryInit) override;
381 
SetIsIPC(bool)382     NS_IMETHOD SetIsIPC(bool) override {
383         return NS_ERROR_NOT_IMPLEMENTED;
384     }
385 
386     /**
387      * An abstract base class to be implemented by callers wanting to be notified
388      * that a refresh has occurred. Callers must ensure an observer is removed
389      * before it is destroyed.
390      */
391     virtual void DidRefresh() override;
392 
Redraw(const gfxRect &)393     NS_IMETHOD Redraw(const gfxRect&) override {
394         return NS_ERROR_NOT_IMPLEMENTED;
395     }
396 
397     void SynthesizeGLError(GLenum err);
398     void SynthesizeGLError(GLenum err, const char* fmt, ...);
399 
400     void ErrorInvalidEnum(const char* fmt = 0, ...);
401     void ErrorInvalidOperation(const char* fmt = 0, ...);
402     void ErrorInvalidValue(const char* fmt = 0, ...);
403     void ErrorInvalidFramebufferOperation(const char* fmt = 0, ...);
404     void ErrorInvalidEnumInfo(const char* info, GLenum enumValue);
405     void ErrorInvalidEnumInfo(const char* info, const char* funcName,
406                               GLenum enumValue);
407     void ErrorOutOfMemory(const char* fmt = 0, ...);
408     void ErrorImplementationBug(const char* fmt = 0, ...);
409 
410     void ErrorInvalidEnumArg(const char* funcName, const char* argName, GLenum val);
411 
412     const char* ErrorName(GLenum error);
413 
414     /**
415      * Return displayable name for GLenum.
416      * This version is like gl::GLenumToStr but with out the GL_ prefix to
417      * keep consistency with how errors are reported from WebGL.
418      * Returns hex formatted version of glenum if glenum is unknown.
419      */
420     static void EnumName(GLenum val, nsCString* out_name);
421 
422     void DummyReadFramebufferOperation(const char* funcName);
423 
ActiveBoundTextureForTarget(const TexTarget texTarget)424     WebGLTexture* ActiveBoundTextureForTarget(const TexTarget texTarget) const {
425         switch (texTarget.get()) {
426         case LOCAL_GL_TEXTURE_2D:
427             return mBound2DTextures[mActiveTexture];
428         case LOCAL_GL_TEXTURE_CUBE_MAP:
429             return mBoundCubeMapTextures[mActiveTexture];
430         case LOCAL_GL_TEXTURE_3D:
431             return mBound3DTextures[mActiveTexture];
432         case LOCAL_GL_TEXTURE_2D_ARRAY:
433             return mBound2DArrayTextures[mActiveTexture];
434         default:
435             MOZ_CRASH("GFX: bad target");
436         }
437     }
438 
439     /* Use this function when you have the texture image target, for example:
440      * GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_[POSITIVE|NEGATIVE]_[X|Y|Z], and
441      * not the actual texture binding target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
442      */
443     WebGLTexture*
ActiveBoundTextureForTexImageTarget(const TexImageTarget texImgTarget)444     ActiveBoundTextureForTexImageTarget(const TexImageTarget texImgTarget) const
445     {
446         const TexTarget texTarget = TexImageTargetToTexTarget(texImgTarget);
447         return ActiveBoundTextureForTarget(texTarget);
448     }
449 
450     void InvalidateResolveCacheForTextureWithTexUnit(const GLuint);
451 
452     already_AddRefed<Layer>
453     GetCanvasLayer(nsDisplayListBuilder* builder, Layer* oldLayer,
454                    LayerManager* manager,
455                    bool aMirror = false) override;
456 
457     // Note that 'clean' here refers to its invalidation state, not the
458     // contents of the buffer.
MarkContextClean()459     void MarkContextClean() override { mInvalidated = false; }
460 
MarkContextCleanForFrameCapture()461     void MarkContextCleanForFrameCapture() override { mCapturedFrameInvalidated = false; }
462 
IsContextCleanForFrameCapture()463     bool IsContextCleanForFrameCapture() override { return !mCapturedFrameInvalidated; }
464 
GL()465     gl::GLContext* GL() const { return gl; }
466 
IsPremultAlpha()467     bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
468 
IsPreservingDrawingBuffer()469     bool IsPreservingDrawingBuffer() const { return mOptions.preserveDrawingBuffer; }
470 
471     bool PresentScreenBuffer();
472 
473     // Prepare the context for capture before compositing
474     void BeginComposition();
475     // Clean up the context after captured for compositing
476     void EndComposition();
477 
478     // a number that increments every time we have an event that causes
479     // all context resources to be lost.
Generation()480     uint32_t Generation() const { return mGeneration.value(); }
481 
482     // This is similar to GLContext::ClearSafely, but tries to minimize the
483     // amount of work it does.
484     // It only clears the buffers we specify, and can reset its state without
485     // first having to query anything, as WebGL knows its state at all times.
486     void ForceClearFramebufferWithDefaultValues(GLbitfield bufferBits, bool fakeNoAlpha);
487 
488     // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
489     void ClearScreen();
490     void ClearBackbufferIfNeeded();
491 
MinCapabilityMode()492     bool MinCapabilityMode() const { return mMinCapability; }
493 
494     void RunContextLossTimer();
495     void UpdateContextLossStatus();
496     void EnqueueUpdateContextLossStatus();
497 
498     bool TryToRestoreContext();
499 
500     void AssertCachedBindings();
501     void AssertCachedGlobalState();
502 
GetCanvas()503     dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
504 
505     // WebIDL WebGLRenderingContext API
506     void Commit();
507     void GetCanvas(Nullable<dom::OwningHTMLCanvasElementOrOffscreenCanvas>& retval);
DrawingBufferWidth()508     GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; }
DrawingBufferHeight()509     GLsizei DrawingBufferHeight() const {
510         return IsContextLost() ? 0 : mHeight;
511     }
512 
513     layers::LayersBackend GetCompositorBackendType() const;
514 
515     void
516     GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
517 
IsContextLost()518     bool IsContextLost() const { return mContextStatus != ContextNotLost; }
519     void GetSupportedExtensions(dom::Nullable< nsTArray<nsString> >& retval,
520                                 dom::CallerType callerType);
521     void GetExtension(JSContext* cx, const nsAString& name,
522                       JS::MutableHandle<JSObject*> retval,
523                       dom::CallerType callerType, ErrorResult& rv);
524     void AttachShader(WebGLProgram& prog, WebGLShader& shader);
525     void BindAttribLocation(WebGLProgram& prog, GLuint location,
526                             const nsAString& name);
527     void BindFramebuffer(GLenum target, WebGLFramebuffer* fb);
528     void BindRenderbuffer(GLenum target, WebGLRenderbuffer* fb);
529     void BindVertexArray(WebGLVertexArray* vao);
530     void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
531     void BlendEquation(GLenum mode);
532     void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
533     void BlendFunc(GLenum sfactor, GLenum dfactor);
534     void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
535                            GLenum srcAlpha, GLenum dstAlpha);
536     GLenum CheckFramebufferStatus(GLenum target);
537     void Clear(GLbitfield mask);
538     void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
539     void ClearDepth(GLclampf v);
540     void ClearStencil(GLint v);
541     void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a);
542     void CompileShader(WebGLShader& shader);
543     void CompileShaderANGLE(WebGLShader* shader);
544     void CompileShaderBypass(WebGLShader* shader, const nsCString& shaderSource);
545     already_AddRefed<WebGLFramebuffer> CreateFramebuffer();
546     already_AddRefed<WebGLProgram> CreateProgram();
547     already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer();
548     already_AddRefed<WebGLShader> CreateShader(GLenum type);
549     already_AddRefed<WebGLVertexArray> CreateVertexArray();
550     void CullFace(GLenum face);
551     void DeleteFramebuffer(WebGLFramebuffer* fb);
552     void DeleteProgram(WebGLProgram* prog);
553     void DeleteRenderbuffer(WebGLRenderbuffer* rb);
554     void DeleteShader(WebGLShader* shader);
555     void DeleteVertexArray(WebGLVertexArray* vao);
556     void DepthFunc(GLenum func);
557     void DepthMask(WebGLboolean b);
558     void DepthRange(GLclampf zNear, GLclampf zFar);
559     void DetachShader(WebGLProgram& prog, const WebGLShader& shader);
560     void DrawBuffers(const dom::Sequence<GLenum>& buffers);
561     void Flush();
562     void Finish();
563     void FramebufferRenderbuffer(GLenum target, GLenum attachment,
564                                  GLenum rbTarget, WebGLRenderbuffer* rb);
565     void FramebufferTexture2D(GLenum target, GLenum attachment,
566                               GLenum texImageTarget, WebGLTexture* tex,
567                               GLint level);
568 
569     void FrontFace(GLenum mode);
570     already_AddRefed<WebGLActiveInfo> GetActiveAttrib(const WebGLProgram& prog,
571                                                       GLuint index);
572     already_AddRefed<WebGLActiveInfo> GetActiveUniform(const WebGLProgram& prog,
573                                                        GLuint index);
574 
575     void
576     GetAttachedShaders(const WebGLProgram& prog,
577                        dom::Nullable<nsTArray<RefPtr<WebGLShader>>>& retval);
578 
579     GLint GetAttribLocation(const WebGLProgram& prog, const nsAString& name);
580     JS::Value GetBufferParameter(GLenum target, GLenum pname);
581 
GetBufferParameter(JSContext *,GLenum target,GLenum pname,JS::MutableHandle<JS::Value> retval)582     void GetBufferParameter(JSContext*, GLenum target, GLenum pname,
583                             JS::MutableHandle<JS::Value> retval)
584     {
585         retval.set(GetBufferParameter(target, pname));
586     }
587 
588     GLenum GetError();
589     virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
590                                                         GLenum attachment, GLenum pname,
591                                                         ErrorResult& rv);
592 
GetFramebufferAttachmentParameter(JSContext * cx,GLenum target,GLenum attachment,GLenum pname,JS::MutableHandle<JS::Value> retval,ErrorResult & rv)593     void GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
594                                            GLenum attachment, GLenum pname,
595                                            JS::MutableHandle<JS::Value> retval,
596                                            ErrorResult& rv)
597     {
598         retval.set(GetFramebufferAttachmentParameter(cx, target, attachment,
599                                                      pname, rv));
600     }
601 
602     JS::Value GetProgramParameter(const WebGLProgram& prog, GLenum pname);
603 
GetProgramParameter(JSContext *,const WebGLProgram & prog,GLenum pname,JS::MutableHandle<JS::Value> retval)604     void  GetProgramParameter(JSContext*, const WebGLProgram& prog, GLenum pname,
605                               JS::MutableHandle<JS::Value> retval)
606     {
607         retval.set(GetProgramParameter(prog, pname));
608     }
609 
610     void GetProgramInfoLog(const WebGLProgram& prog, nsACString& retval);
611     void GetProgramInfoLog(const WebGLProgram& prog, nsAString& retval);
612     JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
613 
GetRenderbufferParameter(JSContext *,GLenum target,GLenum pname,JS::MutableHandle<JS::Value> retval)614     void GetRenderbufferParameter(JSContext*, GLenum target, GLenum pname,
615                                   JS::MutableHandle<JS::Value> retval)
616     {
617         retval.set(GetRenderbufferParameter(target, pname));
618     }
619 
620     JS::Value GetShaderParameter(const WebGLShader& shader, GLenum pname);
621 
GetShaderParameter(JSContext *,const WebGLShader & shader,GLenum pname,JS::MutableHandle<JS::Value> retval)622     void GetShaderParameter(JSContext*, const WebGLShader& shader, GLenum pname,
623                             JS::MutableHandle<JS::Value> retval)
624     {
625         retval.set(GetShaderParameter(shader, pname));
626     }
627 
628     already_AddRefed<WebGLShaderPrecisionFormat>
629     GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
630 
631     void GetShaderInfoLog(const WebGLShader& shader, nsACString& retval);
632     void GetShaderInfoLog(const WebGLShader& shader, nsAString& retval);
633     void GetShaderSource(const WebGLShader& shader, nsAString& retval);
634 
635     JS::Value GetUniform(JSContext* cx, const WebGLProgram& prog,
636                          const WebGLUniformLocation& loc);
637 
GetUniform(JSContext * cx,const WebGLProgram & prog,const WebGLUniformLocation & loc,JS::MutableHandle<JS::Value> retval)638     void GetUniform(JSContext* cx, const WebGLProgram& prog,
639                     const WebGLUniformLocation& loc,
640                     JS::MutableHandle<JS::Value> retval)
641     {
642         retval.set(GetUniform(cx, prog, loc));
643     }
644 
645     already_AddRefed<WebGLUniformLocation>
646     GetUniformLocation(const WebGLProgram& prog, const nsAString& name);
647 
648     void Hint(GLenum target, GLenum mode);
649     bool IsFramebuffer(const WebGLFramebuffer* fb);
650     bool IsProgram(const WebGLProgram* prog);
651     bool IsRenderbuffer(const WebGLRenderbuffer* rb);
652     bool IsShader(const WebGLShader* shader);
653     bool IsVertexArray(const WebGLVertexArray* vao);
654     void LineWidth(GLfloat width);
655     void LinkProgram(WebGLProgram& prog);
656     void PixelStorei(GLenum pname, GLint param);
657     void PolygonOffset(GLfloat factor, GLfloat units);
658 
659     already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
660     bool StartVRPresentation();
661 
662     ////
663 
664     webgl::PackingInfo
665     ValidImplementationColorReadPI(const webgl::FormatUsageInfo* usage) const;
666 
667 protected:
668     bool ReadPixels_SharedPrecheck(ErrorResult* const out_error);
669     void ReadPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
670                         GLenum type, void* data, uint32_t dataLen);
671     bool DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat, GLint x, GLint y,
672                                 GLsizei width, GLsizei height, GLenum format,
673                                 GLenum destType, void* dest, uint32_t dataLen,
674                                 uint32_t rowStride);
675 public:
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,const dom::Nullable<dom::ArrayBufferView> & maybeView,ErrorResult & rv)676     void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
677                     GLenum type, const dom::Nullable<dom::ArrayBufferView>& maybeView,
678                     ErrorResult& rv)
679     {
680         const char funcName[] = "readPixels";
681         if (maybeView.IsNull()) {
682             ErrorInvalidValue("%s: `pixels` must not be null.", funcName);
683             return;
684         }
685         ReadPixels(x, y, width, height, format, type, maybeView.Value(), 0, rv);
686     }
687 
688     void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
689                     GLenum type, WebGLsizeiptr offset, ErrorResult& out_error);
690 
691     void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
692                     GLenum type, const dom::ArrayBufferView& dstData, GLuint dstOffset,
693                     ErrorResult& out_error);
694 
695     ////
696 
697     void RenderbufferStorage(GLenum target, GLenum internalFormat,
698                              GLsizei width, GLsizei height);
699 protected:
700     void RenderbufferStorage_base(const char* funcName, GLenum target,
701                                   GLsizei samples, GLenum internalformat,
702                                   GLsizei width, GLsizei height);
703 public:
704     void SampleCoverage(GLclampf value, WebGLboolean invert);
705     void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
706     void ShaderSource(WebGLShader& shader, const nsAString& source);
707     void StencilFunc(GLenum func, GLint ref, GLuint mask);
708     void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
709     void StencilMask(GLuint mask);
710     void StencilMaskSeparate(GLenum face, GLuint mask);
711     void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
712     void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
713                            GLenum dppass);
714 
715     //////
716 
717     void Uniform1f(WebGLUniformLocation* loc, GLfloat x);
718     void Uniform2f(WebGLUniformLocation* loc, GLfloat x, GLfloat y);
719     void Uniform3f(WebGLUniformLocation* loc, GLfloat x, GLfloat y, GLfloat z);
720     void Uniform4f(WebGLUniformLocation* loc, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
721 
722     void Uniform1i(WebGLUniformLocation* loc, GLint x);
723     void Uniform2i(WebGLUniformLocation* loc, GLint x, GLint y);
724     void Uniform3i(WebGLUniformLocation* loc, GLint x, GLint y, GLint z);
725     void Uniform4i(WebGLUniformLocation* loc, GLint x, GLint y, GLint z, GLint w);
726 
727     void Uniform1ui(WebGLUniformLocation* loc, GLuint v0);
728     void Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1);
729     void Uniform3ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2);
730     void Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2,
731                     GLuint v3);
732 
733     //////////////////////////
734 
735     typedef dom::Float32ArrayOrUnrestrictedFloatSequence Float32ListU;
736     typedef dom::Int32ArrayOrLongSequence Int32ListU;
737     typedef dom::Uint32ArrayOrUnsignedLongSequence Uint32ListU;
738 
739 protected:
740     template<typename elemT, typename viewT>
741     struct Arr {
742         const size_t elemCount;
743         const elemT* const elemBytes;
744 
745     private:
ComputeAndReturnLengthArr746         static size_t ComputeAndReturnLength(const viewT& view) {
747             view.ComputeLengthAndData();
748             return view.LengthAllowShared();
749         }
750 
751     public:
ArrArr752         explicit Arr(const viewT& view)
753             : elemCount(ComputeAndReturnLength(view))
754             , elemBytes(view.DataAllowShared())
755         { }
756 
ArrArr757         explicit Arr(const dom::Sequence<elemT>& seq)
758             : elemCount(seq.Length())
759             , elemBytes(seq.Elements())
760         { }
761 
ArrArr762         Arr(size_t _elemCount, const elemT* _elemBytes)
763             : elemCount(_elemCount)
764             , elemBytes(_elemBytes)
765         { }
766 
767         ////
768 
FromArr769         static Arr From(const Float32ListU& list) {
770             if (list.IsFloat32Array())
771                 return Arr(list.GetAsFloat32Array());
772 
773             return Arr(list.GetAsUnrestrictedFloatSequence());
774         }
775 
FromArr776         static Arr From(const Int32ListU& list) {
777             if (list.IsInt32Array())
778                 return Arr(list.GetAsInt32Array());
779 
780             return Arr(list.GetAsLongSequence());
781         }
782 
FromArr783         static Arr From(const Uint32ListU& list) {
784             if (list.IsUint32Array())
785                 return Arr(list.GetAsUint32Array());
786 
787             return Arr(list.GetAsUnsignedLongSequence());
788         }
789     };
790 
791     typedef Arr<GLfloat, dom::Float32Array> Float32Arr;
792     typedef Arr<GLint, dom::Int32Array> Int32Arr;
793     typedef Arr<GLuint, dom::Uint32Array> Uint32Arr;
794 
795     ////////////////
796 
797     void UniformNfv(const char* funcName, uint8_t N, WebGLUniformLocation* loc,
798                     const Float32Arr& arr, GLuint elemOffset, GLuint elemCountOverride);
799     void UniformNiv(const char* funcName, uint8_t N, WebGLUniformLocation* loc,
800                     const Int32Arr& arr, GLuint elemOffset, GLuint elemCountOverride);
801     void UniformNuiv(const char* funcName, uint8_t N, WebGLUniformLocation* loc,
802                      const Uint32Arr& arr, GLuint elemOffset, GLuint elemCountOverride);
803 
804     void UniformMatrixAxBfv(const char* funcName, uint8_t A, uint8_t B,
805                             WebGLUniformLocation* loc, bool transpose,
806                             const Float32Arr& arr, GLuint elemOffset,
807                             GLuint elemCountOverride);
808 
809     ////////////////
810 
811 public:
812     #define FOO(N) \
813         void Uniform ## N ## fv(WebGLUniformLocation* loc, const Float32ListU& list,  \
814                                 GLuint elemOffset = 0, GLuint elemCountOverride = 0)  \
815         {                                                                             \
816             UniformNfv("uniform" #N "fv", N, loc, Float32Arr::From(list), elemOffset, \
817                        elemCountOverride);                                            \
818         }
819 
820     FOO(1)
821     FOO(2)
822     FOO(3)
823     FOO(4)
824 
825     #undef FOO
826 
827     //////
828 
829     #define FOO(N) \
830         void Uniform ## N ## iv(WebGLUniformLocation* loc, const Int32ListU& list,   \
831                                 GLuint elemOffset = 0, GLuint elemCountOverride = 0) \
832         {                                                                            \
833             UniformNiv("uniform" #N "iv", N, loc, Int32Arr::From(list), elemOffset,  \
834                        elemCountOverride);                                           \
835         }
836 
837     FOO(1)
838     FOO(2)
839     FOO(3)
840     FOO(4)
841 
842     #undef FOO
843 
844     //////
845 
846     #define FOO(N) \
847         void Uniform ## N ## uiv(WebGLUniformLocation* loc, const Uint32ListU& list,   \
848                                  GLuint elemOffset = 0, GLuint elemCountOverride = 0)  \
849         {                                                                              \
850             UniformNuiv("uniform" #N "uiv", N, loc, Uint32Arr::From(list), elemOffset, \
851                         elemCountOverride);                                            \
852         }
853 
854     FOO(1)
855     FOO(2)
856     FOO(3)
857     FOO(4)
858 
859     #undef FOO
860 
861     //////
862 
863     #define FOO(X,A,B) \
864         void UniformMatrix ## X ## fv(WebGLUniformLocation* loc, bool transpose,       \
865                                       const Float32ListU& list, GLuint elemOffset = 0, \
866                                       GLuint elemCountOverride = 0)                    \
867         {                                                                              \
868             UniformMatrixAxBfv("uniformMatrix" #X "fv", A, B, loc, transpose,          \
869                                Float32Arr::From(list), elemOffset, elemCountOverride); \
870         }
871 
872     FOO(2,2,2)
873     FOO(2x3,2,3)
874     FOO(2x4,2,4)
875 
876     FOO(3x2,3,2)
877     FOO(3,3,3)
878     FOO(3x4,3,4)
879 
880     FOO(4x2,4,2)
881     FOO(4x3,4,3)
882     FOO(4,4,4)
883 
884     #undef FOO
885 
886     ////////////////////////////////////
887 
888     void UseProgram(WebGLProgram* prog);
889 
890     bool ValidateAttribArraySetter(const char* name, uint32_t count,
891                                    uint32_t arrayLength);
892     bool ValidateUniformLocation(WebGLUniformLocation* loc, const char* funcName);
893     bool ValidateUniformSetter(WebGLUniformLocation* loc, uint8_t setterSize,
894                                GLenum setterType, const char* funcName);
895     bool ValidateUniformArraySetter(WebGLUniformLocation* loc,
896                                     uint8_t setterElemSize, GLenum setterType,
897                                     uint32_t setterArraySize, const char* funcName,
898                                     uint32_t* out_numElementsToUpload);
899     bool ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
900                                           uint8_t setterCols,
901                                           uint8_t setterRows,
902                                           GLenum setterType,
903                                           uint32_t setterArraySize,
904                                           bool setterTranspose,
905                                           const char* funcName,
906                                           uint32_t* out_numElementsToUpload);
907     void ValidateProgram(const WebGLProgram& prog);
908     bool ValidateUniformLocation(const char* info, WebGLUniformLocation* loc);
909     bool ValidateSamplerUniformSetter(const char* info,
910                                       WebGLUniformLocation* loc, GLint value);
911     void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
912 // -----------------------------------------------------------------------------
913 // WEBGL_lose_context
914 public:
915     void LoseContext();
916     void RestoreContext();
917 
918 // -----------------------------------------------------------------------------
919 // Buffer Objects (WebGLContextBuffers.cpp)
920     void BindBuffer(GLenum target, WebGLBuffer* buffer);
921     void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buf);
922     void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buf,
923                          WebGLintptr offset, WebGLsizeiptr size);
924 
925 private:
926     void BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data, GLenum usage);
927 
928 public:
929     void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
930     void BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
931                     GLenum usage);
932     void BufferData(GLenum target, const dom::ArrayBufferView& srcData, GLenum usage,
933                     GLuint srcElemOffset = 0, GLuint srcElemCountOverride = 0);
934 
935 private:
936     void BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
937                            size_t srcDataLen, const uint8_t* srcData);
938 
939 public:
940     void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
941                        const dom::ArrayBufferView& src, GLuint srcElemOffset = 0,
942                        GLuint srcElemCountOverride = 0);
943     void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
944                        const dom::ArrayBuffer& src);
945     void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
946                        const dom::SharedArrayBuffer& src);
947 
948     already_AddRefed<WebGLBuffer> CreateBuffer();
949     void DeleteBuffer(WebGLBuffer* buf);
950     bool IsBuffer(WebGLBuffer* buf);
951 
952 protected:
953     // bound buffer state
954     WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
955     WebGLRefPtr<WebGLBuffer> mBoundCopyReadBuffer;
956     WebGLRefPtr<WebGLBuffer> mBoundCopyWriteBuffer;
957     WebGLRefPtr<WebGLBuffer> mBoundPixelPackBuffer;
958     WebGLRefPtr<WebGLBuffer> mBoundPixelUnpackBuffer;
959     WebGLRefPtr<WebGLBuffer> mBoundUniformBuffer;
960 
961     std::vector<IndexedBufferBinding> mIndexedUniformBufferBindings;
962 
963     WebGLRefPtr<WebGLBuffer>& GetBufferSlotByTarget(GLenum target);
964     WebGLRefPtr<WebGLBuffer>& GetBufferSlotByTargetIndexed(GLenum target,
965                                                            GLuint index);
966 
967 // -----------------------------------------------------------------------------
968 // Queries (WebGL2ContextQueries.cpp)
969 protected:
970     WebGLRefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
971     WebGLRefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
972     WebGLRefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
973 
974     WebGLRefPtr<WebGLQuery>*
975     ValidateQuerySlotByTarget(const char* funcName, GLenum target);
976 
977 public:
978     already_AddRefed<WebGLQuery> CreateQuery(const char* funcName = nullptr);
979     void DeleteQuery(WebGLQuery* query, const char* funcName = nullptr);
980     bool IsQuery(const WebGLQuery* query, const char* funcName = nullptr);
981     void BeginQuery(GLenum target, WebGLQuery& query, const char* funcName = nullptr);
982     void EndQuery(GLenum target, const char* funcName = nullptr);
983     void GetQuery(JSContext* cx, GLenum target, GLenum pname,
984                   JS::MutableHandleValue retval, const char* funcName = nullptr);
985     void GetQueryParameter(JSContext* cx, const WebGLQuery& query, GLenum pname,
986                            JS::MutableHandleValue retval, const char* funcName = nullptr);
987 
988 
989 // -----------------------------------------------------------------------------
990 // State and State Requests (WebGLContextState.cpp)
991 public:
992     void Disable(GLenum cap);
993     void Enable(GLenum cap);
994     bool GetStencilBits(GLint* const out_stencilBits);
995     bool GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val);
996     virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
997 
GetParameter(JSContext * cx,GLenum pname,JS::MutableHandle<JS::Value> retval,ErrorResult & rv)998     void GetParameter(JSContext* cx, GLenum pname,
999                       JS::MutableHandle<JS::Value> retval, ErrorResult& rv)
1000     {
1001         retval.set(GetParameter(cx, pname, rv));
1002     }
1003 
1004     void GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
1005                              JS::MutableHandle<JS::Value> retval);
1006     bool IsEnabled(GLenum cap);
1007 
1008 private:
1009     // State tracking slots
1010     realGLboolean mDitherEnabled;
1011     realGLboolean mRasterizerDiscardEnabled;
1012     realGLboolean mScissorTestEnabled;
1013     realGLboolean mDepthTestEnabled;
1014     realGLboolean mStencilTestEnabled;
1015     GLenum mGenerateMipmapHint;
1016 
1017     bool ValidateCapabilityEnum(GLenum cap, const char* info);
1018     realGLboolean* GetStateTrackingSlot(GLenum cap);
1019 
1020 // -----------------------------------------------------------------------------
1021 // Texture funcions (WebGLContextTextures.cpp)
1022 public:
1023     void ActiveTexture(GLenum texUnit);
1024     void BindTexture(GLenum texTarget, WebGLTexture* tex);
1025     already_AddRefed<WebGLTexture> CreateTexture();
1026     void DeleteTexture(WebGLTexture* tex);
1027     void GenerateMipmap(GLenum texTarget);
1028 
GetTexParameter(JSContext *,GLenum texTarget,GLenum pname,JS::MutableHandle<JS::Value> retval)1029     void GetTexParameter(JSContext*, GLenum texTarget, GLenum pname,
1030                          JS::MutableHandle<JS::Value> retval)
1031     {
1032         retval.set(GetTexParameter(texTarget, pname));
1033     }
1034 
1035     bool IsTexture(WebGLTexture* tex);
1036 
TexParameterf(GLenum texTarget,GLenum pname,GLfloat param)1037     void TexParameterf(GLenum texTarget, GLenum pname, GLfloat param) {
1038         TexParameter_base(texTarget, pname, FloatOrInt(param));
1039     }
1040 
TexParameteri(GLenum texTarget,GLenum pname,GLint param)1041     void TexParameteri(GLenum texTarget, GLenum pname, GLint param) {
1042         TexParameter_base(texTarget, pname, FloatOrInt(param));
1043     }
1044 
1045 protected:
1046     JS::Value GetTexParameter(GLenum texTarget, GLenum pname);
1047     void TexParameter_base(GLenum texTarget, GLenum pname, const FloatOrInt& param);
1048 
1049     virtual bool IsTexParamValid(GLenum pname) const;
1050 
1051     ////////////////////////////////////
1052 
1053 public:
1054     template<typename T>
1055     void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat,
1056                               GLsizei width, GLsizei height, GLint border,
1057                               const T& anySrc, GLuint viewElemOffset = 0,
1058                               GLuint viewElemLengthOverride = 0)
1059     {
1060         const char funcName[] = "compressedTexImage2D";
1061         const uint8_t funcDims = 2;
1062         const GLsizei depth = 1;
1063         const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
1064         CompressedTexImage(funcName, funcDims, target, level, internalFormat, width,
1065                            height, depth, border, src);
1066     }
1067 
1068     template<typename T>
1069     void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1070                                  GLsizei width, GLsizei height, GLenum unpackFormat,
1071                                  const T& anySrc, GLuint viewElemOffset = 0,
1072                                  GLuint viewElemLengthOverride = 0)
1073     {
1074         const char funcName[] = "compressedTexSubImage2D";
1075         const uint8_t funcDims = 2;
1076         const GLint zOffset = 0;
1077         const GLsizei depth = 1;
1078         const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride);
1079         CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset,
1080                               zOffset, width, height, depth, unpackFormat, src);
1081     }
1082 
1083 protected:
1084     void CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum target,
1085                             GLint level, GLenum internalFormat, GLsizei width,
1086                             GLsizei height, GLsizei depth, GLint border,
1087                             const TexImageSource& src);
1088 
1089     void CompressedTexSubImage(const char* funcName, uint8_t funcDims, GLenum target,
1090                                GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
1091                                GLsizei width, GLsizei height, GLsizei depth,
1092                                GLenum unpackFormat, const TexImageSource& src);
1093 
1094     ////////////////////////////////////
1095 
1096 public:
1097     void CopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x,
1098                         GLint y, GLsizei width, GLsizei height, GLint border);
1099 
CopyTexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLint x,GLint y,GLsizei width,GLsizei height)1100     void CopyTexSubImage2D(GLenum target, GLint level, GLint xOffset,
1101                            GLint yOffset, GLint x, GLint y, GLsizei width,
1102                            GLsizei height)
1103     {
1104         const char funcName[] = "copyTexSubImage2D";
1105         const uint8_t funcDims = 2;
1106         const GLint zOffset = 0;
1107         CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset,
1108                         x, y, width, height);
1109     }
1110 
1111 protected:
1112     void CopyTexSubImage(const char* funcName, uint8_t funcDims, GLenum target,
1113                          GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
1114                          GLint x, GLint y, GLsizei width, GLsizei height);
1115 
1116     ////////////////////////////////////
1117     // TexImage
1118 
1119     // Implicit width/height uploads
1120 
1121 public:
1122     template<typename T>
TexImage2D(GLenum target,GLint level,GLenum internalFormat,GLenum unpackFormat,GLenum unpackType,const T & src,ErrorResult & out_error)1123     void TexImage2D(GLenum target, GLint level, GLenum internalFormat,
1124                     GLenum unpackFormat, GLenum unpackType, const T& src,
1125                     ErrorResult& out_error)
1126     {
1127         GLsizei width = 0;
1128         GLsizei height = 0;
1129         GLint border = 0;
1130         TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
1131                    unpackType, src, out_error);
1132     }
1133 
1134     template<typename T>
TexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLenum unpackFormat,GLenum unpackType,const T & src,ErrorResult & out_error)1135     void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1136                        GLenum unpackFormat, GLenum unpackType, const T& src,
1137                        ErrorResult& out_error)
1138     {
1139         GLsizei width = 0;
1140         GLsizei height = 0;
1141         TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
1142                       unpackType, src, out_error);
1143     }
1144 
1145     ////
1146 
1147     template<typename T>
TexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLenum unpackFormat,GLenum unpackType,const T & anySrc,ErrorResult & out_error)1148     void TexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
1149                     GLsizei height, GLint border, GLenum unpackFormat, GLenum unpackType,
1150                     const T& anySrc, ErrorResult& out_error)
1151     {
1152         const TexImageSourceAdapter src(&anySrc, &out_error);
1153         TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
1154                    unpackType, src);
1155     }
1156 
TexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLenum unpackFormat,GLenum unpackType,const dom::ArrayBufferView & view,GLuint viewElemOffset,ErrorResult &)1157     void TexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
1158                     GLsizei height, GLint border, GLenum unpackFormat, GLenum unpackType,
1159                     const dom::ArrayBufferView& view, GLuint viewElemOffset,
1160                     ErrorResult&)
1161     {
1162         const TexImageSourceAdapter src(&view, viewElemOffset);
1163         TexImage2D(target, level, internalFormat, width, height, border, unpackFormat,
1164                    unpackType, src);
1165     }
1166 
1167 protected:
TexImage2D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLint border,GLenum unpackFormat,GLenum unpackType,const TexImageSource & src)1168     void TexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width,
1169                     GLsizei height, GLint border, GLenum unpackFormat,
1170                     GLenum unpackType, const TexImageSource& src)
1171     {
1172         const char funcName[] = "texImage2D";
1173         const uint8_t funcDims = 2;
1174         const GLsizei depth = 1;
1175         TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth,
1176                  border, unpackFormat, unpackType, src);
1177     }
1178 
1179     void TexImage(const char* funcName, uint8_t funcDims, GLenum target, GLint level,
1180                   GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
1181                   GLint border, GLenum unpackFormat, GLenum unpackType,
1182                   const TexImageSource& src);
1183 
1184     ////
1185 
1186 public:
1187     template<typename T>
TexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei width,GLsizei height,GLenum unpackFormat,GLenum unpackType,const T & anySrc,ErrorResult & out_error)1188     void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1189                        GLsizei width, GLsizei height, GLenum unpackFormat,
1190                        GLenum unpackType, const T& anySrc, ErrorResult& out_error)
1191     {
1192         const TexImageSourceAdapter src(&anySrc, &out_error);
1193         TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
1194                       unpackType, src);
1195     }
1196 
TexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei width,GLsizei height,GLenum unpackFormat,GLenum unpackType,const dom::ArrayBufferView & view,GLuint viewElemOffset,ErrorResult &)1197     void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1198                        GLsizei width, GLsizei height, GLenum unpackFormat,
1199                        GLenum unpackType, const dom::ArrayBufferView& view,
1200                        GLuint viewElemOffset, ErrorResult&)
1201     {
1202         const TexImageSourceAdapter src(&view, viewElemOffset);
1203         TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat,
1204                       unpackType, src);
1205     }
1206 
1207 protected:
TexSubImage2D(GLenum target,GLint level,GLint xOffset,GLint yOffset,GLsizei width,GLsizei height,GLenum unpackFormat,GLenum unpackType,const TexImageSource & src)1208     void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
1209                        GLsizei width, GLsizei height, GLenum unpackFormat,
1210                        GLenum unpackType, const TexImageSource& src)
1211     {
1212         const char funcName[] = "texSubImage2D";
1213         const uint8_t funcDims = 2;
1214         const GLint zOffset = 0;
1215         const GLsizei depth = 1;
1216         TexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width,
1217                     height, depth, unpackFormat, unpackType, src);
1218     }
1219 
1220     void TexSubImage(const char* funcName, uint8_t funcDims, GLenum target, GLint level,
1221                      GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
1222                      GLsizei height, GLsizei depth, GLenum unpackFormat,
1223                      GLenum unpackType, const TexImageSource& src);
1224 
1225     ////////////////////////////////////
1226     // WebGLTextureUpload.cpp
1227 public:
1228     UniquePtr<webgl::TexUnpackBlob>
1229     From(const char* funcName, TexImageTarget target, GLsizei rawWidth, GLsizei rawHeight,
1230          GLsizei rawDepth, GLint border, const TexImageSource& src,
1231          dom::Uint8ClampedArray* const scopedArr);
1232 
1233 protected:
1234     bool ValidateTexImageSpecification(const char* funcName, uint8_t funcDims,
1235                                        GLenum texImageTarget, GLint level,
1236                                        GLsizei width, GLsizei height, GLsizei depth,
1237                                        GLint border,
1238                                        TexImageTarget* const out_target,
1239                                        WebGLTexture** const out_texture,
1240                                        WebGLTexture::ImageInfo** const out_imageInfo);
1241     bool ValidateTexImageSelection(const char* funcName, uint8_t funcDims,
1242                                    GLenum texImageTarget, GLint level, GLint xOffset,
1243                                    GLint yOffset, GLint zOffset, GLsizei width,
1244                                    GLsizei height, GLsizei depth,
1245                                    TexImageTarget* const out_target,
1246                                    WebGLTexture** const out_texture,
1247                                    WebGLTexture::ImageInfo** const out_imageInfo);
1248     bool ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format,
1249                             GLenum type, webgl::PackingInfo* const out);
1250 
1251     UniquePtr<webgl::TexUnpackBlob>
1252     FromDomElem(const char* funcName, TexImageTarget target, uint32_t width,
1253                 uint32_t height, uint32_t depth, const dom::Element& elem,
1254                 ErrorResult* const out_error);
1255 
1256     UniquePtr<webgl::TexUnpackBytes>
1257     FromCompressed(const char* funcName, TexImageTarget target, GLsizei rawWidth,
1258                    GLsizei rawHeight, GLsizei rawDepth, GLint border,
1259                    const TexImageSource& src);
1260 
1261 // -----------------------------------------------------------------------------
1262 // Vertices Feature (WebGLContextVertices.cpp)
1263     GLenum mPrimRestartTypeBytes;
1264 
1265 public:
1266     void DrawArrays(GLenum mode, GLint first, GLsizei count);
1267     void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
1268                              GLsizei primcount);
1269     void DrawElements(GLenum mode, GLsizei count, GLenum type,
1270                       WebGLintptr byteOffset, const char* funcName = nullptr);
1271     void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1272                                WebGLintptr byteOffset, GLsizei primcount);
1273 
1274     void EnableVertexAttribArray(GLuint index);
1275     void DisableVertexAttribArray(GLuint index);
1276 
1277     JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
1278                               ErrorResult& rv);
1279 
GetVertexAttrib(JSContext * cx,GLuint index,GLenum pname,JS::MutableHandle<JS::Value> retval,ErrorResult & rv)1280     void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
1281                          JS::MutableHandle<JS::Value> retval, ErrorResult& rv)
1282     {
1283         retval.set(GetVertexAttrib(cx, index, pname, rv));
1284     }
1285 
1286     WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
1287 
1288     ////
1289 
1290     void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w,
1291                         const char* funcName = nullptr);
1292 
1293     ////
1294 
VertexAttrib1f(GLuint index,GLfloat x)1295     void VertexAttrib1f(GLuint index, GLfloat x) {
1296         VertexAttrib4f(index, x, 0, 0, 1, "vertexAttrib1f");
1297     }
VertexAttrib2f(GLuint index,GLfloat x,GLfloat y)1298     void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1299         VertexAttrib4f(index, x, y, 0, 1, "vertexAttrib2f");
1300     }
VertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)1301     void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1302         VertexAttrib4f(index, x, y, z, 1, "vertexAttrib3f");
1303     }
1304 
1305     ////
1306 
VertexAttrib1fv(GLuint index,const Float32ListU & list)1307     void VertexAttrib1fv(GLuint index, const Float32ListU& list) {
1308         const char funcName[] = "vertexAttrib1fv";
1309         const auto& arr = Float32Arr::From(list);
1310         if (!ValidateAttribArraySetter(funcName, 1, arr.elemCount))
1311             return;
1312 
1313         VertexAttrib4f(index, arr.elemBytes[0], 0, 0, 1, funcName);
1314     }
1315 
VertexAttrib2fv(GLuint index,const Float32ListU & list)1316     void VertexAttrib2fv(GLuint index, const Float32ListU& list) {
1317         const char funcName[] = "vertexAttrib2fv";
1318         const auto& arr = Float32Arr::From(list);
1319         if (!ValidateAttribArraySetter(funcName, 2, arr.elemCount))
1320             return;
1321 
1322         VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], 0, 1, funcName);
1323     }
1324 
VertexAttrib3fv(GLuint index,const Float32ListU & list)1325     void VertexAttrib3fv(GLuint index, const Float32ListU& list) {
1326         const char funcName[] = "vertexAttrib3fv";
1327         const auto& arr = Float32Arr::From(list);
1328         if (!ValidateAttribArraySetter(funcName, 3, arr.elemCount))
1329             return;
1330 
1331         VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2], 1,
1332                        funcName);
1333     }
1334 
VertexAttrib4fv(GLuint index,const Float32ListU & list)1335     void VertexAttrib4fv(GLuint index, const Float32ListU& list) {
1336         const char funcName[] = "vertexAttrib4fv";
1337         const auto& arr = Float32Arr::From(list);
1338         if (!ValidateAttribArraySetter(funcName, 4, arr.elemCount))
1339             return;
1340 
1341         VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2],
1342                        arr.elemBytes[3], funcName);
1343     }
1344 
1345     ////
1346 
1347     void VertexAttribPointer(GLuint index, GLint size, GLenum type,
1348                              WebGLboolean normalized, GLsizei stride,
1349                              WebGLintptr byteOffset);
1350     void VertexAttribDivisor(GLuint index, GLuint divisor);
1351 
1352 private:
1353     // Cache the max number of vertices and instances that can be read from
1354     // bound VBOs (result of ValidateBuffers).
1355     bool mBufferFetchingIsVerified;
1356     bool mBufferFetchingHasPerVertex;
1357     uint32_t mMaxFetchedVertices;
1358     uint32_t mMaxFetchedInstances;
1359     bool mBufferFetch_IsAttrib0Active;
1360 
1361     bool DrawArrays_check(const char* funcName, GLenum mode, GLint first,
1362                           GLsizei vertCount, GLsizei instanceCount);
1363     bool DrawElements_check(const char* funcName, GLenum mode, GLsizei vertCount,
1364                             GLenum type, WebGLintptr byteOffset,
1365                             GLsizei instanceCount);
1366     bool DrawInstanced_check(const char* info);
1367     void Draw_cleanup(const char* funcName);
1368 
1369     void VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
1370                               const GLfloat* ptr);
1371     void VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
1372                               const GLfloat* ptr);
1373     void VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
1374                               const GLfloat* ptr);
1375     void VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
1376                               const GLfloat* ptr);
1377 
1378     bool ValidateBufferFetching(const char* info);
1379     bool BindArrayAttribToLocation0(WebGLProgram* prog);
1380 
1381 // -----------------------------------------------------------------------------
1382 // PROTECTED
1383 protected:
1384     WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
1385     bool DoFakeVertexAttrib0(const char* funcName, GLuint vertexCount);
1386     void UndoFakeVertexAttrib0();
1387 
InvalidateBufferFetching()1388     inline void InvalidateBufferFetching()
1389     {
1390         mBufferFetchingIsVerified = false;
1391         mBufferFetchingHasPerVertex = false;
1392         mMaxFetchedVertices = 0;
1393         mMaxFetchedInstances = 0;
1394     }
1395 
1396     CheckedUint32 mGeneration;
1397 
1398     WebGLContextOptions mOptions;
1399 
1400     bool mInvalidated;
1401     bool mCapturedFrameInvalidated;
1402     bool mResetLayer;
1403     bool mLayerIsMirror;
1404     bool mOptionsFrozen;
1405     bool mMinCapability;
1406     bool mDisableExtensions;
1407     bool mIsMesa;
1408     bool mLoseContextOnMemoryPressure;
1409     bool mCanLoseContextInForeground;
1410     bool mRestoreWhenVisible;
1411     bool mShouldPresent;
1412     bool mBackbufferNeedsClear;
1413     bool mDisableFragHighP;
1414 
1415     template<typename WebGLObjectType>
1416     void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
1417 
1418     GLuint mActiveTexture;
1419     GLenum mDefaultFB_DrawBuffer0;
1420 
1421     // glGetError sources:
1422     bool mEmitContextLostErrorOnce;
1423     GLenum mWebGLError;
1424     GLenum mUnderlyingGLError;
1425     GLenum GetAndFlushUnderlyingGLErrors();
1426 
1427     bool mBypassShaderValidation;
1428 
1429     webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
1430 
1431     // some GL constants
1432     uint32_t mGLMaxVertexAttribs;
1433     int32_t mGLMaxTextureUnits;
1434     int32_t mGLMaxTextureImageUnits;
1435     int32_t mGLMaxVertexTextureImageUnits;
1436     int32_t mGLMaxVaryingVectors;
1437     int32_t mGLMaxFragmentUniformVectors;
1438     int32_t mGLMaxVertexUniformVectors;
1439     uint32_t  mGLMaxTransformFeedbackSeparateAttribs;
1440     GLuint  mGLMaxUniformBufferBindings;
1441 
1442     // What is supported:
1443     uint32_t mGLMaxColorAttachments;
1444     uint32_t mGLMaxDrawBuffers;
1445     // What we're allowing:
1446     uint32_t mImplMaxColorAttachments;
1447     uint32_t mImplMaxDrawBuffers;
1448 
1449     uint32_t mImplMaxViewportDims[2];
1450 
1451 public:
LastColorAttachmentEnum()1452     GLenum LastColorAttachmentEnum() const {
1453         return LOCAL_GL_COLOR_ATTACHMENT0 + mImplMaxColorAttachments - 1;
1454     }
1455 
decltype(mOptions)1456     const decltype(mOptions)& Options() const { return mOptions; }
1457 
1458 protected:
1459 
1460     // Texture sizes are often not actually the GL values. Let's be explicit that these
1461     // are implementation limits.
1462     uint32_t mImplMaxTextureSize;
1463     uint32_t mImplMaxCubeMapTextureSize;
1464     uint32_t mImplMax3DTextureSize;
1465     uint32_t mImplMaxArrayTextureLayers;
1466     uint32_t mImplMaxRenderbufferSize;
1467 
1468 public:
MaxVertexAttribs()1469     GLuint MaxVertexAttribs() const {
1470         return mGLMaxVertexAttribs;
1471     }
1472 
GLMaxTextureUnits()1473     GLuint GLMaxTextureUnits() const {
1474         return mGLMaxTextureUnits;
1475     }
1476 
1477     bool IsFormatValidForFB(TexInternalFormat format) const;
1478 
1479 protected:
1480     // Represents current status of the context with respect to context loss.
1481     // That is, whether the context is lost, and what part of the context loss
1482     // process we currently are at.
1483     // This is used to support the WebGL spec's asyncronous nature in handling
1484     // context loss.
1485     enum ContextStatus {
1486         // The context is stable; there either are none or we don't know of any.
1487         ContextNotLost,
1488         // The context has been lost, but we have not yet sent an event to the
1489         // script informing it of this.
1490         ContextLostAwaitingEvent,
1491         // The context has been lost, and we have sent the script an event
1492         // informing it of this.
1493         ContextLost,
1494         // The context is lost, an event has been sent to the script, and the
1495         // script correctly handled the event. We are waiting for the context to
1496         // be restored.
1497         ContextLostAwaitingRestore
1498     };
1499 
1500     // -------------------------------------------------------------------------
1501     // WebGL extensions (implemented in WebGLContextExtensions.cpp)
1502     typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max,
1503                             RefPtr<WebGLExtensionBase>> ExtensionsArrayType;
1504 
1505     ExtensionsArrayType mExtensions;
1506 
1507     // enable an extension. the extension should not be enabled before.
1508     void EnableExtension(WebGLExtensionID ext);
1509 
1510     // Enable an extension if it's supported. Return the extension on success.
1511     WebGLExtensionBase* EnableSupportedExtension(dom::CallerType callerType,
1512                                                  WebGLExtensionID ext);
1513 
1514 public:
1515     // returns true if the extension has been enabled by calling getExtension.
1516     bool IsExtensionEnabled(WebGLExtensionID ext) const;
1517 
1518 protected:
1519     // returns true if the extension is supported for this caller type (this decides what getSupportedExtensions exposes)
1520     bool IsExtensionSupported(dom::CallerType callerType,
1521                               WebGLExtensionID ext) const;
1522     bool IsExtensionSupported(WebGLExtensionID ext) const;
1523 
1524     static const char* GetExtensionString(WebGLExtensionID ext);
1525 
1526     nsTArray<GLenum> mCompressedTextureFormats;
1527 
1528     // -------------------------------------------------------------------------
1529     // WebGL 2 specifics (implemented in WebGL2Context.cpp)
1530 public:
1531     virtual bool IsWebGL2() const = 0;
1532 
1533     struct FailureReason {
1534         nsCString key; // For reporting.
1535         nsCString info;
1536 
FailureReasonFailureReason1537         FailureReason() { }
1538 
1539         template<typename A, typename B>
FailureReasonFailureReason1540         FailureReason(const A& _key, const B& _info)
1541             : key(nsCString(_key))
1542             , info(nsCString(_info))
1543         { }
1544     };
1545 protected:
1546     bool InitWebGL2(FailureReason* const out_failReason);
1547 
1548     bool CreateAndInitGL(bool forceEnabled,
1549                          std::vector<FailureReason>* const out_failReasons);
1550 
1551     bool ResizeBackbuffer(uint32_t width, uint32_t height);
1552 
1553     typedef already_AddRefed<gl::GLContext> FnCreateGL_T(const gl::SurfaceCaps& caps,
1554                                                          gl::CreateContextFlags flags,
1555                                                          WebGLContext* webgl,
1556                                                          std::vector<FailureReason>* const out_failReasons);
1557 
1558     bool CreateAndInitGLWith(FnCreateGL_T fnCreateGL, const gl::SurfaceCaps& baseCaps,
1559                              gl::CreateContextFlags flags,
1560                              std::vector<FailureReason>* const out_failReasons);
1561 
1562     void ThrowEvent_WebGLContextCreationError(const nsACString& text);
1563 
1564     // -------------------------------------------------------------------------
1565     // Validation functions (implemented in WebGLContextValidate.cpp)
1566     bool InitAndValidateGL(FailureReason* const out_failReason);
1567 
1568     bool ValidateBlendEquationEnum(GLenum cap, const char* info);
1569     bool ValidateBlendFuncDstEnum(GLenum mode, const char* info);
1570     bool ValidateBlendFuncSrcEnum(GLenum mode, const char* info);
1571     bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor,
1572                                              const char* info);
1573     bool ValidateComparisonEnum(GLenum target, const char* info);
1574     bool ValidateStencilOpEnum(GLenum action, const char* info);
1575     bool ValidateFaceEnum(GLenum face, const char* info);
1576     bool ValidateTexInputData(GLenum type, js::Scalar::Type jsArrayType,
1577                               WebGLTexImageFunc func, WebGLTexDimensions dims);
1578     bool ValidateDrawModeEnum(GLenum mode, const char* info);
1579     bool ValidateAttribIndex(GLuint index, const char* info);
1580     bool ValidateAttribPointer(bool integerMode, GLuint index, GLint size, GLenum type,
1581                                WebGLboolean normalized, GLsizei stride,
1582                                WebGLintptr byteOffset, const char* info);
1583     bool ValidateStencilParamsForDrawCall();
1584 
1585     bool ValidateCopyTexImage(TexInternalFormat srcFormat, TexInternalFormat dstformat,
1586                               WebGLTexImageFunc func, WebGLTexDimensions dims);
1587 
1588     bool ValidateTexImage(TexImageTarget texImageTarget,
1589                           GLint level, GLenum internalFormat,
1590                           GLint xoffset, GLint yoffset, GLint zoffset,
1591                           GLint width, GLint height, GLint depth,
1592                           GLint border, GLenum format, GLenum type,
1593                           WebGLTexImageFunc func, WebGLTexDimensions dims);
1594     bool ValidateTexImageFormat(GLenum internalFormat, WebGLTexImageFunc func,
1595                                 WebGLTexDimensions dims);
1596     bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func,
1597                               WebGLTexDimensions dims);
1598     bool ValidateTexImageFormatAndType(GLenum format, GLenum type,
1599                                        WebGLTexImageFunc func,
1600                                        WebGLTexDimensions dims);
1601     bool ValidateCompTexImageInternalFormat(GLenum format,
1602                                             WebGLTexImageFunc func,
1603                                             WebGLTexDimensions dims);
1604     bool ValidateCopyTexImageInternalFormat(GLenum format,
1605                                             WebGLTexImageFunc func,
1606                                             WebGLTexDimensions dims);
1607     bool ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
1608                               GLint width, GLint height, GLint depth,
1609                               WebGLTexImageFunc func, WebGLTexDimensions dims);
1610     bool ValidateTexSubImageSize(GLint x, GLint y, GLint z, GLsizei width,
1611                                  GLsizei height, GLsizei depth,
1612                                  GLsizei baseWidth, GLsizei baseHeight,
1613                                  GLsizei baseDepth, WebGLTexImageFunc func,
1614                                  WebGLTexDimensions dims);
1615     bool ValidateCompTexImageSize(GLint level, GLenum internalFormat,
1616                                   GLint xoffset, GLint yoffset, GLsizei width,
1617                                   GLsizei height, GLsizei levelWidth,
1618                                   GLsizei levelHeight, WebGLTexImageFunc func,
1619                                   WebGLTexDimensions dims);
1620     bool ValidateCompTexImageDataSize(GLint level, GLenum internalFormat,
1621                                       GLsizei width, GLsizei height,
1622                                       uint32_t byteLength,
1623                                       WebGLTexImageFunc func,
1624                                       WebGLTexDimensions dims);
1625 
1626     bool ValidateUniformLocationForProgram(WebGLUniformLocation* location,
1627                                            WebGLProgram* program,
1628                                            const char* funcName);
1629 
1630     bool ValidateCurFBForRead(const char* funcName,
1631                               const webgl::FormatUsageInfo** const out_format,
1632                               uint32_t* const out_width, uint32_t* const out_height);
1633 
HasDrawBuffers()1634     bool HasDrawBuffers() const {
1635         return IsWebGL2() ||
1636                IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers);
1637     }
1638 
1639     WebGLRefPtr<WebGLBuffer>* ValidateBufferSlot(const char* funcName, GLenum target);
1640 public:
1641     WebGLBuffer* ValidateBufferSelection(const char* funcName, GLenum target);
1642 protected:
1643     IndexedBufferBinding* ValidateIndexedBufferSlot(const char* funcName, GLenum target,
1644                                                     GLuint index);
1645 
1646     bool ValidateIndexedBufferBinding(const char* funcName, GLenum target, GLuint index,
1647                                       WebGLRefPtr<WebGLBuffer>** const out_genericBinding,
1648                                       IndexedBufferBinding** const out_indexedBinding);
1649 
ValidateNonNegative(const char * funcName,const char * argName,int64_t val)1650     bool ValidateNonNegative(const char* funcName, const char* argName, int64_t val) {
1651         if (MOZ_UNLIKELY(val < 0)) {
1652             ErrorInvalidValue("%s: `%s` must be non-negative.", funcName, argName);
1653             return false;
1654         }
1655         return true;
1656     }
1657 
1658 public:
1659     template<typename T>
ValidateNonNull(const char * funcName,const dom::Nullable<T> & maybe)1660     bool ValidateNonNull(const char* funcName, const dom::Nullable<T>& maybe) {
1661         if (maybe.IsNull()) {
1662             ErrorInvalidValue("%s: `null` is invalid.", funcName);
1663             return false;
1664         }
1665         return true;
1666     }
1667 
1668     bool ValidateArrayBufferView(const char* funcName, const dom::ArrayBufferView& view,
1669                                  GLuint elemOffset, GLuint elemCountOverride,
1670                                  uint8_t** const out_bytes, size_t* const out_byteLen);
1671 
1672 protected:
1673     ////
1674 
1675     void Invalidate();
1676     void DestroyResourcesAndContext();
1677 
1678     void MakeContextCurrent() const;
1679 
1680     // helpers
1681 
1682     bool ConvertImage(size_t width, size_t height, size_t srcStride,
1683                       size_t dstStride, const uint8_t* src, uint8_t* dst,
1684                       WebGLTexelFormat srcFormat, bool srcPremultiplied,
1685                       WebGLTexelFormat dstFormat, bool dstPremultiplied,
1686                       size_t dstTexelSize);
1687 
1688     //////
1689 public:
ValidateObjectAllowDeleted(const char * funcName,const WebGLContextBoundObject & object)1690     bool ValidateObjectAllowDeleted(const char* funcName,
1691                                     const WebGLContextBoundObject& object)
1692     {
1693         if (!object.IsCompatibleWithContext(this)) {
1694             ErrorInvalidOperation("%s: Object from different WebGL context (or older"
1695                                   " generation of this one) passed as argument.",
1696                                   funcName);
1697             return false;
1698         }
1699 
1700         return true;
1701     }
1702 
1703     bool ValidateObject(const char* funcName, const WebGLDeletableObject& object,
1704                         bool isShaderOrProgram = false)
1705     {
1706         if (!ValidateObjectAllowDeleted(funcName, object))
1707             return false;
1708 
1709         if (isShaderOrProgram) {
1710             /* GLES 3.0.5 p45:
1711              * "Commands that accept shader or program object names will generate the
1712              *  error INVALID_VALUE if the provided name is not the name of either a
1713              *  shader or program object[.]"
1714              * Further, shaders and programs appear to be different from other objects,
1715              * in that their lifetimes are better defined. However, they also appear to
1716              * allow use of objects marked for deletion, and only reject
1717              * actually-destroyed objects.
1718              */
1719             if (object.IsDeleted()) {
1720                 ErrorInvalidValue("%s: Shader or program object argument cannot have been"
1721                                   " deleted.",
1722                                   funcName);
1723                 return false;
1724             }
1725         } else {
1726             if (object.IsDeleteRequested()) {
1727                 ErrorInvalidOperation("%s: Object argument cannot have been marked for"
1728                                       " deletion.",
1729                                       funcName);
1730                 return false;
1731             }
1732         }
1733 
1734         return true;
1735     }
1736 
1737     ////
1738 
1739     bool ValidateObject(const char* funcName, const WebGLProgram& object);
1740     bool ValidateObject(const char* funcName, const WebGLShader& object);
1741 
1742     ////
1743 
ValidateIsObject(const char * funcName,const WebGLDeletableObject * object)1744     bool ValidateIsObject(const char* funcName,
1745                           const WebGLDeletableObject* object) const
1746     {
1747         if (IsContextLost())
1748             return false;
1749 
1750         if (!object)
1751             return false;
1752 
1753         if (!object->IsCompatibleWithContext(this))
1754             return false;
1755 
1756         if (object->IsDeleted())
1757             return false;
1758 
1759         return true;
1760     }
1761 
ValidateDeleteObject(const char * funcName,const WebGLDeletableObject * object)1762     bool ValidateDeleteObject(const char* funcName, const WebGLDeletableObject* object) {
1763         if (IsContextLost())
1764             return false;
1765 
1766         if (!object)
1767             return false;
1768 
1769         if (!ValidateObjectAllowDeleted(funcName, *object))
1770             return false;
1771 
1772         if (object->IsDeleteRequested())
1773             return false;
1774 
1775         return true;
1776     }
1777 
1778     ////
1779 
1780 private:
1781     // -------------------------------------------------------------------------
1782     // Context customization points
1783     virtual WebGLVertexArray* CreateVertexArrayImpl();
1784 
1785     virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, uint32_t* alignment, const char* info) = 0;
1786     virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0;
1787 
1788 public:
1789     void ForceLoseContext(bool simulateLoss = false);
1790 
1791 protected:
1792     void ForceRestoreContext();
1793 
1794     nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
1795     nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
1796     nsTArray<WebGLRefPtr<WebGLTexture> > mBound3DTextures;
1797     nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DArrayTextures;
1798     nsTArray<WebGLRefPtr<WebGLSampler> > mBoundSamplers;
1799 
1800     void ResolveTexturesForDraw() const;
1801 
1802     WebGLRefPtr<WebGLProgram> mCurrentProgram;
1803     RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
1804 
1805     bool ValidateFramebufferTarget(GLenum target, const char* const info);
1806     bool ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
1807                                        const dom::Sequence<GLenum>& attachments,
1808                                        ErrorResult* const out_rv,
1809                                        std::vector<GLenum>* const scopedVector,
1810                                        GLsizei* const out_glNumAttachments,
1811                                        const GLenum** const out_glAttachments);
1812 
1813     WebGLRefPtr<WebGLFramebuffer> mBoundDrawFramebuffer;
1814     WebGLRefPtr<WebGLFramebuffer> mBoundReadFramebuffer;
1815     WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
1816     WebGLRefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
1817     WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
1818 
1819     LinkedList<WebGLBuffer> mBuffers;
1820     LinkedList<WebGLFramebuffer> mFramebuffers;
1821     LinkedList<WebGLProgram> mPrograms;
1822     LinkedList<WebGLQuery> mQueries;
1823     LinkedList<WebGLRenderbuffer> mRenderbuffers;
1824     LinkedList<WebGLSampler> mSamplers;
1825     LinkedList<WebGLShader> mShaders;
1826     LinkedList<WebGLSync> mSyncs;
1827     LinkedList<WebGLTexture> mTextures;
1828     LinkedList<WebGLTransformFeedback> mTransformFeedbacks;
1829     LinkedList<WebGLVertexArray> mVertexArrays;
1830 
1831     WebGLRefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
1832     WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
1833 
1834     // PixelStore parameters
1835     uint32_t mPixelStore_UnpackImageHeight;
1836     uint32_t mPixelStore_UnpackSkipImages;
1837     uint32_t mPixelStore_UnpackRowLength;
1838     uint32_t mPixelStore_UnpackSkipRows;
1839     uint32_t mPixelStore_UnpackSkipPixels;
1840     uint32_t mPixelStore_UnpackAlignment;
1841     uint32_t mPixelStore_PackRowLength;
1842     uint32_t mPixelStore_PackSkipRows;
1843     uint32_t mPixelStore_PackSkipPixels;
1844     uint32_t mPixelStore_PackAlignment;
1845 
1846     CheckedUint32 GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
1847                                 uint32_t depth, uint8_t bytesPerPixel);
1848 
1849     bool ValidatePackSize(const char* funcName, uint32_t width, uint32_t height,
1850                           uint8_t bytesPerPixel, uint32_t* const out_rowStride,
1851                           uint32_t* const out_endOffset);
1852 
1853     GLenum mPixelStore_ColorspaceConversion;
1854     bool mPixelStore_FlipY;
1855     bool mPixelStore_PremultiplyAlpha;
1856 
1857     ////////////////////////////////////
1858     class FakeBlackTexture {
1859     public:
1860         static UniquePtr<FakeBlackTexture> Create(gl::GLContext* gl,
1861                                                   TexTarget target,
1862                                                   FakeBlackType type);
1863         gl::GLContext* const mGL;
1864         const GLuint mGLName;
1865 
1866         ~FakeBlackTexture();
1867     protected:
1868         explicit FakeBlackTexture(gl::GLContext* gl);
1869     };
1870 
1871     UniquePtr<FakeBlackTexture> mFakeBlack_2D_0000;
1872     UniquePtr<FakeBlackTexture> mFakeBlack_2D_0001;
1873     UniquePtr<FakeBlackTexture> mFakeBlack_CubeMap_0000;
1874     UniquePtr<FakeBlackTexture> mFakeBlack_CubeMap_0001;
1875     UniquePtr<FakeBlackTexture> mFakeBlack_3D_0000;
1876     UniquePtr<FakeBlackTexture> mFakeBlack_3D_0001;
1877     UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0000;
1878     UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0001;
1879 
1880     bool BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
1881 
1882     ////////////////////////////////////
1883 
1884 protected:
1885     GLuint mEmptyTFO;
1886 
1887     // Generic Vertex Attributes
1888     // Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the spec
1889     // state tables, this isn't vertex shader /object/ state. This array is merely state
1890     // useful to vertex shaders, but is global state.
1891     UniquePtr<GLenum[]> mGenericVertexAttribTypes;
1892     uint8_t mGenericVertexAttrib0Data[sizeof(float) * 4];
1893 
1894     GLuint mFakeVertexAttrib0BufferObject;
1895     size_t mFakeVertexAttrib0BufferObjectSize;
1896     bool mFakeVertexAttrib0DataDefined;
1897     uint8_t mFakeVertexAttrib0Data[sizeof(float) * 4];
1898 
1899     JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
1900     JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
1901     JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);
1902 
1903     GLint mStencilRefFront;
1904     GLint mStencilRefBack;
1905     GLuint mStencilValueMaskFront;
1906     GLuint mStencilValueMaskBack;
1907     GLuint mStencilWriteMaskFront;
1908     GLuint mStencilWriteMaskBack;
1909     realGLboolean mColorWriteMask[4];
1910     realGLboolean mDepthWriteMask;
1911     GLfloat mColorClearValue[4];
1912     GLint mStencilClearValue;
1913     GLfloat mDepthClearValue;
1914 
1915     GLint mViewportX;
1916     GLint mViewportY;
1917     GLsizei mViewportWidth;
1918     GLsizei mViewportHeight;
1919     bool mAlreadyWarnedAboutViewportLargerThanDest;
1920 
1921     GLfloat mLineWidth;
1922 
1923     WebGLContextLossHandler mContextLossHandler;
1924     bool mAllowContextRestore;
1925     bool mLastLossWasSimulated;
1926     ContextStatus mContextStatus;
1927     bool mContextLostErrorSet;
1928 
1929     // Used for some hardware (particularly Tegra 2 and 4) that likes to
1930     // be Flushed while doing hundreds of draw calls.
1931     int mDrawCallsSinceLastFlush;
1932 
1933     int mAlreadyGeneratedWarnings;
1934     int mMaxWarnings;
1935     bool mAlreadyWarnedAboutFakeVertexAttrib0;
1936 
1937     bool ShouldGenerateWarnings() const;
1938 
1939     uint64_t mLastUseIndex;
1940 
1941     bool mNeedsFakeNoAlpha;
1942     bool mNeedsFakeNoDepth;
1943     bool mNeedsFakeNoStencil;
1944     bool mNeedsEmulatedLoneDepthStencil;
1945 
1946     const bool mAllowFBInvalidation;
1947 
1948     bool Has64BitTimestamps() const;
1949 
1950     struct ScopedDrawCallWrapper final {
1951         WebGLContext& mWebGL;
1952         const bool mFakeNoAlpha;
1953         const bool mFakeNoDepth;
1954         const bool mFakeNoStencil;
1955 
ShouldFakeNoAlphafinal1956         static bool ShouldFakeNoAlpha(WebGLContext& webgl) {
1957             // We should only be doing this if we're about to draw to the backbuffer, but
1958             // the backbuffer needs to have this fake-no-alpha workaround.
1959             return !webgl.mBoundDrawFramebuffer &&
1960                    webgl.mNeedsFakeNoAlpha &&
1961                    webgl.mColorWriteMask[3] != false;
1962         }
1963 
ShouldFakeNoDepthfinal1964         static bool ShouldFakeNoDepth(WebGLContext& webgl) {
1965             // We should only be doing this if we're about to draw to the backbuffer.
1966             return !webgl.mBoundDrawFramebuffer &&
1967                    webgl.mNeedsFakeNoDepth &&
1968                    webgl.mDepthTestEnabled;
1969         }
1970 
1971         static bool HasDepthButNoStencil(const WebGLFramebuffer* fb);
1972 
ShouldFakeNoStencilfinal1973         static bool ShouldFakeNoStencil(WebGLContext& webgl) {
1974             if (!webgl.mStencilTestEnabled)
1975                 return false;
1976 
1977             if (!webgl.mBoundDrawFramebuffer) {
1978                 if (webgl.mNeedsFakeNoStencil)
1979                     return true;
1980 
1981                 if (webgl.mNeedsEmulatedLoneDepthStencil &&
1982                     webgl.mOptions.depth && !webgl.mOptions.stencil)
1983                 {
1984                     return true;
1985                 }
1986 
1987                 return false;
1988             }
1989 
1990             if (webgl.mNeedsEmulatedLoneDepthStencil &&
1991                 HasDepthButNoStencil(webgl.mBoundDrawFramebuffer))
1992             {
1993                 return true;
1994             }
1995 
1996             return false;
1997         }
1998 
1999         ////
2000 
2001         explicit ScopedDrawCallWrapper(WebGLContext& webgl);
2002         ~ScopedDrawCallWrapper();
2003     };
2004 
2005     void OnBeforeReadCall();
2006 
2007     void LoseOldestWebGLContextIfLimitExceeded();
2008     void UpdateLastUseIndex();
2009 
2010     template <typename WebGLObjectType>
2011     JS::Value WebGLObjectAsJSValue(JSContext* cx, const WebGLObjectType*,
2012                                    ErrorResult& rv) const;
2013     template <typename WebGLObjectType>
2014     JSObject* WebGLObjectAsJSObject(JSContext* cx, const WebGLObjectType*,
2015                                     ErrorResult& rv) const;
2016 
2017 #ifdef XP_MACOSX
2018     // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
2019     // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
2020     // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
2021     // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
2022     // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
2023     ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
2024 #endif
2025 
2026 public:
2027     // console logging helpers
2028     void GenerateWarning(const char* fmt, ...);
2029     void GenerateWarning(const char* fmt, va_list ap);
2030 
2031 public:
2032     UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
2033 
2034     virtual UniquePtr<webgl::FormatUsageAuthority>
2035     CreateFormatUsage(gl::GLContext* gl) const = 0;
2036 
2037 
2038     const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
2039 
2040     // Friend list
2041     friend class ScopedCopyTexImageSource;
2042     friend class ScopedResolveTexturesForDraw;
2043     friend class ScopedUnpackReset;
2044     friend class webgl::TexUnpackBlob;
2045     friend class webgl::TexUnpackBytes;
2046     friend class webgl::TexUnpackImage;
2047     friend class webgl::TexUnpackSurface;
2048     friend struct webgl::UniformInfo;
2049     friend class WebGLTexture;
2050     friend class WebGLFBAttachPoint;
2051     friend class WebGLFramebuffer;
2052     friend class WebGLRenderbuffer;
2053     friend class WebGLProgram;
2054     friend class WebGLQuery;
2055     friend class WebGLBuffer;
2056     friend class WebGLSampler;
2057     friend class WebGLShader;
2058     friend class WebGLSync;
2059     friend class WebGLTransformFeedback;
2060     friend class WebGLUniformLocation;
2061     friend class WebGLVertexArray;
2062     friend class WebGLVertexArrayFake;
2063     friend class WebGLVertexArrayGL;
2064 };
2065 
2066 // used by DOM bindings in conjunction with GetParentObject
2067 inline nsISupports*
ToSupports(WebGLContext * webgl)2068 ToSupports(WebGLContext* webgl)
2069 {
2070     return static_cast<nsIDOMWebGLRenderingContext*>(webgl);
2071 }
2072 
2073 // Returns `value` rounded to the next highest multiple of `multiple`.
2074 // AKA PadToAlignment, StrideForAlignment.
2075 template<typename V, typename M>
2076 V
RoundUpToMultipleOf(const V & value,const M & multiple)2077 RoundUpToMultipleOf(const V& value, const M& multiple)
2078 {
2079     return ((value + multiple - 1) / multiple) * multiple;
2080 }
2081 
2082 bool
2083 ValidateTexTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims,
2084                   GLenum rawTexTarget, TexTarget* const out_texTarget,
2085                   WebGLTexture** const out_tex);
2086 bool
2087 ValidateTexImageTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims,
2088                        GLenum rawTexImageTarget, TexImageTarget* const out_texImageTarget,
2089                        WebGLTexture** const out_tex);
2090 
2091 class UniqueBuffer
2092 {
2093     // Like UniquePtr<>, but for void* and malloc/calloc/free.
2094     void* mBuffer;
2095 
2096 public:
UniqueBuffer()2097     UniqueBuffer()
2098         : mBuffer(nullptr)
2099     { }
2100 
UniqueBuffer(void * buffer)2101     MOZ_IMPLICIT UniqueBuffer(void* buffer)
2102         : mBuffer(buffer)
2103     { }
2104 
~UniqueBuffer()2105     ~UniqueBuffer() {
2106         free(mBuffer);
2107     }
2108 
UniqueBuffer(UniqueBuffer && other)2109     UniqueBuffer(UniqueBuffer&& other) {
2110         this->mBuffer = other.mBuffer;
2111         other.mBuffer = nullptr;
2112     }
2113 
2114     UniqueBuffer& operator =(UniqueBuffer&& other) {
2115         free(this->mBuffer);
2116         this->mBuffer = other.mBuffer;
2117         other.mBuffer = nullptr;
2118         return *this;
2119     }
2120 
2121     UniqueBuffer& operator =(void* newBuffer) {
2122         free(this->mBuffer);
2123         this->mBuffer = newBuffer;
2124         return *this;
2125     }
2126 
2127     explicit operator bool() const { return bool(mBuffer); }
2128 
get()2129     void* get() const { return mBuffer; }
2130 
2131     UniqueBuffer(const UniqueBuffer& other) = delete; // construct using Move()!
2132     void operator =(const UniqueBuffer& other) = delete; // assign using Move()!
2133 };
2134 
2135 class ScopedUnpackReset final
2136     : public gl::ScopedGLWrapper<ScopedUnpackReset>
2137 {
2138     friend struct gl::ScopedGLWrapper<ScopedUnpackReset>;
2139 
2140 private:
2141     WebGLContext* const mWebGL;
2142 
2143 public:
2144     explicit ScopedUnpackReset(WebGLContext* webgl);
2145 
2146 private:
2147     void UnwrapImpl();
2148 };
2149 
2150 class ScopedFBRebinder final
2151     : public gl::ScopedGLWrapper<ScopedFBRebinder>
2152 {
2153     friend struct gl::ScopedGLWrapper<ScopedFBRebinder>;
2154 
2155 private:
2156     WebGLContext* const mWebGL;
2157 
2158 public:
2159     explicit ScopedFBRebinder(WebGLContext* webgl)
2160         : ScopedGLWrapper<ScopedFBRebinder>(webgl->gl)
2161         , mWebGL(webgl)
2162     { }
2163 
2164 private:
2165     void UnwrapImpl();
2166 };
2167 
2168 class ScopedLazyBind final
2169     : public gl::ScopedGLWrapper<ScopedLazyBind>
2170 {
2171     friend struct gl::ScopedGLWrapper<ScopedLazyBind>;
2172 
2173     const GLenum mTarget;
2174     const WebGLBuffer* const mBuf;
2175 
2176 public:
2177     ScopedLazyBind(gl::GLContext* gl, GLenum target, const WebGLBuffer* buf);
2178 
2179 private:
2180     void UnwrapImpl();
2181 };
2182 
2183 ////
2184 
2185 bool
2186 Intersect(int32_t srcSize, int32_t read0, int32_t readSize, int32_t* out_intRead0,
2187           int32_t* out_intWrite0, int32_t* out_intSize);
2188 
2189 ////
2190 
2191 void
2192 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
2193                             const std::vector<IndexedBufferBinding>& field,
2194                             const char* name, uint32_t flags = 0);
2195 
2196 void
2197 ImplCycleCollectionUnlink(std::vector<IndexedBufferBinding>& field);
2198 
2199 } // namespace mozilla
2200 
2201 #endif
2202