/* | |
* 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) |