1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #if ENABLE(3D_CANVAS)
29
30 #include "JSWebGLRenderingContext.h"
31
32 #include "ExceptionCode.h"
33 #include "HTMLCanvasElement.h"
34 #include "HTMLImageElement.h"
35 #include "HTMLVideoElement.h"
36 #include "JSHTMLCanvasElement.h"
37 #include "JSHTMLImageElement.h"
38 #include "JSHTMLVideoElement.h"
39 #include "JSImageData.h"
40 #include "JSWebGLBuffer.h"
41 #include "JSWebGLFloatArray.h"
42 #include "JSWebGLFramebuffer.h"
43 #include "JSWebGLIntArray.h"
44 #include "JSWebGLProgram.h"
45 #include "JSWebGLRenderbuffer.h"
46 #include "JSWebGLShader.h"
47 #include "JSWebGLTexture.h"
48 #include "JSWebGLUniformLocation.h"
49 #include "JSWebGLUnsignedByteArray.h"
50 #include "JSWebKitCSSMatrix.h"
51 #include "NotImplemented.h"
52 #include "WebGLBuffer.h"
53 #include "WebGLFloatArray.h"
54 #include "WebGLFramebuffer.h"
55 #include "WebGLGetInfo.h"
56 #include "WebGLIntArray.h"
57 #include "WebGLProgram.h"
58 #include "WebGLRenderingContext.h"
59 #include <runtime/Error.h>
60 #include <wtf/FastMalloc.h>
61 #include <wtf/OwnFastMallocPtr.h>
62
63 using namespace JSC;
64
65 namespace WebCore {
66
bufferData(JSC::ExecState * exec,JSC::ArgList const & args)67 JSValue JSWebGLRenderingContext::bufferData(JSC::ExecState* exec, JSC::ArgList const& args)
68 {
69 if (args.size() != 3)
70 return throwError(exec, SyntaxError);
71
72 unsigned target = args.at(0).toInt32(exec);
73 unsigned usage = args.at(2).toInt32(exec);
74 ExceptionCode ec = 0;
75
76 // If argument 1 is a number, we are initializing this buffer to that size
77 if (!args.at(1).isObject()) {
78 unsigned int count = args.at(1).toInt32(exec);
79 static_cast<WebGLRenderingContext*>(impl())->bufferData(target, count, usage, ec);
80 } else {
81 WebGLArray* array = toWebGLArray(args.at(1));
82 static_cast<WebGLRenderingContext*>(impl())->bufferData(target, array, usage, ec);
83 }
84
85 setDOMException(exec, ec);
86 return jsUndefined();
87 }
88
bufferSubData(JSC::ExecState * exec,JSC::ArgList const & args)89 JSValue JSWebGLRenderingContext::bufferSubData(JSC::ExecState* exec, JSC::ArgList const& args)
90 {
91 if (args.size() != 3)
92 return throwError(exec, SyntaxError);
93
94 unsigned target = args.at(0).toInt32(exec);
95 unsigned offset = args.at(1).toInt32(exec);
96 ExceptionCode ec = 0;
97
98 WebGLArray* array = toWebGLArray(args.at(2));
99
100 static_cast<WebGLRenderingContext*>(impl())->bufferSubData(target, offset, array, ec);
101
102 setDOMException(exec, ec);
103 return jsUndefined();
104 }
105
toJS(ExecState * exec,JSDOMGlobalObject * globalObject,const WebGLGetInfo & info)106 static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, const WebGLGetInfo& info)
107 {
108 switch (info.getType()) {
109 case WebGLGetInfo::kTypeBool:
110 return jsBoolean(info.getBool());
111 case WebGLGetInfo::kTypeFloat:
112 return jsNumber(exec, info.getFloat());
113 case WebGLGetInfo::kTypeLong:
114 return jsNumber(exec, info.getLong());
115 case WebGLGetInfo::kTypeNull:
116 return jsNull();
117 case WebGLGetInfo::kTypeString:
118 return jsString(exec, info.getString());
119 case WebGLGetInfo::kTypeUnsignedLong:
120 return jsNumber(exec, info.getUnsignedLong());
121 case WebGLGetInfo::kTypeWebGLBuffer:
122 return toJS(exec, globalObject, info.getWebGLBuffer());
123 case WebGLGetInfo::kTypeWebGLFloatArray:
124 return toJS(exec, globalObject, info.getWebGLFloatArray());
125 case WebGLGetInfo::kTypeWebGLFramebuffer:
126 return toJS(exec, globalObject, info.getWebGLFramebuffer());
127 case WebGLGetInfo::kTypeWebGLIntArray:
128 return toJS(exec, globalObject, info.getWebGLIntArray());
129 // FIXME: implement WebGLObjectArray
130 // case WebGLGetInfo::kTypeWebGLObjectArray:
131 case WebGLGetInfo::kTypeWebGLProgram:
132 return toJS(exec, globalObject, info.getWebGLProgram());
133 case WebGLGetInfo::kTypeWebGLRenderbuffer:
134 return toJS(exec, globalObject, info.getWebGLRenderbuffer());
135 case WebGLGetInfo::kTypeWebGLTexture:
136 return toJS(exec, globalObject, info.getWebGLTexture());
137 case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
138 return toJS(exec, globalObject, info.getWebGLUnsignedByteArray());
139 default:
140 notImplemented();
141 return jsUndefined();
142 }
143 }
144
145 enum ObjectType {
146 kBuffer, kRenderbuffer, kTexture, kVertexAttrib
147 };
148
getObjectParameter(JSWebGLRenderingContext * obj,ExecState * exec,const ArgList & args,ObjectType objectType)149 static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, const ArgList& args, ObjectType objectType)
150 {
151 if (args.size() != 2)
152 return throwError(exec, SyntaxError);
153
154 ExceptionCode ec = 0;
155 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl());
156 unsigned target = args.at(0).toInt32(exec);
157 if (exec->hadException())
158 return jsUndefined();
159 unsigned pname = args.at(1).toInt32(exec);
160 if (exec->hadException())
161 return jsUndefined();
162 WebGLGetInfo info;
163 switch (objectType) {
164 case kBuffer:
165 info = context->getBufferParameter(target, pname, ec);
166 break;
167 case kRenderbuffer:
168 info = context->getRenderbufferParameter(target, pname, ec);
169 break;
170 case kTexture:
171 info = context->getTexParameter(target, pname, ec);
172 break;
173 case kVertexAttrib:
174 // target => index
175 info = context->getVertexAttrib(target, pname, ec);
176 break;
177 default:
178 notImplemented();
179 break;
180 }
181 if (ec) {
182 setDOMException(exec, ec);
183 return jsUndefined();
184 }
185 return toJS(exec, obj->globalObject(), info);
186 }
187
188 enum WhichProgramCall {
189 kProgramParameter, kUniform
190 };
191
getBufferParameter(ExecState * exec,const ArgList & args)192 JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec, const ArgList& args)
193 {
194 return getObjectParameter(this, exec, args, kBuffer);
195 }
196
getFramebufferAttachmentParameter(ExecState * exec,const ArgList & args)197 JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec, const ArgList& args)
198 {
199 if (args.size() != 3)
200 return throwError(exec, SyntaxError);
201
202 ExceptionCode ec = 0;
203 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
204 unsigned target = args.at(0).toInt32(exec);
205 if (exec->hadException())
206 return jsUndefined();
207 unsigned attachment = args.at(1).toInt32(exec);
208 if (exec->hadException())
209 return jsUndefined();
210 unsigned pname = args.at(2).toInt32(exec);
211 if (exec->hadException())
212 return jsUndefined();
213 WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec);
214 if (ec) {
215 setDOMException(exec, ec);
216 return jsUndefined();
217 }
218 return toJS(exec, globalObject(), info);
219 }
220
getParameter(ExecState * exec,const ArgList & args)221 JSValue JSWebGLRenderingContext::getParameter(ExecState* exec, const ArgList& args)
222 {
223 if (args.size() != 1)
224 return throwError(exec, SyntaxError);
225
226 ExceptionCode ec = 0;
227 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
228 unsigned pname = args.at(0).toInt32(exec);
229 if (exec->hadException())
230 return jsUndefined();
231 WebGLGetInfo info = context->getParameter(pname, ec);
232 if (ec) {
233 setDOMException(exec, ec);
234 return jsUndefined();
235 }
236 return toJS(exec, globalObject(), info);
237 }
238
getProgramParameter(ExecState * exec,const ArgList & args)239 JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec, const ArgList& args)
240 {
241 if (args.size() != 2)
242 return throwError(exec, SyntaxError);
243
244 ExceptionCode ec = 0;
245 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
246 WebGLProgram* program = toWebGLProgram(args.at(0));
247 unsigned pname = args.at(1).toInt32(exec);
248 if (exec->hadException())
249 return jsUndefined();
250 WebGLGetInfo info = context->getProgramParameter(program, pname, ec);
251 if (ec) {
252 setDOMException(exec, ec);
253 return jsUndefined();
254 }
255 return toJS(exec, globalObject(), info);
256 }
257
getRenderbufferParameter(ExecState * exec,const ArgList & args)258 JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec, const ArgList& args)
259 {
260 return getObjectParameter(this, exec, args, kRenderbuffer);
261 }
262
getShaderParameter(ExecState * exec,const ArgList & args)263 JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec, const ArgList& args)
264 {
265 if (args.size() != 2)
266 return throwError(exec, SyntaxError);
267
268 ExceptionCode ec = 0;
269 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
270 WebGLShader* shader = toWebGLShader(args.at(0));
271 unsigned pname = args.at(1).toInt32(exec);
272 if (exec->hadException())
273 return jsUndefined();
274 WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
275 if (ec) {
276 setDOMException(exec, ec);
277 return jsUndefined();
278 }
279 return toJS(exec, globalObject(), info);
280 }
281
getTexParameter(ExecState * exec,const ArgList & args)282 JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec, const ArgList& args)
283 {
284 return getObjectParameter(this, exec, args, kTexture);
285 }
286
getUniform(ExecState * exec,const ArgList & args)287 JSValue JSWebGLRenderingContext::getUniform(ExecState* exec, const ArgList& args)
288 {
289 if (args.size() != 2)
290 return throwError(exec, SyntaxError);
291
292 ExceptionCode ec = 0;
293 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
294 WebGLProgram* program = toWebGLProgram(args.at(0));
295 WebGLUniformLocation* loc = toWebGLUniformLocation(args.at(1));
296 if (exec->hadException())
297 return jsUndefined();
298 WebGLGetInfo info = context->getUniform(program, loc, ec);
299 if (ec) {
300 setDOMException(exec, ec);
301 return jsUndefined();
302 }
303 return toJS(exec, globalObject(), info);
304 }
305
getVertexAttrib(ExecState * exec,const ArgList & args)306 JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec, const ArgList& args)
307 {
308 return getObjectParameter(this, exec, args, kVertexAttrib);
309 }
310
311 // void texImage2D(in GLenum target, in GLint level, in GLenum internalformat, in GLsizei width, in GLsizei height, in GLint border, in GLenum format, in GLenum type, in WebGLArray pixels);
312 // void texImage2D(in GLenum target, in GLint level, in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha);
313 // void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha);
314 // void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement canvas, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha);
315 // void texImage2D(in GLenum target, in GLint level, in HTMLVideoElement video, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha);
texImage2D(ExecState * exec,const ArgList & args)316 JSValue JSWebGLRenderingContext::texImage2D(ExecState* exec, const ArgList& args)
317 {
318 if (args.size() < 3 || args.size() > 9)
319 return throwError(exec, SyntaxError);
320
321 ExceptionCode ec = 0;
322
323 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
324 unsigned target = args.at(0).toInt32(exec);
325 if (exec->hadException())
326 return jsUndefined();
327
328 unsigned level = args.at(1).toInt32(exec);
329 if (exec->hadException())
330 return jsUndefined();
331
332 JSObject* o = 0;
333
334 if (args.size() <= 5) {
335 // This is one of the last 4 forms. Param 2 can be ImageData or <img>, <canvas> or <video> element.
336 JSValue value = args.at(2);
337
338 if (!value.isObject())
339 return throwError(exec, TypeError);
340
341 o = asObject(value);
342
343 bool flipY = args.at(3).toBoolean(exec);
344 bool premultiplyAlpha = args.at(4).toBoolean(exec);
345
346 if (o->inherits(&JSImageData::s_info)) {
347 ImageData* data = static_cast<ImageData*>(static_cast<JSImageData*>(o)->impl());
348 context->texImage2D(target, level, data, flipY, premultiplyAlpha, ec);
349 } else if (o->inherits(&JSHTMLImageElement::s_info)) {
350 HTMLImageElement* element = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(o)->impl());
351 context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec);
352 } else if (o->inherits(&JSHTMLCanvasElement::s_info)) {
353 HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLCanvasElement*>(o)->impl());
354 context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec);
355 } else if (o->inherits(&JSHTMLVideoElement::s_info)) {
356 HTMLVideoElement* element = static_cast<HTMLVideoElement*>(static_cast<JSHTMLVideoElement*>(o)->impl());
357 context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec);
358 } else
359 ec = TYPE_MISMATCH_ERR;
360 } else {
361 if (args.size() != 9)
362 return throwError(exec, SyntaxError);
363
364 // This must be the WebGLArray case
365 unsigned internalformat = args.at(2).toInt32(exec);
366 if (exec->hadException())
367 return jsUndefined();
368
369 unsigned width = args.at(3).toInt32(exec);
370 if (exec->hadException())
371 return jsUndefined();
372
373 unsigned height = args.at(4).toInt32(exec);
374 if (exec->hadException())
375 return jsUndefined();
376
377 unsigned border = args.at(5).toInt32(exec);
378 if (exec->hadException())
379 return jsUndefined();
380
381 unsigned format = args.at(6).toInt32(exec);
382 if (exec->hadException())
383 return jsUndefined();
384
385 unsigned type = args.at(7).toInt32(exec);
386 if (exec->hadException())
387 return jsUndefined();
388
389 JSValue value = args.at(8);
390
391 // For this case passing 0 (for a null array) is allowed
392 if (value.isNull())
393 context->texImage2D(target, level, internalformat, width, height, border, format, type, 0, ec);
394 else if (value.isObject()) {
395 o = asObject(value);
396
397 if (o->inherits(&JSWebGLArray::s_info)) {
398 // FIXME: Need to check to make sure WebGLArray is a WebGLByteArray or WebGLShortArray,
399 // depending on the passed type parameter.
400 WebGLArray* obj = static_cast<WebGLArray*>(static_cast<JSWebGLArray*>(o)->impl());
401 context->texImage2D(target, level, internalformat, width, height, border, format, type, obj, ec);
402 } else
403 return throwError(exec, TypeError);
404 } else
405 return throwError(exec, TypeError);
406 }
407
408 setDOMException(exec, ec);
409 return jsUndefined();
410 }
411
412 // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in GLsizei width, in GLsizei height, in GLenum format, in GLenum type, in WebGLArray pixels);
413 // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha);
414 // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLImageElement image, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha);
415 // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLCanvasElement canvas, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha);
416 // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLVideoElement video, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha);
texSubImage2D(ExecState * exec,const ArgList & args)417 JSValue JSWebGLRenderingContext::texSubImage2D(ExecState* exec, const ArgList& args)
418 {
419 if (args.size() < 5 || args.size() > 9)
420 return throwError(exec, SyntaxError);
421
422 ExceptionCode ec = 0;
423
424 WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
425 unsigned target = args.at(0).toInt32(exec);
426 if (exec->hadException())
427 return jsUndefined();
428
429 unsigned level = args.at(1).toInt32(exec);
430 if (exec->hadException())
431 return jsUndefined();
432
433 unsigned xoff = args.at(2).toInt32(exec);
434 if (exec->hadException())
435 return jsUndefined();
436
437 unsigned yoff = args.at(3).toInt32(exec);
438 if (exec->hadException())
439 return jsUndefined();
440
441 JSObject* o = 0;
442
443 if (args.size() <= 7) {
444 // This is one of the last 4 forms. Param 4 can be <img>, <canvas> or <video> element, of the format param.
445 JSValue value = args.at(4);
446
447 if (!value.isObject())
448 return throwError(exec, SyntaxError);
449
450 o = asObject(value);
451
452 bool flipY = args.at(5).toBoolean(exec);
453 bool premultiplyAlpha = args.at(6).toBoolean(exec);
454
455 if (o->inherits(&JSImageData::s_info)) {
456 ImageData* data = static_cast<ImageData*>(static_cast<JSImageData*>(o)->impl());
457 context->texSubImage2D(target, level, xoff, yoff, data, flipY, premultiplyAlpha, ec);
458 } else if (o->inherits(&JSHTMLImageElement::s_info)) {
459 HTMLImageElement* element = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(o)->impl());
460 context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec);
461 } else if (o->inherits(&JSHTMLCanvasElement::s_info)) {
462 HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLCanvasElement*>(o)->impl());
463 context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec);
464 } else if (o->inherits(&JSHTMLVideoElement::s_info)) {
465 HTMLVideoElement* element = static_cast<HTMLVideoElement*>(static_cast<JSHTMLVideoElement*>(o)->impl());
466 context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec);
467 } else
468 ec = TYPE_MISMATCH_ERR;
469 } else {
470 // This must be the WebGLArray form
471 if (args.size() != 9)
472 return throwError(exec, SyntaxError);
473
474 unsigned width = args.at(4).toInt32(exec);
475 if (exec->hadException())
476 return jsUndefined();
477
478 unsigned height = args.at(5).toInt32(exec);
479 if (exec->hadException())
480 return jsUndefined();
481
482 unsigned format = args.at(6).toInt32(exec);
483 if (exec->hadException())
484 return jsUndefined();
485
486 unsigned type = args.at(7).toInt32(exec);
487 if (exec->hadException())
488 return jsUndefined();
489
490 JSValue value = args.at(8);
491 if (!value.isObject())
492 context->texSubImage2D(target, level, xoff, yoff, width, height, format, type, 0, ec);
493 else {
494 o = asObject(value);
495
496 if (o->inherits(&JSWebGLArray::s_info)) {
497 WebGLArray* obj = static_cast<WebGLArray*>(static_cast<JSWebGLArray*>(o)->impl());
498 context->texSubImage2D(target, level, xoff, yoff, width, height, format, type, obj, ec);
499 } else
500 return throwError(exec, TypeError);
501 }
502 }
503
504 setDOMException(exec, ec);
505 return jsUndefined();
506 }
507
508 template<typename T, size_t inlineCapacity>
toVector(JSC::ExecState * exec,JSC::JSValue value,Vector<T,inlineCapacity> & vector)509 bool toVector(JSC::ExecState* exec, JSC::JSValue value, Vector<T, inlineCapacity>& vector)
510 {
511 if (!value.isObject())
512 return false;
513
514 JSC::JSObject* object = asObject(value);
515 int32_t length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
516 vector.resize(length);
517
518 for (int32_t i = 0; i < length; ++i) {
519 JSC::JSValue v = object->get(exec, i);
520 if (exec->hadException())
521 return false;
522 vector[i] = static_cast<T>(v.toNumber(exec));
523 }
524
525 return true;
526 }
527
528 enum DataFunctionToCall {
529 f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v,
530 f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v
531 };
532
533 enum DataFunctionMatrixToCall {
534 f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv
535 };
536
functionForUniform(DataFunctionToCall f)537 static bool functionForUniform(DataFunctionToCall f)
538 {
539 switch (f) {
540 case f_uniform1v:
541 case f_uniform2v:
542 case f_uniform3v:
543 case f_uniform4v:
544 return true;
545 break;
546 default: break;
547 }
548 return false;
549 }
550
dataFunctionf(DataFunctionToCall f,JSC::ExecState * exec,const JSC::ArgList & args,WebGLRenderingContext * context)551 static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context)
552 {
553 if (args.size() != 2)
554 return throwError(exec, SyntaxError);
555
556 WebGLUniformLocation* location = 0;
557 long index = -1;
558
559 if (functionForUniform(f))
560 location = toWebGLUniformLocation(args.at(0));
561 else
562 index = args.at(0).toInt32(exec);
563
564 if (exec->hadException())
565 return jsUndefined();
566
567 RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(1));
568 if (exec->hadException())
569 return jsUndefined();
570
571 ExceptionCode ec = 0;
572 if (webGLArray) {
573 switch (f) {
574 case f_uniform1v:
575 context->uniform1fv(location, webGLArray.get(), ec);
576 break;
577 case f_uniform2v:
578 context->uniform2fv(location, webGLArray.get(), ec);
579 break;
580 case f_uniform3v:
581 context->uniform3fv(location, webGLArray.get(), ec);
582 break;
583 case f_uniform4v:
584 context->uniform4fv(location, webGLArray.get(), ec);
585 break;
586 case f_vertexAttrib1v:
587 context->vertexAttrib1fv(index, webGLArray.get());
588 break;
589 case f_vertexAttrib2v:
590 context->vertexAttrib2fv(index, webGLArray.get());
591 break;
592 case f_vertexAttrib3v:
593 context->vertexAttrib3fv(index, webGLArray.get());
594 break;
595 case f_vertexAttrib4v:
596 context->vertexAttrib4fv(index, webGLArray.get());
597 break;
598 }
599
600 setDOMException(exec, ec);
601 return jsUndefined();
602 }
603
604 Vector<float, 64> array;
605 if (!toVector(exec, args.at(1), array))
606 return throwError(exec, TypeError);
607
608 switch (f) {
609 case f_uniform1v:
610 context->uniform1fv(location, array.data(), array.size(), ec);
611 break;
612 case f_uniform2v:
613 context->uniform2fv(location, array.data(), array.size(), ec);
614 break;
615 case f_uniform3v:
616 context->uniform3fv(location, array.data(), array.size(), ec);
617 break;
618 case f_uniform4v:
619 context->uniform4fv(location, array.data(), array.size(), ec);
620 break;
621 case f_vertexAttrib1v:
622 context->vertexAttrib1fv(index, array.data(), array.size());
623 break;
624 case f_vertexAttrib2v:
625 context->vertexAttrib2fv(index, array.data(), array.size());
626 break;
627 case f_vertexAttrib3v:
628 context->vertexAttrib3fv(index, array.data(), array.size());
629 break;
630 case f_vertexAttrib4v:
631 context->vertexAttrib4fv(index, array.data(), array.size());
632 break;
633 }
634
635 setDOMException(exec, ec);
636 return jsUndefined();
637 }
638
dataFunctioni(DataFunctionToCall f,JSC::ExecState * exec,const JSC::ArgList & args,WebGLRenderingContext * context)639 static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context)
640 {
641 if (args.size() != 2)
642 return throwError(exec, SyntaxError);
643
644 WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0));
645
646 if (exec->hadException())
647 return jsUndefined();
648
649 RefPtr<WebGLIntArray> webGLArray = toWebGLIntArray(args.at(1));
650 if (exec->hadException())
651 return jsUndefined();
652
653 ExceptionCode ec = 0;
654 if (webGLArray) {
655 switch (f) {
656 case f_uniform1v:
657 context->uniform1iv(location, webGLArray.get(), ec);
658 break;
659 case f_uniform2v:
660 context->uniform2iv(location, webGLArray.get(), ec);
661 break;
662 case f_uniform3v:
663 context->uniform3iv(location, webGLArray.get(), ec);
664 break;
665 case f_uniform4v:
666 context->uniform4iv(location, webGLArray.get(), ec);
667 break;
668 default:
669 break;
670 }
671
672 setDOMException(exec, ec);
673 return jsUndefined();
674 }
675
676
677 Vector<int, 64> array;
678 if (!toVector(exec, args.at(1), array))
679 return throwError(exec, TypeError);
680
681 switch (f) {
682 case f_uniform1v:
683 context->uniform1iv(location, array.data(), array.size(), ec);
684 break;
685 case f_uniform2v:
686 context->uniform2iv(location, array.data(), array.size(), ec);
687 break;
688 case f_uniform3v:
689 context->uniform3iv(location, array.data(), array.size(), ec);
690 break;
691 case f_uniform4v:
692 context->uniform4iv(location, array.data(), array.size(), ec);
693 break;
694 default:
695 break;
696 }
697
698 setDOMException(exec, ec);
699 return jsUndefined();
700 }
701
dataFunctionMatrix(DataFunctionMatrixToCall f,JSC::ExecState * exec,const JSC::ArgList & args,WebGLRenderingContext * context)702 static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context)
703 {
704 if (args.size() != 3)
705 return throwError(exec, SyntaxError);
706
707 WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0));
708
709 if (exec->hadException())
710 return jsUndefined();
711
712 bool transpose = args.at(1).toBoolean(exec);
713 if (exec->hadException())
714 return jsUndefined();
715
716 RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(2));
717 if (exec->hadException())
718 return jsUndefined();
719
720 ExceptionCode ec = 0;
721 if (webGLArray) {
722 switch (f) {
723 case f_uniformMatrix2fv:
724 context->uniformMatrix2fv(location, transpose, webGLArray.get(), ec);
725 break;
726 case f_uniformMatrix3fv:
727 context->uniformMatrix3fv(location, transpose, webGLArray.get(), ec);
728 break;
729 case f_uniformMatrix4fv:
730 context->uniformMatrix4fv(location, transpose, webGLArray.get(), ec);
731 break;
732 }
733
734 setDOMException(exec, ec);
735 return jsUndefined();
736 }
737
738 Vector<float, 64> array;
739 if (!toVector(exec, args.at(2), array))
740 return throwError(exec, TypeError);
741
742 switch (f) {
743 case f_uniformMatrix2fv:
744 context->uniformMatrix2fv(location, transpose, array.data(), array.size(), ec);
745 break;
746 case f_uniformMatrix3fv:
747 context->uniformMatrix3fv(location, transpose, array.data(), array.size(), ec);
748 break;
749 case f_uniformMatrix4fv:
750 context->uniformMatrix4fv(location, transpose, array.data(), array.size(), ec);
751 break;
752 }
753
754 setDOMException(exec, ec);
755 return jsUndefined();
756 }
757
uniform1fv(JSC::ExecState * exec,const JSC::ArgList & args)758 JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args)
759 {
760 return dataFunctionf(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
761 }
762
uniform1iv(JSC::ExecState * exec,const JSC::ArgList & args)763 JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args)
764 {
765 return dataFunctioni(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
766 }
767
uniform2fv(JSC::ExecState * exec,const JSC::ArgList & args)768 JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args)
769 {
770 return dataFunctionf(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
771 }
772
uniform2iv(JSC::ExecState * exec,const JSC::ArgList & args)773 JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args)
774 {
775 return dataFunctioni(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
776 }
777
uniform3fv(JSC::ExecState * exec,const JSC::ArgList & args)778 JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args)
779 {
780 return dataFunctionf(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
781 }
782
uniform3iv(JSC::ExecState * exec,const JSC::ArgList & args)783 JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args)
784 {
785 return dataFunctioni(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
786 }
787
uniform4fv(JSC::ExecState * exec,const JSC::ArgList & args)788 JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args)
789 {
790 return dataFunctionf(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
791 }
792
uniform4iv(JSC::ExecState * exec,const JSC::ArgList & args)793 JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args)
794 {
795 return dataFunctioni(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
796 }
797
uniformMatrix2fv(JSC::ExecState * exec,const JSC::ArgList & args)798 JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args)
799 {
800 return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<WebGLRenderingContext*>(impl()));
801 }
802
uniformMatrix3fv(JSC::ExecState * exec,const JSC::ArgList & args)803 JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args)
804 {
805 return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<WebGLRenderingContext*>(impl()));
806 }
807
uniformMatrix4fv(JSC::ExecState * exec,const JSC::ArgList & args)808 JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args)
809 {
810 return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<WebGLRenderingContext*>(impl()));
811 }
812
vertexAttrib1fv(JSC::ExecState * exec,const JSC::ArgList & args)813 JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args)
814 {
815 return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
816 }
817
vertexAttrib2fv(JSC::ExecState * exec,const JSC::ArgList & args)818 JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args)
819 {
820 return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
821 }
822
vertexAttrib3fv(JSC::ExecState * exec,const JSC::ArgList & args)823 JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args)
824 {
825 return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
826 }
827
vertexAttrib4fv(JSC::ExecState * exec,const JSC::ArgList & args)828 JSC::JSValue JSWebGLRenderingContext::vertexAttrib4fv(JSC::ExecState* exec, const JSC::ArgList& args)
829 {
830 return dataFunctionf(f_vertexAttrib4v, exec, args, static_cast<WebGLRenderingContext*>(impl()));
831 }
832
833 } // namespace WebCore
834
835 #endif // ENABLE(3D_CANVAS)
836