content/canvas/src/WebGLContext.h

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

mercurial