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 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 INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27 28#if ENABLE(WEBGL) 29 30#include "JSWebGLRenderingContext.h" 31 32#include "ANGLEInstancedArrays.h" 33#include "EXTShaderTextureLOD.h" 34#include "EXTTextureFilterAnisotropic.h" 35#include "ExceptionCode.h" 36#include "HTMLCanvasElement.h" 37#include "HTMLImageElement.h" 38#include "JSANGLEInstancedArrays.h" 39#include "JSEXTShaderTextureLOD.h" 40#include "JSEXTTextureFilterAnisotropic.h" 41#include "JSHTMLCanvasElement.h" 42#include "JSHTMLImageElement.h" 43#include "JSImageData.h" 44#include "JSOESElementIndexUint.h" 45#include "JSOESStandardDerivatives.h" 46#include "JSOESTextureFloat.h" 47#include "JSOESTextureFloatLinear.h" 48#include "JSOESTextureHalfFloat.h" 49#include "JSOESTextureHalfFloatLinear.h" 50#include "JSOESVertexArrayObject.h" 51#include "JSWebGLBuffer.h" 52#include "JSWebGLCompressedTextureATC.h" 53#include "JSWebGLCompressedTexturePVRTC.h" 54#include "JSWebGLCompressedTextureS3TC.h" 55#include "JSWebGLDebugRendererInfo.h" 56#include "JSWebGLDebugShaders.h" 57#include "JSWebGLDepthTexture.h" 58#include "JSWebGLDrawBuffers.h" 59#include "JSWebGLFramebuffer.h" 60#include "JSWebGLLoseContext.h" 61#include "JSWebGLProgram.h" 62#include "JSWebGLRenderbuffer.h" 63#include "JSWebGLShader.h" 64#include "JSWebGLTexture.h" 65#include "JSWebGLUniformLocation.h" 66#include "JSWebGLVertexArrayObjectOES.h" 67#include "JSWebKitCSSMatrix.h" 68#include "NotImplemented.h" 69#include "OESElementIndexUint.h" 70#include "OESStandardDerivatives.h" 71#include "OESTextureFloat.h" 72#include "OESTextureFloatLinear.h" 73#include "OESTextureHalfFloat.h" 74#include "OESTextureHalfFloatLinear.h" 75#include "OESVertexArrayObject.h" 76#include "WebGLBuffer.h" 77#include "WebGLCompressedTextureATC.h" 78#include "WebGLCompressedTexturePVRTC.h" 79#include "WebGLCompressedTextureS3TC.h" 80#include "WebGLDebugRendererInfo.h" 81#include "WebGLDebugShaders.h" 82#include "WebGLDepthTexture.h" 83#include "WebGLDrawBuffers.h" 84#include "WebGLExtension.h" 85#include "WebGLFramebuffer.h" 86#include "WebGLGetInfo.h" 87#include "WebGLLoseContext.h" 88#include "WebGLProgram.h" 89#include "WebGLRenderingContext.h" 90#include "WebGLVertexArrayObjectOES.h" 91#include <runtime/Error.h> 92#include <runtime/JSTypedArrays.h> 93#include <runtime/TypedArrayInlines.h> 94#include <runtime/TypedArrays.h> 95#include <wtf/FastMalloc.h> 96 97#if ENABLE(VIDEO) 98#include "HTMLVideoElement.h" 99#include "JSHTMLVideoElement.h" 100#endif 101 102using namespace JSC; 103 104namespace WebCore { 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::kTypeBoolArray: { 112 MarkedArgumentBuffer list; 113 const Vector<bool>& value = info.getBoolArray(); 114 for (size_t ii = 0; ii < value.size(); ++ii) 115 list.append(jsBoolean(value[ii])); 116 return constructArray(exec, 0, globalObject, list); 117 } 118 case WebGLGetInfo::kTypeFloat: 119 return jsNumber(info.getFloat()); 120 case WebGLGetInfo::kTypeInt: 121 return jsNumber(info.getInt()); 122 case WebGLGetInfo::kTypeNull: 123 return jsNull(); 124 case WebGLGetInfo::kTypeString: 125 return jsStringWithCache(exec, info.getString()); 126 case WebGLGetInfo::kTypeUnsignedInt: 127 return jsNumber(info.getUnsignedInt()); 128 case WebGLGetInfo::kTypeWebGLBuffer: 129 return toJS(exec, globalObject, info.getWebGLBuffer()); 130 case WebGLGetInfo::kTypeWebGLFloatArray: 131 return toJS(exec, globalObject, info.getWebGLFloatArray()); 132 case WebGLGetInfo::kTypeWebGLFramebuffer: 133 return toJS(exec, globalObject, info.getWebGLFramebuffer()); 134 case WebGLGetInfo::kTypeWebGLIntArray: 135 return toJS(exec, globalObject, info.getWebGLIntArray()); 136 // FIXME: implement WebGLObjectArray 137 // case WebGLGetInfo::kTypeWebGLObjectArray: 138 case WebGLGetInfo::kTypeWebGLProgram: 139 return toJS(exec, globalObject, info.getWebGLProgram()); 140 case WebGLGetInfo::kTypeWebGLRenderbuffer: 141 return toJS(exec, globalObject, info.getWebGLRenderbuffer()); 142 case WebGLGetInfo::kTypeWebGLTexture: 143 return toJS(exec, globalObject, info.getWebGLTexture()); 144 case WebGLGetInfo::kTypeWebGLUnsignedByteArray: 145 return toJS(exec, globalObject, info.getWebGLUnsignedByteArray()); 146 case WebGLGetInfo::kTypeWebGLUnsignedIntArray: 147 return toJS(exec, globalObject, info.getWebGLUnsignedIntArray()); 148 case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES: 149 return toJS(exec, globalObject, info.getWebGLVertexArrayObjectOES()); 150 default: 151 notImplemented(); 152 return jsUndefined(); 153 } 154} 155 156enum ObjectType { 157 kBuffer, kRenderbuffer, kTexture, kVertexAttrib 158}; 159 160static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, ObjectType objectType) 161{ 162 if (exec->argumentCount() != 2) 163 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 164 165 ExceptionCode ec = 0; 166 WebGLRenderingContext& context = obj->impl(); 167 unsigned target = exec->uncheckedArgument(0).toInt32(exec); 168 if (exec->hadException()) 169 return jsUndefined(); 170 unsigned pname = exec->uncheckedArgument(1).toInt32(exec); 171 if (exec->hadException()) 172 return jsUndefined(); 173 WebGLGetInfo info; 174 switch (objectType) { 175 case kBuffer: 176 info = context.getBufferParameter(target, pname, ec); 177 break; 178 case kRenderbuffer: 179 info = context.getRenderbufferParameter(target, pname, ec); 180 break; 181 case kTexture: 182 info = context.getTexParameter(target, pname, ec); 183 break; 184 case kVertexAttrib: 185 // target => index 186 info = context.getVertexAttrib(target, pname, ec); 187 break; 188 default: 189 notImplemented(); 190 break; 191 } 192 if (ec) { 193 setDOMException(exec, ec); 194 return jsUndefined(); 195 } 196 return toJS(exec, obj->globalObject(), info); 197} 198 199enum WhichProgramCall { 200 kProgramParameter, kUniform 201}; 202 203static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, WebGLExtension* extension) 204{ 205 if (!extension) 206 return jsNull(); 207 switch (extension->getName()) { 208 case WebGLExtension::WebGLLoseContextName: 209 return toJS(exec, globalObject, static_cast<WebGLLoseContext*>(extension)); 210 case WebGLExtension::EXTShaderTextureLODName: 211 return toJS(exec, globalObject, static_cast<EXTShaderTextureLOD*>(extension)); 212 case WebGLExtension::EXTTextureFilterAnisotropicName: 213 return toJS(exec, globalObject, static_cast<EXTTextureFilterAnisotropic*>(extension)); 214 case WebGLExtension::OESStandardDerivativesName: 215 return toJS(exec, globalObject, static_cast<OESStandardDerivatives*>(extension)); 216 case WebGLExtension::OESTextureFloatName: 217 return toJS(exec, globalObject, static_cast<OESTextureFloat*>(extension)); 218 case WebGLExtension::OESTextureFloatLinearName: 219 return toJS(exec, globalObject, static_cast<OESTextureFloatLinear*>(extension)); 220 case WebGLExtension::OESTextureHalfFloatName: 221 return toJS(exec, globalObject, static_cast<OESTextureHalfFloat*>(extension)); 222 case WebGLExtension::OESTextureHalfFloatLinearName: 223 return toJS(exec, globalObject, static_cast<OESTextureHalfFloatLinear*>(extension)); 224 case WebGLExtension::OESVertexArrayObjectName: 225 return toJS(exec, globalObject, static_cast<OESVertexArrayObject*>(extension)); 226 case WebGLExtension::OESElementIndexUintName: 227 return toJS(exec, globalObject, static_cast<OESElementIndexUint*>(extension)); 228 case WebGLExtension::WebGLDebugRendererInfoName: 229 return toJS(exec, globalObject, static_cast<WebGLDebugRendererInfo*>(extension)); 230 case WebGLExtension::WebGLDebugShadersName: 231 return toJS(exec, globalObject, static_cast<WebGLDebugShaders*>(extension)); 232 case WebGLExtension::WebGLCompressedTextureATCName: 233 return toJS(exec, globalObject, static_cast<WebGLCompressedTextureATC*>(extension)); 234 case WebGLExtension::WebGLCompressedTexturePVRTCName: 235 return toJS(exec, globalObject, static_cast<WebGLCompressedTexturePVRTC*>(extension)); 236 case WebGLExtension::WebGLCompressedTextureS3TCName: 237 return toJS(exec, globalObject, static_cast<WebGLCompressedTextureS3TC*>(extension)); 238 case WebGLExtension::WebGLDepthTextureName: 239 return toJS(exec, globalObject, static_cast<WebGLDepthTexture*>(extension)); 240 case WebGLExtension::WebGLDrawBuffersName: 241 return toJS(exec, globalObject, static_cast<WebGLDrawBuffers*>(extension)); 242 case WebGLExtension::ANGLEInstancedArraysName: 243 return toJS(exec, globalObject, static_cast<ANGLEInstancedArrays*>(extension)); 244 } 245 ASSERT_NOT_REACHED(); 246 return jsNull(); 247} 248 249void JSWebGLRenderingContext::visitAdditionalChildren(SlotVisitor& visitor) 250{ 251 visitor.addOpaqueRoot(&impl()); 252} 253 254JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec) 255{ 256 if (exec->argumentCount() < 1) 257 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 258 ExceptionCode ec = 0; 259 WebGLRenderingContext& context = impl(); 260 WebGLProgram* program = toWebGLProgram(exec->uncheckedArgument(0)); 261 if (!program && !exec->uncheckedArgument(0).isUndefinedOrNull()) 262 return throwTypeError(exec); 263 Vector<RefPtr<WebGLShader>> shaders; 264 bool succeed = context.getAttachedShaders(program, shaders, ec); 265 if (ec) { 266 setDOMException(exec, ec); 267 return jsNull(); 268 } 269 if (!succeed) 270 return jsNull(); 271 MarkedArgumentBuffer list; 272 for (size_t ii = 0; ii < shaders.size(); ++ii) 273 list.append(toJS(exec, globalObject(), shaders[ii].get())); 274 return constructArray(exec, 0, globalObject(), list); 275} 276 277JSValue JSWebGLRenderingContext::getExtension(ExecState* exec) 278{ 279 if (exec->argumentCount() < 1) 280 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 281 282 WebGLRenderingContext& context = impl(); 283 const String name = exec->uncheckedArgument(0).toString(exec)->value(exec); 284 if (exec->hadException()) 285 return jsUndefined(); 286 WebGLExtension* extension = context.getExtension(name); 287 return toJS(exec, globalObject(), extension); 288} 289 290JSValue JSWebGLRenderingContext::getBufferParameter(ExecState* exec) 291{ 292 return getObjectParameter(this, exec, kBuffer); 293} 294 295JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec) 296{ 297 if (exec->argumentCount() != 3) 298 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 299 300 ExceptionCode ec = 0; 301 WebGLRenderingContext& context = impl(); 302 unsigned target = exec->uncheckedArgument(0).toInt32(exec); 303 if (exec->hadException()) 304 return jsUndefined(); 305 unsigned attachment = exec->uncheckedArgument(1).toInt32(exec); 306 if (exec->hadException()) 307 return jsUndefined(); 308 unsigned pname = exec->uncheckedArgument(2).toInt32(exec); 309 if (exec->hadException()) 310 return jsUndefined(); 311 WebGLGetInfo info = context.getFramebufferAttachmentParameter(target, attachment, pname, ec); 312 if (ec) { 313 setDOMException(exec, ec); 314 return jsUndefined(); 315 } 316 return toJS(exec, globalObject(), info); 317} 318 319JSValue JSWebGLRenderingContext::getParameter(ExecState* exec) 320{ 321 if (exec->argumentCount() != 1) 322 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 323 324 ExceptionCode ec = 0; 325 WebGLRenderingContext& context = impl(); 326 unsigned pname = exec->uncheckedArgument(0).toInt32(exec); 327 if (exec->hadException()) 328 return jsUndefined(); 329 WebGLGetInfo info = context.getParameter(pname, ec); 330 if (ec) { 331 setDOMException(exec, ec); 332 return jsUndefined(); 333 } 334 return toJS(exec, globalObject(), info); 335} 336 337JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec) 338{ 339 if (exec->argumentCount() != 2) 340 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 341 342 ExceptionCode ec = 0; 343 WebGLRenderingContext& context = impl(); 344 WebGLProgram* program = toWebGLProgram(exec->uncheckedArgument(0)); 345 if (!program && !exec->uncheckedArgument(0).isUndefinedOrNull()) 346 return throwTypeError(exec); 347 unsigned pname = exec->uncheckedArgument(1).toInt32(exec); 348 if (exec->hadException()) 349 return jsUndefined(); 350 WebGLGetInfo info = context.getProgramParameter(program, pname, ec); 351 if (ec) { 352 setDOMException(exec, ec); 353 return jsUndefined(); 354 } 355 return toJS(exec, globalObject(), info); 356} 357 358JSValue JSWebGLRenderingContext::getRenderbufferParameter(ExecState* exec) 359{ 360 return getObjectParameter(this, exec, kRenderbuffer); 361} 362 363JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec) 364{ 365 if (exec->argumentCount() != 2) 366 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 367 368 ExceptionCode ec = 0; 369 WebGLRenderingContext& context = impl(); 370 if (!exec->uncheckedArgument(0).isUndefinedOrNull() && !exec->uncheckedArgument(0).inherits(JSWebGLShader::info())) 371 return throwTypeError(exec); 372 WebGLShader* shader = toWebGLShader(exec->uncheckedArgument(0)); 373 unsigned pname = exec->uncheckedArgument(1).toInt32(exec); 374 if (exec->hadException()) 375 return jsUndefined(); 376 WebGLGetInfo info = context.getShaderParameter(shader, pname, ec); 377 if (ec) { 378 setDOMException(exec, ec); 379 return jsUndefined(); 380 } 381 return toJS(exec, globalObject(), info); 382} 383 384JSValue JSWebGLRenderingContext::getSupportedExtensions(ExecState* exec) 385{ 386 WebGLRenderingContext& context = impl(); 387 if (context.isContextLost()) 388 return jsNull(); 389 Vector<String> value = context.getSupportedExtensions(); 390 MarkedArgumentBuffer list; 391 for (size_t ii = 0; ii < value.size(); ++ii) 392 list.append(jsStringWithCache(exec, value[ii])); 393 return constructArray(exec, 0, globalObject(), list); 394} 395 396JSValue JSWebGLRenderingContext::getTexParameter(ExecState* exec) 397{ 398 return getObjectParameter(this, exec, kTexture); 399} 400 401JSValue JSWebGLRenderingContext::getUniform(ExecState* exec) 402{ 403 if (exec->argumentCount() != 2) 404 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 405 406 ExceptionCode ec = 0; 407 WebGLRenderingContext& context = impl(); 408 WebGLProgram* program = toWebGLProgram(exec->uncheckedArgument(0)); 409 if (!program && !exec->uncheckedArgument(0).isUndefinedOrNull()) 410 return throwTypeError(exec); 411 WebGLUniformLocation* location = toWebGLUniformLocation(exec->uncheckedArgument(1)); 412 if (!location && !exec->uncheckedArgument(1).isUndefinedOrNull()) 413 return throwTypeError(exec); 414 WebGLGetInfo info = context.getUniform(program, location, ec); 415 if (ec) { 416 setDOMException(exec, ec); 417 return jsUndefined(); 418 } 419 return toJS(exec, globalObject(), info); 420} 421 422JSValue JSWebGLRenderingContext::getVertexAttrib(ExecState* exec) 423{ 424 return getObjectParameter(this, exec, kVertexAttrib); 425} 426 427template<typename T, size_t inlineCapacity> 428bool toVector(JSC::ExecState* exec, JSC::JSValue value, Vector<T, inlineCapacity>& vector) 429{ 430 if (!value.isObject()) 431 return false; 432 433 JSC::JSObject* object = asObject(value); 434 int32_t length = object->get(exec, exec->vm().propertyNames->length).toInt32(exec); 435 436 if (!vector.tryReserveCapacity(length)) 437 return false; 438 vector.resize(length); 439 440 for (int32_t i = 0; i < length; ++i) { 441 JSC::JSValue v = object->get(exec, i); 442 if (exec->hadException()) 443 return false; 444 vector[i] = static_cast<T>(v.toNumber(exec)); 445 } 446 447 return true; 448} 449 450enum DataFunctionToCall { 451 f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v, 452 f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v 453}; 454 455enum DataFunctionMatrixToCall { 456 f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv 457}; 458 459static bool functionForUniform(DataFunctionToCall f) 460{ 461 switch (f) { 462 case f_uniform1v: 463 case f_uniform2v: 464 case f_uniform3v: 465 case f_uniform4v: 466 return true; 467 default: break; 468 } 469 return false; 470} 471 472static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext& context) 473{ 474 if (exec->argumentCount() != 2) 475 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 476 477 WebGLUniformLocation* location = 0; 478 long index = -1; 479 480 if (functionForUniform(f)) { 481 location = toWebGLUniformLocation(exec->uncheckedArgument(0)); 482 if (!location && !exec->uncheckedArgument(0).isUndefinedOrNull()) 483 return throwTypeError(exec); 484 } else 485 index = exec->uncheckedArgument(0).toInt32(exec); 486 487 if (exec->hadException()) 488 return jsUndefined(); 489 490 RefPtr<Float32Array> webGLArray = toFloat32Array(exec->uncheckedArgument(1)); 491 if (exec->hadException()) 492 return jsUndefined(); 493 494 ExceptionCode ec = 0; 495 if (webGLArray) { 496 switch (f) { 497 case f_uniform1v: 498 context.uniform1fv(location, webGLArray.get(), ec); 499 break; 500 case f_uniform2v: 501 context.uniform2fv(location, webGLArray.get(), ec); 502 break; 503 case f_uniform3v: 504 context.uniform3fv(location, webGLArray.get(), ec); 505 break; 506 case f_uniform4v: 507 context.uniform4fv(location, webGLArray.get(), ec); 508 break; 509 case f_vertexAttrib1v: 510 context.vertexAttrib1fv(index, webGLArray.get()); 511 break; 512 case f_vertexAttrib2v: 513 context.vertexAttrib2fv(index, webGLArray.get()); 514 break; 515 case f_vertexAttrib3v: 516 context.vertexAttrib3fv(index, webGLArray.get()); 517 break; 518 case f_vertexAttrib4v: 519 context.vertexAttrib4fv(index, webGLArray.get()); 520 break; 521 } 522 523 setDOMException(exec, ec); 524 return jsUndefined(); 525 } 526 527 Vector<float, 64> array; 528 if (!toVector(exec, exec->uncheckedArgument(1), array)) 529 return throwTypeError(exec); 530 531 switch (f) { 532 case f_uniform1v: 533 context.uniform1fv(location, array.data(), array.size(), ec); 534 break; 535 case f_uniform2v: 536 context.uniform2fv(location, array.data(), array.size(), ec); 537 break; 538 case f_uniform3v: 539 context.uniform3fv(location, array.data(), array.size(), ec); 540 break; 541 case f_uniform4v: 542 context.uniform4fv(location, array.data(), array.size(), ec); 543 break; 544 case f_vertexAttrib1v: 545 context.vertexAttrib1fv(index, array.data(), array.size()); 546 break; 547 case f_vertexAttrib2v: 548 context.vertexAttrib2fv(index, array.data(), array.size()); 549 break; 550 case f_vertexAttrib3v: 551 context.vertexAttrib3fv(index, array.data(), array.size()); 552 break; 553 case f_vertexAttrib4v: 554 context.vertexAttrib4fv(index, array.data(), array.size()); 555 break; 556 } 557 558 setDOMException(exec, ec); 559 return jsUndefined(); 560} 561 562static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext& context) 563{ 564 if (exec->argumentCount() != 2) 565 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 566 567 WebGLUniformLocation* location = toWebGLUniformLocation(exec->uncheckedArgument(0)); 568 if (!location && !exec->uncheckedArgument(0).isUndefinedOrNull()) 569 return throwTypeError(exec); 570 571 RefPtr<Int32Array> webGLArray = toInt32Array(exec->uncheckedArgument(1)); 572 573 ExceptionCode ec = 0; 574 if (webGLArray) { 575 switch (f) { 576 case f_uniform1v: 577 context.uniform1iv(location, webGLArray.get(), ec); 578 break; 579 case f_uniform2v: 580 context.uniform2iv(location, webGLArray.get(), ec); 581 break; 582 case f_uniform3v: 583 context.uniform3iv(location, webGLArray.get(), ec); 584 break; 585 case f_uniform4v: 586 context.uniform4iv(location, webGLArray.get(), ec); 587 break; 588 default: 589 break; 590 } 591 592 setDOMException(exec, ec); 593 return jsUndefined(); 594 } 595 596 597 Vector<int, 64> array; 598 if (!toVector(exec, exec->uncheckedArgument(1), array)) 599 return throwTypeError(exec); 600 601 switch (f) { 602 case f_uniform1v: 603 context.uniform1iv(location, array.data(), array.size(), ec); 604 break; 605 case f_uniform2v: 606 context.uniform2iv(location, array.data(), array.size(), ec); 607 break; 608 case f_uniform3v: 609 context.uniform3iv(location, array.data(), array.size(), ec); 610 break; 611 case f_uniform4v: 612 context.uniform4iv(location, array.data(), array.size(), ec); 613 break; 614 default: 615 break; 616 } 617 618 setDOMException(exec, ec); 619 return jsUndefined(); 620} 621 622static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, WebGLRenderingContext& context) 623{ 624 if (exec->argumentCount() != 3) 625 return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); 626 627 WebGLUniformLocation* location = toWebGLUniformLocation(exec->uncheckedArgument(0)); 628 if (!location && !exec->uncheckedArgument(0).isUndefinedOrNull()) 629 return throwTypeError(exec); 630 631 bool transpose = exec->uncheckedArgument(1).toBoolean(exec); 632 if (exec->hadException()) 633 return jsUndefined(); 634 635 RefPtr<Float32Array> webGLArray = toFloat32Array(exec->uncheckedArgument(2)); 636 637 ExceptionCode ec = 0; 638 if (webGLArray) { 639 switch (f) { 640 case f_uniformMatrix2fv: 641 context.uniformMatrix2fv(location, transpose, webGLArray.get(), ec); 642 break; 643 case f_uniformMatrix3fv: 644 context.uniformMatrix3fv(location, transpose, webGLArray.get(), ec); 645 break; 646 case f_uniformMatrix4fv: 647 context.uniformMatrix4fv(location, transpose, webGLArray.get(), ec); 648 break; 649 } 650 651 setDOMException(exec, ec); 652 return jsUndefined(); 653 } 654 655 Vector<float, 64> array; 656 if (!toVector(exec, exec->uncheckedArgument(2), array)) 657 return throwTypeError(exec); 658 659 switch (f) { 660 case f_uniformMatrix2fv: 661 context.uniformMatrix2fv(location, transpose, array.data(), array.size(), ec); 662 break; 663 case f_uniformMatrix3fv: 664 context.uniformMatrix3fv(location, transpose, array.data(), array.size(), ec); 665 break; 666 case f_uniformMatrix4fv: 667 context.uniformMatrix4fv(location, transpose, array.data(), array.size(), ec); 668 break; 669 } 670 671 setDOMException(exec, ec); 672 return jsUndefined(); 673} 674 675JSC::JSValue JSWebGLRenderingContext::uniform1fv(JSC::ExecState* exec) 676{ 677 return dataFunctionf(f_uniform1v, exec, impl()); 678} 679 680JSC::JSValue JSWebGLRenderingContext::uniform1iv(JSC::ExecState* exec) 681{ 682 return dataFunctioni(f_uniform1v, exec, impl()); 683} 684 685JSC::JSValue JSWebGLRenderingContext::uniform2fv(JSC::ExecState* exec) 686{ 687 return dataFunctionf(f_uniform2v, exec, impl()); 688} 689 690JSC::JSValue JSWebGLRenderingContext::uniform2iv(JSC::ExecState* exec) 691{ 692 return dataFunctioni(f_uniform2v, exec, impl()); 693} 694 695JSC::JSValue JSWebGLRenderingContext::uniform3fv(JSC::ExecState* exec) 696{ 697 return dataFunctionf(f_uniform3v, exec, impl()); 698} 699 700JSC::JSValue JSWebGLRenderingContext::uniform3iv(JSC::ExecState* exec) 701{ 702 return dataFunctioni(f_uniform3v, exec, impl()); 703} 704 705JSC::JSValue JSWebGLRenderingContext::uniform4fv(JSC::ExecState* exec) 706{ 707 return dataFunctionf(f_uniform4v, exec, impl()); 708} 709 710JSC::JSValue JSWebGLRenderingContext::uniform4iv(JSC::ExecState* exec) 711{ 712 return dataFunctioni(f_uniform4v, exec, impl()); 713} 714 715JSC::JSValue JSWebGLRenderingContext::uniformMatrix2fv(JSC::ExecState* exec) 716{ 717 return dataFunctionMatrix(f_uniformMatrix2fv, exec, impl()); 718} 719 720JSC::JSValue JSWebGLRenderingContext::uniformMatrix3fv(JSC::ExecState* exec) 721{ 722 return dataFunctionMatrix(f_uniformMatrix3fv, exec, impl()); 723} 724 725JSC::JSValue JSWebGLRenderingContext::uniformMatrix4fv(JSC::ExecState* exec) 726{ 727 return dataFunctionMatrix(f_uniformMatrix4fv, exec, impl()); 728} 729 730JSC::JSValue JSWebGLRenderingContext::vertexAttrib1fv(JSC::ExecState* exec) 731{ 732 return dataFunctionf(f_vertexAttrib1v, exec, impl()); 733} 734 735JSC::JSValue JSWebGLRenderingContext::vertexAttrib2fv(JSC::ExecState* exec) 736{ 737 return dataFunctionf(f_vertexAttrib2v, exec, impl()); 738} 739 740JSC::JSValue JSWebGLRenderingContext::vertexAttrib3fv(JSC::ExecState* exec) 741{ 742 return dataFunctionf(f_vertexAttrib3v, exec, impl()); 743} 744 745JSC::JSValue JSWebGLRenderingContext::vertexAttrib4fv(JSC::ExecState* exec) 746{ 747 return dataFunctionf(f_vertexAttrib4v, exec, impl()); 748} 749 750} // namespace WebCore 751 752#endif // ENABLE(WEBGL) 753