Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / dom / canvas / WebGLContext.h
bloba7825746e8c2047885bea1af8e32cb365a1210f7
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"
16 #include "GLDefs.h"
17 #include "WebGLActiveInfo.h"
18 #include "WebGLObjectModel.h"
19 #include "WebGLRenderbuffer.h"
20 #include <stdarg.h>
22 #include "nsTArray.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"
37 #ifdef XP_MACOSX
38 #include "ForceDiscreteGPUHelperCGL.h"
39 #endif
41 #include "mozilla/dom/TypedArray.h"
42 #include "mozilla/ErrorResult.h"
44 class nsIDocShell;
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
64 namespace mozilla {
66 class WebGLContextLossHandler;
67 class WebGLObserver;
68 class WebGLContextBoundObject;
69 class WebGLActiveInfo;
70 class WebGLExtensionBase;
71 class WebGLBuffer;
72 struct WebGLVertexAttribData;
73 class WebGLShader;
74 class WebGLProgram;
75 class WebGLQuery;
76 class WebGLUniformLocation;
77 class WebGLFramebuffer;
78 class WebGLRenderbuffer;
79 class WebGLShaderPrecisionFormat;
80 class WebGLTexture;
81 class WebGLVertexArray;
83 namespace dom {
84 class ImageData;
85 class Element;
87 struct WebGLContextAttributes;
88 template<typename> struct Nullable;
91 namespace gfx {
92 class SourceSurface;
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 {
104 return
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);
117 bool alpha;
118 bool depth;
119 bool stencil;
120 bool premultipliedAlpha;
121 bool antialias;
122 bool preserveDrawingBuffer;
125 #ifdef DEBUG
126 static bool
127 IsTextureBinding(GLenum binding)
129 switch (binding) {
130 case LOCAL_GL_TEXTURE_BINDING_2D:
131 case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP:
132 return true;
134 return false;
136 #endif
138 class WebGLContext :
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;
158 enum {
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
168 public:
169 WebGLContext();
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
183 #ifdef DEBUG
184 virtual int32_t GetWidth() const MOZ_OVERRIDE;
185 virtual int32_t GetHeight() const MOZ_OVERRIDE;
186 #endif
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'.
271 void ClearScreen();
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,
295 ErrorResult& rv);
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,
324 GLenum format,
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);
350 void Flush();
351 void Finish();
352 void FramebufferRenderbuffer(GLenum target, GLenum attachment,
353 GLenum rbtarget, WebGLRenderbuffer *wrb);
354 void FramebufferTexture2D(GLenum target, GLenum attachment,
355 GLenum textarget, WebGLTexture *tobj,
356 GLint level);
357 void FrontFace(GLenum mode);
358 void GenerateMipmap(GLenum target);
359 already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,
360 GLuint index);
361 already_AddRefed<WebGLActiveInfo> GetActiveUniform(WebGLProgram *prog,
362 GLuint index);
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,
368 GLenum pname,
369 JS::MutableHandle<JS::Value> retval) {
370 retval.set(GetBufferParameter(target, pname));
372 GLenum GetError();
373 JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
374 GLenum target,
375 GLenum attachment,
376 GLenum pname,
377 ErrorResult& rv);
378 void GetFramebufferAttachmentParameter(JSContext* cx,
379 GLenum target,
380 GLenum attachment,
381 GLenum pname,
382 JS::MutableHandle<JS::Value> retval,
383 ErrorResult& rv) {
384 retval.set(GetFramebufferAttachmentParameter(cx, target, attachment,
385 pname, rv));
387 JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname);
388 void GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
389 GLenum pname,
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,
403 GLenum pname,
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,
415 GLenum pname,
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,
442 ErrorResult& rv);
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,
450 GLuint mask);
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,
455 GLenum dppass);
456 void TexImage2D(GLenum target, GLint level,
457 GLenum internalformat, GLsizei width,
458 GLsizei height, GLint border, GLenum format,
459 GLenum type,
460 const Nullable<dom::ArrayBufferView> &pixels,
461 ErrorResult& rv);
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
466 // us in TexImage2D
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)
476 if (IsContextLost())
477 return;
479 WebGLTexture* tex = activeBoundTextureForTarget(target);
481 if (!tex)
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)) {
486 return;
489 RefPtr<gfx::DataSourceSurface> data;
490 WebGLTexelFormat srcFormat;
491 nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
492 rv = SurfaceFromElementResultToImageSurface(res, data,
493 &srcFormat);
494 if (rv.Failed() || !data)
495 return;
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, &param);
508 void TexParameteri(GLenum target, GLenum pname, GLint param) {
509 TexParameter_base(target, pname, &param, nullptr);
512 void TexSubImage2D(GLenum target, GLint level,
513 GLint xoffset, GLint yoffset,
514 GLsizei width, GLsizei height, GLenum format,
515 GLenum type,
516 const Nullable<dom::ArrayBufferView> &pixels,
517 ErrorResult& rv);
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)
528 if (IsContextLost())
529 return;
531 // Trying to handle the video by GPU directly first
532 if (TexImageFromVideoElement(target, level, format, format, type, elt)) {
533 return;
536 RefPtr<gfx::DataSourceSurface> data;
537 WebGLTexelFormat srcFormat;
538 nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
539 rv = SurfaceFromElementResultToImageSurface(res, data,
540 &srcFormat);
541 if (rv.Failed() || !data)
542 return;
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,
557 GLint z);
558 void Uniform4i(WebGLUniformLocation* location, GLint x, GLint y,
559 GLint z, GLint w);
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,
564 GLfloat z);
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,
578 const GLint* data);
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,
590 const GLint* data);
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,
602 const GLint* data);
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,
614 const GLint* data);
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(),
674 value.Elements());
676 void UniformMatrix2fv_base(WebGLUniformLocation* location,
677 WebGLboolean transpose, uint32_t arrayLength,
678 const float* data);
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(),
690 value.Elements());
692 void UniformMatrix3fv_base(WebGLUniformLocation* location,
693 WebGLboolean transpose, uint32_t arrayLength,
694 const float* data);
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(),
706 value.Elements());
708 void UniformMatrix4fv_base(WebGLUniformLocation* location,
709 WebGLboolean transpose, uint32_t arrayLength,
710 const float* data);
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,
724 GLint value);
725 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
726 // -----------------------------------------------------------------------------
727 // WEBGL_lose_context
728 public:
729 void LoseContext();
730 void RestoreContext();
732 // -----------------------------------------------------------------------------
733 // Asynchronous Queries (WebGLContextAsyncQueries.cpp)
734 public:
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));
747 private:
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)
758 public:
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,
765 GLenum usage);
766 void BufferData(GLenum target,
767 const Nullable<dom::ArrayBuffer> &maybeData,
768 GLenum usage);
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);
777 private:
778 // ARRAY_BUFFER slot
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)
791 public:
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);
803 private:
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)
814 public:
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,
825 ErrorResult& rv);
826 void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
827 JS::MutableHandle<JS::Value> retval,
828 ErrorResult& rv) {
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,
836 GLfloat x2);
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);
877 private:
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);
898 void Draw_cleanup();
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 // -----------------------------------------------------------------------------
909 // PROTECTED
910 protected:
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,
928 GLsizei width,
929 uint32_t pixelSize,
930 uint32_t alignment);
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;
943 bool mInvalidated;
944 bool mResetLayer;
945 bool mOptionsFrozen;
946 bool mMinCapability;
947 bool mDisableExtensions;
948 bool mIsMesa;
949 bool mLoseContextOnMemoryPressure;
950 bool mCanLoseContextInForeground;
951 bool mRestoreWhenVisible;
952 bool mShouldPresent;
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;
963 GLenum mWebGLError;
964 GLenum mUnderlyingGLError;
965 GLenum GetAndFlushUnderlyingGLErrors();
967 // whether shader validation is supported
968 bool mShaderValidation;
970 // some GL constants
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
989 // context loss.
990 enum ContextStatus {
991 // The context is stable; there either are none or we don't know of any.
992 ContextNotLost,
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.
998 ContextLost,
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
1001 // be restored.
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;
1032 bool InitWebGL2();
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);
1090 void Invalidate();
1091 void DestroyResourcesAndContext();
1093 void MakeContextCurrent() const;
1095 // helpers
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,
1100 int jsArrayType,
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,
1107 int jsArrayType,
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);
1121 uint32_t flags =
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,
1141 GLint level,
1142 GLenum internalformat,
1143 GLint xoffset,
1144 GLint yoffset,
1145 GLint x,
1146 GLint y,
1147 GLsizei width,
1148 GLsizei height,
1149 bool sub);
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
1162 // objects valid.
1163 template<class ObjectType>
1164 bool ValidateObjectAllowDeleted(const char* info, ObjectType *aObject);
1165 private:
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);
1171 protected:
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,
1183 GLsizeiptr size,
1184 const GLvoid *data,
1185 GLenum usage);
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,
1189 GLint level,
1190 GLenum internalFormat,
1191 GLsizei width,
1192 GLsizei height,
1193 GLint border,
1194 GLenum format,
1195 GLenum type,
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
1231 gl::GLContext* mGL;
1232 GLuint mGLName;
1234 public:
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(
1246 GLenum target,
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;
1266 GLint mViewportX;
1267 GLint mViewportY;
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;
1283 int mMaxWarnings;
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;
1298 #ifdef XP_MACOSX
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;
1305 #endif
1307 nsRefPtr<WebGLObserver> mContextObserver;
1309 public:
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
1328 inline nsISupports*
1329 ToSupports(WebGLContext* context)
1331 return static_cast<nsIDOMWebGLRenderingContext*>(context);
1335 ** Template implementations
1338 template<class ObjectType>
1339 inline bool
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);
1347 return false;
1350 return true;
1353 template<class ObjectType>
1354 inline bool
1355 WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject)
1357 MOZ_ASSERT(aObject);
1359 if (!ValidateObjectAllowDeletedOrNull(info, aObject))
1360 return false;
1362 if (aObject->IsDeleted()) {
1363 ErrorInvalidValue("%s: deleted object passed as argument", info);
1364 return false;
1367 return true;
1370 template<class ObjectType>
1371 inline bool
1372 WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType *aObject)
1374 if (!aObject) {
1375 return true;
1378 return ValidateObjectAssumeNonNull(info, aObject);
1381 template<class ObjectType>
1382 inline bool
1383 WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType *aObject)
1385 if (!aObject) {
1386 ErrorInvalidValue("%s: null object passed as argument", info);
1387 return false;
1390 return ValidateObjectAllowDeletedOrNull(info, aObject);
1393 template<class ObjectType>
1394 inline bool
1395 WebGLContext::ValidateObject(const char* info, ObjectType *aObject)
1397 if (!aObject) {
1398 ErrorInvalidValue("%s: null object passed as argument", info);
1399 return false;
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
1410 public:
1411 NS_DECL_ISUPPORTS
1412 NS_DECL_NSIOBSERVER
1413 NS_DECL_NSIDOMEVENTLISTENER
1415 explicit WebGLObserver(WebGLContext* aContext);
1417 void Destroy();
1419 void RegisterVisibilityChangeEvent();
1420 void UnregisterVisibilityChangeEvent();
1422 void RegisterMemoryPressureEvent();
1423 void UnregisterMemoryPressureEvent();
1425 private:
1426 ~WebGLObserver();
1428 WebGLContext* mContext;
1431 } // namespace mozilla
1433 #endif