Home | History | Annotate | Download | only in js
      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 
     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 
    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 
    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 
    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 
    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 
    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 
    242 JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec)
    243 {
    244     return getObjectParameter(this, exec, kBuffer);
    245 }
    246 
    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 
    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 
    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 
    310 JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec)
    311 {
    312     return getObjectParameter(this, exec, kRenderbuffer);
    313 }
    314 
    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 
    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 
    348 JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec)
    349 {
    350     return getObjectParameter(this, exec, kTexture);
    351 }
    352 
    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 
    376 JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec)
    377 {
    378     return getObjectParameter(this, exec, kVertexAttrib);
    379 }
    380 
    381 template<typename T, size_t inlineCapacity>
    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 
    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 
    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 
    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 
    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 
    637 JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec)
    638 {
    639     return dataFunctionf(f_uniform1v, exec, static_cast<WebGLRenderingContext*>(impl()));
    640 }
    641 
    642 JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec)
    643 {
    644     return dataFunctioni(f_uniform1v, exec, static_cast<WebGLRenderingContext*>(impl()));
    645 }
    646 
    647 JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec)
    648 {
    649     return dataFunctionf(f_uniform2v, exec, static_cast<WebGLRenderingContext*>(impl()));
    650 }
    651 
    652 JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec)
    653 {
    654     return dataFunctioni(f_uniform2v, exec, static_cast<WebGLRenderingContext*>(impl()));
    655 }
    656 
    657 JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec)
    658 {
    659     return dataFunctionf(f_uniform3v, exec, static_cast<WebGLRenderingContext*>(impl()));
    660 }
    661 
    662 JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec)
    663 {
    664     return dataFunctioni(f_uniform3v, exec, static_cast<WebGLRenderingContext*>(impl()));
    665 }
    666 
    667 JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec)
    668 {
    669     return dataFunctionf(f_uniform4v, exec, static_cast<WebGLRenderingContext*>(impl()));
    670 }
    671 
    672 JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec)
    673 {
    674     return dataFunctioni(f_uniform4v, exec, static_cast<WebGLRenderingContext*>(impl()));
    675 }
    676 
    677 JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec)
    678 {
    679     return dataFunctionMatrix(f_uniformMatrix2fv, exec, static_cast<WebGLRenderingContext*>(impl()));
    680 }
    681 
    682 JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec)
    683 {
    684     return dataFunctionMatrix(f_uniformMatrix3fv, exec, static_cast<WebGLRenderingContext*>(impl()));
    685 }
    686 
    687 JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec)
    688 {
    689     return dataFunctionMatrix(f_uniformMatrix4fv, exec, static_cast<WebGLRenderingContext*>(impl()));
    690 }
    691 
    692 JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec)
    693 {
    694     return dataFunctionf(f_vertexAttrib1v, exec, static_cast<WebGLRenderingContext*>(impl()));
    695 }
    696 
    697 JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec)
    698 {
    699     return dataFunctionf(f_vertexAttrib2v, exec, static_cast<WebGLRenderingContext*>(impl()));
    700 }
    701 
    702 JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec)
    703 {
    704     return dataFunctionf(f_vertexAttrib3v, exec, static_cast<WebGLRenderingContext*>(impl()));
    705 }
    706 
    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