1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef WEBGLCONTEXT_H_
7 #define WEBGLCONTEXT_H_
9 #include "mozilla/Attributes.h"
10 #include "mozilla/CheckedInt.h"
11 #include "mozilla/EnumeratedArray.h"
12 #include "mozilla/LinkedList.h"
13 #include "mozilla/UniquePtr.h"
14 #include "mozilla/WeakPtr.h"
17 #include "WebGLActiveInfo.h"
18 #include "WebGLObjectModel.h"
19 #include "WebGLRenderbuffer.h"
23 #include "nsCycleCollectionNoteChild.h"
25 #include "nsIDOMWebGLRenderingContext.h"
26 #include "nsICanvasRenderingContextInternal.h"
27 #include "mozilla/dom/HTMLCanvasElement.h"
28 #include "nsWrapperCache.h"
29 #include "nsIObserver.h"
30 #include "nsIDOMEventListener.h"
31 #include "nsLayoutUtils.h"
33 #include "GLContextProvider.h"
35 #include "mozilla/gfx/2D.h"
38 #include "ForceDiscreteGPUHelperCGL.h"
41 #include "mozilla/dom/TypedArray.h"
42 #include "mozilla/ErrorResult.h"
47 * Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
48 * https://bugzilla.mozilla.org/show_bug.cgi?id=686732
50 * Exceptions: some of the following values are set to higher values than in the spec because
51 * the values in the spec are ridiculously low. They are explicitly marked below
53 #define MINVALUE_GL_MAX_TEXTURE_SIZE 1024 // Different from the spec, which sets it to 64 on page 162
54 #define MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE 512 // Different from the spec, which sets it to 16 on page 162
55 #define MINVALUE_GL_MAX_VERTEX_ATTRIBS 8 // Page 164
56 #define MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS 16 // Page 164
57 #define MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS 128 // Page 164
58 #define MINVALUE_GL_MAX_VARYING_VECTORS 8 // Page 164
59 #define MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS 8 // Page 164
60 #define MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0 // Page 164
61 #define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
62 #define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
66 class WebGLContextLossHandler
;
68 class WebGLContextBoundObject
;
69 class WebGLActiveInfo
;
70 class WebGLExtensionBase
;
72 struct WebGLVertexAttribData
;
76 class WebGLUniformLocation
;
77 class WebGLFramebuffer
;
78 class WebGLRenderbuffer
;
79 class WebGLShaderPrecisionFormat
;
81 class WebGLVertexArray
;
87 struct WebGLContextAttributes
;
88 template<typename
> struct Nullable
;
95 WebGLTexelFormat
GetWebGLTexelFormat(GLenum format
, GLenum type
);
97 void AssertUintParamCorrect(gl::GLContext
* gl
, GLenum pname
, GLuint shadow
);
99 struct WebGLContextOptions
{
100 // these are defaults
101 WebGLContextOptions();
103 bool operator==(const WebGLContextOptions
& other
) const {
105 alpha
== other
.alpha
&&
106 depth
== other
.depth
&&
107 stencil
== other
.stencil
&&
108 premultipliedAlpha
== other
.premultipliedAlpha
&&
109 antialias
== other
.antialias
&&
110 preserveDrawingBuffer
== other
.preserveDrawingBuffer
;
113 bool operator!=(const WebGLContextOptions
& other
) const {
114 return !operator==(other
);
120 bool premultipliedAlpha
;
122 bool preserveDrawingBuffer
;
127 IsTextureBinding(GLenum binding
)
130 case LOCAL_GL_TEXTURE_BINDING_2D
:
131 case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP
:
139 public nsIDOMWebGLRenderingContext
,
140 public nsICanvasRenderingContextInternal
,
141 public nsSupportsWeakReference
,
142 public WebGLRectangleObject
,
143 public nsWrapperCache
,
144 public SupportsWeakPtr
<WebGLContext
>
146 friend class WebGLContextUserData
;
147 friend class WebGLExtensionCompressedTextureATC
;
148 friend class WebGLExtensionCompressedTextureETC1
;
149 friend class WebGLExtensionCompressedTexturePVRTC
;
150 friend class WebGLExtensionCompressedTextureS3TC
;
151 friend class WebGLExtensionDepthTexture
;
152 friend class WebGLExtensionDrawBuffers
;
153 friend class WebGLExtensionLoseContext
;
154 friend class WebGLExtensionVertexArray
;
155 friend class WebGLObserver
;
156 friend class WebGLMemoryTracker
;
159 UNPACK_FLIP_Y_WEBGL
= 0x9240,
160 UNPACK_PREMULTIPLY_ALPHA_WEBGL
= 0x9241,
161 CONTEXT_LOST_WEBGL
= 0x9242,
162 UNPACK_COLORSPACE_CONVERSION_WEBGL
= 0x9243,
163 BROWSER_DEFAULT_WEBGL
= 0x9244,
164 UNMASKED_VENDOR_WEBGL
= 0x9245,
165 UNMASKED_RENDERER_WEBGL
= 0x9246
171 MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLContext
)
173 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
175 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext
,
176 nsIDOMWebGLRenderingContext
)
178 virtual JSObject
* WrapObject(JSContext
*cx
) = 0;
180 NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
182 // nsICanvasRenderingContextInternal
184 virtual int32_t GetWidth() const MOZ_OVERRIDE
;
185 virtual int32_t GetHeight() const MOZ_OVERRIDE
;
187 NS_IMETHOD
SetDimensions(int32_t width
, int32_t height
) MOZ_OVERRIDE
;
188 NS_IMETHOD
InitializeWithSurface(nsIDocShell
*docShell
, gfxASurface
*surface
, int32_t width
, int32_t height
) MOZ_OVERRIDE
189 { return NS_ERROR_NOT_IMPLEMENTED
; }
190 NS_IMETHOD
Reset() MOZ_OVERRIDE
191 { /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED
; }
192 virtual void GetImageBuffer(uint8_t** aImageBuffer
, int32_t* aFormat
);
193 NS_IMETHOD
GetInputStream(const char* aMimeType
,
194 const char16_t
* aEncoderOptions
,
195 nsIInputStream
**aStream
) MOZ_OVERRIDE
;
196 mozilla::TemporaryRef
<mozilla::gfx::SourceSurface
> GetSurfaceSnapshot(bool* aPremultAlpha
) MOZ_OVERRIDE
;
198 NS_IMETHOD
SetIsOpaque(bool b
) MOZ_OVERRIDE
{ return NS_OK
; };
199 bool GetIsOpaque() MOZ_OVERRIDE
{ return false; }
200 NS_IMETHOD
SetContextOptions(JSContext
* aCx
,
201 JS::Handle
<JS::Value
> aOptions
) MOZ_OVERRIDE
;
203 NS_IMETHOD
SetIsIPC(bool b
) MOZ_OVERRIDE
{ return NS_ERROR_NOT_IMPLEMENTED
; }
204 NS_IMETHOD
Redraw(const gfxRect
&) { return NS_ERROR_NOT_IMPLEMENTED
; }
205 NS_IMETHOD
Swap(mozilla::ipc::Shmem
& aBack
,
206 int32_t x
, int32_t y
, int32_t w
, int32_t h
)
207 { return NS_ERROR_NOT_IMPLEMENTED
; }
208 NS_IMETHOD
Swap(uint32_t nativeID
,
209 int32_t x
, int32_t y
, int32_t w
, int32_t h
)
210 { return NS_ERROR_NOT_IMPLEMENTED
; }
212 void SynthesizeGLError(GLenum err
);
213 void SynthesizeGLError(GLenum err
, const char *fmt
, ...);
215 void ErrorInvalidEnum(const char *fmt
= 0, ...);
216 void ErrorInvalidOperation(const char *fmt
= 0, ...);
217 void ErrorInvalidValue(const char *fmt
= 0, ...);
218 void ErrorInvalidFramebufferOperation(const char *fmt
= 0, ...);
219 void ErrorInvalidEnumInfo(const char *info
, GLenum enumvalue
);
220 void ErrorOutOfMemory(const char *fmt
= 0, ...);
222 const char *ErrorName(GLenum error
);
225 * Return displayable name for GLenum.
226 * This version is like gl::GLenumToStr but with out the GL_ prefix to
227 * keep consistency with how errors are reported from WebGL.
229 static const char *EnumName(GLenum glenum
);
231 bool IsTextureFormatCompressed(GLenum format
);
233 void DummyFramebufferOperation(const char *info
);
235 WebGLTexture
* activeBoundTextureForTarget(GLenum target
) const {
236 MOZ_ASSERT(!IsTextureBinding(target
));
237 return target
== LOCAL_GL_TEXTURE_2D
? mBound2DTextures
[mActiveTexture
]
238 : mBoundCubeMapTextures
[mActiveTexture
];
241 already_AddRefed
<CanvasLayer
> GetCanvasLayer(nsDisplayListBuilder
* aBuilder
,
242 CanvasLayer
*aOldLayer
,
243 LayerManager
*aManager
) MOZ_OVERRIDE
;
245 // Note that 'clean' here refers to its invalidation state, not the
246 // contents of the buffer.
247 void MarkContextClean() MOZ_OVERRIDE
{ mInvalidated
= false; }
249 gl::GLContext
* GL() const { return gl
; }
251 bool IsPremultAlpha() const { return mOptions
.premultipliedAlpha
; }
253 bool PresentScreenBuffer();
255 // a number that increments every time we have an event that causes
256 // all context resources to be lost.
257 uint32_t Generation() { return mGeneration
.value(); }
259 // Returns null if the current bound FB is not likely complete.
260 const WebGLRectangleObject
* CurValidFBRectObject() const;
262 static const size_t kMaxColorAttachments
= 16;
264 // This is similar to GLContext::ClearSafely, but tries to minimize the
265 // amount of work it does.
266 // It only clears the buffers we specify, and can reset its state without
267 // first having to query anything, as WebGL knows its state at all times.
268 void ForceClearFramebufferWithDefaultValues(GLbitfield mask
, const bool colorAttachmentsMask
[kMaxColorAttachments
]);
270 // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
272 void ClearBackbufferIfNeeded();
274 bool MinCapabilityMode() const { return mMinCapability
; }
276 void RunContextLossTimer();
277 void UpdateContextLossStatus();
278 void EnqueueUpdateContextLossStatus();
280 bool TryToRestoreContext();
282 void AssertCachedBindings();
283 void AssertCachedState();
285 // WebIDL WebGLRenderingContext API
286 dom::HTMLCanvasElement
* GetCanvas() const { return mCanvasElement
; }
287 GLsizei
DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth
; }
288 GLsizei
DrawingBufferHeight() const { return IsContextLost() ? 0 : mHeight
; }
290 void GetContextAttributes(dom::Nullable
<dom::WebGLContextAttributes
>& retval
);
291 bool IsContextLost() const { return mContextStatus
!= ContextNotLost
; }
292 void GetSupportedExtensions(JSContext
*cx
, dom::Nullable
< nsTArray
<nsString
> > &retval
);
293 void GetExtension(JSContext
* cx
, const nsAString
& aName
,
294 JS::MutableHandle
<JSObject
*> aRetval
,
296 void ActiveTexture(GLenum texture
);
297 void AttachShader(WebGLProgram
* program
, WebGLShader
* shader
);
298 void BindAttribLocation(WebGLProgram
* program
, GLuint location
,
299 const nsAString
& name
);
300 void BindFramebuffer(GLenum target
, WebGLFramebuffer
* wfb
);
301 void BindRenderbuffer(GLenum target
, WebGLRenderbuffer
* wrb
);
302 void BindTexture(GLenum target
, WebGLTexture
*tex
);
303 void BindVertexArray(WebGLVertexArray
*vao
);
304 void BlendColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
);
305 void BlendEquation(GLenum mode
);
306 void BlendEquationSeparate(GLenum modeRGB
, GLenum modeAlpha
);
307 void BlendFunc(GLenum sfactor
, GLenum dfactor
);
308 void BlendFuncSeparate(GLenum srcRGB
, GLenum dstRGB
,
309 GLenum srcAlpha
, GLenum dstAlpha
);
310 GLenum
CheckFramebufferStatus(GLenum target
);
311 void Clear(GLbitfield mask
);
312 void ClearColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
);
313 void ClearDepth(GLclampf v
);
314 void ClearStencil(GLint v
);
315 void ColorMask(WebGLboolean r
, WebGLboolean g
, WebGLboolean b
, WebGLboolean a
);
316 void CompileShader(WebGLShader
*shader
);
317 void CompressedTexImage2D(GLenum target
, GLint level
,
318 GLenum internalformat
, GLsizei width
,
319 GLsizei height
, GLint border
,
320 const dom::ArrayBufferView
& view
);
321 void CompressedTexSubImage2D(GLenum target
, GLint level
,
322 GLint xoffset
, GLint yoffset
,
323 GLsizei width
, GLsizei height
,
325 const dom::ArrayBufferView
& view
);
326 void CopyTexImage2D(GLenum target
, GLint level
,
327 GLenum internalformat
, GLint x
, GLint y
,
328 GLsizei width
, GLsizei height
, GLint border
);
329 void CopyTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
,
330 GLint yoffset
, GLint x
, GLint y
,
331 GLsizei width
, GLsizei height
);
332 already_AddRefed
<WebGLFramebuffer
> CreateFramebuffer();
333 already_AddRefed
<WebGLProgram
> CreateProgram();
334 already_AddRefed
<WebGLRenderbuffer
> CreateRenderbuffer();
335 already_AddRefed
<WebGLTexture
> CreateTexture();
336 already_AddRefed
<WebGLShader
> CreateShader(GLenum type
);
337 already_AddRefed
<WebGLVertexArray
> CreateVertexArray();
338 void CullFace(GLenum face
);
339 void DeleteFramebuffer(WebGLFramebuffer
*fbuf
);
340 void DeleteProgram(WebGLProgram
*prog
);
341 void DeleteRenderbuffer(WebGLRenderbuffer
*rbuf
);
342 void DeleteShader(WebGLShader
*shader
);
343 void DeleteVertexArray(WebGLVertexArray
*vao
);
344 void DeleteTexture(WebGLTexture
*tex
);
345 void DepthFunc(GLenum func
);
346 void DepthMask(WebGLboolean b
);
347 void DepthRange(GLclampf zNear
, GLclampf zFar
);
348 void DetachShader(WebGLProgram
*program
, WebGLShader
*shader
);
349 void DrawBuffers(const dom::Sequence
<GLenum
>& buffers
);
352 void FramebufferRenderbuffer(GLenum target
, GLenum attachment
,
353 GLenum rbtarget
, WebGLRenderbuffer
*wrb
);
354 void FramebufferTexture2D(GLenum target
, GLenum attachment
,
355 GLenum textarget
, WebGLTexture
*tobj
,
357 void FrontFace(GLenum mode
);
358 void GenerateMipmap(GLenum target
);
359 already_AddRefed
<WebGLActiveInfo
> GetActiveAttrib(WebGLProgram
*prog
,
361 already_AddRefed
<WebGLActiveInfo
> GetActiveUniform(WebGLProgram
*prog
,
363 void GetAttachedShaders(WebGLProgram
* prog
,
364 dom::Nullable
< nsTArray
<WebGLShader
*> > &retval
);
365 GLint
GetAttribLocation(WebGLProgram
* prog
, const nsAString
& name
);
366 JS::Value
GetBufferParameter(GLenum target
, GLenum pname
);
367 void GetBufferParameter(JSContext
* /* unused */, GLenum target
,
369 JS::MutableHandle
<JS::Value
> retval
) {
370 retval
.set(GetBufferParameter(target
, pname
));
373 JS::Value
GetFramebufferAttachmentParameter(JSContext
* cx
,
378 void GetFramebufferAttachmentParameter(JSContext
* cx
,
382 JS::MutableHandle
<JS::Value
> retval
,
384 retval
.set(GetFramebufferAttachmentParameter(cx
, target
, attachment
,
387 JS::Value
GetProgramParameter(WebGLProgram
*prog
, GLenum pname
);
388 void GetProgramParameter(JSContext
* /* unused */, WebGLProgram
*prog
,
390 JS::MutableHandle
<JS::Value
> retval
) {
391 retval
.set(GetProgramParameter(prog
, pname
));
393 void GetProgramInfoLog(WebGLProgram
*prog
, nsACString
& retval
);
394 void GetProgramInfoLog(WebGLProgram
*prog
, nsAString
& retval
);
395 JS::Value
GetRenderbufferParameter(GLenum target
, GLenum pname
);
396 void GetRenderbufferParameter(JSContext
* /* unused */,
397 GLenum target
, GLenum pname
,
398 JS::MutableHandle
<JS::Value
> retval
) {
399 retval
.set(GetRenderbufferParameter(target
, pname
));
401 JS::Value
GetShaderParameter(WebGLShader
*shader
, GLenum pname
);
402 void GetShaderParameter(JSContext
* /* unused */, WebGLShader
*shader
,
404 JS::MutableHandle
<JS::Value
> retval
) {
405 retval
.set(GetShaderParameter(shader
, pname
));
407 already_AddRefed
<WebGLShaderPrecisionFormat
>
408 GetShaderPrecisionFormat(GLenum shadertype
, GLenum precisiontype
);
409 void GetShaderInfoLog(WebGLShader
*shader
, nsACString
& retval
);
410 void GetShaderInfoLog(WebGLShader
*shader
, nsAString
& retval
);
411 void GetShaderSource(WebGLShader
*shader
, nsAString
& retval
);
412 void GetShaderTranslatedSource(WebGLShader
*shader
, nsAString
& retval
);
413 JS::Value
GetTexParameter(GLenum target
, GLenum pname
);
414 void GetTexParameter(JSContext
* /* unused */, GLenum target
,
416 JS::MutableHandle
<JS::Value
> retval
) {
417 retval
.set(GetTexParameter(target
, pname
));
419 JS::Value
GetUniform(JSContext
* cx
, WebGLProgram
*prog
,
420 WebGLUniformLocation
*location
);
421 void GetUniform(JSContext
* cx
, WebGLProgram
*prog
,
422 WebGLUniformLocation
*location
,
423 JS::MutableHandle
<JS::Value
> retval
) {
424 retval
.set(GetUniform(cx
, prog
, location
));
426 already_AddRefed
<WebGLUniformLocation
>
427 GetUniformLocation(WebGLProgram
*prog
, const nsAString
& name
);
428 void Hint(GLenum target
, GLenum mode
);
429 bool IsFramebuffer(WebGLFramebuffer
*fb
);
430 bool IsProgram(WebGLProgram
*prog
);
431 bool IsRenderbuffer(WebGLRenderbuffer
*rb
);
432 bool IsShader(WebGLShader
*shader
);
433 bool IsTexture(WebGLTexture
*tex
);
434 bool IsVertexArray(WebGLVertexArray
*vao
);
435 void LineWidth(GLfloat width
);
436 void LinkProgram(WebGLProgram
*program
);
437 void PixelStorei(GLenum pname
, GLint param
);
438 void PolygonOffset(GLfloat factor
, GLfloat units
);
439 void ReadPixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
440 GLenum format
, GLenum type
,
441 const Nullable
<dom::ArrayBufferView
> &pixels
,
443 void RenderbufferStorage(GLenum target
, GLenum internalformat
,
444 GLsizei width
, GLsizei height
);
445 void SampleCoverage(GLclampf value
, WebGLboolean invert
);
446 void Scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
);
447 void ShaderSource(WebGLShader
*shader
, const nsAString
& source
);
448 void StencilFunc(GLenum func
, GLint ref
, GLuint mask
);
449 void StencilFuncSeparate(GLenum face
, GLenum func
, GLint ref
,
451 void StencilMask(GLuint mask
);
452 void StencilMaskSeparate(GLenum face
, GLuint mask
);
453 void StencilOp(GLenum sfail
, GLenum dpfail
, GLenum dppass
);
454 void StencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
456 void TexImage2D(GLenum target
, GLint level
,
457 GLenum internalformat
, GLsizei width
,
458 GLsizei height
, GLint border
, GLenum format
,
460 const Nullable
<dom::ArrayBufferView
> &pixels
,
462 void TexImage2D(GLenum target
, GLint level
,
463 GLenum internalformat
, GLenum format
, GLenum type
,
464 dom::ImageData
* pixels
, ErrorResult
& rv
);
465 // Allow whatever element types the bindings are willing to pass
467 bool TexImageFromVideoElement(GLenum target
, GLint level
,
468 GLenum internalformat
, GLenum format
, GLenum type
,
469 mozilla::dom::Element
& image
);
471 template<class ElementType
>
472 void TexImage2D(GLenum target
, GLint level
,
473 GLenum internalformat
, GLenum format
, GLenum type
,
474 ElementType
& elt
, ErrorResult
& rv
)
479 WebGLTexture
* tex
= activeBoundTextureForTarget(target
);
482 return ErrorInvalidOperation("no texture is bound to this target");
484 // Trying to handle the video by GPU directly first
485 if (TexImageFromVideoElement(target
, level
, internalformat
, format
, type
, elt
)) {
489 RefPtr
<gfx::DataSourceSurface
> data
;
490 WebGLTexelFormat srcFormat
;
491 nsLayoutUtils::SurfaceFromElementResult res
= SurfaceFromElement(elt
);
492 rv
= SurfaceFromElementResultToImageSurface(res
, data
,
494 if (rv
.Failed() || !data
)
497 gfx::IntSize size
= data
->GetSize();
498 uint32_t byteLength
= data
->Stride() * size
.height
;
499 return TexImage2D_base(target
, level
, internalformat
,
500 size
.width
, size
.height
, data
->Stride(),
501 0, format
, type
, data
->GetData(), byteLength
,
502 -1, srcFormat
, mPixelStorePremultiplyAlpha
);
505 void TexParameterf(GLenum target
, GLenum pname
, GLfloat param
) {
506 TexParameter_base(target
, pname
, nullptr, ¶m
);
508 void TexParameteri(GLenum target
, GLenum pname
, GLint param
) {
509 TexParameter_base(target
, pname
, ¶m
, nullptr);
512 void TexSubImage2D(GLenum target
, GLint level
,
513 GLint xoffset
, GLint yoffset
,
514 GLsizei width
, GLsizei height
, GLenum format
,
516 const Nullable
<dom::ArrayBufferView
> &pixels
,
518 void TexSubImage2D(GLenum target
, GLint level
,
519 GLint xoffset
, GLint yoffset
, GLenum format
,
520 GLenum type
, dom::ImageData
* pixels
, ErrorResult
& rv
);
521 // Allow whatever element types the bindings are willing to pass
522 // us in TexSubImage2D
523 template<class ElementType
>
524 void TexSubImage2D(GLenum target
, GLint level
,
525 GLint xoffset
, GLint yoffset
, GLenum format
,
526 GLenum type
, ElementType
& elt
, ErrorResult
& rv
)
531 // Trying to handle the video by GPU directly first
532 if (TexImageFromVideoElement(target
, level
, format
, format
, type
, elt
)) {
536 RefPtr
<gfx::DataSourceSurface
> data
;
537 WebGLTexelFormat srcFormat
;
538 nsLayoutUtils::SurfaceFromElementResult res
= SurfaceFromElement(elt
);
539 rv
= SurfaceFromElementResultToImageSurface(res
, data
,
541 if (rv
.Failed() || !data
)
544 gfx::IntSize size
= data
->GetSize();
545 uint32_t byteLength
= data
->Stride() * size
.height
;
546 return TexSubImage2D_base(target
, level
, xoffset
, yoffset
,
547 size
.width
, size
.height
,
548 data
->Stride(), format
, type
,
549 data
->GetData(), byteLength
,
550 -1, srcFormat
, mPixelStorePremultiplyAlpha
);
554 void Uniform1i(WebGLUniformLocation
* location
, GLint x
);
555 void Uniform2i(WebGLUniformLocation
* location
, GLint x
, GLint y
);
556 void Uniform3i(WebGLUniformLocation
* location
, GLint x
, GLint y
,
558 void Uniform4i(WebGLUniformLocation
* location
, GLint x
, GLint y
,
561 void Uniform1f(WebGLUniformLocation
* location
, GLfloat x
);
562 void Uniform2f(WebGLUniformLocation
* location
, GLfloat x
, GLfloat y
);
563 void Uniform3f(WebGLUniformLocation
* location
, GLfloat x
, GLfloat y
,
565 void Uniform4f(WebGLUniformLocation
* location
, GLfloat x
, GLfloat y
,
566 GLfloat z
, GLfloat w
);
568 void Uniform1iv(WebGLUniformLocation
* location
,
569 const dom::Int32Array
& arr
) {
570 arr
.ComputeLengthAndData();
571 Uniform1iv_base(location
, arr
.Length(), arr
.Data());
573 void Uniform1iv(WebGLUniformLocation
* location
,
574 const dom::Sequence
<GLint
>& arr
) {
575 Uniform1iv_base(location
, arr
.Length(), arr
.Elements());
577 void Uniform1iv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
580 void Uniform2iv(WebGLUniformLocation
* location
,
581 const dom::Int32Array
& arr
) {
582 arr
.ComputeLengthAndData();
583 Uniform2iv_base(location
, arr
.Length(), arr
.Data());
585 void Uniform2iv(WebGLUniformLocation
* location
,
586 const dom::Sequence
<GLint
>& arr
) {
587 Uniform2iv_base(location
, arr
.Length(), arr
.Elements());
589 void Uniform2iv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
592 void Uniform3iv(WebGLUniformLocation
* location
,
593 const dom::Int32Array
& arr
) {
594 arr
.ComputeLengthAndData();
595 Uniform3iv_base(location
, arr
.Length(), arr
.Data());
597 void Uniform3iv(WebGLUniformLocation
* location
,
598 const dom::Sequence
<GLint
>& arr
) {
599 Uniform3iv_base(location
, arr
.Length(), arr
.Elements());
601 void Uniform3iv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
604 void Uniform4iv(WebGLUniformLocation
* location
,
605 const dom::Int32Array
& arr
) {
606 arr
.ComputeLengthAndData();
607 Uniform4iv_base(location
, arr
.Length(), arr
.Data());
609 void Uniform4iv(WebGLUniformLocation
* location
,
610 const dom::Sequence
<GLint
>& arr
) {
611 Uniform4iv_base(location
, arr
.Length(), arr
.Elements());
613 void Uniform4iv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
616 void Uniform1fv(WebGLUniformLocation
* location
,
617 const dom::Float32Array
& arr
) {
618 arr
.ComputeLengthAndData();
619 Uniform1fv_base(location
, arr
.Length(), arr
.Data());
621 void Uniform1fv(WebGLUniformLocation
* location
,
622 const dom::Sequence
<GLfloat
>& arr
) {
623 Uniform1fv_base(location
, arr
.Length(), arr
.Elements());
625 void Uniform1fv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
626 const GLfloat
* data
);
628 void Uniform2fv(WebGLUniformLocation
* location
,
629 const dom::Float32Array
& arr
) {
630 arr
.ComputeLengthAndData();
631 Uniform2fv_base(location
, arr
.Length(), arr
.Data());
633 void Uniform2fv(WebGLUniformLocation
* location
,
634 const dom::Sequence
<GLfloat
>& arr
) {
635 Uniform2fv_base(location
, arr
.Length(), arr
.Elements());
637 void Uniform2fv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
638 const GLfloat
* data
);
640 void Uniform3fv(WebGLUniformLocation
* location
,
641 const dom::Float32Array
& arr
) {
642 arr
.ComputeLengthAndData();
643 Uniform3fv_base(location
, arr
.Length(), arr
.Data());
645 void Uniform3fv(WebGLUniformLocation
* location
,
646 const dom::Sequence
<GLfloat
>& arr
) {
647 Uniform3fv_base(location
, arr
.Length(), arr
.Elements());
649 void Uniform3fv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
650 const GLfloat
* data
);
652 void Uniform4fv(WebGLUniformLocation
* location
,
653 const dom::Float32Array
& arr
) {
654 arr
.ComputeLengthAndData();
655 Uniform4fv_base(location
, arr
.Length(), arr
.Data());
657 void Uniform4fv(WebGLUniformLocation
* location
,
658 const dom::Sequence
<GLfloat
>& arr
) {
659 Uniform4fv_base(location
, arr
.Length(), arr
.Elements());
661 void Uniform4fv_base(WebGLUniformLocation
* location
, uint32_t arrayLength
,
662 const GLfloat
* data
);
664 void UniformMatrix2fv(WebGLUniformLocation
* location
,
665 WebGLboolean transpose
,
666 const dom::Float32Array
&value
) {
667 value
.ComputeLengthAndData();
668 UniformMatrix2fv_base(location
, transpose
, value
.Length(), value
.Data());
670 void UniformMatrix2fv(WebGLUniformLocation
* location
,
671 WebGLboolean transpose
,
672 const dom::Sequence
<float> &value
) {
673 UniformMatrix2fv_base(location
, transpose
, value
.Length(),
676 void UniformMatrix2fv_base(WebGLUniformLocation
* location
,
677 WebGLboolean transpose
, uint32_t arrayLength
,
680 void UniformMatrix3fv(WebGLUniformLocation
* location
,
681 WebGLboolean transpose
,
682 const dom::Float32Array
&value
) {
683 value
.ComputeLengthAndData();
684 UniformMatrix3fv_base(location
, transpose
, value
.Length(), value
.Data());
686 void UniformMatrix3fv(WebGLUniformLocation
* location
,
687 WebGLboolean transpose
,
688 const dom::Sequence
<float> &value
) {
689 UniformMatrix3fv_base(location
, transpose
, value
.Length(),
692 void UniformMatrix3fv_base(WebGLUniformLocation
* location
,
693 WebGLboolean transpose
, uint32_t arrayLength
,
696 void UniformMatrix4fv(WebGLUniformLocation
* location
,
697 WebGLboolean transpose
,
698 const dom::Float32Array
&value
) {
699 value
.ComputeLengthAndData();
700 UniformMatrix4fv_base(location
, transpose
, value
.Length(), value
.Data());
702 void UniformMatrix4fv(WebGLUniformLocation
* location
,
703 WebGLboolean transpose
,
704 const dom::Sequence
<float> &value
) {
705 UniformMatrix4fv_base(location
, transpose
, value
.Length(),
708 void UniformMatrix4fv_base(WebGLUniformLocation
* location
,
709 WebGLboolean transpose
, uint32_t arrayLength
,
712 void UseProgram(WebGLProgram
*prog
);
713 bool ValidateAttribArraySetter(const char* name
, uint32_t cnt
, uint32_t arrayLength
);
714 bool ValidateUniformArraySetter(const char* name
, uint32_t expectedElemSize
, WebGLUniformLocation
*location_object
,
715 GLint
& location
, uint32_t& numElementsToUpload
, uint32_t arrayLength
);
716 bool ValidateUniformMatrixArraySetter(const char* name
, int dim
, WebGLUniformLocation
*location_object
,
717 GLint
& location
, uint32_t& numElementsToUpload
, uint32_t arrayLength
,
718 WebGLboolean aTranspose
);
719 bool ValidateUniformSetter(const char* name
, WebGLUniformLocation
*location_object
, GLint
& location
);
720 void ValidateProgram(WebGLProgram
*prog
);
721 bool ValidateUniformLocation(const char* info
, WebGLUniformLocation
*location_object
);
722 bool ValidateSamplerUniformSetter(const char* info
,
723 WebGLUniformLocation
*location
,
725 void Viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
);
726 // -----------------------------------------------------------------------------
727 // WEBGL_lose_context
730 void RestoreContext();
732 // -----------------------------------------------------------------------------
733 // Asynchronous Queries (WebGLContextAsyncQueries.cpp)
735 already_AddRefed
<WebGLQuery
> CreateQuery();
736 void DeleteQuery(WebGLQuery
*query
);
737 void BeginQuery(GLenum target
, WebGLQuery
*query
);
738 void EndQuery(GLenum target
);
739 bool IsQuery(WebGLQuery
*query
);
740 already_AddRefed
<WebGLQuery
> GetQuery(GLenum target
, GLenum pname
);
741 JS::Value
GetQueryObject(JSContext
* cx
, WebGLQuery
*query
, GLenum pname
);
742 void GetQueryObject(JSContext
* cx
, WebGLQuery
*query
, GLenum pname
,
743 JS::MutableHandle
<JS::Value
> retval
) {
744 retval
.set(GetQueryObject(cx
, query
, pname
));
748 // ANY_SAMPLES_PASSED(_CONSERVATIVE) slot
749 WebGLRefPtr
<WebGLQuery
> mActiveOcclusionQuery
;
751 // LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN slot
752 WebGLRefPtr
<WebGLQuery
> mActiveTransformFeedbackQuery
;
754 WebGLRefPtr
<WebGLQuery
>* GetQueryTargetSlot(GLenum target
, const char* infos
);
756 // -----------------------------------------------------------------------------
757 // Buffer Objects (WebGLContextBuffers.cpp)
759 void BindBuffer(GLenum target
, WebGLBuffer
* buf
);
760 void BindBufferBase(GLenum target
, GLuint index
, WebGLBuffer
* buffer
);
761 void BindBufferRange(GLenum target
, GLuint index
, WebGLBuffer
* buffer
,
762 WebGLintptr offset
, WebGLsizeiptr size
);
763 void BufferData(GLenum target
, WebGLsizeiptr size
, GLenum usage
);
764 void BufferData(GLenum target
, const dom::ArrayBufferView
&data
,
766 void BufferData(GLenum target
,
767 const Nullable
<dom::ArrayBuffer
> &maybeData
,
769 void BufferSubData(GLenum target
, WebGLsizeiptr byteOffset
,
770 const dom::ArrayBufferView
&data
);
771 void BufferSubData(GLenum target
, WebGLsizeiptr byteOffset
,
772 const Nullable
<dom::ArrayBuffer
> &maybeData
);
773 already_AddRefed
<WebGLBuffer
> CreateBuffer();
774 void DeleteBuffer(WebGLBuffer
*buf
);
775 bool IsBuffer(WebGLBuffer
*buffer
);
779 WebGLRefPtr
<WebGLBuffer
> mBoundArrayBuffer
;
781 // TRANSFORM_FEEDBACK_BUFFER slot
782 WebGLRefPtr
<WebGLBuffer
> mBoundTransformFeedbackBuffer
;
784 // these two functions emit INVALID_ENUM for invalid `target`.
785 WebGLRefPtr
<WebGLBuffer
>* GetBufferSlotByTarget(GLenum target
, const char* infos
);
786 WebGLRefPtr
<WebGLBuffer
>* GetBufferSlotByTargetIndexed(GLenum target
, GLuint index
, const char* infos
);
787 bool ValidateBufferUsageEnum(GLenum target
, const char* infos
);
789 // -----------------------------------------------------------------------------
790 // State and State Requests (WebGLContextState.cpp)
792 void Disable(GLenum cap
);
793 void Enable(GLenum cap
);
794 JS::Value
GetParameter(JSContext
* cx
, GLenum pname
, ErrorResult
& rv
);
795 void GetParameter(JSContext
* cx
, GLenum pname
,
796 JS::MutableHandle
<JS::Value
> retval
, ErrorResult
& rv
) {
797 retval
.set(GetParameter(cx
, pname
, rv
));
799 void GetParameterIndexed(JSContext
* cx
, GLenum pname
, GLuint index
,
800 JS::MutableHandle
<JS::Value
> retval
);
801 bool IsEnabled(GLenum cap
);
804 // State tracking slots
805 realGLboolean mDitherEnabled
;
806 realGLboolean mRasterizerDiscardEnabled
;
807 realGLboolean mScissorTestEnabled
;
809 bool ValidateCapabilityEnum(GLenum cap
, const char* info
);
810 realGLboolean
* GetStateTrackingSlot(GLenum cap
);
812 // -----------------------------------------------------------------------------
813 // Vertices Feature (WebGLContextVertices.cpp)
815 void DrawArrays(GLenum mode
, GLint first
, GLsizei count
);
816 void DrawArraysInstanced(GLenum mode
, GLint first
, GLsizei count
, GLsizei primcount
);
817 void DrawElements(GLenum mode
, GLsizei count
, GLenum type
, WebGLintptr byteOffset
);
818 void DrawElementsInstanced(GLenum mode
, GLsizei count
, GLenum type
,
819 WebGLintptr byteOffset
, GLsizei primcount
);
821 void EnableVertexAttribArray(GLuint index
);
822 void DisableVertexAttribArray(GLuint index
);
824 JS::Value
GetVertexAttrib(JSContext
* cx
, GLuint index
, GLenum pname
,
826 void GetVertexAttrib(JSContext
* cx
, GLuint index
, GLenum pname
,
827 JS::MutableHandle
<JS::Value
> retval
,
829 retval
.set(GetVertexAttrib(cx
, index
, pname
, rv
));
831 WebGLsizeiptr
GetVertexAttribOffset(GLuint index
, GLenum pname
);
833 void VertexAttrib1f(GLuint index
, GLfloat x0
);
834 void VertexAttrib2f(GLuint index
, GLfloat x0
, GLfloat x1
);
835 void VertexAttrib3f(GLuint index
, GLfloat x0
, GLfloat x1
,
837 void VertexAttrib4f(GLuint index
, GLfloat x0
, GLfloat x1
,
838 GLfloat x2
, GLfloat x3
);
840 void VertexAttrib1fv(GLuint idx
, const dom::Float32Array
&arr
) {
841 arr
.ComputeLengthAndData();
842 VertexAttrib1fv_base(idx
, arr
.Length(), arr
.Data());
844 void VertexAttrib1fv(GLuint idx
, const dom::Sequence
<GLfloat
>& arr
) {
845 VertexAttrib1fv_base(idx
, arr
.Length(), arr
.Elements());
848 void VertexAttrib2fv(GLuint idx
, const dom::Float32Array
&arr
) {
849 arr
.ComputeLengthAndData();
850 VertexAttrib2fv_base(idx
, arr
.Length(), arr
.Data());
852 void VertexAttrib2fv(GLuint idx
, const dom::Sequence
<GLfloat
>& arr
) {
853 VertexAttrib2fv_base(idx
, arr
.Length(), arr
.Elements());
856 void VertexAttrib3fv(GLuint idx
, const dom::Float32Array
&arr
) {
857 arr
.ComputeLengthAndData();
858 VertexAttrib3fv_base(idx
, arr
.Length(), arr
.Data());
860 void VertexAttrib3fv(GLuint idx
, const dom::Sequence
<GLfloat
>& arr
) {
861 VertexAttrib3fv_base(idx
, arr
.Length(), arr
.Elements());
864 void VertexAttrib4fv(GLuint idx
, const dom::Float32Array
&arr
) {
865 arr
.ComputeLengthAndData();
866 VertexAttrib4fv_base(idx
, arr
.Length(), arr
.Data());
868 void VertexAttrib4fv(GLuint idx
, const dom::Sequence
<GLfloat
>& arr
) {
869 VertexAttrib4fv_base(idx
, arr
.Length(), arr
.Elements());
872 void VertexAttribPointer(GLuint index
, GLint size
, GLenum type
,
873 WebGLboolean normalized
, GLsizei stride
,
874 WebGLintptr byteOffset
);
875 void VertexAttribDivisor(GLuint index
, GLuint divisor
);
878 // Cache the max number of vertices and instances that can be read from
879 // bound VBOs (result of ValidateBuffers).
880 bool mBufferFetchingIsVerified
;
881 bool mBufferFetchingHasPerVertex
;
882 uint32_t mMaxFetchedVertices
;
883 uint32_t mMaxFetchedInstances
;
885 inline void InvalidateBufferFetching()
887 mBufferFetchingIsVerified
= false;
888 mBufferFetchingHasPerVertex
= false;
889 mMaxFetchedVertices
= 0;
890 mMaxFetchedInstances
= 0;
893 bool DrawArrays_check(GLint first
, GLsizei count
, GLsizei primcount
, const char* info
);
894 bool DrawElements_check(GLsizei count
, GLenum type
, WebGLintptr byteOffset
,
895 GLsizei primcount
, const char* info
,
896 GLuint
* out_upperBound
);
897 bool DrawInstanced_check(const char* info
);
900 void VertexAttrib1fv_base(GLuint idx
, uint32_t arrayLength
, const GLfloat
* ptr
);
901 void VertexAttrib2fv_base(GLuint idx
, uint32_t arrayLength
, const GLfloat
* ptr
);
902 void VertexAttrib3fv_base(GLuint idx
, uint32_t arrayLength
, const GLfloat
* ptr
);
903 void VertexAttrib4fv_base(GLuint idx
, uint32_t arrayLength
, const GLfloat
* ptr
);
905 bool ValidateBufferFetching(const char *info
);
906 bool BindArrayAttribToLocation0(WebGLProgram
*program
);
908 // -----------------------------------------------------------------------------
911 virtual ~WebGLContext();
913 void SetFakeBlackStatus(WebGLContextFakeBlackStatus x
) {
914 mFakeBlackStatus
= x
;
916 // Returns the current fake-black-status, except if it was Unknown,
917 // in which case this function resolves it first, so it never returns Unknown.
918 WebGLContextFakeBlackStatus
ResolvedFakeBlackStatus();
920 void BindFakeBlackTextures();
921 void UnbindFakeBlackTextures();
923 WebGLVertexAttrib0Status
WhatDoesVertexAttrib0Need();
924 bool DoFakeVertexAttrib0(GLuint vertexCount
);
925 void UndoFakeVertexAttrib0();
927 static CheckedUint32
GetImageSize(GLsizei height
,
932 // Returns x rounded to the next highest multiple of y.
933 static CheckedUint32
RoundedToNextMultipleOf(CheckedUint32 x
, CheckedUint32 y
) {
934 return ((x
+ y
- 1) / y
) * y
;
937 nsRefPtr
<gl::GLContext
> gl
;
939 CheckedUint32 mGeneration
;
941 WebGLContextOptions mOptions
;
947 bool mDisableExtensions
;
949 bool mLoseContextOnMemoryPressure
;
950 bool mCanLoseContextInForeground
;
951 bool mRestoreWhenVisible
;
953 bool mBackbufferNeedsClear
;
954 bool mDisableFragHighP
;
956 template<typename WebGLObjectType
>
957 void DeleteWebGLObjectsArray(nsTArray
<WebGLObjectType
>& array
);
959 GLuint mActiveTexture
;
961 // glGetError sources:
962 bool mEmitContextLostErrorOnce
;
964 GLenum mUnderlyingGLError
;
965 GLenum
GetAndFlushUnderlyingGLErrors();
967 // whether shader validation is supported
968 bool mShaderValidation
;
971 int32_t mGLMaxVertexAttribs
;
972 int32_t mGLMaxTextureUnits
;
973 int32_t mGLMaxTextureSize
;
974 int32_t mGLMaxCubeMapTextureSize
;
975 int32_t mGLMaxRenderbufferSize
;
976 int32_t mGLMaxTextureImageUnits
;
977 int32_t mGLMaxVertexTextureImageUnits
;
978 int32_t mGLMaxVaryingVectors
;
979 int32_t mGLMaxFragmentUniformVectors
;
980 int32_t mGLMaxVertexUniformVectors
;
981 int32_t mGLMaxColorAttachments
;
982 int32_t mGLMaxDrawBuffers
;
983 uint32_t mGLMaxTransformFeedbackSeparateAttribs
;
985 // Represents current status of the context with respect to context loss.
986 // That is, whether the context is lost, and what part of the context loss
987 // process we currently are at.
988 // This is used to support the WebGL spec's asyncronous nature in handling
991 // The context is stable; there either are none or we don't know of any.
993 // The context has been lost, but we have not yet sent an event to the
994 // script informing it of this.
995 ContextLostAwaitingEvent
,
996 // The context has been lost, and we have sent the script an event
997 // informing it of this.
999 // The context is lost, an event has been sent to the script, and the
1000 // script correctly handled the event. We are waiting for the context to
1002 ContextLostAwaitingRestore
1005 // -------------------------------------------------------------------------
1006 // WebGL extensions (implemented in WebGLContextExtensions.cpp)
1007 typedef EnumeratedArray
<WebGLExtensionID
,
1008 WebGLExtensionID::Max
,
1009 nsRefPtr
<WebGLExtensionBase
>> ExtensionsArrayType
;
1011 ExtensionsArrayType mExtensions
;
1013 // enable an extension. the extension should not be enabled before.
1014 void EnableExtension(WebGLExtensionID ext
);
1016 // returns true if the extension has been enabled by calling getExtension.
1017 bool IsExtensionEnabled(WebGLExtensionID ext
) const;
1019 // returns true if the extension is supported for this JSContext (this decides what getSupportedExtensions exposes)
1020 bool IsExtensionSupported(JSContext
*cx
, WebGLExtensionID ext
) const;
1021 bool IsExtensionSupported(WebGLExtensionID ext
) const;
1023 static const char* GetExtensionString(WebGLExtensionID ext
);
1025 nsTArray
<GLenum
> mCompressedTextureFormats
;
1027 // -------------------------------------------------------------------------
1028 // WebGL 2 specifics (implemented in WebGL2Context.cpp)
1030 virtual bool IsWebGL2() const = 0;
1035 // -------------------------------------------------------------------------
1036 // Validation functions (implemented in WebGLContextValidate.cpp)
1037 GLenum
BaseTexFormat(GLenum internalFormat
) const;
1039 bool CreateOffscreenGL(bool forceEnabled
);
1040 bool InitAndValidateGL();
1041 bool ResizeBackbuffer(uint32_t width
, uint32_t height
);
1042 bool ValidateBlendEquationEnum(GLenum cap
, const char *info
);
1043 bool ValidateBlendFuncDstEnum(GLenum mode
, const char *info
);
1044 bool ValidateBlendFuncSrcEnum(GLenum mode
, const char *info
);
1045 bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor
, GLenum dfactor
, const char *info
);
1046 bool ValidateTextureTargetEnum(GLenum target
, const char *info
);
1047 bool ValidateComparisonEnum(GLenum target
, const char *info
);
1048 bool ValidateStencilOpEnum(GLenum action
, const char *info
);
1049 bool ValidateFaceEnum(GLenum face
, const char *info
);
1050 bool ValidateTexInputData(GLenum type
, int jsArrayType
, WebGLTexImageFunc func
);
1051 bool ValidateDrawModeEnum(GLenum mode
, const char *info
);
1052 bool ValidateAttribIndex(GLuint index
, const char *info
);
1053 bool ValidateStencilParamsForDrawCall();
1055 bool ValidateGLSLVariableName(const nsAString
& name
, const char *info
);
1056 bool ValidateGLSLCharacter(char16_t c
);
1057 bool ValidateGLSLString(const nsAString
& string
, const char *info
);
1059 bool ValidateCopyTexImage(GLenum format
, WebGLTexImageFunc func
);
1060 bool ValidateTexImage(GLuint dims
, GLenum target
,
1061 GLint level
, GLint internalFormat
,
1062 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1063 GLint width
, GLint height
, GLint depth
,
1064 GLint border
, GLenum format
, GLenum type
,
1065 WebGLTexImageFunc func
);
1066 bool ValidateTexImageTarget(GLuint dims
, GLenum target
, WebGLTexImageFunc func
);
1067 bool ValidateTexImageFormat(GLenum format
, WebGLTexImageFunc func
);
1068 bool ValidateTexImageType(GLenum type
, WebGLTexImageFunc func
);
1069 bool ValidateTexImageFormatAndType(GLenum format
, GLenum type
, WebGLTexImageFunc func
);
1070 bool ValidateTexImageSize(GLenum target
, GLint level
,
1071 GLint width
, GLint height
, GLint depth
,
1072 WebGLTexImageFunc func
);
1073 bool ValidateTexSubImageSize(GLint x
, GLint y
, GLint z
,
1074 GLsizei width
, GLsizei height
, GLsizei depth
,
1075 GLsizei baseWidth
, GLsizei baseHeight
, GLsizei baseDepth
,
1076 WebGLTexImageFunc func
);
1078 bool ValidateCompTexImageSize(GLenum target
, GLint level
, GLenum format
,
1079 GLint xoffset
, GLint yoffset
,
1080 GLsizei width
, GLsizei height
,
1081 GLsizei levelWidth
, GLsizei levelHeight
,
1082 WebGLTexImageFunc func
);
1083 bool ValidateCompTexImageDataSize(GLint level
, GLenum format
,
1084 GLsizei width
, GLsizei height
,
1085 uint32_t byteLength
, WebGLTexImageFunc func
);
1088 static uint32_t GetBitsPerTexel(GLenum format
, GLenum type
);
1091 void DestroyResourcesAndContext();
1093 void MakeContextCurrent() const;
1096 void TexImage2D_base(GLenum target
, GLint level
, GLenum internalformat
,
1097 GLsizei width
, GLsizei height
, GLsizei srcStrideOrZero
, GLint border
,
1098 GLenum format
, GLenum type
,
1099 void *data
, uint32_t byteLength
,
1101 WebGLTexelFormat srcFormat
, bool srcPremultiplied
);
1102 void TexSubImage2D_base(GLenum target
, GLint level
,
1103 GLint xoffset
, GLint yoffset
,
1104 GLsizei width
, GLsizei height
, GLsizei srcStrideOrZero
,
1105 GLenum format
, GLenum type
,
1106 void *pixels
, uint32_t byteLength
,
1108 WebGLTexelFormat srcFormat
, bool srcPremultiplied
);
1109 void TexParameter_base(GLenum target
, GLenum pname
,
1110 GLint
*intParamPtr
, GLfloat
*floatParamPtr
);
1112 void ConvertImage(size_t width
, size_t height
, size_t srcStride
, size_t dstStride
,
1113 const uint8_t* src
, uint8_t *dst
,
1114 WebGLTexelFormat srcFormat
, bool srcPremultiplied
,
1115 WebGLTexelFormat dstFormat
, bool dstPremultiplied
,
1116 size_t dstTexelSize
);
1118 template<class ElementType
>
1119 nsLayoutUtils::SurfaceFromElementResult
SurfaceFromElement(ElementType
* aElement
) {
1120 MOZ_ASSERT(aElement
);
1122 nsLayoutUtils::SFE_WANT_IMAGE_SURFACE
;
1124 if (mPixelStoreColorspaceConversion
== LOCAL_GL_NONE
)
1125 flags
|= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION
;
1126 if (!mPixelStorePremultiplyAlpha
)
1127 flags
|= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA
;
1128 return nsLayoutUtils::SurfaceFromElement(aElement
, flags
);
1130 template<class ElementType
>
1131 nsLayoutUtils::SurfaceFromElementResult
SurfaceFromElement(ElementType
& aElement
)
1133 return SurfaceFromElement(&aElement
);
1136 nsresult
SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult
& res
,
1137 RefPtr
<gfx::DataSourceSurface
>& imageOut
,
1138 WebGLTexelFormat
*format
);
1140 void CopyTexSubImage2D_base(GLenum target
,
1142 GLenum internalformat
,
1151 // Returns false if aObject is null or not valid
1152 template<class ObjectType
>
1153 bool ValidateObject(const char* info
, ObjectType
*aObject
);
1154 // Returns false if aObject is not valid. Considers null to be valid.
1155 template<class ObjectType
>
1156 bool ValidateObjectAllowNull(const char* info
, ObjectType
*aObject
);
1157 // Returns false if aObject is not valid, but considers deleted
1158 // objects and null objects valid.
1159 template<class ObjectType
>
1160 bool ValidateObjectAllowDeletedOrNull(const char* info
, ObjectType
*aObject
);
1161 // Returns false if aObject is null or not valid, but considers deleted
1163 template<class ObjectType
>
1164 bool ValidateObjectAllowDeleted(const char* info
, ObjectType
*aObject
);
1166 // Like ValidateObject, but only for cases when aObject is known
1167 // to not be null already.
1168 template<class ObjectType
>
1169 bool ValidateObjectAssumeNonNull(const char* info
, ObjectType
*aObject
);
1172 int32_t MaxTextureSizeForTarget(GLenum target
) const {
1173 MOZ_ASSERT(target
== LOCAL_GL_TEXTURE_2D
||
1174 (target
>= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
1175 target
<= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
),
1176 "Invalid target enum");
1177 return (target
== LOCAL_GL_TEXTURE_2D
) ? mGLMaxTextureSize
: mGLMaxCubeMapTextureSize
;
1180 /** like glBufferData but if the call may change the buffer size, checks any GL error generated
1181 * by this glBufferData call and returns it */
1182 GLenum
CheckedBufferData(GLenum target
,
1186 /** like glTexImage2D but if the call may change the texture size, checks any GL error generated
1187 * by this glTexImage2D call and returns it */
1188 GLenum
CheckedTexImage2D(GLenum target
,
1190 GLenum internalFormat
,
1196 const GLvoid
*data
);
1198 void ForceLoseContext(bool simulateLosing
= false);
1199 void ForceRestoreContext();
1201 nsTArray
<WebGLRefPtr
<WebGLTexture
> > mBound2DTextures
;
1202 nsTArray
<WebGLRefPtr
<WebGLTexture
> > mBoundCubeMapTextures
;
1204 WebGLRefPtr
<WebGLProgram
> mCurrentProgram
;
1206 uint32_t mMaxFramebufferColorAttachments
;
1208 WebGLRefPtr
<WebGLFramebuffer
> mBoundFramebuffer
;
1209 WebGLRefPtr
<WebGLRenderbuffer
> mBoundRenderbuffer
;
1210 WebGLRefPtr
<WebGLVertexArray
> mBoundVertexArray
;
1212 LinkedList
<WebGLTexture
> mTextures
;
1213 LinkedList
<WebGLBuffer
> mBuffers
;
1214 LinkedList
<WebGLProgram
> mPrograms
;
1215 LinkedList
<WebGLQuery
> mQueries
;
1216 LinkedList
<WebGLShader
> mShaders
;
1217 LinkedList
<WebGLRenderbuffer
> mRenderbuffers
;
1218 LinkedList
<WebGLFramebuffer
> mFramebuffers
;
1219 LinkedList
<WebGLVertexArray
> mVertexArrays
;
1221 WebGLRefPtr
<WebGLVertexArray
> mDefaultVertexArray
;
1223 // PixelStore parameters
1224 uint32_t mPixelStorePackAlignment
, mPixelStoreUnpackAlignment
, mPixelStoreColorspaceConversion
;
1225 bool mPixelStoreFlipY
, mPixelStorePremultiplyAlpha
;
1227 WebGLContextFakeBlackStatus mFakeBlackStatus
;
1229 class FakeBlackTexture
1235 FakeBlackTexture(gl::GLContext
* gl
, GLenum target
, GLenum format
);
1236 ~FakeBlackTexture();
1237 GLuint
GLName() const { return mGLName
; }
1240 UniquePtr
<FakeBlackTexture
> mBlackOpaqueTexture2D
,
1241 mBlackOpaqueTextureCubeMap
,
1242 mBlackTransparentTexture2D
,
1243 mBlackTransparentTextureCubeMap
;
1245 void BindFakeBlackTexturesHelper(
1247 const nsTArray
<WebGLRefPtr
<WebGLTexture
> >& boundTexturesArray
,
1248 UniquePtr
<FakeBlackTexture
> & opaqueTextureScopedPtr
,
1249 UniquePtr
<FakeBlackTexture
> & transparentTextureScopedPtr
);
1251 GLfloat mVertexAttrib0Vector
[4];
1252 GLfloat mFakeVertexAttrib0BufferObjectVector
[4];
1253 size_t mFakeVertexAttrib0BufferObjectSize
;
1254 GLuint mFakeVertexAttrib0BufferObject
;
1255 WebGLVertexAttrib0Status mFakeVertexAttrib0BufferStatus
;
1257 GLint mStencilRefFront
, mStencilRefBack
;
1258 GLuint mStencilValueMaskFront
, mStencilValueMaskBack
,
1259 mStencilWriteMaskFront
, mStencilWriteMaskBack
;
1260 realGLboolean mColorWriteMask
[4];
1261 realGLboolean mDepthWriteMask
;
1262 GLfloat mColorClearValue
[4];
1263 GLint mStencilClearValue
;
1264 GLfloat mDepthClearValue
;
1268 GLsizei mViewportWidth
;
1269 GLsizei mViewportHeight
;
1270 bool mAlreadyWarnedAboutViewportLargerThanDest
;
1272 RefPtr
<WebGLContextLossHandler
> mContextLossHandler
;
1273 bool mAllowContextRestore
;
1274 bool mLastLossWasSimulated
;
1275 ContextStatus mContextStatus
;
1276 bool mContextLostErrorSet
;
1278 // Used for some hardware (particularly Tegra 2 and 4) that likes to
1279 // be Flushed while doing hundreds of draw calls.
1280 int mDrawCallsSinceLastFlush
;
1282 int mAlreadyGeneratedWarnings
;
1284 bool mAlreadyWarnedAboutFakeVertexAttrib0
;
1286 bool ShouldGenerateWarnings() const;
1288 uint64_t mLastUseIndex
;
1290 void LoseOldestWebGLContextIfLimitExceeded();
1291 void UpdateLastUseIndex();
1293 template <typename WebGLObjectType
>
1294 JS::Value
WebGLObjectAsJSValue(JSContext
*cx
, const WebGLObjectType
*, ErrorResult
& rv
) const;
1295 template <typename WebGLObjectType
>
1296 JSObject
* WebGLObjectAsJSObject(JSContext
*cx
, const WebGLObjectType
*, ErrorResult
& rv
) const;
1299 // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
1300 // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
1301 // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
1302 // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
1303 // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
1304 ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper
;
1307 nsRefPtr
<WebGLObserver
> mContextObserver
;
1310 // console logging helpers
1311 void GenerateWarning(const char *fmt
, ...);
1312 void GenerateWarning(const char *fmt
, va_list ap
);
1314 friend class WebGLTexture
;
1315 friend class WebGLFramebuffer
;
1316 friend class WebGLRenderbuffer
;
1317 friend class WebGLProgram
;
1318 friend class WebGLQuery
;
1319 friend class WebGLBuffer
;
1320 friend class WebGLShader
;
1321 friend class WebGLUniformLocation
;
1322 friend class WebGLVertexArray
;
1323 friend class WebGLVertexArrayFake
;
1324 friend class WebGLVertexArrayGL
;
1327 // used by DOM bindings in conjunction with GetParentObject
1329 ToSupports(WebGLContext
* context
)
1331 return static_cast<nsIDOMWebGLRenderingContext
*>(context
);
1335 ** Template implementations
1338 template<class ObjectType
>
1340 WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info
,
1341 ObjectType
*aObject
)
1343 if (aObject
&& !aObject
->IsCompatibleWithContext(this)) {
1344 ErrorInvalidOperation("%s: object from different WebGL context "
1345 "(or older generation of this one) "
1346 "passed as argument", info
);
1353 template<class ObjectType
>
1355 WebGLContext::ValidateObjectAssumeNonNull(const char* info
, ObjectType
*aObject
)
1357 MOZ_ASSERT(aObject
);
1359 if (!ValidateObjectAllowDeletedOrNull(info
, aObject
))
1362 if (aObject
->IsDeleted()) {
1363 ErrorInvalidValue("%s: deleted object passed as argument", info
);
1370 template<class ObjectType
>
1372 WebGLContext::ValidateObjectAllowNull(const char* info
, ObjectType
*aObject
)
1378 return ValidateObjectAssumeNonNull(info
, aObject
);
1381 template<class ObjectType
>
1383 WebGLContext::ValidateObjectAllowDeleted(const char* info
, ObjectType
*aObject
)
1386 ErrorInvalidValue("%s: null object passed as argument", info
);
1390 return ValidateObjectAllowDeletedOrNull(info
, aObject
);
1393 template<class ObjectType
>
1395 WebGLContext::ValidateObject(const char* info
, ObjectType
*aObject
)
1398 ErrorInvalidValue("%s: null object passed as argument", info
);
1402 return ValidateObjectAssumeNonNull(info
, aObject
);
1405 // Listen visibilitychange and memory-pressure event for context lose/restore
1406 class WebGLObserver MOZ_FINAL
1407 : public nsIObserver
1408 , public nsIDOMEventListener
1413 NS_DECL_NSIDOMEVENTLISTENER
1415 explicit WebGLObserver(WebGLContext
* aContext
);
1419 void RegisterVisibilityChangeEvent();
1420 void UnregisterVisibilityChangeEvent();
1422 void RegisterMemoryPressureEvent();
1423 void UnregisterMemoryPressureEvent();
1428 WebGLContext
* mContext
;
1431 } // namespace mozilla