• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(WEBGL)
29 
30 #include "JSWebGLRenderingContext.h"
31 
32 #include "WebKitLoseContext.h"
33 #include "ExceptionCode.h"
34 #include "HTMLCanvasElement.h"
35 #include "HTMLImageElement.h"
36 #include "JSWebKitLoseContext.h"
37 #include "JSHTMLCanvasElement.h"
38 #include "JSHTMLImageElement.h"
39 #include "JSImageData.h"
40 #include "JSOESStandardDerivatives.h"
41 #include "JSOESTextureFloat.h"
42 #include "JSOESVertexArrayObject.h"
43 #include "JSWebGLVertexArrayObjectOES.h"
44 #include "JSWebGLBuffer.h"
45 #include "JSFloat32Array.h"
46 #include "JSWebGLFramebuffer.h"
47 #include "JSInt32Array.h"
48 #include "JSWebGLProgram.h"
49 #include "JSWebGLRenderbuffer.h"
50 #include "JSWebGLShader.h"
51 #include "JSWebGLTexture.h"
52 #include "JSWebGLUniformLocation.h"
53 #include "JSUint8Array.h"
54 #include "JSWebKitCSSMatrix.h"
55 #include "NotImplemented.h"
56 #include "OESStandardDerivatives.h"
57 #include "OESTextureFloat.h"
58 #include "OESVertexArrayObject.h"
59 #include "WebGLVertexArrayObjectOES.h"
60 #include "WebGLBuffer.h"
61 #include "Float32Array.h"
62 #include "WebGLExtension.h"
63 #include "WebGLFramebuffer.h"
64 #include "WebGLGetInfo.h"
65 #include "Int32Array.h"
66 #include "WebGLProgram.h"
67 #include "WebGLRenderingContext.h"
68 #include <runtime/Error.h>
69 #include <runtime/JSArray.h>
70 #include <wtf/FastMalloc.h>
71 #include <wtf/OwnFastMallocPtr.h>
72 
73 #if ENABLE(VIDEO)
74 #include "HTMLVideoElement.h"
75 #include "JSHTMLVideoElement.h"
76 #endif
77 
78 using namespace JSC;
79 
80 namespace WebCore {
81 
toJS(ExecState * exec,JSDOMGlobalObject * globalObject,const WebGLGetInfo & info)82 static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, const WebGLGetInfo& info)
83 {
84     switch (info.getType()) {
85     case WebGLGetInfo::kTypeBool:
86         return jsBoolean(info.getBool());
87     case WebGLGetInfo::kTypeBoolArray: {
88         MarkedArgumentBuffer list;
89         const Vector<bool>& value = info.getBoolArray();
90         for (size_t ii = 0; ii < value.size(); ++ii)
91             list.append(jsBoolean(value[ii]));
92         return constructArray(exec, list);
93     }
94     case WebGLGetInfo::kTypeFloat:
95         return jsNumber(info.getFloat());
96     case WebGLGetInfo::kTypeInt:
97         return jsNumber(info.getInt());
98     case WebGLGetInfo::kTypeNull:
99         return jsNull();
100     case WebGLGetInfo::kTypeString:
101         return jsString(exec, info.getString());
102     case WebGLGetInfo::kTypeUnsignedInt:
103         return jsNumber(info.getUnsignedInt());
104     case WebGLGetInfo::kTypeWebGLBuffer:
105         return toJS(exec, globalObject, info.getWebGLBuffer());
106     case WebGLGetInfo::kTypeWebGLFloatArray:
107         return toJS(exec, globalObject, info.getWebGLFloatArray());
108     case WebGLGetInfo::kTypeWebGLFramebuffer:
109         return toJS(exec, globalObject, info.getWebGLFramebuffer());
110     case WebGLGetInfo::kTypeWebGLIntArray:
111         return toJS(exec, globalObject, info.getWebGLIntArray());
112     // FIXME: implement WebGLObjectArray
113     // case WebGLGetInfo::kTypeWebGLObjectArray:
114     case WebGLGetInfo::kTypeWebGLProgram:
115         return toJS(exec, globalObject, info.getWebGLProgram());
116     case WebGLGetInfo::kTypeWebGLRenderbuffer:
117         return toJS(exec, globalObject, info.getWebGLRenderbuffer());
118     case WebGLGetInfo::kTypeWebGLTexture:
119         return toJS(exec, globalObject, info.getWebGLTexture());
120     case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
121         return toJS(exec, globalObject, info.getWebGLUnsignedByteArray());
122     case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
123         return toJS(exec, globalObject, info.getWebGLVertexArrayObjectOES());
124     default:
125         notImplemented();
126         return jsUndefined();
127     }
128 }
129 
130 enum ObjectType {
131     kBuffer, kRenderbuffer, kTexture, kVertexAttrib
132 };
133 
getObjectParameter(JSWebGLRenderingContext * obj,ExecState * exec,ObjectType objectType)134 static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, ObjectType objectType)
135 {
136     if (exec->argumentCount() != 2)
137         return throwSyntaxError(exec);
138 
139     ExceptionCode ec = 0;
140     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl());
141     unsigned target = exec->argument(0).toInt32(exec);
142     if (exec->hadException())
143         return jsUndefined();
144     unsigned pname = exec->argument(1).toInt32(exec);
145     if (exec->hadException())
146         return jsUndefined();
147     WebGLGetInfo info;
148     switch (objectType) {
149     case kBuffer:
150         info = context->getBufferParameter(target, pname, ec);
151         break;
152     case kRenderbuffer:
153         info = context->getRenderbufferParameter(target, pname, ec);
154         break;
155     case kTexture:
156         info = context->getTexParameter(target, pname, ec);
157         break;
158     case kVertexAttrib:
159         // target => index
160         info = context->getVertexAttrib(target, pname, ec);
161         break;
162     default:
163         notImplemented();
164         break;
165     }
166     if (ec) {
167         setDOMException(exec, ec);
168         return jsUndefined();
169     }
170     return toJS(exec, obj->globalObject(), info);
171 }
172 
173 enum WhichProgramCall {
174     kProgramParameter, kUniform
175 };
176 
toJS(ExecState * exec,JSDOMGlobalObject * globalObject,WebGLExtension * extension)177 static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, WebGLExtension* extension)
178 {
179     if (!extension)
180         return jsNull();
181     switch (extension->getName()) {
182     case WebGLExtension::WebKitLoseContextName:
183         return toJS(exec, globalObject, static_cast<WebKitLoseContext*>(extension));
184     case WebGLExtension::OESStandardDerivativesName:
185         return toJS(exec, globalObject, static_cast<OESStandardDerivatives*>(extension));
186     case WebGLExtension::OESTextureFloatName:
187         return toJS(exec, globalObject, static_cast<OESTextureFloat*>(extension));
188     case WebGLExtension::OESVertexArrayObjectName:
189         return toJS(exec, globalObject, static_cast<OESVertexArrayObject*>(extension));
190     }
191     ASSERT_NOT_REACHED();
192     return jsNull();
193 }
194 
markChildren(MarkStack & markStack)195 void JSWebGLRenderingContext::markChildren(MarkStack& markStack)
196 {
197     Base::markChildren(markStack);
198 
199     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
200     for (int i = 0; i < context->getNumberOfExtensions(); ++i)
201         markDOMObjectWrapper(markStack, *Heap::heap(this)->globalData(), context->getExtensionNumber(i));
202 }
203 
getAttachedShaders(ExecState * exec)204 JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec)
205 {
206     if (exec->argumentCount() < 1)
207         return throwSyntaxError(exec);
208     ExceptionCode ec = 0;
209     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
210     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
211         return throwTypeError(exec);
212     WebGLProgram* program = toWebGLProgram(exec->argument(0));
213     if (exec->hadException())
214         return jsNull();
215     Vector<WebGLShader*> shaders;
216     bool succeed = context->getAttachedShaders(program, shaders, ec);
217     if (ec) {
218         setDOMException(exec, ec);
219         return jsNull();
220     }
221     if (!succeed)
222         return jsNull();
223     MarkedArgumentBuffer list;
224     for (size_t ii = 0; ii < shaders.size(); ++ii)
225         list.append(toJS(exec, globalObject(), shaders[ii]));
226     return constructArray(exec, list);
227 }
228 
getExtension(ExecState * exec)229 JSValue JSWebGLRenderingContext::getExtension(ExecState* exec)
230 {
231     if (exec->argumentCount() < 1)
232         return throwSyntaxError(exec);
233 
234     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
235     const String& name = ustringToString(exec->argument(0).toString(exec));
236     if (exec->hadException())
237         return jsUndefined();
238     WebGLExtension* extension = context->getExtension(name);
239     return toJS(exec, globalObject(), extension);
240 }
241 
getBufferParameter(ExecState * exec)242 JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec)
243 {
244     return getObjectParameter(this, exec, kBuffer);
245 }
246 
getFramebufferAttachmentParameter(ExecState * exec)247 JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec)
248 {
249     if (exec->argumentCount() != 3)
250         return throwSyntaxError(exec);
251 
252     ExceptionCode ec = 0;
253     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
254     unsigned target = exec->argument(0).toInt32(exec);
255     if (exec->hadException())
256         return jsUndefined();
257     unsigned attachment = exec->argument(1).toInt32(exec);
258     if (exec->hadException())
259         return jsUndefined();
260     unsigned pname = exec->argument(2).toInt32(exec);
261     if (exec->hadException())
262         return jsUndefined();
263     WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec);
264     if (ec) {
265         setDOMException(exec, ec);
266         return jsUndefined();
267     }
268     return toJS(exec, globalObject(), info);
269 }
270 
getParameter(ExecState * exec)271 JSValue JSWebGLRenderingContext::getParameter(ExecState* exec)
272 {
273     if (exec->argumentCount() != 1)
274         return throwSyntaxError(exec);
275 
276     ExceptionCode ec = 0;
277     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
278     unsigned pname = exec->argument(0).toInt32(exec);
279     if (exec->hadException())
280         return jsUndefined();
281     WebGLGetInfo info = context->getParameter(pname, ec);
282     if (ec) {
283         setDOMException(exec, ec);
284         return jsUndefined();
285     }
286     return toJS(exec, globalObject(), info);
287 }
288 
getProgramParameter(ExecState * exec)289 JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec)
290 {
291     if (exec->argumentCount() != 2)
292         return throwSyntaxError(exec);
293 
294     ExceptionCode ec = 0;
295     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
296     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
297         return throwTypeError(exec);
298     WebGLProgram* program = toWebGLProgram(exec->argument(0));
299     unsigned pname = exec->argument(1).toInt32(exec);
300     if (exec->hadException())
301         return jsUndefined();
302     WebGLGetInfo info = context->getProgramParameter(program, pname, ec);
303     if (ec) {
304         setDOMException(exec, ec);
305         return jsUndefined();
306     }
307     return toJS(exec, globalObject(), info);
308 }
309 
getRenderbufferParameter(ExecState * exec)310 JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec)
311 {
312     return getObjectParameter(this, exec, kRenderbuffer);
313 }
314 
getShaderParameter(ExecState * exec)315 JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec)
316 {
317     if (exec->argumentCount() != 2)
318         return throwSyntaxError(exec);
319 
320     ExceptionCode ec = 0;
321     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
322     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLShader::s_info))
323         return throwTypeError(exec);
324     WebGLShader* shader = toWebGLShader(exec->argument(0));
325     unsigned pname = exec->argument(1).toInt32(exec);
326     if (exec->hadException())
327         return jsUndefined();
328     WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
329     if (ec) {
330         setDOMException(exec, ec);
331         return jsUndefined();
332     }
333     return toJS(exec, globalObject(), info);
334 }
335 
getSupportedExtensions(ExecState * exec)336 JSValue JSWebGLRenderingContext::getSupportedExtensions(ExecState* exec)
337 {
338     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
339     if (context->isContextLost())
340         return jsNull();
341     Vector<String> value = context->getSupportedExtensions();
342     MarkedArgumentBuffer list;
343     for (size_t ii = 0; ii < value.size(); ++ii)
344         list.append(jsString(exec, value[ii]));
345     return constructArray(exec, list);
346 }
347 
getTexParameter(ExecState * exec)348 JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec)
349 {
350     return getObjectParameter(this, exec, kTexture);
351 }
352 
getUniform(ExecState * exec)353 JSValue JSWebGLRenderingContext::getUniform(ExecState* exec)
354 {
355     if (exec->argumentCount() != 2)
356         return throwSyntaxError(exec);
357 
358     ExceptionCode ec = 0;
359     WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
360     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
361         return throwTypeError(exec);
362     WebGLProgram* program = toWebGLProgram(exec->argument(0));
363     if (exec->argumentCount() > 1 && !exec->argument(1).isUndefinedOrNull() && !exec->argument(1).inherits(&JSWebGLUniformLocation::s_info))
364         return throwTypeError(exec);
365     WebGLUniformLocation* loc = toWebGLUniformLocation(exec->argument(1));
366     if (exec->hadException())
367         return jsUndefined();
368     WebGLGetInfo info = context->getUniform(program, loc, ec);
369     if (ec) {
370         setDOMException(exec, ec);
371         return jsUndefined();
372     }
373     return toJS(exec, globalObject(), info);
374 }
375 
getVertexAttrib(ExecState * exec)376 JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec)
377 {
378     return getObjectParameter(this, exec, kVertexAttrib);
379 }
380 
381 template<typename T, size_t inlineCapacity>
toVector(JSC::ExecState * exec,JSC::JSValue value,Vector<T,inlineCapacity> & vector)382 bool toVector(JSC::ExecState* exec, JSC::JSValue value, Vector<T, inlineCapacity>& vector)
383 {
384     if (!value.isObject())
385         return false;
386 
387     JSC::JSObject* object = asObject(value);
388     int32_t length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
389     vector.resize(length);
390 
391     for (int32_t i = 0; i < length; ++i) {
392         JSC::JSValue v = object->get(exec, i);
393         if (exec->hadException())
394             return false;
395         vector[i] = static_cast<T>(v.toNumber(exec));
396     }
397 
398     return true;
399 }
400 
401 enum DataFunctionToCall {
402     f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v,
403     f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v
404 };
405 
406 enum DataFunctionMatrixToCall {
407     f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv
408 };
409 
functionForUniform(DataFunctionToCall f)410 static bool functionForUniform(DataFunctionToCall f)
411 {
412     switch (f) {
413     case f_uniform1v:
414     case f_uniform2v:
415     case f_uniform3v:
416     case f_uniform4v:
417         return true;
418         break;
419     default: break;
420     }
421     return false;
422 }
423 
dataFunctionf(DataFunctionToCall f,JSC::ExecState * exec,WebGLRenderingContext * context)424 static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext* context)
425 {
426     if (exec->argumentCount() != 2)
427         return throwSyntaxError(exec);
428 
429     WebGLUniformLocation* location = 0;
430     long index = -1;
431 
432     if (functionForUniform(f)) {
433         if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
434             return throwTypeError(exec);
435         location = toWebGLUniformLocation(exec->argument(0));
436     } else
437         index = exec->argument(0).toInt32(exec);
438 
439     if (exec->hadException())
440         return jsUndefined();
441 
442     RefPtr<Float32Array> webGLArray = toFloat32Array(exec->argument(1));
443     if (exec->hadException())
444         return jsUndefined();
445 
446     ExceptionCode ec = 0;
447     if (webGLArray) {
448         switch (f) {
449         case f_uniform1v:
450             context->uniform1fv(location, webGLArray.get(), ec);
451             break;
452         case f_uniform2v:
453             context->uniform2fv(location, webGLArray.get(), ec);
454             break;
455         case f_uniform3v:
456             context->uniform3fv(location, webGLArray.get(), ec);
457             break;
458         case f_uniform4v:
459             context->uniform4fv(location, webGLArray.get(), ec);
460             break;
461         case f_vertexAttrib1v:
462             context->vertexAttrib1fv(index, webGLArray.get());
463             break;
464         case f_vertexAttrib2v:
465             context->vertexAttrib2fv(index, webGLArray.get());
466             break;
467         case f_vertexAttrib3v:
468             context->vertexAttrib3fv(index, webGLArray.get());
469             break;
470         case f_vertexAttrib4v:
471             context->vertexAttrib4fv(index, webGLArray.get());
472             break;
473         }
474 
475         setDOMException(exec, ec);
476         return jsUndefined();
477     }
478 
479     Vector<float, 64> array;
480     if (!toVector(exec, exec->argument(1), array))
481         return throwTypeError(exec);
482 
483     switch (f) {
484     case f_uniform1v:
485         context->uniform1fv(location, array.data(), array.size(), ec);
486         break;
487     case f_uniform2v:
488         context->uniform2fv(location, array.data(), array.size(), ec);
489         break;
490     case f_uniform3v:
491         context->uniform3fv(location, array.data(), array.size(), ec);
492         break;
493     case f_uniform4v:
494         context->uniform4fv(location, array.data(), array.size(), ec);
495         break;
496     case f_vertexAttrib1v:
497         context->vertexAttrib1fv(index, array.data(), array.size());
498         break;
499     case f_vertexAttrib2v:
500         context->vertexAttrib2fv(index, array.data(), array.size());
501         break;
502     case f_vertexAttrib3v:
503         context->vertexAttrib3fv(index, array.data(), array.size());
504         break;
505     case f_vertexAttrib4v:
506         context->vertexAttrib4fv(index, array.data(), array.size());
507         break;
508     }
509 
510     setDOMException(exec, ec);
511     return jsUndefined();
512 }
513 
dataFunctioni(DataFunctionToCall f,JSC::ExecState * exec,WebGLRenderingContext * context)514 static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext* context)
515 {
516     if (exec->argumentCount() != 2)
517         return throwSyntaxError(exec);
518 
519     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
520         return throwTypeError(exec);
521     WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0));
522 
523     if (exec->hadException())
524         return jsUndefined();
525 
526     RefPtr<Int32Array> webGLArray = toInt32Array(exec->argument(1));
527     if (exec->hadException())
528         return jsUndefined();
529 
530     ExceptionCode ec = 0;
531     if (webGLArray) {
532         switch (f) {
533         case f_uniform1v:
534             context->uniform1iv(location, webGLArray.get(), ec);
535             break;
536         case f_uniform2v:
537             context->uniform2iv(location, webGLArray.get(), ec);
538             break;
539         case f_uniform3v:
540             context->uniform3iv(location, webGLArray.get(), ec);
541             break;
542         case f_uniform4v:
543             context->uniform4iv(location, webGLArray.get(), ec);
544             break;
545         default:
546             break;
547         }
548 
549         setDOMException(exec, ec);
550         return jsUndefined();
551     }
552 
553 
554     Vector<int, 64> array;
555     if (!toVector(exec, exec->argument(1), array))
556         return throwTypeError(exec);
557 
558     switch (f) {
559     case f_uniform1v:
560         context->uniform1iv(location, array.data(), array.size(), ec);
561         break;
562     case f_uniform2v:
563         context->uniform2iv(location, array.data(), array.size(), ec);
564         break;
565     case f_uniform3v:
566         context->uniform3iv(location, array.data(), array.size(), ec);
567         break;
568     case f_uniform4v:
569         context->uniform4iv(location, array.data(), array.size(), ec);
570         break;
571     default:
572         break;
573     }
574 
575     setDOMException(exec, ec);
576     return jsUndefined();
577 }
578 
dataFunctionMatrix(DataFunctionMatrixToCall f,JSC::ExecState * exec,WebGLRenderingContext * context)579 static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, WebGLRenderingContext* context)
580 {
581     if (exec->argumentCount() != 3)
582         return throwSyntaxError(exec);
583 
584     if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
585         return throwTypeError(exec);
586     WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0));
587 
588     if (exec->hadException())
589         return jsUndefined();
590 
591     bool transpose = exec->argument(1).toBoolean(exec);
592     if (exec->hadException())
593         return jsUndefined();
594 
595     RefPtr<Float32Array> webGLArray = toFloat32Array(exec->argument(2));
596     if (exec->hadException())
597         return jsUndefined();
598 
599     ExceptionCode ec = 0;
600     if (webGLArray) {
601         switch (f) {
602         case f_uniformMatrix2fv:
603             context->uniformMatrix2fv(location, transpose, webGLArray.get(), ec);
604             break;
605         case f_uniformMatrix3fv:
606             context->uniformMatrix3fv(location, transpose, webGLArray.get(), ec);
607             break;
608         case f_uniformMatrix4fv:
609             context->uniformMatrix4fv(location, transpose, webGLArray.get(), ec);
610             break;
611         }
612 
613         setDOMException(exec, ec);
614         return jsUndefined();
615     }
616 
617     Vector<float, 64> array;
618     if (!toVector(exec, exec->argument(2), array))
619         return throwTypeError(exec);
620 
621     switch (f) {
622     case f_uniformMatrix2fv:
623         context->uniformMatrix2fv(location, transpose, array.data(), array.size(), ec);
624         break;
625     case f_uniformMatrix3fv:
626         context->uniformMatrix3fv(location, transpose, array.data(), array.size(), ec);
627         break;
628     case f_uniformMatrix4fv:
629         context->uniformMatrix4fv(location, transpose, array.data(), array.size(), ec);
630         break;
631     }
632 
633     setDOMException(exec, ec);
634     return jsUndefined();
635 }
636 
uniform1fv(JSC::ExecState * exec)637 JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec)
638 {
639     return dataFunctionf(f_uniform1v, exec, static_cast<WebGLRenderingContext*>(impl()));
640 }
641 
uniform1iv(JSC::ExecState * exec)642 JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec)
643 {
644     return dataFunctioni(f_uniform1v, exec, static_cast<WebGLRenderingContext*>(impl()));
645 }
646 
uniform2fv(JSC::ExecState * exec)647 JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec)
648 {
649     return dataFunctionf(f_uniform2v, exec, static_cast<WebGLRenderingContext*>(impl()));
650 }
651 
uniform2iv(JSC::ExecState * exec)652 JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec)
653 {
654     return dataFunctioni(f_uniform2v, exec, static_cast<WebGLRenderingContext*>(impl()));
655 }
656 
uniform3fv(JSC::ExecState * exec)657 JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec)
658 {
659     return dataFunctionf(f_uniform3v, exec, static_cast<WebGLRenderingContext*>(impl()));
660 }
661 
uniform3iv(JSC::ExecState * exec)662 JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec)
663 {
664     return dataFunctioni(f_uniform3v, exec, static_cast<WebGLRenderingContext*>(impl()));
665 }
666 
uniform4fv(JSC::ExecState * exec)667 JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec)
668 {
669     return dataFunctionf(f_uniform4v, exec, static_cast<WebGLRenderingContext*>(impl()));
670 }
671 
uniform4iv(JSC::ExecState * exec)672 JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec)
673 {
674     return dataFunctioni(f_uniform4v, exec, static_cast<WebGLRenderingContext*>(impl()));
675 }
676 
uniformMatrix2fv(JSC::ExecState * exec)677 JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec)
678 {
679     return dataFunctionMatrix(f_uniformMatrix2fv, exec, static_cast<WebGLRenderingContext*>(impl()));
680 }
681 
uniformMatrix3fv(JSC::ExecState * exec)682 JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec)
683 {
684     return dataFunctionMatrix(f_uniformMatrix3fv, exec, static_cast<WebGLRenderingContext*>(impl()));
685 }
686 
uniformMatrix4fv(JSC::ExecState * exec)687 JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec)
688 {
689     return dataFunctionMatrix(f_uniformMatrix4fv, exec, static_cast<WebGLRenderingContext*>(impl()));
690 }
691 
vertexAttrib1fv(JSC::ExecState * exec)692 JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec)
693 {
694     return dataFunctionf(f_vertexAttrib1v, exec, static_cast<WebGLRenderingContext*>(impl()));
695 }
696 
vertexAttrib2fv(JSC::ExecState * exec)697 JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec)
698 {
699     return dataFunctionf(f_vertexAttrib2v, exec, static_cast<WebGLRenderingContext*>(impl()));
700 }
701 
vertexAttrib3fv(JSC::ExecState * exec)702 JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec)
703 {
704     return dataFunctionf(f_vertexAttrib3v, exec, static_cast<WebGLRenderingContext*>(impl()));
705 }
706 
vertexAttrib4fv(JSC::ExecState * exec)707 JSC::JSValue JSWebGLRenderingContext::vertexAttrib4fv(JSC::ExecState* exec)
708 {
709     return dataFunctionf(f_vertexAttrib4v, exec, static_cast<WebGLRenderingContext*>(impl()));
710 }
711 
712 } // namespace WebCore
713 
714 #endif // ENABLE(WEBGL)
715