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