content/canvas/src/WebGLContext.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     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/. */
     6 #ifndef WEBGLCONTEXT_H_
     7 #define WEBGLCONTEXT_H_
     9 #include "mozilla/Attributes.h"
    10 #include "GLDefs.h"
    11 #include "WebGLActiveInfo.h"
    12 #include "WebGLObjectModel.h"
    13 #include <stdarg.h>
    15 #include "nsTArray.h"
    16 #include "nsCycleCollectionNoteChild.h"
    18 #include "nsIDOMWebGLRenderingContext.h"
    19 #include "nsICanvasRenderingContextInternal.h"
    20 #include "mozilla/dom/HTMLCanvasElement.h"
    21 #include "nsWrapperCache.h"
    22 #include "nsIObserver.h"
    23 #include "nsLayoutUtils.h"
    25 #include "GLContextProvider.h"
    27 #include "mozilla/EnumeratedArray.h"
    28 #include "mozilla/LinkedList.h"
    29 #include "mozilla/CheckedInt.h"
    30 #include "mozilla/Scoped.h"
    31 #include "mozilla/gfx/2D.h"
    33 #ifdef XP_MACOSX
    34 #include "ForceDiscreteGPUHelperCGL.h"
    35 #endif
    37 #include "mozilla/dom/TypedArray.h"
    38 #include "mozilla/ErrorResult.h"
    40 class nsIDocShell;
    42 /*
    43  * Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
    44  *   https://bugzilla.mozilla.org/show_bug.cgi?id=686732
    45  *
    46  * Exceptions: some of the following values are set to higher values than in the spec because
    47  * the values in the spec are ridiculously low. They are explicitly marked below
    48 */
    49 #define MINVALUE_GL_MAX_TEXTURE_SIZE                  1024  // Different from the spec, which sets it to 64 on page 162
    50 #define MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE         512   // Different from the spec, which sets it to 16 on page 162
    51 #define MINVALUE_GL_MAX_VERTEX_ATTRIBS                8     // Page 164
    52 #define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS      16    // Page 164
    53 #define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS        128   // Page 164
    54 #define MINVALUE_GL_MAX_VARYING_VECTORS               8     // Page 164
    55 #define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS           8     // Page 164
    56 #define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS    0     // Page 164
    57 #define MINVALUE_GL_MAX_RENDERBUFFER_SIZE             1024  // Different from the spec, which sets it to 1 on page 164
    58 #define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS  8     // Page 164
    60 namespace mozilla {
    62 class WebGLMemoryPressureObserver;
    63 class WebGLContextBoundObject;
    64 class WebGLActiveInfo;
    65 class WebGLExtensionBase;
    66 class WebGLBuffer;
    67 class WebGLVertexAttribData;
    68 class WebGLShader;
    69 class WebGLProgram;
    70 class WebGLQuery;
    71 class WebGLUniformLocation;
    72 class WebGLFramebuffer;
    73 class WebGLRenderbuffer;
    74 class WebGLShaderPrecisionFormat;
    75 class WebGLTexture;
    76 class WebGLVertexArray;
    78 namespace dom {
    79 class ImageData;
    81 struct WebGLContextAttributes;
    82 template<typename> struct Nullable;
    83 }
    85 namespace gfx {
    86 class SourceSurface;
    87 }
    89 WebGLTexelFormat GetWebGLTexelFormat(GLenum format, GLenum type);
    91 struct WebGLContextOptions {
    92     // these are defaults
    93     WebGLContextOptions();
    95     bool operator==(const WebGLContextOptions& other) const {
    96         return
    97             alpha == other.alpha &&
    98             depth == other.depth &&
    99             stencil == other.stencil &&
   100             premultipliedAlpha == other.premultipliedAlpha &&
   101             antialias == other.antialias &&
   102             preserveDrawingBuffer == other.preserveDrawingBuffer;
   103     }
   105     bool operator!=(const WebGLContextOptions& other) const {
   106         return !operator==(other);
   107     }
   109     bool alpha;
   110     bool depth;
   111     bool stencil;
   112     bool premultipliedAlpha;
   113     bool antialias;
   114     bool preserveDrawingBuffer;
   115 };
   117 class WebGLContext :
   118     public nsIDOMWebGLRenderingContext,
   119     public nsICanvasRenderingContextInternal,
   120     public nsSupportsWeakReference,
   121     public WebGLRectangleObject,
   122     public nsWrapperCache
   123 {
   124     friend class WebGLContextUserData;
   125     friend class WebGLExtensionCompressedTextureATC;
   126     friend class WebGLExtensionCompressedTextureETC1;
   127     friend class WebGLExtensionCompressedTexturePVRTC;
   128     friend class WebGLExtensionCompressedTextureS3TC;
   129     friend class WebGLExtensionDepthTexture;
   130     friend class WebGLExtensionDrawBuffers;
   131     friend class WebGLExtensionLoseContext;
   132     friend class WebGLExtensionVertexArray;
   133     friend class WebGLMemoryPressureObserver;
   134     friend class WebGLMemoryTracker;
   136     enum {
   137         UNPACK_FLIP_Y_WEBGL = 0x9240,
   138         UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
   139         CONTEXT_LOST_WEBGL = 0x9242,
   140         UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243,
   141         BROWSER_DEFAULT_WEBGL = 0x9244,
   142         UNMASKED_VENDOR_WEBGL = 0x9245,
   143         UNMASKED_RENDERER_WEBGL = 0x9246
   144     };
   146 public:
   147     WebGLContext();
   148     virtual ~WebGLContext();
   150     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   152     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
   153                                                            nsIDOMWebGLRenderingContext)
   155     virtual JSObject* WrapObject(JSContext *cx) = 0;
   157     NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
   159     // nsICanvasRenderingContextInternal
   160 #ifdef DEBUG
   161     virtual int32_t GetWidth() const MOZ_OVERRIDE;
   162     virtual int32_t GetHeight() const MOZ_OVERRIDE;
   163 #endif
   164     NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
   165     NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE
   166         { return NS_ERROR_NOT_IMPLEMENTED; }
   167     NS_IMETHOD Reset() MOZ_OVERRIDE
   168         { /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
   169     virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
   170     NS_IMETHOD GetInputStream(const char* aMimeType,
   171                               const char16_t* aEncoderOptions,
   172                               nsIInputStream **aStream) MOZ_OVERRIDE;
   173     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha) MOZ_OVERRIDE;
   175     NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
   176     bool GetIsOpaque() MOZ_OVERRIDE { return false; }
   177     NS_IMETHOD SetContextOptions(JSContext* aCx,
   178                                  JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
   180     NS_IMETHOD SetIsIPC(bool b) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
   181     NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
   182     NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
   183                     int32_t x, int32_t y, int32_t w, int32_t h)
   184                     { return NS_ERROR_NOT_IMPLEMENTED; }
   185     NS_IMETHOD Swap(uint32_t nativeID,
   186                     int32_t x, int32_t y, int32_t w, int32_t h)
   187                     { return NS_ERROR_NOT_IMPLEMENTED; }
   189     bool LoseContext();
   190     bool RestoreContext();
   192     void SynthesizeGLError(GLenum err);
   193     void SynthesizeGLError(GLenum err, const char *fmt, ...);
   195     void ErrorInvalidEnum(const char *fmt = 0, ...);
   196     void ErrorInvalidOperation(const char *fmt = 0, ...);
   197     void ErrorInvalidValue(const char *fmt = 0, ...);
   198     void ErrorInvalidFramebufferOperation(const char *fmt = 0, ...);
   199     void ErrorInvalidEnumInfo(const char *info, GLenum enumvalue);
   200     void ErrorOutOfMemory(const char *fmt = 0, ...);
   202     const char *ErrorName(GLenum error);
   203     bool IsTextureFormatCompressed(GLenum format);
   205     void DummyFramebufferOperation(const char *info);
   207     WebGLTexture *activeBoundTextureForTarget(GLenum target) const {
   208         return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
   209                                              : mBoundCubeMapTextures[mActiveTexture];
   210     }
   212     already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
   213                                                  CanvasLayer *aOldLayer,
   214                                                  LayerManager *aManager) MOZ_OVERRIDE;
   216     // Note that 'clean' here refers to its invalidation state, not the
   217     // contents of the buffer.
   218     void MarkContextClean() MOZ_OVERRIDE { mInvalidated = false; }
   220     gl::GLContext* GL() const { return gl; }
   222     bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
   224     bool PresentScreenBuffer();
   226     // a number that increments every time we have an event that causes
   227     // all context resources to be lost.
   228     uint32_t Generation() { return mGeneration.value(); }
   230     // Returns null if the current bound FB is not likely complete.
   231     const WebGLRectangleObject* CurValidFBRectObject() const;
   233     static const size_t sMaxColorAttachments = 16;
   235     // This is similar to GLContext::ClearSafely, but tries to minimize the
   236     // amount of work it does.
   237     // It only clears the buffers we specify, and can reset its state without
   238     // first having to query anything, as WebGL knows its state at all times.
   239     void ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool colorAttachmentsMask[sMaxColorAttachments]);
   241     // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
   242     void ClearScreen();
   243     void ClearBackbufferIfNeeded();
   245     bool MinCapabilityMode() const { return mMinCapability; }
   247     void RobustnessTimerCallback(nsITimer* timer);
   248     static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer);
   249     void SetupContextLossTimer();
   250     void TerminateContextLossTimer();
   252     // WebIDL WebGLRenderingContext API
   253     dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
   254     GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; }
   255     GLsizei DrawingBufferHeight() const { return IsContextLost() ? 0 : mHeight; }
   257     void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
   258     bool IsContextLost() const { return mContextStatus != ContextNotLost; }
   259     void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
   260     void GetExtension(JSContext* cx, const nsAString& aName,
   261                       JS::MutableHandle<JSObject*> aRetval,
   262                       ErrorResult& rv);
   263     void ActiveTexture(GLenum texture);
   264     void AttachShader(WebGLProgram* program, WebGLShader* shader);
   265     void BindAttribLocation(WebGLProgram* program, GLuint location,
   266                             const nsAString& name);
   267     void BindFramebuffer(GLenum target, WebGLFramebuffer* wfb);
   268     void BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb);
   269     void BindTexture(GLenum target, WebGLTexture *tex);
   270     void BindVertexArray(WebGLVertexArray *vao);
   271     void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
   272     void BlendEquation(GLenum mode);
   273     void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
   274     void BlendFunc(GLenum sfactor, GLenum dfactor);
   275     void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
   276                            GLenum srcAlpha, GLenum dstAlpha);
   277     GLenum CheckFramebufferStatus(GLenum target);
   278     void Clear(GLbitfield mask);
   279     void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
   280     void ClearDepth(GLclampf v);
   281     void ClearStencil(GLint v);
   282     void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a);
   283     void CompileShader(WebGLShader *shader);
   284     void CompressedTexImage2D(GLenum target, GLint level,
   285                               GLenum internalformat, GLsizei width,
   286                               GLsizei height, GLint border,
   287                               const dom::ArrayBufferView& view);
   288     void CompressedTexSubImage2D(GLenum target, GLint level,
   289                                  GLint xoffset, GLint yoffset,
   290                                  GLsizei width, GLsizei height,
   291                                  GLenum format,
   292                                  const dom::ArrayBufferView& view);
   293     void CopyTexImage2D(GLenum target, GLint level,
   294                         GLenum internalformat, GLint x, GLint y,
   295                         GLsizei width, GLsizei height, GLint border);
   296     void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
   297                            GLint yoffset, GLint x, GLint y,
   298                            GLsizei width, GLsizei height);
   299     already_AddRefed<WebGLFramebuffer> CreateFramebuffer();
   300     already_AddRefed<WebGLProgram> CreateProgram();
   301     already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer();
   302     already_AddRefed<WebGLTexture> CreateTexture();
   303     already_AddRefed<WebGLShader> CreateShader(GLenum type);
   304     already_AddRefed<WebGLVertexArray> CreateVertexArray();
   305     void CullFace(GLenum face);
   306     void DeleteFramebuffer(WebGLFramebuffer *fbuf);
   307     void DeleteProgram(WebGLProgram *prog);
   308     void DeleteRenderbuffer(WebGLRenderbuffer *rbuf);
   309     void DeleteShader(WebGLShader *shader);
   310     void DeleteVertexArray(WebGLVertexArray *vao);
   311     void DeleteTexture(WebGLTexture *tex);
   312     void DepthFunc(GLenum func);
   313     void DepthMask(WebGLboolean b);
   314     void DepthRange(GLclampf zNear, GLclampf zFar);
   315     void DetachShader(WebGLProgram *program, WebGLShader *shader);
   316     void DrawBuffers(const dom::Sequence<GLenum>& buffers);
   317     void Flush();
   318     void Finish();
   319     void FramebufferRenderbuffer(GLenum target, GLenum attachment,
   320                                  GLenum rbtarget, WebGLRenderbuffer *wrb);
   321     void FramebufferTexture2D(GLenum target, GLenum attachment,
   322                               GLenum textarget, WebGLTexture *tobj,
   323                               GLint level);
   324     void FrontFace(GLenum mode);
   325     void GenerateMipmap(GLenum target);
   326     already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,
   327                                                       GLuint index);
   328     already_AddRefed<WebGLActiveInfo> GetActiveUniform(WebGLProgram *prog,
   329                                                        GLuint index);
   330     void GetAttachedShaders(WebGLProgram* prog,
   331                             dom::Nullable< nsTArray<WebGLShader*> > &retval);
   332     GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
   333     JS::Value GetBufferParameter(GLenum target, GLenum pname);
   334     void GetBufferParameter(JSContext* /* unused */, GLenum target,
   335                             GLenum pname,
   336                             JS::MutableHandle<JS::Value> retval) {
   337         retval.set(GetBufferParameter(target, pname));
   338     }
   339     GLenum GetError();
   340     JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
   341                                                 GLenum target,
   342                                                 GLenum attachment,
   343                                                 GLenum pname,
   344                                                 ErrorResult& rv);
   345     void GetFramebufferAttachmentParameter(JSContext* cx,
   346                                            GLenum target,
   347                                            GLenum attachment,
   348                                            GLenum pname,
   349                                            JS::MutableHandle<JS::Value> retval,
   350                                            ErrorResult& rv) {
   351         retval.set(GetFramebufferAttachmentParameter(cx, target, attachment,
   352                                                      pname, rv));
   353     }
   354     JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname);
   355     void  GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
   356                               GLenum pname,
   357                               JS::MutableHandle<JS::Value> retval) {
   358         retval.set(GetProgramParameter(prog, pname));
   359     }
   360     void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval);
   361     void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval);
   362     JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
   363     void GetRenderbufferParameter(JSContext* /* unused */,
   364                                   GLenum target, GLenum pname,
   365                                   JS::MutableHandle<JS::Value> retval) {
   366         retval.set(GetRenderbufferParameter(target, pname));
   367     }
   368     JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname);
   369     void GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
   370                             GLenum pname,
   371                             JS::MutableHandle<JS::Value> retval) {
   372         retval.set(GetShaderParameter(shader, pname));
   373     }
   374     already_AddRefed<WebGLShaderPrecisionFormat>
   375       GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
   376     void GetShaderInfoLog(WebGLShader *shader, nsACString& retval);
   377     void GetShaderInfoLog(WebGLShader *shader, nsAString& retval);
   378     void GetShaderSource(WebGLShader *shader, nsAString& retval);
   379     void GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval);
   380     JS::Value GetTexParameter(GLenum target, GLenum pname);
   381     void GetTexParameter(JSContext * /* unused */, GLenum target,
   382                          GLenum pname,
   383                          JS::MutableHandle<JS::Value> retval) {
   384         retval.set(GetTexParameter(target, pname));
   385     }
   386     JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
   387                          WebGLUniformLocation *location);
   388     void GetUniform(JSContext* cx, WebGLProgram *prog,
   389                     WebGLUniformLocation *location,
   390                     JS::MutableHandle<JS::Value> retval) {
   391         retval.set(GetUniform(cx, prog, location));
   392     }
   393     already_AddRefed<WebGLUniformLocation>
   394       GetUniformLocation(WebGLProgram *prog, const nsAString& name);
   395     void Hint(GLenum target, GLenum mode);
   396     bool IsFramebuffer(WebGLFramebuffer *fb);
   397     bool IsProgram(WebGLProgram *prog);
   398     bool IsRenderbuffer(WebGLRenderbuffer *rb);
   399     bool IsShader(WebGLShader *shader);
   400     bool IsTexture(WebGLTexture *tex);
   401     bool IsVertexArray(WebGLVertexArray *vao);
   402     void LineWidth(GLfloat width);
   403     void LinkProgram(WebGLProgram *program);
   404     void PixelStorei(GLenum pname, GLint param);
   405     void PolygonOffset(GLfloat factor, GLfloat units);
   406     void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   407                     GLenum format, GLenum type,
   408                     const Nullable<dom::ArrayBufferView> &pixels,
   409                     ErrorResult& rv);
   410     void RenderbufferStorage(GLenum target, GLenum internalformat,
   411                              GLsizei width, GLsizei height);
   412     void SampleCoverage(GLclampf value, WebGLboolean invert);
   413     void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
   414     void ShaderSource(WebGLShader *shader, const nsAString& source);
   415     void StencilFunc(GLenum func, GLint ref, GLuint mask);
   416     void StencilFuncSeparate(GLenum face, GLenum func, GLint ref,
   417                              GLuint mask);
   418     void StencilMask(GLuint mask);
   419     void StencilMaskSeparate(GLenum face, GLuint mask);
   420     void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
   421     void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
   422                            GLenum dppass);
   423     void TexImage2D(GLenum target, GLint level,
   424                     GLenum internalformat, GLsizei width,
   425                     GLsizei height, GLint border, GLenum format,
   426                     GLenum type,
   427                     const Nullable<dom::ArrayBufferView> &pixels,
   428                     ErrorResult& rv);
   429     void TexImage2D(GLenum target, GLint level,
   430                     GLenum internalformat, GLenum format, GLenum type,
   431                     dom::ImageData* pixels, ErrorResult& rv);
   432     // Allow whatever element types the bindings are willing to pass
   433     // us in TexImage2D
   434     template<class ElementType>
   435     void TexImage2D(GLenum target, GLint level,
   436                     GLenum internalformat, GLenum format, GLenum type,
   437                     ElementType& elt, ErrorResult& rv)
   438     {
   439         if (IsContextLost())
   440             return;
   441         RefPtr<gfx::DataSourceSurface> data;
   442         WebGLTexelFormat srcFormat;
   443         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
   444         rv = SurfaceFromElementResultToImageSurface(res, data,
   445                                                     &srcFormat);
   446         if (rv.Failed() || !data)
   447             return;
   449         gfx::IntSize size = data->GetSize();
   450         uint32_t byteLength = data->Stride() * size.height;
   451         return TexImage2D_base(target, level, internalformat,
   452                                size.width, size.height, data->Stride(),
   453                                0, format, type, data->GetData(), byteLength,
   454                                -1, srcFormat, mPixelStorePremultiplyAlpha);
   455     }
   456     void TexParameterf(GLenum target, GLenum pname, GLfloat param) {
   457         TexParameter_base(target, pname, nullptr, &param);
   458     }
   459     void TexParameteri(GLenum target, GLenum pname, GLint param) {
   460         TexParameter_base(target, pname, &param, nullptr);
   461     }
   463     void TexSubImage2D(GLenum target, GLint level,
   464                        GLint xoffset, GLint yoffset,
   465                        GLsizei width, GLsizei height, GLenum format,
   466                        GLenum type,
   467                        const Nullable<dom::ArrayBufferView> &pixels,
   468                        ErrorResult& rv);
   469     void TexSubImage2D(GLenum target, GLint level,
   470                        GLint xoffset, GLint yoffset, GLenum format,
   471                        GLenum type, dom::ImageData* pixels, ErrorResult& rv);
   472     // Allow whatever element types the bindings are willing to pass
   473     // us in TexSubImage2D
   474     template<class ElementType>
   475     void TexSubImage2D(GLenum target, GLint level,
   476                        GLint xoffset, GLint yoffset, GLenum format,
   477                        GLenum type, ElementType& elt, ErrorResult& rv)
   478     {
   479         if (IsContextLost())
   480             return;
   481         RefPtr<gfx::DataSourceSurface> data;
   482         WebGLTexelFormat srcFormat;
   483         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
   484         rv = SurfaceFromElementResultToImageSurface(res, data,
   485                                                     &srcFormat);
   486         if (rv.Failed() || !data)
   487             return;
   489         gfx::IntSize size = data->GetSize();
   490         uint32_t byteLength = data->Stride() * size.height;
   491         return TexSubImage2D_base(target, level, xoffset, yoffset,
   492                                   size.width, size.height,
   493                                   data->Stride(), format, type,
   494                                   data->GetData(), byteLength,
   495                                   -1, srcFormat, mPixelStorePremultiplyAlpha);
   497     }
   499     void Uniform1i(WebGLUniformLocation* location, GLint x);
   500     void Uniform2i(WebGLUniformLocation* location, GLint x, GLint y);
   501     void Uniform3i(WebGLUniformLocation* location, GLint x, GLint y,
   502                    GLint z);
   503     void Uniform4i(WebGLUniformLocation* location, GLint x, GLint y,
   504                    GLint z, GLint w);
   506     void Uniform1f(WebGLUniformLocation* location, GLfloat x);
   507     void Uniform2f(WebGLUniformLocation* location, GLfloat x, GLfloat y);
   508     void Uniform3f(WebGLUniformLocation* location, GLfloat x, GLfloat y,
   509                    GLfloat z);
   510     void Uniform4f(WebGLUniformLocation* location, GLfloat x, GLfloat y,
   511                    GLfloat z, GLfloat w);
   513     void Uniform1iv(WebGLUniformLocation* location,
   514                     const dom::Int32Array& arr) {
   515         arr.ComputeLengthAndData();
   516         Uniform1iv_base(location, arr.Length(), arr.Data());
   517     }
   518     void Uniform1iv(WebGLUniformLocation* location,
   519                     const dom::Sequence<GLint>& arr) {
   520         Uniform1iv_base(location, arr.Length(), arr.Elements());
   521     }
   522     void Uniform1iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   523                          const GLint* data);
   525     void Uniform2iv(WebGLUniformLocation* location,
   526                     const dom::Int32Array& arr) {
   527         arr.ComputeLengthAndData();
   528         Uniform2iv_base(location, arr.Length(), arr.Data());
   529     }
   530     void Uniform2iv(WebGLUniformLocation* location,
   531                     const dom::Sequence<GLint>& arr) {
   532         Uniform2iv_base(location, arr.Length(), arr.Elements());
   533     }
   534     void Uniform2iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   535                          const GLint* data);
   537     void Uniform3iv(WebGLUniformLocation* location,
   538                     const dom::Int32Array& arr) {
   539         arr.ComputeLengthAndData();
   540         Uniform3iv_base(location, arr.Length(), arr.Data());
   541     }
   542     void Uniform3iv(WebGLUniformLocation* location,
   543                     const dom::Sequence<GLint>& arr) {
   544         Uniform3iv_base(location, arr.Length(), arr.Elements());
   545     }
   546     void Uniform3iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   547                          const GLint* data);
   549     void Uniform4iv(WebGLUniformLocation* location,
   550                     const dom::Int32Array& arr) {
   551         arr.ComputeLengthAndData();
   552         Uniform4iv_base(location, arr.Length(), arr.Data());
   553     }
   554     void Uniform4iv(WebGLUniformLocation* location,
   555                     const dom::Sequence<GLint>& arr) {
   556         Uniform4iv_base(location, arr.Length(), arr.Elements());
   557     }
   558     void Uniform4iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   559                          const GLint* data);
   561     void Uniform1fv(WebGLUniformLocation* location,
   562                     const dom::Float32Array& arr) {
   563         arr.ComputeLengthAndData();
   564         Uniform1fv_base(location, arr.Length(), arr.Data());
   565     }
   566     void Uniform1fv(WebGLUniformLocation* location,
   567                     const dom::Sequence<GLfloat>& arr) {
   568         Uniform1fv_base(location, arr.Length(), arr.Elements());
   569     }
   570     void Uniform1fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   571                          const GLfloat* data);
   573     void Uniform2fv(WebGLUniformLocation* location,
   574                     const dom::Float32Array& arr) {
   575         arr.ComputeLengthAndData();
   576         Uniform2fv_base(location, arr.Length(), arr.Data());
   577     }
   578     void Uniform2fv(WebGLUniformLocation* location,
   579                     const dom::Sequence<GLfloat>& arr) {
   580         Uniform2fv_base(location, arr.Length(), arr.Elements());
   581     }
   582     void Uniform2fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   583                          const GLfloat* data);
   585     void Uniform3fv(WebGLUniformLocation* location,
   586                     const dom::Float32Array& arr) {
   587         arr.ComputeLengthAndData();
   588         Uniform3fv_base(location, arr.Length(), arr.Data());
   589     }
   590     void Uniform3fv(WebGLUniformLocation* location,
   591                     const dom::Sequence<GLfloat>& arr) {
   592         Uniform3fv_base(location, arr.Length(), arr.Elements());
   593     }
   594     void Uniform3fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   595                          const GLfloat* data);
   597     void Uniform4fv(WebGLUniformLocation* location,
   598                     const dom::Float32Array& arr) {
   599         arr.ComputeLengthAndData();
   600         Uniform4fv_base(location, arr.Length(), arr.Data());
   601     }
   602     void Uniform4fv(WebGLUniformLocation* location,
   603                     const dom::Sequence<GLfloat>& arr) {
   604         Uniform4fv_base(location, arr.Length(), arr.Elements());
   605     }
   606     void Uniform4fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   607                          const GLfloat* data);
   609     void UniformMatrix2fv(WebGLUniformLocation* location,
   610                           WebGLboolean transpose,
   611                           const dom::Float32Array &value) {
   612         value.ComputeLengthAndData();
   613         UniformMatrix2fv_base(location, transpose, value.Length(), value.Data());
   614     }
   615     void UniformMatrix2fv(WebGLUniformLocation* location,
   616                           WebGLboolean transpose,
   617                           const dom::Sequence<float> &value) {
   618         UniformMatrix2fv_base(location, transpose, value.Length(),
   619                               value.Elements());
   620     }
   621     void UniformMatrix2fv_base(WebGLUniformLocation* location,
   622                                WebGLboolean transpose, uint32_t arrayLength,
   623                                const float* data);
   625     void UniformMatrix3fv(WebGLUniformLocation* location,
   626                           WebGLboolean transpose,
   627                           const dom::Float32Array &value) {
   628         value.ComputeLengthAndData();
   629         UniformMatrix3fv_base(location, transpose, value.Length(), value.Data());
   630     }
   631     void UniformMatrix3fv(WebGLUniformLocation* location,
   632                           WebGLboolean transpose,
   633                           const dom::Sequence<float> &value) {
   634         UniformMatrix3fv_base(location, transpose, value.Length(),
   635                               value.Elements());
   636     }
   637     void UniformMatrix3fv_base(WebGLUniformLocation* location,
   638                                WebGLboolean transpose, uint32_t arrayLength,
   639                                const float* data);
   641     void UniformMatrix4fv(WebGLUniformLocation* location,
   642                           WebGLboolean transpose,
   643                           const dom::Float32Array &value) {
   644         value.ComputeLengthAndData();
   645         UniformMatrix4fv_base(location, transpose, value.Length(), value.Data());
   646     }
   647     void UniformMatrix4fv(WebGLUniformLocation* location,
   648                           WebGLboolean transpose,
   649                           const dom::Sequence<float> &value) {
   650         UniformMatrix4fv_base(location, transpose, value.Length(),
   651                               value.Elements());
   652     }
   653     void UniformMatrix4fv_base(WebGLUniformLocation* location,
   654                                WebGLboolean transpose, uint32_t arrayLength,
   655                                const float* data);
   657     void UseProgram(WebGLProgram *prog);
   658     bool ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength);
   659     bool ValidateUniformArraySetter(const char* name, uint32_t expectedElemSize, WebGLUniformLocation *location_object,
   660                                     GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength);
   661     bool ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLUniformLocation *location_object,
   662                                           GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength,
   663                                           WebGLboolean aTranspose);
   664     bool ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location);
   665     void ValidateProgram(WebGLProgram *prog);
   666     bool ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object);
   667     bool ValidateSamplerUniformSetter(const char* info,
   668                                     WebGLUniformLocation *location,
   669                                     GLint value);
   671     void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
   673 // -----------------------------------------------------------------------------
   674 // Asynchronous Queries (WebGLContextAsyncQueries.cpp)
   675 public:
   676     already_AddRefed<WebGLQuery> CreateQuery();
   677     void DeleteQuery(WebGLQuery *query);
   678     void BeginQuery(GLenum target, WebGLQuery *query);
   679     void EndQuery(GLenum target);
   680     bool IsQuery(WebGLQuery *query);
   681     already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
   682     JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname);
   683     void GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname,
   684                         JS::MutableHandle<JS::Value> retval) {
   685         retval.set(GetQueryObject(cx, query, pname));
   686     }
   688 private:
   689     // ANY_SAMPLES_PASSED(_CONSERVATIVE) slot
   690     WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
   692     // LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN slot
   693     WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
   695     WebGLRefPtr<WebGLQuery>* GetQueryTargetSlot(GLenum target, const char* infos);
   697 // -----------------------------------------------------------------------------
   698 // Buffer Objects (WebGLContextBuffers.cpp)
   699 public:
   700     void BindBuffer(GLenum target, WebGLBuffer* buf);
   701     void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
   702     void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
   703                          WebGLintptr offset, WebGLsizeiptr size);
   704     void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
   705     void BufferData(GLenum target, const dom::ArrayBufferView &data,
   706                     GLenum usage);
   707     void BufferData(GLenum target,
   708                     const Nullable<dom::ArrayBuffer> &maybeData,
   709                     GLenum usage);
   710     void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
   711                        const dom::ArrayBufferView &data);
   712     void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
   713                        const Nullable<dom::ArrayBuffer> &maybeData);
   714     already_AddRefed<WebGLBuffer> CreateBuffer();
   715     void DeleteBuffer(WebGLBuffer *buf);
   716     bool IsBuffer(WebGLBuffer *buffer);
   718 private:
   719     // ARRAY_BUFFER slot
   720     WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
   722     // TRANSFORM_FEEDBACK_BUFFER slot
   723     WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
   725     // these two functions emit INVALID_ENUM for invalid `target`.
   726     WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target, const char* infos);
   727     WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos);
   728     bool ValidateBufferUsageEnum(GLenum target, const char* infos);
   730 // -----------------------------------------------------------------------------
   731 // State and State Requests (WebGLContextState.cpp)
   732 public:
   733     void Disable(GLenum cap);
   734     void Enable(GLenum cap);
   735     JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
   736     void GetParameter(JSContext* cx, GLenum pname,
   737                       JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
   738         retval.set(GetParameter(cx, pname, rv));
   739     }
   740     void GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
   741                              JS::MutableHandle<JS::Value> retval);
   742     bool IsEnabled(GLenum cap);
   744 private:
   745     // State tracking slots
   746     realGLboolean mDitherEnabled;
   747     realGLboolean mRasterizerDiscardEnabled;
   748     realGLboolean mScissorTestEnabled;
   750     bool ValidateCapabilityEnum(GLenum cap, const char* info);
   751     realGLboolean* GetStateTrackingSlot(GLenum cap);
   753 // -----------------------------------------------------------------------------
   754 // Vertices Feature (WebGLContextVertices.cpp)
   755 public:
   756     void DrawArrays(GLenum mode, GLint first, GLsizei count);
   757     void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
   758     void DrawElements(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset);
   759     void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
   760                                WebGLintptr byteOffset, GLsizei primcount);
   762     void EnableVertexAttribArray(GLuint index);
   763     void DisableVertexAttribArray(GLuint index);
   765     JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
   766                               ErrorResult& rv);
   767     void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
   768                          JS::MutableHandle<JS::Value> retval,
   769                          ErrorResult& rv) {
   770         retval.set(GetVertexAttrib(cx, index, pname, rv));
   771     }
   772     WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
   774     void VertexAttrib1f(GLuint index, GLfloat x0);
   775     void VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1);
   776     void VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1,
   777                         GLfloat x2);
   778     void VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
   779                         GLfloat x2, GLfloat x3);
   781     void VertexAttrib1fv(GLuint idx, const dom::Float32Array &arr) {
   782         arr.ComputeLengthAndData();
   783         VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
   784     }
   785     void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   786         VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
   787     }
   789     void VertexAttrib2fv(GLuint idx, const dom::Float32Array &arr) {
   790         arr.ComputeLengthAndData();
   791         VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
   792     }
   793     void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   794         VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
   795     }
   797     void VertexAttrib3fv(GLuint idx, const dom::Float32Array &arr) {
   798         arr.ComputeLengthAndData();
   799         VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
   800     }
   801     void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   802         VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
   803     }
   805     void VertexAttrib4fv(GLuint idx, const dom::Float32Array &arr) {
   806         arr.ComputeLengthAndData();
   807         VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
   808     }
   809     void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   810         VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());
   811     }
   813     void VertexAttribPointer(GLuint index, GLint size, GLenum type,
   814                              WebGLboolean normalized, GLsizei stride,
   815                              WebGLintptr byteOffset);
   816     void VertexAttribDivisor(GLuint index, GLuint divisor);
   818 private:
   819     // Cache the max number of vertices and instances that can be read from
   820     // bound VBOs (result of ValidateBuffers).
   821     bool mBufferFetchingIsVerified;
   822     bool mBufferFetchingHasPerVertex;
   823     uint32_t mMaxFetchedVertices;
   824     uint32_t mMaxFetchedInstances;
   826     inline void InvalidateBufferFetching()
   827     {
   828         mBufferFetchingIsVerified = false;
   829         mBufferFetchingHasPerVertex = false;
   830         mMaxFetchedVertices = 0;
   831         mMaxFetchedInstances = 0;
   832     }
   834     bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info);
   835     bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset,
   836                             GLsizei primcount, const char* info,
   837                             GLuint* out_upperBound = nullptr);
   838     bool DrawInstanced_check(const char* info);
   839     void Draw_cleanup();
   841     void VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   842     void VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   843     void VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   844     void VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   846     bool ValidateBufferFetching(const char *info);
   847     bool BindArrayAttribToLocation0(WebGLProgram *program);
   849 // -----------------------------------------------------------------------------
   850 // PROTECTED
   851 protected:
   852     void SetFakeBlackStatus(WebGLContextFakeBlackStatus x) {
   853         mFakeBlackStatus = x;
   854     }
   855     // Returns the current fake-black-status, except if it was Unknown,
   856     // in which case this function resolves it first, so it never returns Unknown.
   857     WebGLContextFakeBlackStatus ResolvedFakeBlackStatus();
   859     void BindFakeBlackTextures();
   860     void UnbindFakeBlackTextures();
   862     WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need();
   863     bool DoFakeVertexAttrib0(GLuint vertexCount);
   864     void UndoFakeVertexAttrib0();
   866     static CheckedUint32 GetImageSize(GLsizei height,
   867                                       GLsizei width,
   868                                       uint32_t pixelSize,
   869                                       uint32_t alignment);
   871     // Returns x rounded to the next highest multiple of y.
   872     static CheckedUint32 RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y) {
   873         return ((x + y - 1) / y) * y;
   874     }
   876     nsRefPtr<gl::GLContext> gl;
   878     CheckedUint32 mGeneration;
   880     WebGLContextOptions mOptions;
   882     bool mInvalidated;
   883     bool mResetLayer;
   884     bool mOptionsFrozen;
   885     bool mMinCapability;
   886     bool mDisableExtensions;
   887     bool mHasRobustness;
   888     bool mIsMesa;
   889     bool mLoseContextOnHeapMinimize;
   890     bool mCanLoseContextInForeground;
   891     bool mShouldPresent;
   892     bool mBackbufferNeedsClear;
   893     bool mDisableFragHighP;
   895     template<typename WebGLObjectType>
   896     void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
   898     GLuint mActiveTexture;
   900     // glGetError sources:
   901     bool mEmitContextLostErrorOnce;
   902     GLenum mWebGLError;
   903     GLenum mUnderlyingGLError;
   904     GLenum GetAndFlushUnderlyingGLErrors();
   906     // whether shader validation is supported
   907     bool mShaderValidation;
   909     // some GL constants
   910     int32_t mGLMaxVertexAttribs;
   911     int32_t mGLMaxTextureUnits;
   912     int32_t mGLMaxTextureSize;
   913     int32_t mGLMaxCubeMapTextureSize;
   914     int32_t mGLMaxRenderbufferSize;
   915     int32_t mGLMaxTextureImageUnits;
   916     int32_t mGLMaxVertexTextureImageUnits;
   917     int32_t mGLMaxVaryingVectors;
   918     int32_t mGLMaxFragmentUniformVectors;
   919     int32_t mGLMaxVertexUniformVectors;
   920     int32_t mGLMaxColorAttachments;
   921     int32_t mGLMaxDrawBuffers;
   922     uint32_t mGLMaxTransformFeedbackSeparateAttribs;
   924     // Represents current status of the context with respect to context loss.
   925     // That is, whether the context is lost, and what part of the context loss
   926     // process we currently are at.
   927     // This is used to support the WebGL spec's asyncronous nature in handling
   928     // context loss.
   929     enum ContextStatus {
   930         // The context is stable; there either are none or we don't know of any.
   931         ContextNotLost,
   932         // The context has been lost, but we have not yet sent an event to the
   933         // script informing it of this.
   934         ContextLostAwaitingEvent,
   935         // The context has been lost, and we have sent the script an event
   936         // informing it of this.
   937         ContextLost,
   938         // The context is lost, an event has been sent to the script, and the
   939         // script correctly handled the event. We are waiting for the context to
   940         // be restored.
   941         ContextLostAwaitingRestore
   942     };
   944     // -------------------------------------------------------------------------
   945     // WebGL extensions (implemented in WebGLContextExtensions.cpp)
   946     typedef EnumeratedArray<WebGLExtensionID,
   947                             WebGLExtensionID::Max,
   948                             nsRefPtr<WebGLExtensionBase>> ExtensionsArrayType;
   950     ExtensionsArrayType mExtensions;
   952     // enable an extension. the extension should not be enabled before.
   953     void EnableExtension(WebGLExtensionID ext);
   955     // returns true if the extension has been enabled by calling getExtension.
   956     bool IsExtensionEnabled(WebGLExtensionID ext) const;
   958     // returns true if the extension is supported for this JSContext (this decides what getSupportedExtensions exposes)
   959     bool IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const;
   960     bool IsExtensionSupported(WebGLExtensionID ext) const;
   962     static const char* GetExtensionString(WebGLExtensionID ext);
   964     nsTArray<GLenum> mCompressedTextureFormats;
   966     // -------------------------------------------------------------------------
   967     // WebGL 2 specifics (implemented in WebGL2Context.cpp)
   969     virtual bool IsWebGL2() const = 0;
   971     bool InitWebGL2();
   974     // -------------------------------------------------------------------------
   975     // Validation functions (implemented in WebGLContextValidate.cpp)
   976     GLenum BaseTexFormat(GLenum internalFormat) const;
   978     bool InitAndValidateGL();
   979     bool ValidateBlendEquationEnum(GLenum cap, const char *info);
   980     bool ValidateBlendFuncDstEnum(GLenum mode, const char *info);
   981     bool ValidateBlendFuncSrcEnum(GLenum mode, const char *info);
   982     bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info);
   983     bool ValidateTextureTargetEnum(GLenum target, const char *info);
   984     bool ValidateComparisonEnum(GLenum target, const char *info);
   985     bool ValidateStencilOpEnum(GLenum action, const char *info);
   986     bool ValidateFaceEnum(GLenum face, const char *info);
   987     bool ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFunc func);
   988     bool ValidateDrawModeEnum(GLenum mode, const char *info);
   989     bool ValidateAttribIndex(GLuint index, const char *info);
   990     bool ValidateStencilParamsForDrawCall();
   992     bool ValidateGLSLVariableName(const nsAString& name, const char *info);
   993     bool ValidateGLSLCharacter(char16_t c);
   994     bool ValidateGLSLString(const nsAString& string, const char *info);
   996     bool ValidateTexImage(GLuint dims, GLenum target,
   997                           GLint level, GLint internalFormat,
   998                           GLint xoffset, GLint yoffset, GLint zoffset,
   999                           GLint width, GLint height, GLint depth,
  1000                           GLint border, GLenum format, GLenum type,
  1001                           WebGLTexImageFunc func);
  1002     bool ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFunc func);
  1003     bool ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func);
  1004     bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func);
  1005     bool ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func);
  1006     bool ValidateTexImageSize(GLenum target, GLint level,
  1007                               GLint width, GLint height, GLint depth,
  1008                               WebGLTexImageFunc func);
  1009     bool ValidateTexSubImageSize(GLint x, GLint y, GLint z,
  1010                                  GLsizei width, GLsizei height, GLsizei depth,
  1011                                  GLsizei baseWidth, GLsizei baseHeight, GLsizei baseDepth,
  1012                                  WebGLTexImageFunc func);
  1014     bool ValidateCompTexImageSize(GLenum target, GLint level, GLenum format,
  1015                                   GLint xoffset, GLint yoffset,
  1016                                   GLsizei width, GLsizei height,
  1017                                   GLsizei levelWidth, GLsizei levelHeight,
  1018                                   WebGLTexImageFunc func);
  1019     bool ValidateCompTexImageDataSize(GLint level, GLenum format,
  1020                                       GLsizei width, GLsizei height,
  1021                                       uint32_t byteLength, WebGLTexImageFunc func);
  1024     static uint32_t GetBitsPerTexel(GLenum format, GLenum type);
  1026     void Invalidate();
  1027     void DestroyResourcesAndContext();
  1029     void MakeContextCurrent() const;
  1031     // helpers
  1032     void TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
  1033                          GLsizei width, GLsizei height, GLsizei srcStrideOrZero, GLint border,
  1034                          GLenum format, GLenum type,
  1035                          void *data, uint32_t byteLength,
  1036                          int jsArrayType,
  1037                          WebGLTexelFormat srcFormat, bool srcPremultiplied);
  1038     void TexSubImage2D_base(GLenum target, GLint level,
  1039                             GLint xoffset, GLint yoffset,
  1040                             GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
  1041                             GLenum format, GLenum type,
  1042                             void *pixels, uint32_t byteLength,
  1043                             int jsArrayType,
  1044                             WebGLTexelFormat srcFormat, bool srcPremultiplied);
  1045     void TexParameter_base(GLenum target, GLenum pname,
  1046                            GLint *intParamPtr, GLfloat *floatParamPtr);
  1048     void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
  1049                       const uint8_t* src, uint8_t *dst,
  1050                       WebGLTexelFormat srcFormat, bool srcPremultiplied,
  1051                       WebGLTexelFormat dstFormat, bool dstPremultiplied,
  1052                       size_t dstTexelSize);
  1054     template<class ElementType>
  1055     nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(ElementType* aElement) {
  1056         MOZ_ASSERT(aElement);
  1057         uint32_t flags =
  1058              nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
  1060         if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
  1061             flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
  1062         if (!mPixelStorePremultiplyAlpha)
  1063             flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
  1064         return nsLayoutUtils::SurfaceFromElement(aElement, flags);
  1066     template<class ElementType>
  1067     nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(ElementType& aElement)
  1069       return SurfaceFromElement(&aElement);
  1072     nsresult SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
  1073                                                     RefPtr<gfx::DataSourceSurface>& imageOut,
  1074                                                     WebGLTexelFormat *format);
  1076     void CopyTexSubImage2D_base(GLenum target,
  1077                                 GLint level,
  1078                                 GLenum internalformat,
  1079                                 GLint xoffset,
  1080                                 GLint yoffset,
  1081                                 GLint x,
  1082                                 GLint y,
  1083                                 GLsizei width,
  1084                                 GLsizei height,
  1085                                 bool sub);
  1087     // Returns false if aObject is null or not valid
  1088     template<class ObjectType>
  1089     bool ValidateObject(const char* info, ObjectType *aObject);
  1090     // Returns false if aObject is not valid.  Considers null to be valid.
  1091     template<class ObjectType>
  1092     bool ValidateObjectAllowNull(const char* info, ObjectType *aObject);
  1093     // Returns false if aObject is not valid, but considers deleted
  1094     // objects and null objects valid.
  1095     template<class ObjectType>
  1096     bool ValidateObjectAllowDeletedOrNull(const char* info, ObjectType *aObject);
  1097     // Returns false if aObject is null or not valid, but considers deleted
  1098     // objects valid.
  1099     template<class ObjectType>
  1100     bool ValidateObjectAllowDeleted(const char* info, ObjectType *aObject);
  1101 private:
  1102     // Like ValidateObject, but only for cases when aObject is known
  1103     // to not be null already.
  1104     template<class ObjectType>
  1105     bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject);
  1107 protected:
  1108     int32_t MaxTextureSizeForTarget(GLenum target) const {
  1109         MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
  1110                    (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
  1111                     target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z),
  1112                    "Invalid target enum");
  1113         return (target == LOCAL_GL_TEXTURE_2D) ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
  1116     /** like glBufferData but if the call may change the buffer size, checks any GL error generated
  1117      * by this glBufferData call and returns it */
  1118     GLenum CheckedBufferData(GLenum target,
  1119                              GLsizeiptr size,
  1120                              const GLvoid *data,
  1121                              GLenum usage);
  1122     /** like glTexImage2D but if the call may change the texture size, checks any GL error generated
  1123      * by this glTexImage2D call and returns it */
  1124     GLenum CheckedTexImage2D(GLenum target,
  1125                              GLint level,
  1126                              GLenum internalFormat,
  1127                              GLsizei width,
  1128                              GLsizei height,
  1129                              GLint border,
  1130                              GLenum format,
  1131                              GLenum type,
  1132                              const GLvoid *data);
  1134     void MaybeRestoreContext();
  1135     void ForceLoseContext();
  1136     void ForceRestoreContext();
  1138     nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
  1139     nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
  1141     WebGLRefPtr<WebGLProgram> mCurrentProgram;
  1143     uint32_t mMaxFramebufferColorAttachments;
  1145     WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
  1146     WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
  1147     WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
  1149     LinkedList<WebGLTexture> mTextures;
  1150     LinkedList<WebGLBuffer> mBuffers;
  1151     LinkedList<WebGLProgram> mPrograms;
  1152     LinkedList<WebGLQuery> mQueries;
  1153     LinkedList<WebGLShader> mShaders;
  1154     LinkedList<WebGLRenderbuffer> mRenderbuffers;
  1155     LinkedList<WebGLFramebuffer> mFramebuffers;
  1156     LinkedList<WebGLVertexArray> mVertexArrays;
  1158     WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
  1160     // PixelStore parameters
  1161     uint32_t mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
  1162     bool mPixelStoreFlipY, mPixelStorePremultiplyAlpha;
  1164     WebGLContextFakeBlackStatus mFakeBlackStatus;
  1166     class FakeBlackTexture
  1168         gl::GLContext* mGL;
  1169         GLuint mGLName;
  1171     public:
  1172         FakeBlackTexture(gl::GLContext* gl, GLenum target, GLenum format);
  1173         ~FakeBlackTexture();
  1174         GLuint GLName() const { return mGLName; }
  1175     };
  1177     ScopedDeletePtr<FakeBlackTexture> mBlackOpaqueTexture2D,
  1178                                       mBlackOpaqueTextureCubeMap,
  1179                                       mBlackTransparentTexture2D,
  1180                                       mBlackTransparentTextureCubeMap;
  1182     void BindFakeBlackTexturesHelper(
  1183         GLenum target,
  1184         const nsTArray<WebGLRefPtr<WebGLTexture> >& boundTexturesArray,
  1185         ScopedDeletePtr<FakeBlackTexture> & opaqueTextureScopedPtr,
  1186         ScopedDeletePtr<FakeBlackTexture> & transparentTextureScopedPtr);
  1188     GLfloat mVertexAttrib0Vector[4];
  1189     GLfloat mFakeVertexAttrib0BufferObjectVector[4];
  1190     size_t mFakeVertexAttrib0BufferObjectSize;
  1191     GLuint mFakeVertexAttrib0BufferObject;
  1192     WebGLVertexAttrib0Status mFakeVertexAttrib0BufferStatus;
  1194     GLint mStencilRefFront, mStencilRefBack;
  1195     GLuint mStencilValueMaskFront, mStencilValueMaskBack,
  1196               mStencilWriteMaskFront, mStencilWriteMaskBack;
  1197     realGLboolean mColorWriteMask[4];
  1198     realGLboolean mDepthWriteMask;
  1199     GLfloat mColorClearValue[4];
  1200     GLint mStencilClearValue;
  1201     GLfloat mDepthClearValue;
  1203     GLint mViewportX;
  1204     GLint mViewportY;
  1205     GLsizei mViewportWidth;
  1206     GLsizei mViewportHeight;
  1207     bool mAlreadyWarnedAboutViewportLargerThanDest;
  1209     nsCOMPtr<nsITimer> mContextRestorer;
  1210     bool mAllowRestore;
  1211     bool mContextLossTimerRunning;
  1212     bool mDrawSinceContextLossTimerSet;
  1213     ContextStatus mContextStatus;
  1214     bool mContextLostErrorSet;
  1216     // Used for some hardware (particularly Tegra 2 and 4) that likes to
  1217     // be Flushed while doing hundreds of draw calls.
  1218     int mDrawCallsSinceLastFlush;
  1220     int mAlreadyGeneratedWarnings;
  1221     int mMaxWarnings;
  1222     bool mAlreadyWarnedAboutFakeVertexAttrib0;
  1224     bool ShouldGenerateWarnings() const;
  1226     uint64_t mLastUseIndex;
  1228     void LoseOldestWebGLContextIfLimitExceeded();
  1229     void UpdateLastUseIndex();
  1231     template <typename WebGLObjectType>
  1232     JS::Value WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
  1233     template <typename WebGLObjectType>
  1234     JSObject* WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
  1236 #ifdef XP_MACOSX
  1237     // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
  1238     // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
  1239     // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
  1240     // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
  1241     // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
  1242     ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
  1243 #endif
  1245     nsRefPtr<WebGLMemoryPressureObserver> mMemoryPressureObserver;
  1247 public:
  1248     // console logging helpers
  1249     void GenerateWarning(const char *fmt, ...);
  1250     void GenerateWarning(const char *fmt, va_list ap);
  1252     friend class WebGLTexture;
  1253     friend class WebGLFramebuffer;
  1254     friend class WebGLRenderbuffer;
  1255     friend class WebGLProgram;
  1256     friend class WebGLQuery;
  1257     friend class WebGLBuffer;
  1258     friend class WebGLShader;
  1259     friend class WebGLUniformLocation;
  1260     friend class WebGLVertexArray;
  1261 };
  1263 // used by DOM bindings in conjunction with GetParentObject
  1264 inline nsISupports*
  1265 ToSupports(WebGLContext* context)
  1267   return static_cast<nsIDOMWebGLRenderingContext*>(context);
  1270 /**
  1271  ** Template implementations
  1272  **/
  1274 template<class ObjectType>
  1275 inline bool
  1276 WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info,
  1277                                                ObjectType *aObject)
  1279     if (aObject && !aObject->IsCompatibleWithContext(this)) {
  1280         ErrorInvalidOperation("%s: object from different WebGL context "
  1281                               "(or older generation of this one) "
  1282                               "passed as argument", info);
  1283         return false;
  1286     return true;
  1289 template<class ObjectType>
  1290 inline bool
  1291 WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject)
  1293     MOZ_ASSERT(aObject);
  1295     if (!ValidateObjectAllowDeletedOrNull(info, aObject))
  1296         return false;
  1298     if (aObject->IsDeleted()) {
  1299         ErrorInvalidValue("%s: deleted object passed as argument", info);
  1300         return false;
  1303     return true;
  1306 template<class ObjectType>
  1307 inline bool
  1308 WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType *aObject)
  1310     if (!aObject) {
  1311         return true;
  1314     return ValidateObjectAssumeNonNull(info, aObject);
  1317 template<class ObjectType>
  1318 inline bool
  1319 WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType *aObject)
  1321     if (!aObject) {
  1322         ErrorInvalidValue("%s: null object passed as argument", info);
  1323         return false;
  1326     return ValidateObjectAllowDeletedOrNull(info, aObject);
  1329 template<class ObjectType>
  1330 inline bool
  1331 WebGLContext::ValidateObject(const char* info, ObjectType *aObject)
  1333     if (!aObject) {
  1334         ErrorInvalidValue("%s: null object passed as argument", info);
  1335         return false;
  1338     return ValidateObjectAssumeNonNull(info, aObject);
  1341 class WebGLMemoryPressureObserver MOZ_FINAL
  1342     : public nsIObserver
  1344 public:
  1345   NS_DECL_ISUPPORTS
  1346   NS_DECL_NSIOBSERVER
  1348   WebGLMemoryPressureObserver(WebGLContext *context)
  1349     : mContext(context)
  1350   {}
  1352 private:
  1353   WebGLContext *mContext;
  1354 };
  1356 } // namespace mozilla
  1358 #endif

mercurial