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