1 : /* -*- Mode: c++; c-basic-offset: 4; tab-width: 40; indent-tabs-mode: nil; -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2010
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Vladimir Vukicevic <vladimir@pobox.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /*
40 : * Intended to be #included in dom_quickstubs.cpp via qsconf!
41 : */
42 :
43 : #include "jsapi.h"
44 : #include "jstypedarray.h"
45 :
46 : #define GET_INT32_ARG(var, index) \
47 : int32_t var; \
48 : do { \
49 : if (!JS_ValueToECMAInt32(cx, argv[index], &(var))) \
50 : return JS_FALSE; \
51 : } while (0)
52 :
53 : #define GET_UINT32_ARG(var, index) \
54 : uint32_t var; \
55 : do { \
56 : if (!JS_ValueToECMAUint32(cx, argv[index], &(var))) \
57 : return JS_FALSE; \
58 : } while (0)
59 :
60 : #define GET_OPTIONAL_UINT32_ARG(var, index) \
61 : uint32_t var = 0; \
62 : do { \
63 : if (argc > index) \
64 : if (!JS_ValueToECMAUint32(cx, argv[index], &(var))) \
65 : return JS_FALSE; \
66 : } while (0)
67 :
68 :
69 : static inline bool
70 0 : helper_isInt32Array(JSObject *obj) {
71 0 : return js::GetObjectClass(obj) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_INT32];
72 : }
73 :
74 : static inline bool
75 0 : helper_isFloat32Array(JSObject *obj) {
76 0 : return js::GetObjectClass(obj) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32];
77 : }
78 :
79 : /*
80 : * BufferData takes:
81 : * BufferData (int, int, int)
82 : * BufferData_buf (int, js::ArrayBuffer *, int)
83 : * BufferData_array (int, js::TypedArray *, int)
84 : */
85 : static JSBool
86 0 : nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, unsigned argc, jsval *vp)
87 : {
88 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
89 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
90 0 : if (!obj)
91 0 : return JS_FALSE;
92 :
93 : nsIDOMWebGLRenderingContext *self;
94 0 : xpc_qsSelfRef selfref;
95 0 : JS::AutoValueRooter tvr(cx);
96 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
97 0 : return JS_FALSE;
98 :
99 0 : if (argc < 3)
100 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
101 :
102 0 : jsval *argv = JS_ARGV(cx, vp);
103 :
104 : int32_t target;
105 0 : JSObject *wa = 0;
106 0 : JSObject *wb = 0;
107 : int32_t size;
108 : int32_t usage;
109 :
110 0 : if (!JS_ValueToECMAInt32(cx, argv[0], &target))
111 0 : return JS_FALSE;
112 0 : if (!JS_ValueToECMAInt32(cx, argv[2], &usage))
113 0 : return JS_FALSE;
114 :
115 0 : JSBool nullobject = JSVAL_IS_NULL(argv[1]);
116 :
117 0 : if (!nullobject) {
118 0 : if (!JSVAL_IS_PRIMITIVE(argv[1])) {
119 :
120 0 : JSObject *arg2 = JSVAL_TO_OBJECT(argv[1]);
121 0 : if (js_IsArrayBuffer(arg2)) {
122 0 : wb = js::ArrayBuffer::getArrayBuffer(arg2);
123 0 : } else if (js_IsTypedArray(arg2)) {
124 0 : wa = js::TypedArray::getTypedArray(arg2);
125 : }
126 : }
127 :
128 0 : if (!wa && !wb &&
129 0 : !JS_ValueToECMAInt32(cx, argv[1], &size))
130 : {
131 0 : return JS_FALSE;
132 : }
133 : }
134 :
135 : nsresult rv;
136 :
137 0 : if (wa)
138 0 : rv = self->BufferData_array(target, wa, usage);
139 0 : else if (wb)
140 0 : rv = self->BufferData_buf(target, wb, usage);
141 0 : else if (nullobject)
142 0 : rv = self->BufferData_null();
143 : else
144 0 : rv = self->BufferData_size(target, size, usage);
145 :
146 0 : if (NS_FAILED(rv))
147 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
148 :
149 0 : *vp = JSVAL_VOID;
150 0 : return JS_TRUE;
151 : }
152 :
153 : /*
154 : * BufferSubData takes:
155 : * BufferSubData (int, int, js::ArrayBuffer *)
156 : * BufferSubData_array (int, int, js::TypedArray *)
157 : */
158 : static JSBool
159 0 : nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, unsigned argc, jsval *vp)
160 : {
161 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
162 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
163 0 : if (!obj)
164 0 : return JS_FALSE;
165 :
166 : nsIDOMWebGLRenderingContext *self;
167 0 : xpc_qsSelfRef selfref;
168 0 : JS::AutoValueRooter tvr(cx);
169 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
170 0 : return JS_FALSE;
171 :
172 0 : if (argc < 3)
173 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
174 :
175 0 : jsval *argv = JS_ARGV(cx, vp);
176 :
177 : int32_t target;
178 : int32_t offset;
179 0 : JSObject *wa = 0;
180 0 : JSObject *wb = 0;
181 :
182 0 : if (!JS_ValueToECMAInt32(cx, argv[0], &target))
183 0 : return JS_FALSE;
184 0 : if (!JS_ValueToECMAInt32(cx, argv[1], &offset))
185 0 : return JS_FALSE;
186 :
187 0 : if (!JSVAL_IS_OBJECT(argv[2])) {
188 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
189 0 : return JS_FALSE;
190 : }
191 :
192 0 : JSBool nullobject = JSVAL_IS_NULL(argv[2]);
193 :
194 0 : if (!nullobject) {
195 0 : JSObject *arg3 = JSVAL_TO_OBJECT(argv[2]);
196 0 : if (js_IsArrayBuffer(arg3)) {
197 0 : wb = js::ArrayBuffer::getArrayBuffer(arg3);
198 0 : } else if (js_IsTypedArray(arg3)) {
199 0 : wa = js::TypedArray::getTypedArray(arg3);
200 : } else {
201 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
202 0 : return JS_FALSE;
203 : }
204 : }
205 :
206 : nsresult rv;
207 :
208 0 : if (wa) {
209 0 : rv = self->BufferSubData_array(target, offset, wa);
210 0 : } else if (wb) {
211 0 : rv = self->BufferSubData_buf(target, offset, wb);
212 0 : } else if (nullobject) {
213 0 : rv = self->BufferSubData_null();
214 : } else {
215 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
216 0 : return JS_FALSE;
217 : }
218 :
219 0 : if (NS_FAILED(rv))
220 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
221 :
222 0 : *vp = JSVAL_VOID;
223 0 : return JS_TRUE;
224 : }
225 :
226 : /*
227 : * CompressedTexImage2D takes:
228 : * CompressedTexImage2D(uint, int, uint, int, int, int, ArrayBufferView)
229 : */
230 : static JSBool
231 0 : nsIDOMWebGLRenderingContext_CompressedTexImage2D(JSContext *cx, unsigned argc, jsval *vp)
232 : {
233 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
234 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
235 0 : if (!obj)
236 0 : return JS_FALSE;
237 :
238 : nsresult rv;
239 :
240 : nsIDOMWebGLRenderingContext *self;
241 0 : xpc_qsSelfRef selfref;
242 0 : JS::AutoValueRooter tvr(cx);
243 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
244 0 : return JS_FALSE;
245 :
246 0 : if (argc != 7)
247 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
248 :
249 0 : jsval *argv = JS_ARGV(cx, vp);
250 :
251 0 : GET_UINT32_ARG(argv0, 0);
252 0 : GET_INT32_ARG(argv1, 1);
253 0 : GET_UINT32_ARG(argv2, 2);
254 0 : GET_INT32_ARG(argv3, 3);
255 0 : GET_INT32_ARG(argv4, 4);
256 0 : GET_INT32_ARG(argv5, 5);
257 :
258 0 : if (!JSVAL_IS_PRIMITIVE(argv[6])) {
259 0 : JSObject* argv6 = JSVAL_TO_OBJECT(argv[6]);
260 0 : if (js_IsTypedArray(argv6)) {
261 : rv = self->CompressedTexImage2D_array(argv0, argv1, argv2, argv3, argv4, argv5,
262 0 : js::TypedArray::getTypedArray(argv6));
263 : } else {
264 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
265 0 : return JS_FALSE;
266 : }
267 : } else {
268 0 : xpc_qsThrow(cx, NS_ERROR_FAILURE);
269 0 : return JS_FALSE;
270 : }
271 :
272 0 : *vp = JSVAL_VOID;
273 0 : return JS_TRUE;
274 : }
275 :
276 : /*
277 : * CompressedTexSubImage2D takes:
278 : * CompressedTexSubImage2D(uint, int, int, int, int, int, uint, ArrayBufferView)
279 : */
280 : static JSBool
281 0 : nsIDOMWebGLRenderingContext_CompressedTexSubImage2D(JSContext *cx, unsigned argc, jsval *vp)
282 : {
283 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
284 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
285 0 : if (!obj)
286 0 : return JS_FALSE;
287 :
288 : nsresult rv;
289 :
290 : nsIDOMWebGLRenderingContext *self;
291 0 : xpc_qsSelfRef selfref;
292 0 : JS::AutoValueRooter tvr(cx);
293 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
294 0 : return JS_FALSE;
295 :
296 0 : if (argc != 7)
297 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
298 :
299 0 : jsval *argv = JS_ARGV(cx, vp);
300 :
301 0 : GET_UINT32_ARG(argv0, 0);
302 0 : GET_INT32_ARG(argv1, 1);
303 0 : GET_INT32_ARG(argv2, 2);
304 0 : GET_INT32_ARG(argv3, 3);
305 0 : GET_INT32_ARG(argv4, 4);
306 0 : GET_INT32_ARG(argv5, 5);
307 0 : GET_UINT32_ARG(argv6, 6);
308 :
309 0 : if (!JSVAL_IS_PRIMITIVE(argv[7])) {
310 0 : JSObject* argv7 = JSVAL_TO_OBJECT(argv[7]);
311 0 : if (js_IsTypedArray(argv7)) {
312 : rv = self->CompressedTexSubImage2D_array(argv0, argv1, argv2, argv3, argv4, argv5,
313 0 : argv6, js::TypedArray::getTypedArray(argv7));
314 : } else {
315 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 7);
316 0 : return JS_FALSE;
317 : }
318 : } else {
319 0 : xpc_qsThrow(cx, NS_ERROR_FAILURE);
320 0 : return JS_FALSE;
321 : }
322 :
323 0 : *vp = JSVAL_VOID;
324 0 : return JS_TRUE;
325 : }
326 :
327 : /*
328 : * ReadPixels takes:
329 : * ReadPixels(int, int, int, int, uint, uint, ArrayBufferView)
330 : */
331 : static JSBool
332 0 : nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, unsigned argc, jsval *vp)
333 : {
334 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
335 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
336 0 : if (!obj)
337 0 : return JS_FALSE;
338 :
339 : nsresult rv;
340 :
341 : nsIDOMWebGLRenderingContext *self;
342 0 : xpc_qsSelfRef selfref;
343 0 : JS::AutoValueRooter tvr(cx);
344 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
345 0 : return JS_FALSE;
346 :
347 0 : if (argc < 7)
348 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
349 :
350 0 : jsval *argv = JS_ARGV(cx, vp);
351 :
352 : // arguments common to all cases
353 0 : GET_INT32_ARG(argv0, 0);
354 0 : GET_INT32_ARG(argv1, 1);
355 0 : GET_INT32_ARG(argv2, 2);
356 0 : GET_INT32_ARG(argv3, 3);
357 0 : GET_UINT32_ARG(argv4, 4);
358 0 : GET_UINT32_ARG(argv5, 5);
359 :
360 0 : if (argc == 7 &&
361 0 : !JSVAL_IS_PRIMITIVE(argv[6]))
362 : {
363 0 : JSObject *argv6 = JSVAL_TO_OBJECT(argv[6]);
364 0 : if (js_IsTypedArray(argv6)) {
365 : rv = self->ReadPixels_array(argv0, argv1, argv2, argv3,
366 : argv4, argv5,
367 0 : js::TypedArray::getTypedArray(argv6));
368 : } else {
369 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
370 0 : return JS_FALSE;
371 : }
372 : } else {
373 0 : xpc_qsThrow(cx, NS_ERROR_FAILURE);
374 0 : return JS_FALSE;
375 : }
376 :
377 0 : if (NS_FAILED(rv))
378 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
379 :
380 0 : *vp = JSVAL_VOID;
381 0 : return JS_TRUE;
382 : }
383 :
384 :
385 : class CallTexImage2D
386 : {
387 : private:
388 : nsIDOMWebGLRenderingContext* self;
389 : WebGLenum target;
390 : WebGLint level;
391 : WebGLenum internalformat;
392 : WebGLenum format;
393 : WebGLenum type;
394 :
395 : public:
396 0 : explicit CallTexImage2D(nsIDOMWebGLRenderingContext* aSelf,
397 : WebGLenum aTarget,
398 : WebGLint aLevel,
399 : WebGLenum aInternalformat,
400 : WebGLenum aFormat,
401 : WebGLenum aType)
402 : : self(aSelf)
403 : , target(aTarget)
404 : , level(aLevel)
405 : , internalformat(aInternalformat)
406 : , format(aFormat)
407 0 : , type(aType)
408 0 : {}
409 :
410 0 : nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
411 : JSObject* pixels)
412 : {
413 : return self->TexImage2D_imageData(target, level, internalformat, width,
414 0 : height, 0, format, type, pixels);
415 : }
416 0 : nsresult DoCallForElement(mozilla::dom::Element* elt)
417 : {
418 : return self->TexImage2D_dom(target, level, internalformat, format, type,
419 0 : elt);
420 : }
421 : };
422 :
423 : class CallTexSubImage2D
424 : {
425 : private:
426 : nsIDOMWebGLRenderingContext* self;
427 : WebGLenum target;
428 : WebGLint level;
429 : WebGLint xoffset;
430 : WebGLint yoffset;
431 : WebGLenum format;
432 : WebGLenum type;
433 :
434 : public:
435 0 : explicit CallTexSubImage2D(nsIDOMWebGLRenderingContext* aSelf,
436 : WebGLenum aTarget,
437 : WebGLint aLevel,
438 : WebGLint aXoffset,
439 : WebGLint aYoffset,
440 : WebGLenum aFormat,
441 : WebGLenum aType)
442 :
443 : : self(aSelf)
444 : , target(aTarget)
445 : , level(aLevel)
446 : , xoffset(aXoffset)
447 : , yoffset(aYoffset)
448 : , format(aFormat)
449 0 : , type(aType)
450 0 : {}
451 :
452 0 : nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
453 : JSObject* pixels)
454 : {
455 : return self->TexSubImage2D_imageData(target, level, xoffset, yoffset,
456 : width, height, format, type,
457 0 : pixels);
458 : }
459 0 : nsresult DoCallForElement(mozilla::dom::Element* elt)
460 : {
461 : return self->TexSubImage2D_dom(target, level, xoffset, yoffset, format,
462 0 : type, elt);
463 : }
464 : };
465 :
466 : template<class T>
467 : static bool
468 0 : TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object)
469 : {
470 0 : MOZ_ASSERT(object && object->isObject());
471 :
472 : nsGenericElement* elt;
473 0 : xpc_qsSelfRef eltRef;
474 0 : if (NS_SUCCEEDED(xpc_qsUnwrapArg<nsGenericElement>(
475 : cx, *object, &elt, &eltRef.ptr, object))) {
476 0 : nsresult rv = self.DoCallForElement(elt);
477 0 : return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
478 : }
479 :
480 : // Failed to interpret object as an Element, now try to interpret it as
481 : // ImageData.
482 0 : JSObject* imageData = &object->toObject();
483 :
484 : jsval js_width, js_height, js_data;
485 0 : if (!JS_GetProperty(cx, imageData, "width", &js_width) ||
486 : !JS_GetProperty(cx, imageData, "height", &js_height) ||
487 : !JS_GetProperty(cx, imageData, "data", &js_data)) {
488 0 : return false;
489 : }
490 0 : if (js_width == JSVAL_VOID ||
491 : js_height == JSVAL_VOID ||
492 : !js_data.isObject())
493 : {
494 0 : return xpc_qsThrow(cx, NS_ERROR_FAILURE);
495 : }
496 : int32_t int_width, int_height;
497 0 : JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
498 0 : if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
499 : !JS_ValueToECMAInt32(cx, js_height, &int_height))
500 : {
501 0 : return false;
502 : }
503 0 : if (!js_IsTypedArray(obj_data))
504 : {
505 0 : return xpc_qsThrow(cx, NS_ERROR_FAILURE);
506 : }
507 :
508 0 : nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data);
509 0 : return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
510 : }
511 :
512 : /*
513 : * TexImage2D takes:
514 : * TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)
515 : * TexImage2D(uint, int, uint, uint, uint, nsIDOMElement)
516 : * TexImage2D(uint, int, uint, uint, uint, ImageData)
517 : */
518 : static JSBool
519 0 : nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
520 : {
521 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
522 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
523 0 : if (!obj)
524 0 : return JS_FALSE;
525 :
526 : nsresult rv;
527 :
528 : nsIDOMWebGLRenderingContext *self;
529 0 : xpc_qsSelfRef selfref;
530 0 : JS::AutoValueRooter tvr(cx);
531 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
532 0 : return JS_FALSE;
533 :
534 0 : if (argc < 6 || argc == 7 || argc == 8)
535 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
536 :
537 0 : jsval *argv = JS_ARGV(cx, vp);
538 :
539 : // arguments common to all cases
540 0 : GET_UINT32_ARG(argv0, 0);
541 0 : GET_INT32_ARG(argv1, 1);
542 0 : GET_UINT32_ARG(argv2, 2);
543 :
544 0 : if (argc > 5 && !JSVAL_IS_PRIMITIVE(argv[5])) {
545 : // implement the variants taking a DOMElement as argv[5]
546 0 : GET_UINT32_ARG(argv3, 3);
547 0 : GET_UINT32_ARG(argv4, 4);
548 :
549 0 : CallTexImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4);
550 0 : if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 5)) {
551 0 : return false;
552 : }
553 0 : rv = NS_OK;
554 0 : } else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
555 : // here, we allow null !
556 : // implement the variants taking a buffer/array as argv[8]
557 0 : GET_INT32_ARG(argv3, 3);
558 0 : GET_INT32_ARG(argv4, 4);
559 0 : GET_INT32_ARG(argv5, 5);
560 0 : GET_UINT32_ARG(argv6, 6);
561 0 : GET_UINT32_ARG(argv7, 7);
562 :
563 0 : JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
564 :
565 : // then try to grab either a js::TypedArray, or null
566 0 : if (argv8 == nsnull) {
567 : rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
568 : argv4, argv5, argv6, argv7,
569 0 : nsnull);
570 0 : } else if (js_IsTypedArray(argv8)) {
571 : rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
572 : argv4, argv5, argv6, argv7,
573 0 : js::TypedArray::getTypedArray(argv8));
574 : } else {
575 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
576 0 : return JS_FALSE;
577 : }
578 : } else {
579 0 : xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
580 0 : return JS_FALSE;
581 : }
582 :
583 0 : if (NS_FAILED(rv))
584 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
585 :
586 0 : *vp = JSVAL_VOID;
587 0 : return JS_TRUE;
588 : }
589 :
590 : /* TexSubImage2D takes:
591 : * TexSubImage2D(uint, int, int, int, int, int, uint, uint, ArrayBufferView)
592 : * TexSubImage2D(uint, int, int, int, uint, uint, nsIDOMElement)
593 : * TexSubImage2D(uint, int, int, int, uint, uint, ImageData)
594 : */
595 : static JSBool
596 0 : nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, unsigned argc, jsval *vp)
597 : {
598 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
599 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
600 0 : if (!obj)
601 0 : return JS_FALSE;
602 :
603 : nsresult rv;
604 :
605 : nsIDOMWebGLRenderingContext *self;
606 0 : xpc_qsSelfRef selfref;
607 0 : JS::AutoValueRooter tvr(cx);
608 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
609 0 : return JS_FALSE;
610 :
611 0 : if (argc < 7 || argc == 8)
612 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
613 :
614 0 : jsval *argv = JS_ARGV(cx, vp);
615 :
616 : // arguments common to all cases
617 0 : GET_UINT32_ARG(argv0, 0);
618 0 : GET_INT32_ARG(argv1, 1);
619 0 : GET_INT32_ARG(argv2, 2);
620 0 : GET_INT32_ARG(argv3, 3);
621 :
622 0 : if (argc > 6 && !JSVAL_IS_PRIMITIVE(argv[6])) {
623 : // implement the variants taking a DOMElement or an ImageData as argv[6]
624 0 : GET_UINT32_ARG(argv4, 4);
625 0 : GET_UINT32_ARG(argv5, 5);
626 :
627 0 : CallTexSubImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4, argv5);
628 0 : if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 6)) {
629 0 : return false;
630 : }
631 0 : rv = NS_OK;
632 0 : } else if (argc > 8 && !JSVAL_IS_PRIMITIVE(argv[8])) {
633 : // implement the variants taking a buffer/array as argv[8]
634 0 : GET_INT32_ARG(argv4, 4);
635 0 : GET_INT32_ARG(argv5, 5);
636 0 : GET_UINT32_ARG(argv6, 6);
637 0 : GET_UINT32_ARG(argv7, 7);
638 :
639 0 : JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
640 : // try to grab a js::TypedArray
641 0 : if (js_IsTypedArray(argv8)) {
642 : rv = self->TexSubImage2D_array(argv0, argv1, argv2, argv3,
643 : argv4, argv5, argv6, argv7,
644 0 : js::TypedArray::getTypedArray(argv8));
645 : } else {
646 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
647 0 : return JS_FALSE;
648 : }
649 : } else {
650 0 : xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
651 0 : return JS_FALSE;
652 : }
653 :
654 0 : if (NS_FAILED(rv))
655 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
656 :
657 0 : *vp = JSVAL_VOID;
658 0 : return JS_TRUE;
659 : }
660 :
661 : /* NOTE: There is a TN version of this below, update it as well */
662 : static inline JSBool
663 0 : helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
664 : {
665 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
666 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
667 0 : if (!obj)
668 0 : return JS_FALSE;
669 :
670 : nsresult rv;
671 :
672 : nsIDOMWebGLRenderingContext *self;
673 0 : xpc_qsSelfRef selfref;
674 0 : JS::AutoValueRooter tvr(cx);
675 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
676 0 : return JS_FALSE;
677 :
678 0 : if (argc < 2)
679 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
680 :
681 0 : jsval *argv = JS_ARGV(cx, vp);
682 :
683 : nsIWebGLUniformLocation *location;
684 0 : xpc_qsSelfRef location_selfref;
685 0 : rv = xpc_qsUnwrapArg(cx, argv[0], &location, &location_selfref.ptr, &argv[0]);
686 0 : if (NS_FAILED(rv)) {
687 0 : xpc_qsThrowBadArg(cx, rv, vp, 0);
688 0 : return JS_FALSE;
689 : }
690 :
691 0 : if (JSVAL_IS_PRIMITIVE(argv[1])) {
692 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
693 0 : return JS_FALSE;
694 : }
695 :
696 0 : JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
697 :
698 0 : JS::AutoValueRooter obj_tvr(cx);
699 :
700 0 : JSObject *wa = 0;
701 :
702 0 : if (helper_isInt32Array(arg1)) {
703 0 : wa = js::TypedArray::getTypedArray(arg1);
704 0 : } else if (JS_IsArrayObject(cx, arg1)) {
705 0 : JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg1);
706 0 : if (!nobj) {
707 : // XXX this will likely return a strange error message if it goes wrong
708 0 : return JS_FALSE;
709 : }
710 :
711 0 : *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
712 0 : wa = js::TypedArray::getTypedArray(nobj);
713 : } else {
714 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
715 0 : return JS_FALSE;
716 : }
717 :
718 0 : if (nElements == 1) {
719 0 : rv = self->Uniform1iv_array(location, wa);
720 0 : } else if (nElements == 2) {
721 0 : rv = self->Uniform2iv_array(location, wa);
722 0 : } else if (nElements == 3) {
723 0 : rv = self->Uniform3iv_array(location, wa);
724 0 : } else if (nElements == 4) {
725 0 : rv = self->Uniform4iv_array(location, wa);
726 : }
727 :
728 0 : if (NS_FAILED(rv))
729 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
730 :
731 0 : *vp = JSVAL_VOID;
732 0 : return JS_TRUE;
733 : }
734 :
735 : /* NOTE: There is a TN version of this below, update it as well */
736 : static inline JSBool
737 0 : helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
738 : {
739 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
740 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
741 0 : if (!obj)
742 0 : return JS_FALSE;
743 :
744 : nsresult rv;
745 :
746 : nsIDOMWebGLRenderingContext *self;
747 0 : xpc_qsSelfRef selfref;
748 0 : JS::AutoValueRooter tvr(cx);
749 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
750 0 : return JS_FALSE;
751 :
752 0 : if (argc < 2)
753 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
754 :
755 0 : jsval *argv = JS_ARGV(cx, vp);
756 :
757 : nsIWebGLUniformLocation *location;
758 0 : xpc_qsSelfRef location_selfref;
759 0 : rv = xpc_qsUnwrapArg(cx, argv[0], &location, &location_selfref.ptr, &argv[0]);
760 0 : if (NS_FAILED(rv)) {
761 0 : xpc_qsThrowBadArg(cx, rv, vp, 0);
762 0 : return JS_FALSE;
763 : }
764 :
765 0 : if (JSVAL_IS_PRIMITIVE(argv[1])) {
766 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
767 0 : return JS_FALSE;
768 : }
769 :
770 0 : JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
771 :
772 0 : JS::AutoValueRooter obj_tvr(cx);
773 :
774 0 : JSObject *wa = 0;
775 :
776 0 : if (helper_isFloat32Array(arg1)) {
777 0 : wa = js::TypedArray::getTypedArray(arg1);
778 0 : } else if (JS_IsArrayObject(cx, arg1)) {
779 0 : JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
780 0 : if (!nobj) {
781 : // XXX this will likely return a strange error message if it goes wrong
782 0 : return JS_FALSE;
783 : }
784 :
785 0 : *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
786 0 : wa = js::TypedArray::getTypedArray(nobj);
787 : } else {
788 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
789 0 : return JS_FALSE;
790 : }
791 :
792 0 : if (nElements == 1) {
793 0 : rv = self->Uniform1fv_array(location, wa);
794 0 : } else if (nElements == 2) {
795 0 : rv = self->Uniform2fv_array(location, wa);
796 0 : } else if (nElements == 3) {
797 0 : rv = self->Uniform3fv_array(location, wa);
798 0 : } else if (nElements == 4) {
799 0 : rv = self->Uniform4fv_array(location, wa);
800 : }
801 :
802 0 : if (NS_FAILED(rv))
803 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
804 :
805 0 : *vp = JSVAL_VOID;
806 0 : return JS_TRUE;
807 : }
808 :
809 : /* NOTE: There is a TN version of this below, update it as well */
810 : static inline JSBool
811 0 : helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
812 : {
813 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
814 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
815 0 : if (!obj)
816 0 : return JS_FALSE;
817 :
818 : nsIDOMWebGLRenderingContext *self;
819 0 : xpc_qsSelfRef selfref;
820 0 : JS::AutoValueRooter tvr(cx);
821 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
822 0 : return JS_FALSE;
823 :
824 0 : if (argc < 3)
825 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
826 :
827 0 : jsval *argv = JS_ARGV(cx, vp);
828 :
829 : nsIWebGLUniformLocation *location;
830 0 : xpc_qsSelfRef location_selfref;
831 0 : nsresult rv = xpc_qsUnwrapArg(cx, argv[0], &location, &location_selfref.ptr, &argv[0]);
832 0 : if (NS_FAILED(rv)) {
833 0 : xpc_qsThrowBadArg(cx, rv, vp, 0);
834 0 : return JS_FALSE;
835 : }
836 :
837 : int32_t transpose;
838 0 : if (!JS_ValueToECMAInt32(cx, argv[1], &transpose))
839 0 : return JS_FALSE;
840 :
841 0 : if (JSVAL_IS_PRIMITIVE(argv[2])) {
842 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
843 0 : return JS_FALSE;
844 : }
845 :
846 0 : JSObject *arg2 = JSVAL_TO_OBJECT(argv[2]);
847 :
848 0 : JS::AutoValueRooter obj_tvr(cx);
849 :
850 0 : JSObject *wa = 0;
851 :
852 0 : if (helper_isFloat32Array(arg2)) {
853 0 : wa = js::TypedArray::getTypedArray(arg2);
854 0 : } else if (JS_IsArrayObject(cx, arg2)) {
855 0 : JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg2);
856 0 : if (!nobj) {
857 : // XXX this will likely return a strange error message if it goes wrong
858 0 : return JS_FALSE;
859 : }
860 :
861 0 : *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
862 0 : wa = js::TypedArray::getTypedArray(nobj);
863 : } else {
864 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
865 0 : return JS_FALSE;
866 : }
867 :
868 0 : if (nElements == 2) {
869 0 : rv = self->UniformMatrix2fv_array(location, transpose ? 1 : 0, wa);
870 0 : } else if (nElements == 3) {
871 0 : rv = self->UniformMatrix3fv_array(location, transpose ? 1 : 0, wa);
872 0 : } else if (nElements == 4) {
873 0 : rv = self->UniformMatrix4fv_array(location, transpose ? 1 : 0, wa);
874 : }
875 :
876 0 : if (NS_FAILED(rv))
877 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
878 :
879 0 : *vp = JSVAL_VOID;
880 0 : return JS_TRUE;
881 : }
882 :
883 : static inline JSBool
884 0 : helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
885 : {
886 0 : XPC_QS_ASSERT_CONTEXT_OK(cx);
887 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
888 0 : if (!obj)
889 0 : return JS_FALSE;
890 :
891 : nsIDOMWebGLRenderingContext *self;
892 0 : xpc_qsSelfRef selfref;
893 0 : JS::AutoValueRooter tvr(cx);
894 0 : if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
895 0 : return JS_FALSE;
896 :
897 0 : if (argc < 2)
898 0 : return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
899 :
900 0 : jsval *argv = JS_ARGV(cx, vp);
901 :
902 : uint32_t location;
903 0 : if (!JS_ValueToECMAUint32(cx, argv[0], &location))
904 0 : return JS_FALSE;
905 :
906 0 : if (JSVAL_IS_PRIMITIVE(argv[1])) {
907 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
908 0 : return JS_FALSE;
909 : }
910 :
911 0 : JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
912 :
913 0 : JS::AutoValueRooter obj_tvr(cx);
914 :
915 0 : JSObject *wa = 0;
916 :
917 0 : if (helper_isFloat32Array(arg1)) {
918 0 : wa = js::TypedArray::getTypedArray(arg1);
919 0 : } else if (JS_IsArrayObject(cx, arg1)) {
920 0 : JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
921 0 : if (!nobj) {
922 : // XXX this will likely return a strange error message if it goes wrong
923 0 : return JS_FALSE;
924 : }
925 :
926 0 : *obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
927 0 : wa = js::TypedArray::getTypedArray(nobj);
928 : } else {
929 0 : xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
930 0 : return JS_FALSE;
931 : }
932 :
933 0 : nsresult rv = NS_OK;
934 0 : if (nElements == 1) {
935 0 : rv = self->VertexAttrib1fv_array(location, wa);
936 0 : } else if (nElements == 2) {
937 0 : rv = self->VertexAttrib2fv_array(location, wa);
938 0 : } else if (nElements == 3) {
939 0 : rv = self->VertexAttrib3fv_array(location, wa);
940 0 : } else if (nElements == 4) {
941 0 : rv = self->VertexAttrib4fv_array(location, wa);
942 : }
943 :
944 0 : if (NS_FAILED(rv))
945 0 : return xpc_qsThrowMethodFailed(cx, rv, vp);
946 :
947 0 : *vp = JSVAL_VOID;
948 0 : return JS_TRUE;
949 : }
950 :
951 : static JSBool
952 0 : nsIDOMWebGLRenderingContext_Uniform1iv(JSContext *cx, unsigned argc, jsval *vp)
953 : {
954 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 1);
955 : }
956 :
957 : static JSBool
958 0 : nsIDOMWebGLRenderingContext_Uniform2iv(JSContext *cx, unsigned argc, jsval *vp)
959 : {
960 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 2);
961 : }
962 :
963 : static JSBool
964 0 : nsIDOMWebGLRenderingContext_Uniform3iv(JSContext *cx, unsigned argc, jsval *vp)
965 : {
966 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 3);
967 : }
968 :
969 : static JSBool
970 0 : nsIDOMWebGLRenderingContext_Uniform4iv(JSContext *cx, unsigned argc, jsval *vp)
971 : {
972 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 4);
973 : }
974 :
975 : static JSBool
976 0 : nsIDOMWebGLRenderingContext_Uniform1fv(JSContext *cx, unsigned argc, jsval *vp)
977 : {
978 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 1);
979 : }
980 :
981 : static JSBool
982 0 : nsIDOMWebGLRenderingContext_Uniform2fv(JSContext *cx, unsigned argc, jsval *vp)
983 : {
984 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 2);
985 : }
986 :
987 : static JSBool
988 0 : nsIDOMWebGLRenderingContext_Uniform3fv(JSContext *cx, unsigned argc, jsval *vp)
989 : {
990 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 3);
991 : }
992 :
993 : static JSBool
994 0 : nsIDOMWebGLRenderingContext_Uniform4fv(JSContext *cx, unsigned argc, jsval *vp)
995 : {
996 0 : return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 4);
997 : }
998 :
999 : static JSBool
1000 0 : nsIDOMWebGLRenderingContext_UniformMatrix2fv(JSContext *cx, unsigned argc, jsval *vp)
1001 : {
1002 0 : return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 2);
1003 : }
1004 :
1005 : static JSBool
1006 0 : nsIDOMWebGLRenderingContext_UniformMatrix3fv(JSContext *cx, unsigned argc, jsval *vp)
1007 : {
1008 0 : return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 3);
1009 : }
1010 :
1011 : static JSBool
1012 0 : nsIDOMWebGLRenderingContext_UniformMatrix4fv(JSContext *cx, unsigned argc, jsval *vp)
1013 : {
1014 0 : return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 4);
1015 : }
1016 :
1017 : static JSBool
1018 0 : nsIDOMWebGLRenderingContext_VertexAttrib1fv(JSContext *cx, unsigned argc, jsval *vp)
1019 : {
1020 0 : return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 1);
1021 : }
1022 :
1023 : static JSBool
1024 0 : nsIDOMWebGLRenderingContext_VertexAttrib2fv(JSContext *cx, unsigned argc, jsval *vp)
1025 : {
1026 0 : return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 2);
1027 : }
1028 :
1029 : static JSBool
1030 0 : nsIDOMWebGLRenderingContext_VertexAttrib3fv(JSContext *cx, unsigned argc, jsval *vp)
1031 : {
1032 0 : return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 3);
1033 : }
1034 :
1035 : static JSBool
1036 0 : nsIDOMWebGLRenderingContext_VertexAttrib4fv(JSContext *cx, unsigned argc, jsval *vp)
1037 : {
1038 0 : return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 4);
1039 : }
|