/* * Copyright (C) 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #if ENABLE(3D_CANVAS) #include "JSWebGLRenderingContext.h" #include "ExceptionCode.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" #include "HTMLVideoElement.h" #include "JSHTMLCanvasElement.h" #include "JSHTMLImageElement.h" #include "JSHTMLVideoElement.h" #include "JSImageData.h" #include "JSWebGLBuffer.h" #include "JSWebGLFloatArray.h" #include "JSWebGLFramebuffer.h" #include "JSWebGLIntArray.h" #include "JSWebGLProgram.h" #include "JSWebGLRenderbuffer.h" #include "JSWebGLShader.h" #include "JSWebGLTexture.h" #include "JSWebGLUniformLocation.h" #include "JSWebGLUnsignedByteArray.h" #include "JSWebKitCSSMatrix.h" #include "NotImplemented.h" #include "WebGLBuffer.h" #include "WebGLFloatArray.h" #include "WebGLFramebuffer.h" #include "WebGLGetInfo.h" #include "WebGLIntArray.h" #include "WebGLProgram.h" #include "WebGLRenderingContext.h" #include <runtime/Error.h> #include <wtf/FastMalloc.h> #include <wtf/OwnFastMallocPtr.h> using namespace JSC; namespace WebCore { JSValue JSWebGLRenderingContext::bufferData(JSC::ExecState* exec, JSC::ArgList const& args) { if (args.size() != 3) return throwError(exec, SyntaxError); unsigned target = args.at(0).toInt32(exec); unsigned usage = args.at(2).toInt32(exec); ExceptionCode ec = 0; // If argument 1 is a number, we are initializing this buffer to that size if (!args.at(1).isObject()) { unsigned int count = args.at(1).toInt32(exec); static_cast<WebGLRenderingContext*>(impl())->bufferData(target, count, usage, ec); } else { WebGLArray* array = toWebGLArray(args.at(1)); static_cast<WebGLRenderingContext*>(impl())->bufferData(target, array, usage, ec); } setDOMException(exec, ec); return jsUndefined(); } JSValue JSWebGLRenderingContext::bufferSubData(JSC::ExecState* exec, JSC::ArgList const& args) { if (args.size() != 3) return throwError(exec, SyntaxError); unsigned target = args.at(0).toInt32(exec); unsigned offset = args.at(1).toInt32(exec); ExceptionCode ec = 0; WebGLArray* array = toWebGLArray(args.at(2)); static_cast<WebGLRenderingContext*>(impl())->bufferSubData(target, offset, array, ec); setDOMException(exec, ec); return jsUndefined(); } static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, const WebGLGetInfo& info) { switch (info.getType()) { case WebGLGetInfo::kTypeBool: return jsBoolean(info.getBool()); case WebGLGetInfo::kTypeFloat: return jsNumber(exec, info.getFloat()); case WebGLGetInfo::kTypeLong: return jsNumber(exec, info.getLong()); case WebGLGetInfo::kTypeNull: return jsNull(); case WebGLGetInfo::kTypeString: return jsString(exec, info.getString()); case WebGLGetInfo::kTypeUnsignedLong: return jsNumber(exec, info.getUnsignedLong()); case WebGLGetInfo::kTypeWebGLBuffer: return toJS(exec, globalObject, info.getWebGLBuffer()); case WebGLGetInfo::kTypeWebGLFloatArray: return toJS(exec, globalObject, info.getWebGLFloatArray()); case WebGLGetInfo::kTypeWebGLFramebuffer: return toJS(exec, globalObject, info.getWebGLFramebuffer()); case WebGLGetInfo::kTypeWebGLIntArray: return toJS(exec, globalObject, info.getWebGLIntArray()); // FIXME: implement WebGLObjectArray // case WebGLGetInfo::kTypeWebGLObjectArray: case WebGLGetInfo::kTypeWebGLProgram: return toJS(exec, globalObject, info.getWebGLProgram()); case WebGLGetInfo::kTypeWebGLRenderbuffer: return toJS(exec, globalObject, info.getWebGLRenderbuffer()); case WebGLGetInfo::kTypeWebGLTexture: return toJS(exec, globalObject, info.getWebGLTexture()); case WebGLGetInfo::kTypeWebGLUnsignedByteArray: return toJS(exec, globalObject, info.getWebGLUnsignedByteArray()); default: notImplemented(); return jsUndefined(); } } enum ObjectType { kBuffer, kRenderbuffer, kTexture, kVertexAttrib }; static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, const ArgList& args, ObjectType objectType) { if (args.size() != 2) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl()); unsigned target = args.at(0).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned pname = args.at(1).toInt32(exec); if (exec->hadException()) return jsUndefined(); WebGLGetInfo info; switch (objectType) { case kBuffer: info = context->getBufferParameter(target, pname, ec); break; case kRenderbuffer: info = context->getRenderbufferParameter(target, pname, ec); break; case kTexture: info = context->getTexParameter(target, pname, ec); break; case kVertexAttrib: // target => index info = context->getVertexAttrib(target, pname, ec); break; default: notImplemented(); break; } if (ec) { setDOMException(exec, ec); return jsUndefined(); } return toJS(exec, obj->globalObject(), info); } enum WhichProgramCall { kProgramParameter, kUniform }; JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec, const ArgList& args) { return getObjectParameter(this, exec, args, kBuffer); } JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec, const ArgList& args) { if (args.size() != 3) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); unsigned target = args.at(0).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned attachment = args.at(1).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned pname = args.at(2).toInt32(exec); if (exec->hadException()) return jsUndefined(); WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec); if (ec) { setDOMException(exec, ec); return jsUndefined(); } return toJS(exec, globalObject(), info); } JSValue JSWebGLRenderingContext::getParameter(ExecState* exec, const ArgList& args) { if (args.size() != 1) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); unsigned pname = args.at(0).toInt32(exec); if (exec->hadException()) return jsUndefined(); WebGLGetInfo info = context->getParameter(pname, ec); if (ec) { setDOMException(exec, ec); return jsUndefined(); } return toJS(exec, globalObject(), info); } JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec, const ArgList& args) { if (args.size() != 2) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); WebGLProgram* program = toWebGLProgram(args.at(0)); unsigned pname = args.at(1).toInt32(exec); if (exec->hadException()) return jsUndefined(); WebGLGetInfo info = context->getProgramParameter(program, pname, ec); if (ec) { setDOMException(exec, ec); return jsUndefined(); } return toJS(exec, globalObject(), info); } JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec, const ArgList& args) { return getObjectParameter(this, exec, args, kRenderbuffer); } JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec, const ArgList& args) { if (args.size() != 2) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); WebGLShader* shader = toWebGLShader(args.at(0)); unsigned pname = args.at(1).toInt32(exec); if (exec->hadException()) return jsUndefined(); WebGLGetInfo info = context->getShaderParameter(shader, pname, ec); if (ec) { setDOMException(exec, ec); return jsUndefined(); } return toJS(exec, globalObject(), info); } JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec, const ArgList& args) { return getObjectParameter(this, exec, args, kTexture); } JSValue JSWebGLRenderingContext::getUniform(ExecState* exec, const ArgList& args) { if (args.size() != 2) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); WebGLProgram* program = toWebGLProgram(args.at(0)); WebGLUniformLocation* loc = toWebGLUniformLocation(args.at(1)); if (exec->hadException()) return jsUndefined(); WebGLGetInfo info = context->getUniform(program, loc, ec); if (ec) { setDOMException(exec, ec); return jsUndefined(); } return toJS(exec, globalObject(), info); } JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec, const ArgList& args) { return getObjectParameter(this, exec, args, kVertexAttrib); } // 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); // void texImage2D(in GLenum target, in GLint level, in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); // void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement canvas, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); // void texImage2D(in GLenum target, in GLint level, in HTMLVideoElement video, [Optional] in GLboolean flipY, [Optional] in premultiplyAlpha); JSValue JSWebGLRenderingContext::texImage2D(ExecState* exec, const ArgList& args) { if (args.size() < 3 || args.size() > 9) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); unsigned target = args.at(0).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned level = args.at(1).toInt32(exec); if (exec->hadException()) return jsUndefined(); JSObject* o = 0; if (args.size() <= 5) { // This is one of the last 4 forms. Param 2 can be ImageData or <img>, <canvas> or <video> element. JSValue value = args.at(2); if (!value.isObject()) return throwError(exec, TypeError); o = asObject(value); bool flipY = args.at(3).toBoolean(exec); bool premultiplyAlpha = args.at(4).toBoolean(exec); if (o->inherits(&JSImageData::s_info)) { ImageData* data = static_cast<ImageData*>(static_cast<JSImageData*>(o)->impl()); context->texImage2D(target, level, data, flipY, premultiplyAlpha, ec); } else if (o->inherits(&JSHTMLImageElement::s_info)) { HTMLImageElement* element = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(o)->impl()); context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLCanvasElement*>(o)->impl()); context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); } else if (o->inherits(&JSHTMLVideoElement::s_info)) { HTMLVideoElement* element = static_cast<HTMLVideoElement*>(static_cast<JSHTMLVideoElement*>(o)->impl()); context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec); } else ec = TYPE_MISMATCH_ERR; } else { if (args.size() != 9) return throwError(exec, SyntaxError); // This must be the WebGLArray case unsigned internalformat = args.at(2).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned width = args.at(3).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned height = args.at(4).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned border = args.at(5).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned format = args.at(6).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned type = args.at(7).toInt32(exec); if (exec->hadException()) return jsUndefined(); JSValue value = args.at(8); // For this case passing 0 (for a null array) is allowed if (value.isNull()) context->texImage2D(target, level, internalformat, width, height, border, format, type, 0, ec); else if (value.isObject()) { o = asObject(value); if (o->inherits(&JSWebGLArray::s_info)) { // FIXME: Need to check to make sure WebGLArray is a WebGLByteArray or WebGLShortArray, // depending on the passed type parameter. WebGLArray* obj = static_cast<WebGLArray*>(static_cast<JSWebGLArray*>(o)->impl()); context->texImage2D(target, level, internalformat, width, height, border, format, type, obj, ec); } else return throwError(exec, TypeError); } else return throwError(exec, TypeError); } setDOMException(exec, ec); return jsUndefined(); } // 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); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in ImageData pixels, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLImageElement image, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLCanvasElement canvas, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); // void texSubImage2D(in GLenum target, in GLint level, in GLint xoffset, in GLint yoffset, in HTMLVideoElement video, [Optional] GLboolean flipY, [Optional] in premultiplyAlpha); JSValue JSWebGLRenderingContext::texSubImage2D(ExecState* exec, const ArgList& args) { if (args.size() < 5 || args.size() > 9) return throwError(exec, SyntaxError); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); unsigned target = args.at(0).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned level = args.at(1).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned xoff = args.at(2).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned yoff = args.at(3).toInt32(exec); if (exec->hadException()) return jsUndefined(); JSObject* o = 0; if (args.size() <= 7) { // This is one of the last 4 forms. Param 4 can be <img>, <canvas> or <video> element, of the format param. JSValue value = args.at(4); if (!value.isObject()) return throwError(exec, SyntaxError); o = asObject(value); bool flipY = args.at(5).toBoolean(exec); bool premultiplyAlpha = args.at(6).toBoolean(exec); if (o->inherits(&JSImageData::s_info)) { ImageData* data = static_cast<ImageData*>(static_cast<JSImageData*>(o)->impl()); context->texSubImage2D(target, level, xoff, yoff, data, flipY, premultiplyAlpha, ec); } else if (o->inherits(&JSHTMLImageElement::s_info)) { HTMLImageElement* element = static_cast<HTMLImageElement*>(static_cast<JSHTMLImageElement*>(o)->impl()); context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec); } else if (o->inherits(&JSHTMLCanvasElement::s_info)) { HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLCanvasElement*>(o)->impl()); context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec); } else if (o->inherits(&JSHTMLVideoElement::s_info)) { HTMLVideoElement* element = static_cast<HTMLVideoElement*>(static_cast<JSHTMLVideoElement*>(o)->impl()); context->texSubImage2D(target, level, xoff, yoff, element, flipY, premultiplyAlpha, ec); } else ec = TYPE_MISMATCH_ERR; } else { // This must be the WebGLArray form if (args.size() != 9) return throwError(exec, SyntaxError); unsigned width = args.at(4).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned height = args.at(5).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned format = args.at(6).toInt32(exec); if (exec->hadException()) return jsUndefined(); unsigned type = args.at(7).toInt32(exec); if (exec->hadException()) return jsUndefined(); JSValue value = args.at(8); if (!value.isObject()) context->texSubImage2D(target, level, xoff, yoff, width, height, format, type, 0, ec); else { o = asObject(value); if (o->inherits(&JSWebGLArray::s_info)) { WebGLArray* obj = static_cast<WebGLArray*>(static_cast<JSWebGLArray*>(o)->impl()); context->texSubImage2D(target, level, xoff, yoff, width, height, format, type, obj, ec); } else return throwError(exec, TypeError); } } setDOMException(exec, ec); return jsUndefined(); } template<typename T, size_t inlineCapacity> bool toVector(JSC::ExecState* exec, JSC::JSValue value, Vector<T, inlineCapacity>& vector) { if (!value.isObject()) return false; JSC::JSObject* object = asObject(value); int32_t length = object->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); vector.resize(length); for (int32_t i = 0; i < length; ++i) { JSC::JSValue v = object->get(exec, i); if (exec->hadException()) return false; vector[i] = static_cast<T>(v.toNumber(exec)); } return true; } enum DataFunctionToCall { f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v }; enum DataFunctionMatrixToCall { f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv }; static bool functionForUniform(DataFunctionToCall f) { switch (f) { case f_uniform1v: case f_uniform2v: case f_uniform3v: case f_uniform4v: return true; break; default: break; } return false; } static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) { if (args.size() != 2) return throwError(exec, SyntaxError); WebGLUniformLocation* location = 0; long index = -1; if (functionForUniform(f)) location = toWebGLUniformLocation(args.at(0)); else index = args.at(0).toInt32(exec); if (exec->hadException()) return jsUndefined(); RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(1)); if (exec->hadException()) return jsUndefined(); ExceptionCode ec = 0; if (webGLArray) { switch (f) { case f_uniform1v: context->uniform1fv(location, webGLArray.get(), ec); break; case f_uniform2v: context->uniform2fv(location, webGLArray.get(), ec); break; case f_uniform3v: context->uniform3fv(location, webGLArray.get(), ec); break; case f_uniform4v: context->uniform4fv(location, webGLArray.get(), ec); break; case f_vertexAttrib1v: context->vertexAttrib1fv(index, webGLArray.get()); break; case f_vertexAttrib2v: context->vertexAttrib2fv(index, webGLArray.get()); break; case f_vertexAttrib3v: context->vertexAttrib3fv(index, webGLArray.get()); break; case f_vertexAttrib4v: context->vertexAttrib4fv(index, webGLArray.get()); break; } setDOMException(exec, ec); return jsUndefined(); } Vector<float, 64> array; if (!toVector(exec, args.at(1), array)) return throwError(exec, TypeError); switch (f) { case f_uniform1v: context->uniform1fv(location, array.data(), array.size(), ec); break; case f_uniform2v: context->uniform2fv(location, array.data(), array.size(), ec); break; case f_uniform3v: context->uniform3fv(location, array.data(), array.size(), ec); break; case f_uniform4v: context->uniform4fv(location, array.data(), array.size(), ec); break; case f_vertexAttrib1v: context->vertexAttrib1fv(index, array.data(), array.size()); break; case f_vertexAttrib2v: context->vertexAttrib2fv(index, array.data(), array.size()); break; case f_vertexAttrib3v: context->vertexAttrib3fv(index, array.data(), array.size()); break; case f_vertexAttrib4v: context->vertexAttrib4fv(index, array.data(), array.size()); break; } setDOMException(exec, ec); return jsUndefined(); } static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) { if (args.size() != 2) return throwError(exec, SyntaxError); WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0)); if (exec->hadException()) return jsUndefined(); RefPtr<WebGLIntArray> webGLArray = toWebGLIntArray(args.at(1)); if (exec->hadException()) return jsUndefined(); ExceptionCode ec = 0; if (webGLArray) { switch (f) { case f_uniform1v: context->uniform1iv(location, webGLArray.get(), ec); break; case f_uniform2v: context->uniform2iv(location, webGLArray.get(), ec); break; case f_uniform3v: context->uniform3iv(location, webGLArray.get(), ec); break; case f_uniform4v: context->uniform4iv(location, webGLArray.get(), ec); break; default: break; } setDOMException(exec, ec); return jsUndefined(); } Vector<int, 64> array; if (!toVector(exec, args.at(1), array)) return throwError(exec, TypeError); switch (f) { case f_uniform1v: context->uniform1iv(location, array.data(), array.size(), ec); break; case f_uniform2v: context->uniform2iv(location, array.data(), array.size(), ec); break; case f_uniform3v: context->uniform3iv(location, array.data(), array.size(), ec); break; case f_uniform4v: context->uniform4iv(location, array.data(), array.size(), ec); break; default: break; } setDOMException(exec, ec); return jsUndefined(); } static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, const JSC::ArgList& args, WebGLRenderingContext* context) { if (args.size() != 3) return throwError(exec, SyntaxError); WebGLUniformLocation* location = toWebGLUniformLocation(args.at(0)); if (exec->hadException()) return jsUndefined(); bool transpose = args.at(1).toBoolean(exec); if (exec->hadException()) return jsUndefined(); RefPtr<WebGLFloatArray> webGLArray = toWebGLFloatArray(args.at(2)); if (exec->hadException()) return jsUndefined(); ExceptionCode ec = 0; if (webGLArray) { switch (f) { case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, webGLArray.get(), ec); break; case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, webGLArray.get(), ec); break; case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, webGLArray.get(), ec); break; } setDOMException(exec, ec); return jsUndefined(); } Vector<float, 64> array; if (!toVector(exec, args.at(2), array)) return throwError(exec, TypeError); switch (f) { case f_uniformMatrix2fv: context->uniformMatrix2fv(location, transpose, array.data(), array.size(), ec); break; case f_uniformMatrix3fv: context->uniformMatrix3fv(location, transpose, array.data(), array.size(), ec); break; case f_uniformMatrix4fv: context->uniformMatrix4fv(location, transpose, array.data(), array.size(), ec); break; } setDOMException(exec, ec); return jsUndefined(); } JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctioni(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctioni(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctioni(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctioni(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } JSC::JSValue JSWebGLRenderingContext::vertexAttrib4fv(JSC::ExecState* exec, const JSC::ArgList& args) { return dataFunctionf(f_vertexAttrib4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); } } // namespace WebCore #endif // ENABLE(3D_CANVAS)