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 63 using namespace JSC; 64 65 namespace WebCore { 66 67 JSValue 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 89 JSValue 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 106 static 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 145 enum ObjectType { 146 kBuffer, kRenderbuffer, kTexture, kVertexAttrib 147 }; 148 149 static 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 188 enum WhichProgramCall { 189 kProgramParameter, kUniform 190 }; 191 192 JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec, const ArgList& args) 193 { 194 return getObjectParameter(this, exec, args, kBuffer); 195 } 196 197 JSValue 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 221 JSValue 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 239 JSValue 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 258 JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec, const ArgList& args) 259 { 260 return getObjectParameter(this, exec, args, kRenderbuffer); 261 } 262 263 JSValue 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 282 JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec, const ArgList& args) 283 { 284 return getObjectParameter(this, exec, args, kTexture); 285 } 286 287 JSValue 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 306 JSValue 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); 316 JSValue 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); 417 JSValue 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 508 template<typename T, size_t inlineCapacity> 509 bool 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 528 enum DataFunctionToCall { 529 f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, 530 f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v 531 }; 532 533 enum DataFunctionMatrixToCall { 534 f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv 535 }; 536 537 static 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 551 static 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 639 static 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 702 static 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 758 JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec, const JSC::ArgList& args) 759 { 760 return dataFunctionf(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 761 } 762 763 JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec, const JSC::ArgList& args) 764 { 765 return dataFunctioni(f_uniform1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 766 } 767 768 JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec, const JSC::ArgList& args) 769 { 770 return dataFunctionf(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 771 } 772 773 JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec, const JSC::ArgList& args) 774 { 775 return dataFunctioni(f_uniform2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 776 } 777 778 JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec, const JSC::ArgList& args) 779 { 780 return dataFunctionf(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 781 } 782 783 JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec, const JSC::ArgList& args) 784 { 785 return dataFunctioni(f_uniform3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 786 } 787 788 JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec, const JSC::ArgList& args) 789 { 790 return dataFunctionf(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 791 } 792 793 JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec, const JSC::ArgList& args) 794 { 795 return dataFunctioni(f_uniform4v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 796 } 797 798 JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec, const JSC::ArgList& args) 799 { 800 return dataFunctionMatrix(f_uniformMatrix2fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); 801 } 802 803 JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec, const JSC::ArgList& args) 804 { 805 return dataFunctionMatrix(f_uniformMatrix3fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); 806 } 807 808 JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec, const JSC::ArgList& args) 809 { 810 return dataFunctionMatrix(f_uniformMatrix4fv, exec, args, static_cast<WebGLRenderingContext*>(impl())); 811 } 812 813 JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec, const JSC::ArgList& args) 814 { 815 return dataFunctionf(f_vertexAttrib1v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 816 } 817 818 JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec, const JSC::ArgList& args) 819 { 820 return dataFunctionf(f_vertexAttrib2v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 821 } 822 823 JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec, const JSC::ArgList& args) 824 { 825 return dataFunctionf(f_vertexAttrib3v, exec, args, static_cast<WebGLRenderingContext*>(impl())); 826 } 827 828 JSC::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