content/canvas/src/WebGLContext.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/canvas/src/WebGLContext.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1358 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef WEBGLCONTEXT_H_
    1.10 +#define WEBGLCONTEXT_H_
    1.11 +
    1.12 +#include "mozilla/Attributes.h"
    1.13 +#include "GLDefs.h"
    1.14 +#include "WebGLActiveInfo.h"
    1.15 +#include "WebGLObjectModel.h"
    1.16 +#include <stdarg.h>
    1.17 +
    1.18 +#include "nsTArray.h"
    1.19 +#include "nsCycleCollectionNoteChild.h"
    1.20 +
    1.21 +#include "nsIDOMWebGLRenderingContext.h"
    1.22 +#include "nsICanvasRenderingContextInternal.h"
    1.23 +#include "mozilla/dom/HTMLCanvasElement.h"
    1.24 +#include "nsWrapperCache.h"
    1.25 +#include "nsIObserver.h"
    1.26 +#include "nsLayoutUtils.h"
    1.27 +
    1.28 +#include "GLContextProvider.h"
    1.29 +
    1.30 +#include "mozilla/EnumeratedArray.h"
    1.31 +#include "mozilla/LinkedList.h"
    1.32 +#include "mozilla/CheckedInt.h"
    1.33 +#include "mozilla/Scoped.h"
    1.34 +#include "mozilla/gfx/2D.h"
    1.35 +
    1.36 +#ifdef XP_MACOSX
    1.37 +#include "ForceDiscreteGPUHelperCGL.h"
    1.38 +#endif
    1.39 +
    1.40 +#include "mozilla/dom/TypedArray.h"
    1.41 +#include "mozilla/ErrorResult.h"
    1.42 +
    1.43 +class nsIDocShell;
    1.44 +
    1.45 +/*
    1.46 + * Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
    1.47 + *   https://bugzilla.mozilla.org/show_bug.cgi?id=686732
    1.48 + *
    1.49 + * Exceptions: some of the following values are set to higher values than in the spec because
    1.50 + * the values in the spec are ridiculously low. They are explicitly marked below
    1.51 +*/
    1.52 +#define MINVALUE_GL_MAX_TEXTURE_SIZE                  1024  // Different from the spec, which sets it to 64 on page 162
    1.53 +#define MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE         512   // Different from the spec, which sets it to 16 on page 162
    1.54 +#define MINVALUE_GL_MAX_VERTEX_ATTRIBS                8     // Page 164
    1.55 +#define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS      16    // Page 164
    1.56 +#define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS        128   // Page 164
    1.57 +#define MINVALUE_GL_MAX_VARYING_VECTORS               8     // Page 164
    1.58 +#define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS           8     // Page 164
    1.59 +#define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS    0     // Page 164
    1.60 +#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE             1024  // Different from the spec, which sets it to 1 on page 164
    1.61 +#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS  8     // Page 164
    1.62 +
    1.63 +namespace mozilla {
    1.64 +
    1.65 +class WebGLMemoryPressureObserver;
    1.66 +class WebGLContextBoundObject;
    1.67 +class WebGLActiveInfo;
    1.68 +class WebGLExtensionBase;
    1.69 +class WebGLBuffer;
    1.70 +class WebGLVertexAttribData;
    1.71 +class WebGLShader;
    1.72 +class WebGLProgram;
    1.73 +class WebGLQuery;
    1.74 +class WebGLUniformLocation;
    1.75 +class WebGLFramebuffer;
    1.76 +class WebGLRenderbuffer;
    1.77 +class WebGLShaderPrecisionFormat;
    1.78 +class WebGLTexture;
    1.79 +class WebGLVertexArray;
    1.80 +
    1.81 +namespace dom {
    1.82 +class ImageData;
    1.83 +
    1.84 +struct WebGLContextAttributes;
    1.85 +template<typename> struct Nullable;
    1.86 +}
    1.87 +
    1.88 +namespace gfx {
    1.89 +class SourceSurface;
    1.90 +}
    1.91 +
    1.92 +WebGLTexelFormat GetWebGLTexelFormat(GLenum format, GLenum type);
    1.93 +
    1.94 +struct WebGLContextOptions {
    1.95 +    // these are defaults
    1.96 +    WebGLContextOptions();
    1.97 +
    1.98 +    bool operator==(const WebGLContextOptions& other) const {
    1.99 +        return
   1.100 +            alpha == other.alpha &&
   1.101 +            depth == other.depth &&
   1.102 +            stencil == other.stencil &&
   1.103 +            premultipliedAlpha == other.premultipliedAlpha &&
   1.104 +            antialias == other.antialias &&
   1.105 +            preserveDrawingBuffer == other.preserveDrawingBuffer;
   1.106 +    }
   1.107 +
   1.108 +    bool operator!=(const WebGLContextOptions& other) const {
   1.109 +        return !operator==(other);
   1.110 +    }
   1.111 +
   1.112 +    bool alpha;
   1.113 +    bool depth;
   1.114 +    bool stencil;
   1.115 +    bool premultipliedAlpha;
   1.116 +    bool antialias;
   1.117 +    bool preserveDrawingBuffer;
   1.118 +};
   1.119 +
   1.120 +class WebGLContext :
   1.121 +    public nsIDOMWebGLRenderingContext,
   1.122 +    public nsICanvasRenderingContextInternal,
   1.123 +    public nsSupportsWeakReference,
   1.124 +    public WebGLRectangleObject,
   1.125 +    public nsWrapperCache
   1.126 +{
   1.127 +    friend class WebGLContextUserData;
   1.128 +    friend class WebGLExtensionCompressedTextureATC;
   1.129 +    friend class WebGLExtensionCompressedTextureETC1;
   1.130 +    friend class WebGLExtensionCompressedTexturePVRTC;
   1.131 +    friend class WebGLExtensionCompressedTextureS3TC;
   1.132 +    friend class WebGLExtensionDepthTexture;
   1.133 +    friend class WebGLExtensionDrawBuffers;
   1.134 +    friend class WebGLExtensionLoseContext;
   1.135 +    friend class WebGLExtensionVertexArray;
   1.136 +    friend class WebGLMemoryPressureObserver;
   1.137 +    friend class WebGLMemoryTracker;
   1.138 +
   1.139 +    enum {
   1.140 +        UNPACK_FLIP_Y_WEBGL = 0x9240,
   1.141 +        UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
   1.142 +        CONTEXT_LOST_WEBGL = 0x9242,
   1.143 +        UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243,
   1.144 +        BROWSER_DEFAULT_WEBGL = 0x9244,
   1.145 +        UNMASKED_VENDOR_WEBGL = 0x9245,
   1.146 +        UNMASKED_RENDERER_WEBGL = 0x9246
   1.147 +    };
   1.148 +
   1.149 +public:
   1.150 +    WebGLContext();
   1.151 +    virtual ~WebGLContext();
   1.152 +
   1.153 +    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   1.154 +
   1.155 +    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
   1.156 +                                                           nsIDOMWebGLRenderingContext)
   1.157 +
   1.158 +    virtual JSObject* WrapObject(JSContext *cx) = 0;
   1.159 +
   1.160 +    NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
   1.161 +
   1.162 +    // nsICanvasRenderingContextInternal
   1.163 +#ifdef DEBUG
   1.164 +    virtual int32_t GetWidth() const MOZ_OVERRIDE;
   1.165 +    virtual int32_t GetHeight() const MOZ_OVERRIDE;
   1.166 +#endif
   1.167 +    NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
   1.168 +    NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE
   1.169 +        { return NS_ERROR_NOT_IMPLEMENTED; }
   1.170 +    NS_IMETHOD Reset() MOZ_OVERRIDE
   1.171 +        { /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
   1.172 +    virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
   1.173 +    NS_IMETHOD GetInputStream(const char* aMimeType,
   1.174 +                              const char16_t* aEncoderOptions,
   1.175 +                              nsIInputStream **aStream) MOZ_OVERRIDE;
   1.176 +    mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha) MOZ_OVERRIDE;
   1.177 +
   1.178 +    NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
   1.179 +    bool GetIsOpaque() MOZ_OVERRIDE { return false; }
   1.180 +    NS_IMETHOD SetContextOptions(JSContext* aCx,
   1.181 +                                 JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
   1.182 +
   1.183 +    NS_IMETHOD SetIsIPC(bool b) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
   1.184 +    NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
   1.185 +    NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
   1.186 +                    int32_t x, int32_t y, int32_t w, int32_t h)
   1.187 +                    { return NS_ERROR_NOT_IMPLEMENTED; }
   1.188 +    NS_IMETHOD Swap(uint32_t nativeID,
   1.189 +                    int32_t x, int32_t y, int32_t w, int32_t h)
   1.190 +                    { return NS_ERROR_NOT_IMPLEMENTED; }
   1.191 +
   1.192 +    bool LoseContext();
   1.193 +    bool RestoreContext();
   1.194 +
   1.195 +    void SynthesizeGLError(GLenum err);
   1.196 +    void SynthesizeGLError(GLenum err, const char *fmt, ...);
   1.197 +
   1.198 +    void ErrorInvalidEnum(const char *fmt = 0, ...);
   1.199 +    void ErrorInvalidOperation(const char *fmt = 0, ...);
   1.200 +    void ErrorInvalidValue(const char *fmt = 0, ...);
   1.201 +    void ErrorInvalidFramebufferOperation(const char *fmt = 0, ...);
   1.202 +    void ErrorInvalidEnumInfo(const char *info, GLenum enumvalue);
   1.203 +    void ErrorOutOfMemory(const char *fmt = 0, ...);
   1.204 +
   1.205 +    const char *ErrorName(GLenum error);
   1.206 +    bool IsTextureFormatCompressed(GLenum format);
   1.207 +
   1.208 +    void DummyFramebufferOperation(const char *info);
   1.209 +
   1.210 +    WebGLTexture *activeBoundTextureForTarget(GLenum target) const {
   1.211 +        return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
   1.212 +                                             : mBoundCubeMapTextures[mActiveTexture];
   1.213 +    }
   1.214 +
   1.215 +    already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
   1.216 +                                                 CanvasLayer *aOldLayer,
   1.217 +                                                 LayerManager *aManager) MOZ_OVERRIDE;
   1.218 +
   1.219 +    // Note that 'clean' here refers to its invalidation state, not the
   1.220 +    // contents of the buffer.
   1.221 +    void MarkContextClean() MOZ_OVERRIDE { mInvalidated = false; }
   1.222 +
   1.223 +    gl::GLContext* GL() const { return gl; }
   1.224 +
   1.225 +    bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
   1.226 +
   1.227 +    bool PresentScreenBuffer();
   1.228 +
   1.229 +    // a number that increments every time we have an event that causes
   1.230 +    // all context resources to be lost.
   1.231 +    uint32_t Generation() { return mGeneration.value(); }
   1.232 +
   1.233 +    // Returns null if the current bound FB is not likely complete.
   1.234 +    const WebGLRectangleObject* CurValidFBRectObject() const;
   1.235 +
   1.236 +    static const size_t sMaxColorAttachments = 16;
   1.237 +
   1.238 +    // This is similar to GLContext::ClearSafely, but tries to minimize the
   1.239 +    // amount of work it does.
   1.240 +    // It only clears the buffers we specify, and can reset its state without
   1.241 +    // first having to query anything, as WebGL knows its state at all times.
   1.242 +    void ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool colorAttachmentsMask[sMaxColorAttachments]);
   1.243 +
   1.244 +    // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
   1.245 +    void ClearScreen();
   1.246 +    void ClearBackbufferIfNeeded();
   1.247 +
   1.248 +    bool MinCapabilityMode() const { return mMinCapability; }
   1.249 +
   1.250 +    void RobustnessTimerCallback(nsITimer* timer);
   1.251 +    static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer);
   1.252 +    void SetupContextLossTimer();
   1.253 +    void TerminateContextLossTimer();
   1.254 +
   1.255 +    // WebIDL WebGLRenderingContext API
   1.256 +    dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
   1.257 +    GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; }
   1.258 +    GLsizei DrawingBufferHeight() const { return IsContextLost() ? 0 : mHeight; }
   1.259 +
   1.260 +    void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
   1.261 +    bool IsContextLost() const { return mContextStatus != ContextNotLost; }
   1.262 +    void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
   1.263 +    void GetExtension(JSContext* cx, const nsAString& aName,
   1.264 +                      JS::MutableHandle<JSObject*> aRetval,
   1.265 +                      ErrorResult& rv);
   1.266 +    void ActiveTexture(GLenum texture);
   1.267 +    void AttachShader(WebGLProgram* program, WebGLShader* shader);
   1.268 +    void BindAttribLocation(WebGLProgram* program, GLuint location,
   1.269 +                            const nsAString& name);
   1.270 +    void BindFramebuffer(GLenum target, WebGLFramebuffer* wfb);
   1.271 +    void BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb);
   1.272 +    void BindTexture(GLenum target, WebGLTexture *tex);
   1.273 +    void BindVertexArray(WebGLVertexArray *vao);
   1.274 +    void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
   1.275 +    void BlendEquation(GLenum mode);
   1.276 +    void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
   1.277 +    void BlendFunc(GLenum sfactor, GLenum dfactor);
   1.278 +    void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
   1.279 +                           GLenum srcAlpha, GLenum dstAlpha);
   1.280 +    GLenum CheckFramebufferStatus(GLenum target);
   1.281 +    void Clear(GLbitfield mask);
   1.282 +    void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
   1.283 +    void ClearDepth(GLclampf v);
   1.284 +    void ClearStencil(GLint v);
   1.285 +    void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a);
   1.286 +    void CompileShader(WebGLShader *shader);
   1.287 +    void CompressedTexImage2D(GLenum target, GLint level,
   1.288 +                              GLenum internalformat, GLsizei width,
   1.289 +                              GLsizei height, GLint border,
   1.290 +                              const dom::ArrayBufferView& view);
   1.291 +    void CompressedTexSubImage2D(GLenum target, GLint level,
   1.292 +                                 GLint xoffset, GLint yoffset,
   1.293 +                                 GLsizei width, GLsizei height,
   1.294 +                                 GLenum format,
   1.295 +                                 const dom::ArrayBufferView& view);
   1.296 +    void CopyTexImage2D(GLenum target, GLint level,
   1.297 +                        GLenum internalformat, GLint x, GLint y,
   1.298 +                        GLsizei width, GLsizei height, GLint border);
   1.299 +    void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
   1.300 +                           GLint yoffset, GLint x, GLint y,
   1.301 +                           GLsizei width, GLsizei height);
   1.302 +    already_AddRefed<WebGLFramebuffer> CreateFramebuffer();
   1.303 +    already_AddRefed<WebGLProgram> CreateProgram();
   1.304 +    already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer();
   1.305 +    already_AddRefed<WebGLTexture> CreateTexture();
   1.306 +    already_AddRefed<WebGLShader> CreateShader(GLenum type);
   1.307 +    already_AddRefed<WebGLVertexArray> CreateVertexArray();
   1.308 +    void CullFace(GLenum face);
   1.309 +    void DeleteFramebuffer(WebGLFramebuffer *fbuf);
   1.310 +    void DeleteProgram(WebGLProgram *prog);
   1.311 +    void DeleteRenderbuffer(WebGLRenderbuffer *rbuf);
   1.312 +    void DeleteShader(WebGLShader *shader);
   1.313 +    void DeleteVertexArray(WebGLVertexArray *vao);
   1.314 +    void DeleteTexture(WebGLTexture *tex);
   1.315 +    void DepthFunc(GLenum func);
   1.316 +    void DepthMask(WebGLboolean b);
   1.317 +    void DepthRange(GLclampf zNear, GLclampf zFar);
   1.318 +    void DetachShader(WebGLProgram *program, WebGLShader *shader);
   1.319 +    void DrawBuffers(const dom::Sequence<GLenum>& buffers);
   1.320 +    void Flush();
   1.321 +    void Finish();
   1.322 +    void FramebufferRenderbuffer(GLenum target, GLenum attachment,
   1.323 +                                 GLenum rbtarget, WebGLRenderbuffer *wrb);
   1.324 +    void FramebufferTexture2D(GLenum target, GLenum attachment,
   1.325 +                              GLenum textarget, WebGLTexture *tobj,
   1.326 +                              GLint level);
   1.327 +    void FrontFace(GLenum mode);
   1.328 +    void GenerateMipmap(GLenum target);
   1.329 +    already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,
   1.330 +                                                      GLuint index);
   1.331 +    already_AddRefed<WebGLActiveInfo> GetActiveUniform(WebGLProgram *prog,
   1.332 +                                                       GLuint index);
   1.333 +    void GetAttachedShaders(WebGLProgram* prog,
   1.334 +                            dom::Nullable< nsTArray<WebGLShader*> > &retval);
   1.335 +    GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
   1.336 +    JS::Value GetBufferParameter(GLenum target, GLenum pname);
   1.337 +    void GetBufferParameter(JSContext* /* unused */, GLenum target,
   1.338 +                            GLenum pname,
   1.339 +                            JS::MutableHandle<JS::Value> retval) {
   1.340 +        retval.set(GetBufferParameter(target, pname));
   1.341 +    }
   1.342 +    GLenum GetError();
   1.343 +    JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
   1.344 +                                                GLenum target,
   1.345 +                                                GLenum attachment,
   1.346 +                                                GLenum pname,
   1.347 +                                                ErrorResult& rv);
   1.348 +    void GetFramebufferAttachmentParameter(JSContext* cx,
   1.349 +                                           GLenum target,
   1.350 +                                           GLenum attachment,
   1.351 +                                           GLenum pname,
   1.352 +                                           JS::MutableHandle<JS::Value> retval,
   1.353 +                                           ErrorResult& rv) {
   1.354 +        retval.set(GetFramebufferAttachmentParameter(cx, target, attachment,
   1.355 +                                                     pname, rv));
   1.356 +    }
   1.357 +    JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname);
   1.358 +    void  GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
   1.359 +                              GLenum pname,
   1.360 +                              JS::MutableHandle<JS::Value> retval) {
   1.361 +        retval.set(GetProgramParameter(prog, pname));
   1.362 +    }
   1.363 +    void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval);
   1.364 +    void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval);
   1.365 +    JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
   1.366 +    void GetRenderbufferParameter(JSContext* /* unused */,
   1.367 +                                  GLenum target, GLenum pname,
   1.368 +                                  JS::MutableHandle<JS::Value> retval) {
   1.369 +        retval.set(GetRenderbufferParameter(target, pname));
   1.370 +    }
   1.371 +    JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname);
   1.372 +    void GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
   1.373 +                            GLenum pname,
   1.374 +                            JS::MutableHandle<JS::Value> retval) {
   1.375 +        retval.set(GetShaderParameter(shader, pname));
   1.376 +    }
   1.377 +    already_AddRefed<WebGLShaderPrecisionFormat>
   1.378 +      GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
   1.379 +    void GetShaderInfoLog(WebGLShader *shader, nsACString& retval);
   1.380 +    void GetShaderInfoLog(WebGLShader *shader, nsAString& retval);
   1.381 +    void GetShaderSource(WebGLShader *shader, nsAString& retval);
   1.382 +    void GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval);
   1.383 +    JS::Value GetTexParameter(GLenum target, GLenum pname);
   1.384 +    void GetTexParameter(JSContext * /* unused */, GLenum target,
   1.385 +                         GLenum pname,
   1.386 +                         JS::MutableHandle<JS::Value> retval) {
   1.387 +        retval.set(GetTexParameter(target, pname));
   1.388 +    }
   1.389 +    JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
   1.390 +                         WebGLUniformLocation *location);
   1.391 +    void GetUniform(JSContext* cx, WebGLProgram *prog,
   1.392 +                    WebGLUniformLocation *location,
   1.393 +                    JS::MutableHandle<JS::Value> retval) {
   1.394 +        retval.set(GetUniform(cx, prog, location));
   1.395 +    }
   1.396 +    already_AddRefed<WebGLUniformLocation>
   1.397 +      GetUniformLocation(WebGLProgram *prog, const nsAString& name);
   1.398 +    void Hint(GLenum target, GLenum mode);
   1.399 +    bool IsFramebuffer(WebGLFramebuffer *fb);
   1.400 +    bool IsProgram(WebGLProgram *prog);
   1.401 +    bool IsRenderbuffer(WebGLRenderbuffer *rb);
   1.402 +    bool IsShader(WebGLShader *shader);
   1.403 +    bool IsTexture(WebGLTexture *tex);
   1.404 +    bool IsVertexArray(WebGLVertexArray *vao);
   1.405 +    void LineWidth(GLfloat width);
   1.406 +    void LinkProgram(WebGLProgram *program);
   1.407 +    void PixelStorei(GLenum pname, GLint param);
   1.408 +    void PolygonOffset(GLfloat factor, GLfloat units);
   1.409 +    void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   1.410 +                    GLenum format, GLenum type,
   1.411 +                    const Nullable<dom::ArrayBufferView> &pixels,
   1.412 +                    ErrorResult& rv);
   1.413 +    void RenderbufferStorage(GLenum target, GLenum internalformat,
   1.414 +                             GLsizei width, GLsizei height);
   1.415 +    void SampleCoverage(GLclampf value, WebGLboolean invert);
   1.416 +    void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
   1.417 +    void ShaderSource(WebGLShader *shader, const nsAString& source);
   1.418 +    void StencilFunc(GLenum func, GLint ref, GLuint mask);
   1.419 +    void StencilFuncSeparate(GLenum face, GLenum func, GLint ref,
   1.420 +                             GLuint mask);
   1.421 +    void StencilMask(GLuint mask);
   1.422 +    void StencilMaskSeparate(GLenum face, GLuint mask);
   1.423 +    void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
   1.424 +    void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
   1.425 +                           GLenum dppass);
   1.426 +    void TexImage2D(GLenum target, GLint level,
   1.427 +                    GLenum internalformat, GLsizei width,
   1.428 +                    GLsizei height, GLint border, GLenum format,
   1.429 +                    GLenum type,
   1.430 +                    const Nullable<dom::ArrayBufferView> &pixels,
   1.431 +                    ErrorResult& rv);
   1.432 +    void TexImage2D(GLenum target, GLint level,
   1.433 +                    GLenum internalformat, GLenum format, GLenum type,
   1.434 +                    dom::ImageData* pixels, ErrorResult& rv);
   1.435 +    // Allow whatever element types the bindings are willing to pass
   1.436 +    // us in TexImage2D
   1.437 +    template<class ElementType>
   1.438 +    void TexImage2D(GLenum target, GLint level,
   1.439 +                    GLenum internalformat, GLenum format, GLenum type,
   1.440 +                    ElementType& elt, ErrorResult& rv)
   1.441 +    {
   1.442 +        if (IsContextLost())
   1.443 +            return;
   1.444 +        RefPtr<gfx::DataSourceSurface> data;
   1.445 +        WebGLTexelFormat srcFormat;
   1.446 +        nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
   1.447 +        rv = SurfaceFromElementResultToImageSurface(res, data,
   1.448 +                                                    &srcFormat);
   1.449 +        if (rv.Failed() || !data)
   1.450 +            return;
   1.451 +
   1.452 +        gfx::IntSize size = data->GetSize();
   1.453 +        uint32_t byteLength = data->Stride() * size.height;
   1.454 +        return TexImage2D_base(target, level, internalformat,
   1.455 +                               size.width, size.height, data->Stride(),
   1.456 +                               0, format, type, data->GetData(), byteLength,
   1.457 +                               -1, srcFormat, mPixelStorePremultiplyAlpha);
   1.458 +    }
   1.459 +    void TexParameterf(GLenum target, GLenum pname, GLfloat param) {
   1.460 +        TexParameter_base(target, pname, nullptr, &param);
   1.461 +    }
   1.462 +    void TexParameteri(GLenum target, GLenum pname, GLint param) {
   1.463 +        TexParameter_base(target, pname, &param, nullptr);
   1.464 +    }
   1.465 +
   1.466 +    void TexSubImage2D(GLenum target, GLint level,
   1.467 +                       GLint xoffset, GLint yoffset,
   1.468 +                       GLsizei width, GLsizei height, GLenum format,
   1.469 +                       GLenum type,
   1.470 +                       const Nullable<dom::ArrayBufferView> &pixels,
   1.471 +                       ErrorResult& rv);
   1.472 +    void TexSubImage2D(GLenum target, GLint level,
   1.473 +                       GLint xoffset, GLint yoffset, GLenum format,
   1.474 +                       GLenum type, dom::ImageData* pixels, ErrorResult& rv);
   1.475 +    // Allow whatever element types the bindings are willing to pass
   1.476 +    // us in TexSubImage2D
   1.477 +    template<class ElementType>
   1.478 +    void TexSubImage2D(GLenum target, GLint level,
   1.479 +                       GLint xoffset, GLint yoffset, GLenum format,
   1.480 +                       GLenum type, ElementType& elt, ErrorResult& rv)
   1.481 +    {
   1.482 +        if (IsContextLost())
   1.483 +            return;
   1.484 +        RefPtr<gfx::DataSourceSurface> data;
   1.485 +        WebGLTexelFormat srcFormat;
   1.486 +        nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
   1.487 +        rv = SurfaceFromElementResultToImageSurface(res, data,
   1.488 +                                                    &srcFormat);
   1.489 +        if (rv.Failed() || !data)
   1.490 +            return;
   1.491 +
   1.492 +        gfx::IntSize size = data->GetSize();
   1.493 +        uint32_t byteLength = data->Stride() * size.height;
   1.494 +        return TexSubImage2D_base(target, level, xoffset, yoffset,
   1.495 +                                  size.width, size.height,
   1.496 +                                  data->Stride(), format, type,
   1.497 +                                  data->GetData(), byteLength,
   1.498 +                                  -1, srcFormat, mPixelStorePremultiplyAlpha);
   1.499 +
   1.500 +    }
   1.501 +
   1.502 +    void Uniform1i(WebGLUniformLocation* location, GLint x);
   1.503 +    void Uniform2i(WebGLUniformLocation* location, GLint x, GLint y);
   1.504 +    void Uniform3i(WebGLUniformLocation* location, GLint x, GLint y,
   1.505 +                   GLint z);
   1.506 +    void Uniform4i(WebGLUniformLocation* location, GLint x, GLint y,
   1.507 +                   GLint z, GLint w);
   1.508 +
   1.509 +    void Uniform1f(WebGLUniformLocation* location, GLfloat x);
   1.510 +    void Uniform2f(WebGLUniformLocation* location, GLfloat x, GLfloat y);
   1.511 +    void Uniform3f(WebGLUniformLocation* location, GLfloat x, GLfloat y,
   1.512 +                   GLfloat z);
   1.513 +    void Uniform4f(WebGLUniformLocation* location, GLfloat x, GLfloat y,
   1.514 +                   GLfloat z, GLfloat w);
   1.515 +
   1.516 +    void Uniform1iv(WebGLUniformLocation* location,
   1.517 +                    const dom::Int32Array& arr) {
   1.518 +        arr.ComputeLengthAndData();
   1.519 +        Uniform1iv_base(location, arr.Length(), arr.Data());
   1.520 +    }
   1.521 +    void Uniform1iv(WebGLUniformLocation* location,
   1.522 +                    const dom::Sequence<GLint>& arr) {
   1.523 +        Uniform1iv_base(location, arr.Length(), arr.Elements());
   1.524 +    }
   1.525 +    void Uniform1iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.526 +                         const GLint* data);
   1.527 +
   1.528 +    void Uniform2iv(WebGLUniformLocation* location,
   1.529 +                    const dom::Int32Array& arr) {
   1.530 +        arr.ComputeLengthAndData();
   1.531 +        Uniform2iv_base(location, arr.Length(), arr.Data());
   1.532 +    }
   1.533 +    void Uniform2iv(WebGLUniformLocation* location,
   1.534 +                    const dom::Sequence<GLint>& arr) {
   1.535 +        Uniform2iv_base(location, arr.Length(), arr.Elements());
   1.536 +    }
   1.537 +    void Uniform2iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.538 +                         const GLint* data);
   1.539 +
   1.540 +    void Uniform3iv(WebGLUniformLocation* location,
   1.541 +                    const dom::Int32Array& arr) {
   1.542 +        arr.ComputeLengthAndData();
   1.543 +        Uniform3iv_base(location, arr.Length(), arr.Data());
   1.544 +    }
   1.545 +    void Uniform3iv(WebGLUniformLocation* location,
   1.546 +                    const dom::Sequence<GLint>& arr) {
   1.547 +        Uniform3iv_base(location, arr.Length(), arr.Elements());
   1.548 +    }
   1.549 +    void Uniform3iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.550 +                         const GLint* data);
   1.551 +
   1.552 +    void Uniform4iv(WebGLUniformLocation* location,
   1.553 +                    const dom::Int32Array& arr) {
   1.554 +        arr.ComputeLengthAndData();
   1.555 +        Uniform4iv_base(location, arr.Length(), arr.Data());
   1.556 +    }
   1.557 +    void Uniform4iv(WebGLUniformLocation* location,
   1.558 +                    const dom::Sequence<GLint>& arr) {
   1.559 +        Uniform4iv_base(location, arr.Length(), arr.Elements());
   1.560 +    }
   1.561 +    void Uniform4iv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.562 +                         const GLint* data);
   1.563 +
   1.564 +    void Uniform1fv(WebGLUniformLocation* location,
   1.565 +                    const dom::Float32Array& arr) {
   1.566 +        arr.ComputeLengthAndData();
   1.567 +        Uniform1fv_base(location, arr.Length(), arr.Data());
   1.568 +    }
   1.569 +    void Uniform1fv(WebGLUniformLocation* location,
   1.570 +                    const dom::Sequence<GLfloat>& arr) {
   1.571 +        Uniform1fv_base(location, arr.Length(), arr.Elements());
   1.572 +    }
   1.573 +    void Uniform1fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.574 +                         const GLfloat* data);
   1.575 +
   1.576 +    void Uniform2fv(WebGLUniformLocation* location,
   1.577 +                    const dom::Float32Array& arr) {
   1.578 +        arr.ComputeLengthAndData();
   1.579 +        Uniform2fv_base(location, arr.Length(), arr.Data());
   1.580 +    }
   1.581 +    void Uniform2fv(WebGLUniformLocation* location,
   1.582 +                    const dom::Sequence<GLfloat>& arr) {
   1.583 +        Uniform2fv_base(location, arr.Length(), arr.Elements());
   1.584 +    }
   1.585 +    void Uniform2fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.586 +                         const GLfloat* data);
   1.587 +
   1.588 +    void Uniform3fv(WebGLUniformLocation* location,
   1.589 +                    const dom::Float32Array& arr) {
   1.590 +        arr.ComputeLengthAndData();
   1.591 +        Uniform3fv_base(location, arr.Length(), arr.Data());
   1.592 +    }
   1.593 +    void Uniform3fv(WebGLUniformLocation* location,
   1.594 +                    const dom::Sequence<GLfloat>& arr) {
   1.595 +        Uniform3fv_base(location, arr.Length(), arr.Elements());
   1.596 +    }
   1.597 +    void Uniform3fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.598 +                         const GLfloat* data);
   1.599 +
   1.600 +    void Uniform4fv(WebGLUniformLocation* location,
   1.601 +                    const dom::Float32Array& arr) {
   1.602 +        arr.ComputeLengthAndData();
   1.603 +        Uniform4fv_base(location, arr.Length(), arr.Data());
   1.604 +    }
   1.605 +    void Uniform4fv(WebGLUniformLocation* location,
   1.606 +                    const dom::Sequence<GLfloat>& arr) {
   1.607 +        Uniform4fv_base(location, arr.Length(), arr.Elements());
   1.608 +    }
   1.609 +    void Uniform4fv_base(WebGLUniformLocation* location, uint32_t arrayLength,
   1.610 +                         const GLfloat* data);
   1.611 +
   1.612 +    void UniformMatrix2fv(WebGLUniformLocation* location,
   1.613 +                          WebGLboolean transpose,
   1.614 +                          const dom::Float32Array &value) {
   1.615 +        value.ComputeLengthAndData();
   1.616 +        UniformMatrix2fv_base(location, transpose, value.Length(), value.Data());
   1.617 +    }
   1.618 +    void UniformMatrix2fv(WebGLUniformLocation* location,
   1.619 +                          WebGLboolean transpose,
   1.620 +                          const dom::Sequence<float> &value) {
   1.621 +        UniformMatrix2fv_base(location, transpose, value.Length(),
   1.622 +                              value.Elements());
   1.623 +    }
   1.624 +    void UniformMatrix2fv_base(WebGLUniformLocation* location,
   1.625 +                               WebGLboolean transpose, uint32_t arrayLength,
   1.626 +                               const float* data);
   1.627 +
   1.628 +    void UniformMatrix3fv(WebGLUniformLocation* location,
   1.629 +                          WebGLboolean transpose,
   1.630 +                          const dom::Float32Array &value) {
   1.631 +        value.ComputeLengthAndData();
   1.632 +        UniformMatrix3fv_base(location, transpose, value.Length(), value.Data());
   1.633 +    }
   1.634 +    void UniformMatrix3fv(WebGLUniformLocation* location,
   1.635 +                          WebGLboolean transpose,
   1.636 +                          const dom::Sequence<float> &value) {
   1.637 +        UniformMatrix3fv_base(location, transpose, value.Length(),
   1.638 +                              value.Elements());
   1.639 +    }
   1.640 +    void UniformMatrix3fv_base(WebGLUniformLocation* location,
   1.641 +                               WebGLboolean transpose, uint32_t arrayLength,
   1.642 +                               const float* data);
   1.643 +
   1.644 +    void UniformMatrix4fv(WebGLUniformLocation* location,
   1.645 +                          WebGLboolean transpose,
   1.646 +                          const dom::Float32Array &value) {
   1.647 +        value.ComputeLengthAndData();
   1.648 +        UniformMatrix4fv_base(location, transpose, value.Length(), value.Data());
   1.649 +    }
   1.650 +    void UniformMatrix4fv(WebGLUniformLocation* location,
   1.651 +                          WebGLboolean transpose,
   1.652 +                          const dom::Sequence<float> &value) {
   1.653 +        UniformMatrix4fv_base(location, transpose, value.Length(),
   1.654 +                              value.Elements());
   1.655 +    }
   1.656 +    void UniformMatrix4fv_base(WebGLUniformLocation* location,
   1.657 +                               WebGLboolean transpose, uint32_t arrayLength,
   1.658 +                               const float* data);
   1.659 +
   1.660 +    void UseProgram(WebGLProgram *prog);
   1.661 +    bool ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength);
   1.662 +    bool ValidateUniformArraySetter(const char* name, uint32_t expectedElemSize, WebGLUniformLocation *location_object,
   1.663 +                                    GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength);
   1.664 +    bool ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLUniformLocation *location_object,
   1.665 +                                          GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength,
   1.666 +                                          WebGLboolean aTranspose);
   1.667 +    bool ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location);
   1.668 +    void ValidateProgram(WebGLProgram *prog);
   1.669 +    bool ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object);
   1.670 +    bool ValidateSamplerUniformSetter(const char* info,
   1.671 +                                    WebGLUniformLocation *location,
   1.672 +                                    GLint value);
   1.673 +
   1.674 +    void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
   1.675 +
   1.676 +// -----------------------------------------------------------------------------
   1.677 +// Asynchronous Queries (WebGLContextAsyncQueries.cpp)
   1.678 +public:
   1.679 +    already_AddRefed<WebGLQuery> CreateQuery();
   1.680 +    void DeleteQuery(WebGLQuery *query);
   1.681 +    void BeginQuery(GLenum target, WebGLQuery *query);
   1.682 +    void EndQuery(GLenum target);
   1.683 +    bool IsQuery(WebGLQuery *query);
   1.684 +    already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
   1.685 +    JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname);
   1.686 +    void GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname,
   1.687 +                        JS::MutableHandle<JS::Value> retval) {
   1.688 +        retval.set(GetQueryObject(cx, query, pname));
   1.689 +    }
   1.690 +
   1.691 +private:
   1.692 +    // ANY_SAMPLES_PASSED(_CONSERVATIVE) slot
   1.693 +    WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
   1.694 +
   1.695 +    // LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN slot
   1.696 +    WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
   1.697 +
   1.698 +    WebGLRefPtr<WebGLQuery>* GetQueryTargetSlot(GLenum target, const char* infos);
   1.699 +
   1.700 +// -----------------------------------------------------------------------------
   1.701 +// Buffer Objects (WebGLContextBuffers.cpp)
   1.702 +public:
   1.703 +    void BindBuffer(GLenum target, WebGLBuffer* buf);
   1.704 +    void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
   1.705 +    void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
   1.706 +                         WebGLintptr offset, WebGLsizeiptr size);
   1.707 +    void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
   1.708 +    void BufferData(GLenum target, const dom::ArrayBufferView &data,
   1.709 +                    GLenum usage);
   1.710 +    void BufferData(GLenum target,
   1.711 +                    const Nullable<dom::ArrayBuffer> &maybeData,
   1.712 +                    GLenum usage);
   1.713 +    void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
   1.714 +                       const dom::ArrayBufferView &data);
   1.715 +    void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
   1.716 +                       const Nullable<dom::ArrayBuffer> &maybeData);
   1.717 +    already_AddRefed<WebGLBuffer> CreateBuffer();
   1.718 +    void DeleteBuffer(WebGLBuffer *buf);
   1.719 +    bool IsBuffer(WebGLBuffer *buffer);
   1.720 +
   1.721 +private:
   1.722 +    // ARRAY_BUFFER slot
   1.723 +    WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
   1.724 +
   1.725 +    // TRANSFORM_FEEDBACK_BUFFER slot
   1.726 +    WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
   1.727 +
   1.728 +    // these two functions emit INVALID_ENUM for invalid `target`.
   1.729 +    WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target, const char* infos);
   1.730 +    WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos);
   1.731 +    bool ValidateBufferUsageEnum(GLenum target, const char* infos);
   1.732 +
   1.733 +// -----------------------------------------------------------------------------
   1.734 +// State and State Requests (WebGLContextState.cpp)
   1.735 +public:
   1.736 +    void Disable(GLenum cap);
   1.737 +    void Enable(GLenum cap);
   1.738 +    JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
   1.739 +    void GetParameter(JSContext* cx, GLenum pname,
   1.740 +                      JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
   1.741 +        retval.set(GetParameter(cx, pname, rv));
   1.742 +    }
   1.743 +    void GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
   1.744 +                             JS::MutableHandle<JS::Value> retval);
   1.745 +    bool IsEnabled(GLenum cap);
   1.746 +
   1.747 +private:
   1.748 +    // State tracking slots
   1.749 +    realGLboolean mDitherEnabled;
   1.750 +    realGLboolean mRasterizerDiscardEnabled;
   1.751 +    realGLboolean mScissorTestEnabled;
   1.752 +
   1.753 +    bool ValidateCapabilityEnum(GLenum cap, const char* info);
   1.754 +    realGLboolean* GetStateTrackingSlot(GLenum cap);
   1.755 +
   1.756 +// -----------------------------------------------------------------------------
   1.757 +// Vertices Feature (WebGLContextVertices.cpp)
   1.758 +public:
   1.759 +    void DrawArrays(GLenum mode, GLint first, GLsizei count);
   1.760 +    void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
   1.761 +    void DrawElements(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset);
   1.762 +    void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
   1.763 +                               WebGLintptr byteOffset, GLsizei primcount);
   1.764 +
   1.765 +    void EnableVertexAttribArray(GLuint index);
   1.766 +    void DisableVertexAttribArray(GLuint index);
   1.767 +
   1.768 +    JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
   1.769 +                              ErrorResult& rv);
   1.770 +    void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
   1.771 +                         JS::MutableHandle<JS::Value> retval,
   1.772 +                         ErrorResult& rv) {
   1.773 +        retval.set(GetVertexAttrib(cx, index, pname, rv));
   1.774 +    }
   1.775 +    WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
   1.776 +
   1.777 +    void VertexAttrib1f(GLuint index, GLfloat x0);
   1.778 +    void VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1);
   1.779 +    void VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1,
   1.780 +                        GLfloat x2);
   1.781 +    void VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
   1.782 +                        GLfloat x2, GLfloat x3);
   1.783 +
   1.784 +    void VertexAttrib1fv(GLuint idx, const dom::Float32Array &arr) {
   1.785 +        arr.ComputeLengthAndData();
   1.786 +        VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
   1.787 +    }
   1.788 +    void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   1.789 +        VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
   1.790 +    }
   1.791 +
   1.792 +    void VertexAttrib2fv(GLuint idx, const dom::Float32Array &arr) {
   1.793 +        arr.ComputeLengthAndData();
   1.794 +        VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
   1.795 +    }
   1.796 +    void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   1.797 +        VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
   1.798 +    }
   1.799 +
   1.800 +    void VertexAttrib3fv(GLuint idx, const dom::Float32Array &arr) {
   1.801 +        arr.ComputeLengthAndData();
   1.802 +        VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
   1.803 +    }
   1.804 +    void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   1.805 +        VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
   1.806 +    }
   1.807 +
   1.808 +    void VertexAttrib4fv(GLuint idx, const dom::Float32Array &arr) {
   1.809 +        arr.ComputeLengthAndData();
   1.810 +        VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
   1.811 +    }
   1.812 +    void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
   1.813 +        VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());
   1.814 +    }
   1.815 +
   1.816 +    void VertexAttribPointer(GLuint index, GLint size, GLenum type,
   1.817 +                             WebGLboolean normalized, GLsizei stride,
   1.818 +                             WebGLintptr byteOffset);
   1.819 +    void VertexAttribDivisor(GLuint index, GLuint divisor);
   1.820 +
   1.821 +private:
   1.822 +    // Cache the max number of vertices and instances that can be read from
   1.823 +    // bound VBOs (result of ValidateBuffers).
   1.824 +    bool mBufferFetchingIsVerified;
   1.825 +    bool mBufferFetchingHasPerVertex;
   1.826 +    uint32_t mMaxFetchedVertices;
   1.827 +    uint32_t mMaxFetchedInstances;
   1.828 +
   1.829 +    inline void InvalidateBufferFetching()
   1.830 +    {
   1.831 +        mBufferFetchingIsVerified = false;
   1.832 +        mBufferFetchingHasPerVertex = false;
   1.833 +        mMaxFetchedVertices = 0;
   1.834 +        mMaxFetchedInstances = 0;
   1.835 +    }
   1.836 +
   1.837 +    bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info);
   1.838 +    bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset,
   1.839 +                            GLsizei primcount, const char* info,
   1.840 +                            GLuint* out_upperBound = nullptr);
   1.841 +    bool DrawInstanced_check(const char* info);
   1.842 +    void Draw_cleanup();
   1.843 +
   1.844 +    void VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   1.845 +    void VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   1.846 +    void VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   1.847 +    void VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr);
   1.848 +
   1.849 +    bool ValidateBufferFetching(const char *info);
   1.850 +    bool BindArrayAttribToLocation0(WebGLProgram *program);
   1.851 +
   1.852 +// -----------------------------------------------------------------------------
   1.853 +// PROTECTED
   1.854 +protected:
   1.855 +    void SetFakeBlackStatus(WebGLContextFakeBlackStatus x) {
   1.856 +        mFakeBlackStatus = x;
   1.857 +    }
   1.858 +    // Returns the current fake-black-status, except if it was Unknown,
   1.859 +    // in which case this function resolves it first, so it never returns Unknown.
   1.860 +    WebGLContextFakeBlackStatus ResolvedFakeBlackStatus();
   1.861 +
   1.862 +    void BindFakeBlackTextures();
   1.863 +    void UnbindFakeBlackTextures();
   1.864 +
   1.865 +    WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need();
   1.866 +    bool DoFakeVertexAttrib0(GLuint vertexCount);
   1.867 +    void UndoFakeVertexAttrib0();
   1.868 +
   1.869 +    static CheckedUint32 GetImageSize(GLsizei height,
   1.870 +                                      GLsizei width,
   1.871 +                                      uint32_t pixelSize,
   1.872 +                                      uint32_t alignment);
   1.873 +
   1.874 +    // Returns x rounded to the next highest multiple of y.
   1.875 +    static CheckedUint32 RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y) {
   1.876 +        return ((x + y - 1) / y) * y;
   1.877 +    }
   1.878 +
   1.879 +    nsRefPtr<gl::GLContext> gl;
   1.880 +
   1.881 +    CheckedUint32 mGeneration;
   1.882 +
   1.883 +    WebGLContextOptions mOptions;
   1.884 +
   1.885 +    bool mInvalidated;
   1.886 +    bool mResetLayer;
   1.887 +    bool mOptionsFrozen;
   1.888 +    bool mMinCapability;
   1.889 +    bool mDisableExtensions;
   1.890 +    bool mHasRobustness;
   1.891 +    bool mIsMesa;
   1.892 +    bool mLoseContextOnHeapMinimize;
   1.893 +    bool mCanLoseContextInForeground;
   1.894 +    bool mShouldPresent;
   1.895 +    bool mBackbufferNeedsClear;
   1.896 +    bool mDisableFragHighP;
   1.897 +
   1.898 +    template<typename WebGLObjectType>
   1.899 +    void DeleteWebGLObjectsArray(nsTArray<WebGLObjectType>& array);
   1.900 +
   1.901 +    GLuint mActiveTexture;
   1.902 +
   1.903 +    // glGetError sources:
   1.904 +    bool mEmitContextLostErrorOnce;
   1.905 +    GLenum mWebGLError;
   1.906 +    GLenum mUnderlyingGLError;
   1.907 +    GLenum GetAndFlushUnderlyingGLErrors();
   1.908 +
   1.909 +    // whether shader validation is supported
   1.910 +    bool mShaderValidation;
   1.911 +
   1.912 +    // some GL constants
   1.913 +    int32_t mGLMaxVertexAttribs;
   1.914 +    int32_t mGLMaxTextureUnits;
   1.915 +    int32_t mGLMaxTextureSize;
   1.916 +    int32_t mGLMaxCubeMapTextureSize;
   1.917 +    int32_t mGLMaxRenderbufferSize;
   1.918 +    int32_t mGLMaxTextureImageUnits;
   1.919 +    int32_t mGLMaxVertexTextureImageUnits;
   1.920 +    int32_t mGLMaxVaryingVectors;
   1.921 +    int32_t mGLMaxFragmentUniformVectors;
   1.922 +    int32_t mGLMaxVertexUniformVectors;
   1.923 +    int32_t mGLMaxColorAttachments;
   1.924 +    int32_t mGLMaxDrawBuffers;
   1.925 +    uint32_t mGLMaxTransformFeedbackSeparateAttribs;
   1.926 +
   1.927 +    // Represents current status of the context with respect to context loss.
   1.928 +    // That is, whether the context is lost, and what part of the context loss
   1.929 +    // process we currently are at.
   1.930 +    // This is used to support the WebGL spec's asyncronous nature in handling
   1.931 +    // context loss.
   1.932 +    enum ContextStatus {
   1.933 +        // The context is stable; there either are none or we don't know of any.
   1.934 +        ContextNotLost,
   1.935 +        // The context has been lost, but we have not yet sent an event to the
   1.936 +        // script informing it of this.
   1.937 +        ContextLostAwaitingEvent,
   1.938 +        // The context has been lost, and we have sent the script an event
   1.939 +        // informing it of this.
   1.940 +        ContextLost,
   1.941 +        // The context is lost, an event has been sent to the script, and the
   1.942 +        // script correctly handled the event. We are waiting for the context to
   1.943 +        // be restored.
   1.944 +        ContextLostAwaitingRestore
   1.945 +    };
   1.946 +
   1.947 +    // -------------------------------------------------------------------------
   1.948 +    // WebGL extensions (implemented in WebGLContextExtensions.cpp)
   1.949 +    typedef EnumeratedArray<WebGLExtensionID,
   1.950 +                            WebGLExtensionID::Max,
   1.951 +                            nsRefPtr<WebGLExtensionBase>> ExtensionsArrayType;
   1.952 +
   1.953 +    ExtensionsArrayType mExtensions;
   1.954 +
   1.955 +    // enable an extension. the extension should not be enabled before.
   1.956 +    void EnableExtension(WebGLExtensionID ext);
   1.957 +
   1.958 +    // returns true if the extension has been enabled by calling getExtension.
   1.959 +    bool IsExtensionEnabled(WebGLExtensionID ext) const;
   1.960 +
   1.961 +    // returns true if the extension is supported for this JSContext (this decides what getSupportedExtensions exposes)
   1.962 +    bool IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const;
   1.963 +    bool IsExtensionSupported(WebGLExtensionID ext) const;
   1.964 +
   1.965 +    static const char* GetExtensionString(WebGLExtensionID ext);
   1.966 +
   1.967 +    nsTArray<GLenum> mCompressedTextureFormats;
   1.968 +
   1.969 +    // -------------------------------------------------------------------------
   1.970 +    // WebGL 2 specifics (implemented in WebGL2Context.cpp)
   1.971 +
   1.972 +    virtual bool IsWebGL2() const = 0;
   1.973 +
   1.974 +    bool InitWebGL2();
   1.975 +
   1.976 +
   1.977 +    // -------------------------------------------------------------------------
   1.978 +    // Validation functions (implemented in WebGLContextValidate.cpp)
   1.979 +    GLenum BaseTexFormat(GLenum internalFormat) const;
   1.980 +
   1.981 +    bool InitAndValidateGL();
   1.982 +    bool ValidateBlendEquationEnum(GLenum cap, const char *info);
   1.983 +    bool ValidateBlendFuncDstEnum(GLenum mode, const char *info);
   1.984 +    bool ValidateBlendFuncSrcEnum(GLenum mode, const char *info);
   1.985 +    bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info);
   1.986 +    bool ValidateTextureTargetEnum(GLenum target, const char *info);
   1.987 +    bool ValidateComparisonEnum(GLenum target, const char *info);
   1.988 +    bool ValidateStencilOpEnum(GLenum action, const char *info);
   1.989 +    bool ValidateFaceEnum(GLenum face, const char *info);
   1.990 +    bool ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFunc func);
   1.991 +    bool ValidateDrawModeEnum(GLenum mode, const char *info);
   1.992 +    bool ValidateAttribIndex(GLuint index, const char *info);
   1.993 +    bool ValidateStencilParamsForDrawCall();
   1.994 +
   1.995 +    bool ValidateGLSLVariableName(const nsAString& name, const char *info);
   1.996 +    bool ValidateGLSLCharacter(char16_t c);
   1.997 +    bool ValidateGLSLString(const nsAString& string, const char *info);
   1.998 +
   1.999 +    bool ValidateTexImage(GLuint dims, GLenum target,
  1.1000 +                          GLint level, GLint internalFormat,
  1.1001 +                          GLint xoffset, GLint yoffset, GLint zoffset,
  1.1002 +                          GLint width, GLint height, GLint depth,
  1.1003 +                          GLint border, GLenum format, GLenum type,
  1.1004 +                          WebGLTexImageFunc func);
  1.1005 +    bool ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFunc func);
  1.1006 +    bool ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func);
  1.1007 +    bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func);
  1.1008 +    bool ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func);
  1.1009 +    bool ValidateTexImageSize(GLenum target, GLint level,
  1.1010 +                              GLint width, GLint height, GLint depth,
  1.1011 +                              WebGLTexImageFunc func);
  1.1012 +    bool ValidateTexSubImageSize(GLint x, GLint y, GLint z,
  1.1013 +                                 GLsizei width, GLsizei height, GLsizei depth,
  1.1014 +                                 GLsizei baseWidth, GLsizei baseHeight, GLsizei baseDepth,
  1.1015 +                                 WebGLTexImageFunc func);
  1.1016 +
  1.1017 +    bool ValidateCompTexImageSize(GLenum target, GLint level, GLenum format,
  1.1018 +                                  GLint xoffset, GLint yoffset,
  1.1019 +                                  GLsizei width, GLsizei height,
  1.1020 +                                  GLsizei levelWidth, GLsizei levelHeight,
  1.1021 +                                  WebGLTexImageFunc func);
  1.1022 +    bool ValidateCompTexImageDataSize(GLint level, GLenum format,
  1.1023 +                                      GLsizei width, GLsizei height,
  1.1024 +                                      uint32_t byteLength, WebGLTexImageFunc func);
  1.1025 +
  1.1026 +
  1.1027 +    static uint32_t GetBitsPerTexel(GLenum format, GLenum type);
  1.1028 +
  1.1029 +    void Invalidate();
  1.1030 +    void DestroyResourcesAndContext();
  1.1031 +
  1.1032 +    void MakeContextCurrent() const;
  1.1033 +
  1.1034 +    // helpers
  1.1035 +    void TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
  1.1036 +                         GLsizei width, GLsizei height, GLsizei srcStrideOrZero, GLint border,
  1.1037 +                         GLenum format, GLenum type,
  1.1038 +                         void *data, uint32_t byteLength,
  1.1039 +                         int jsArrayType,
  1.1040 +                         WebGLTexelFormat srcFormat, bool srcPremultiplied);
  1.1041 +    void TexSubImage2D_base(GLenum target, GLint level,
  1.1042 +                            GLint xoffset, GLint yoffset,
  1.1043 +                            GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
  1.1044 +                            GLenum format, GLenum type,
  1.1045 +                            void *pixels, uint32_t byteLength,
  1.1046 +                            int jsArrayType,
  1.1047 +                            WebGLTexelFormat srcFormat, bool srcPremultiplied);
  1.1048 +    void TexParameter_base(GLenum target, GLenum pname,
  1.1049 +                           GLint *intParamPtr, GLfloat *floatParamPtr);
  1.1050 +
  1.1051 +    void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
  1.1052 +                      const uint8_t* src, uint8_t *dst,
  1.1053 +                      WebGLTexelFormat srcFormat, bool srcPremultiplied,
  1.1054 +                      WebGLTexelFormat dstFormat, bool dstPremultiplied,
  1.1055 +                      size_t dstTexelSize);
  1.1056 +
  1.1057 +    template<class ElementType>
  1.1058 +    nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(ElementType* aElement) {
  1.1059 +        MOZ_ASSERT(aElement);
  1.1060 +        uint32_t flags =
  1.1061 +             nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
  1.1062 +
  1.1063 +        if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
  1.1064 +            flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
  1.1065 +        if (!mPixelStorePremultiplyAlpha)
  1.1066 +            flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
  1.1067 +        return nsLayoutUtils::SurfaceFromElement(aElement, flags);
  1.1068 +    }
  1.1069 +    template<class ElementType>
  1.1070 +    nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(ElementType& aElement)
  1.1071 +    {
  1.1072 +      return SurfaceFromElement(&aElement);
  1.1073 +    }
  1.1074 +
  1.1075 +    nsresult SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
  1.1076 +                                                    RefPtr<gfx::DataSourceSurface>& imageOut,
  1.1077 +                                                    WebGLTexelFormat *format);
  1.1078 +
  1.1079 +    void CopyTexSubImage2D_base(GLenum target,
  1.1080 +                                GLint level,
  1.1081 +                                GLenum internalformat,
  1.1082 +                                GLint xoffset,
  1.1083 +                                GLint yoffset,
  1.1084 +                                GLint x,
  1.1085 +                                GLint y,
  1.1086 +                                GLsizei width,
  1.1087 +                                GLsizei height,
  1.1088 +                                bool sub);
  1.1089 +
  1.1090 +    // Returns false if aObject is null or not valid
  1.1091 +    template<class ObjectType>
  1.1092 +    bool ValidateObject(const char* info, ObjectType *aObject);
  1.1093 +    // Returns false if aObject is not valid.  Considers null to be valid.
  1.1094 +    template<class ObjectType>
  1.1095 +    bool ValidateObjectAllowNull(const char* info, ObjectType *aObject);
  1.1096 +    // Returns false if aObject is not valid, but considers deleted
  1.1097 +    // objects and null objects valid.
  1.1098 +    template<class ObjectType>
  1.1099 +    bool ValidateObjectAllowDeletedOrNull(const char* info, ObjectType *aObject);
  1.1100 +    // Returns false if aObject is null or not valid, but considers deleted
  1.1101 +    // objects valid.
  1.1102 +    template<class ObjectType>
  1.1103 +    bool ValidateObjectAllowDeleted(const char* info, ObjectType *aObject);
  1.1104 +private:
  1.1105 +    // Like ValidateObject, but only for cases when aObject is known
  1.1106 +    // to not be null already.
  1.1107 +    template<class ObjectType>
  1.1108 +    bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject);
  1.1109 +
  1.1110 +protected:
  1.1111 +    int32_t MaxTextureSizeForTarget(GLenum target) const {
  1.1112 +        MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
  1.1113 +                   (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
  1.1114 +                    target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z),
  1.1115 +                   "Invalid target enum");
  1.1116 +        return (target == LOCAL_GL_TEXTURE_2D) ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
  1.1117 +    }
  1.1118 +
  1.1119 +    /** like glBufferData but if the call may change the buffer size, checks any GL error generated
  1.1120 +     * by this glBufferData call and returns it */
  1.1121 +    GLenum CheckedBufferData(GLenum target,
  1.1122 +                             GLsizeiptr size,
  1.1123 +                             const GLvoid *data,
  1.1124 +                             GLenum usage);
  1.1125 +    /** like glTexImage2D but if the call may change the texture size, checks any GL error generated
  1.1126 +     * by this glTexImage2D call and returns it */
  1.1127 +    GLenum CheckedTexImage2D(GLenum target,
  1.1128 +                             GLint level,
  1.1129 +                             GLenum internalFormat,
  1.1130 +                             GLsizei width,
  1.1131 +                             GLsizei height,
  1.1132 +                             GLint border,
  1.1133 +                             GLenum format,
  1.1134 +                             GLenum type,
  1.1135 +                             const GLvoid *data);
  1.1136 +
  1.1137 +    void MaybeRestoreContext();
  1.1138 +    void ForceLoseContext();
  1.1139 +    void ForceRestoreContext();
  1.1140 +
  1.1141 +    nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
  1.1142 +    nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
  1.1143 +
  1.1144 +    WebGLRefPtr<WebGLProgram> mCurrentProgram;
  1.1145 +
  1.1146 +    uint32_t mMaxFramebufferColorAttachments;
  1.1147 +
  1.1148 +    WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
  1.1149 +    WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
  1.1150 +    WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
  1.1151 +
  1.1152 +    LinkedList<WebGLTexture> mTextures;
  1.1153 +    LinkedList<WebGLBuffer> mBuffers;
  1.1154 +    LinkedList<WebGLProgram> mPrograms;
  1.1155 +    LinkedList<WebGLQuery> mQueries;
  1.1156 +    LinkedList<WebGLShader> mShaders;
  1.1157 +    LinkedList<WebGLRenderbuffer> mRenderbuffers;
  1.1158 +    LinkedList<WebGLFramebuffer> mFramebuffers;
  1.1159 +    LinkedList<WebGLVertexArray> mVertexArrays;
  1.1160 +
  1.1161 +    WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
  1.1162 +
  1.1163 +    // PixelStore parameters
  1.1164 +    uint32_t mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
  1.1165 +    bool mPixelStoreFlipY, mPixelStorePremultiplyAlpha;
  1.1166 +
  1.1167 +    WebGLContextFakeBlackStatus mFakeBlackStatus;
  1.1168 +
  1.1169 +    class FakeBlackTexture
  1.1170 +    {
  1.1171 +        gl::GLContext* mGL;
  1.1172 +        GLuint mGLName;
  1.1173 +
  1.1174 +    public:
  1.1175 +        FakeBlackTexture(gl::GLContext* gl, GLenum target, GLenum format);
  1.1176 +        ~FakeBlackTexture();
  1.1177 +        GLuint GLName() const { return mGLName; }
  1.1178 +    };
  1.1179 +
  1.1180 +    ScopedDeletePtr<FakeBlackTexture> mBlackOpaqueTexture2D,
  1.1181 +                                      mBlackOpaqueTextureCubeMap,
  1.1182 +                                      mBlackTransparentTexture2D,
  1.1183 +                                      mBlackTransparentTextureCubeMap;
  1.1184 +
  1.1185 +    void BindFakeBlackTexturesHelper(
  1.1186 +        GLenum target,
  1.1187 +        const nsTArray<WebGLRefPtr<WebGLTexture> >& boundTexturesArray,
  1.1188 +        ScopedDeletePtr<FakeBlackTexture> & opaqueTextureScopedPtr,
  1.1189 +        ScopedDeletePtr<FakeBlackTexture> & transparentTextureScopedPtr);
  1.1190 +
  1.1191 +    GLfloat mVertexAttrib0Vector[4];
  1.1192 +    GLfloat mFakeVertexAttrib0BufferObjectVector[4];
  1.1193 +    size_t mFakeVertexAttrib0BufferObjectSize;
  1.1194 +    GLuint mFakeVertexAttrib0BufferObject;
  1.1195 +    WebGLVertexAttrib0Status mFakeVertexAttrib0BufferStatus;
  1.1196 +
  1.1197 +    GLint mStencilRefFront, mStencilRefBack;
  1.1198 +    GLuint mStencilValueMaskFront, mStencilValueMaskBack,
  1.1199 +              mStencilWriteMaskFront, mStencilWriteMaskBack;
  1.1200 +    realGLboolean mColorWriteMask[4];
  1.1201 +    realGLboolean mDepthWriteMask;
  1.1202 +    GLfloat mColorClearValue[4];
  1.1203 +    GLint mStencilClearValue;
  1.1204 +    GLfloat mDepthClearValue;
  1.1205 +
  1.1206 +    GLint mViewportX;
  1.1207 +    GLint mViewportY;
  1.1208 +    GLsizei mViewportWidth;
  1.1209 +    GLsizei mViewportHeight;
  1.1210 +    bool mAlreadyWarnedAboutViewportLargerThanDest;
  1.1211 +
  1.1212 +    nsCOMPtr<nsITimer> mContextRestorer;
  1.1213 +    bool mAllowRestore;
  1.1214 +    bool mContextLossTimerRunning;
  1.1215 +    bool mDrawSinceContextLossTimerSet;
  1.1216 +    ContextStatus mContextStatus;
  1.1217 +    bool mContextLostErrorSet;
  1.1218 +
  1.1219 +    // Used for some hardware (particularly Tegra 2 and 4) that likes to
  1.1220 +    // be Flushed while doing hundreds of draw calls.
  1.1221 +    int mDrawCallsSinceLastFlush;
  1.1222 +
  1.1223 +    int mAlreadyGeneratedWarnings;
  1.1224 +    int mMaxWarnings;
  1.1225 +    bool mAlreadyWarnedAboutFakeVertexAttrib0;
  1.1226 +
  1.1227 +    bool ShouldGenerateWarnings() const;
  1.1228 +
  1.1229 +    uint64_t mLastUseIndex;
  1.1230 +
  1.1231 +    void LoseOldestWebGLContextIfLimitExceeded();
  1.1232 +    void UpdateLastUseIndex();
  1.1233 +
  1.1234 +    template <typename WebGLObjectType>
  1.1235 +    JS::Value WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
  1.1236 +    template <typename WebGLObjectType>
  1.1237 +    JSObject* WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
  1.1238 +
  1.1239 +#ifdef XP_MACOSX
  1.1240 +    // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
  1.1241 +    // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
  1.1242 +    // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
  1.1243 +    // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
  1.1244 +    // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
  1.1245 +    ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
  1.1246 +#endif
  1.1247 +
  1.1248 +    nsRefPtr<WebGLMemoryPressureObserver> mMemoryPressureObserver;
  1.1249 +
  1.1250 +public:
  1.1251 +    // console logging helpers
  1.1252 +    void GenerateWarning(const char *fmt, ...);
  1.1253 +    void GenerateWarning(const char *fmt, va_list ap);
  1.1254 +
  1.1255 +    friend class WebGLTexture;
  1.1256 +    friend class WebGLFramebuffer;
  1.1257 +    friend class WebGLRenderbuffer;
  1.1258 +    friend class WebGLProgram;
  1.1259 +    friend class WebGLQuery;
  1.1260 +    friend class WebGLBuffer;
  1.1261 +    friend class WebGLShader;
  1.1262 +    friend class WebGLUniformLocation;
  1.1263 +    friend class WebGLVertexArray;
  1.1264 +};
  1.1265 +
  1.1266 +// used by DOM bindings in conjunction with GetParentObject
  1.1267 +inline nsISupports*
  1.1268 +ToSupports(WebGLContext* context)
  1.1269 +{
  1.1270 +  return static_cast<nsIDOMWebGLRenderingContext*>(context);
  1.1271 +}
  1.1272 +
  1.1273 +/**
  1.1274 + ** Template implementations
  1.1275 + **/
  1.1276 +
  1.1277 +template<class ObjectType>
  1.1278 +inline bool
  1.1279 +WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info,
  1.1280 +                                               ObjectType *aObject)
  1.1281 +{
  1.1282 +    if (aObject && !aObject->IsCompatibleWithContext(this)) {
  1.1283 +        ErrorInvalidOperation("%s: object from different WebGL context "
  1.1284 +                              "(or older generation of this one) "
  1.1285 +                              "passed as argument", info);
  1.1286 +        return false;
  1.1287 +    }
  1.1288 +
  1.1289 +    return true;
  1.1290 +}
  1.1291 +
  1.1292 +template<class ObjectType>
  1.1293 +inline bool
  1.1294 +WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject)
  1.1295 +{
  1.1296 +    MOZ_ASSERT(aObject);
  1.1297 +
  1.1298 +    if (!ValidateObjectAllowDeletedOrNull(info, aObject))
  1.1299 +        return false;
  1.1300 +
  1.1301 +    if (aObject->IsDeleted()) {
  1.1302 +        ErrorInvalidValue("%s: deleted object passed as argument", info);
  1.1303 +        return false;
  1.1304 +    }
  1.1305 +
  1.1306 +    return true;
  1.1307 +}
  1.1308 +
  1.1309 +template<class ObjectType>
  1.1310 +inline bool
  1.1311 +WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType *aObject)
  1.1312 +{
  1.1313 +    if (!aObject) {
  1.1314 +        return true;
  1.1315 +    }
  1.1316 +
  1.1317 +    return ValidateObjectAssumeNonNull(info, aObject);
  1.1318 +}
  1.1319 +
  1.1320 +template<class ObjectType>
  1.1321 +inline bool
  1.1322 +WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType *aObject)
  1.1323 +{
  1.1324 +    if (!aObject) {
  1.1325 +        ErrorInvalidValue("%s: null object passed as argument", info);
  1.1326 +        return false;
  1.1327 +    }
  1.1328 +
  1.1329 +    return ValidateObjectAllowDeletedOrNull(info, aObject);
  1.1330 +}
  1.1331 +
  1.1332 +template<class ObjectType>
  1.1333 +inline bool
  1.1334 +WebGLContext::ValidateObject(const char* info, ObjectType *aObject)
  1.1335 +{
  1.1336 +    if (!aObject) {
  1.1337 +        ErrorInvalidValue("%s: null object passed as argument", info);
  1.1338 +        return false;
  1.1339 +    }
  1.1340 +
  1.1341 +    return ValidateObjectAssumeNonNull(info, aObject);
  1.1342 +}
  1.1343 +
  1.1344 +class WebGLMemoryPressureObserver MOZ_FINAL
  1.1345 +    : public nsIObserver
  1.1346 +{
  1.1347 +public:
  1.1348 +  NS_DECL_ISUPPORTS
  1.1349 +  NS_DECL_NSIOBSERVER
  1.1350 +
  1.1351 +  WebGLMemoryPressureObserver(WebGLContext *context)
  1.1352 +    : mContext(context)
  1.1353 +  {}
  1.1354 +
  1.1355 +private:
  1.1356 +  WebGLContext *mContext;
  1.1357 +};
  1.1358 +
  1.1359 +} // namespace mozilla
  1.1360 +
  1.1361 +#endif

mercurial