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