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 "WebGLRenderingContext.h" 31 32 #include "CanvasPixelArray.h" 33 #include "HTMLCanvasElement.h" 34 #include "HTMLImageElement.h" 35 #include "ImageBuffer.h" 36 #include "ImageData.h" 37 #include "NotImplemented.h" 38 #include "RenderBox.h" 39 #include "RenderLayer.h" 40 #include "WebGLActiveInfo.h" 41 #include "WebGLBuffer.h" 42 #include "WebGLContextAttributes.h" 43 #include "WebGLFramebuffer.h" 44 #include "WebGLProgram.h" 45 #include "WebGLRenderbuffer.h" 46 #include "WebGLTexture.h" 47 #include "WebGLShader.h" 48 #include "WebGLUniformLocation.h" 49 #include "HTMLCanvasElement.h" 50 #include "HTMLImageElement.h" 51 #include "ImageBuffer.h" 52 #include "NotImplemented.h" 53 #include "RenderBox.h" 54 #include "RenderLayer.h" 55 56 #include <wtf/ByteArray.h> 57 58 namespace WebCore { 59 60 class WebGLStateRestorer { 61 public: 62 WebGLStateRestorer(WebGLRenderingContext* context, 63 bool changed) 64 : m_context(context) 65 , m_changed(changed) 66 { 67 } 68 69 ~WebGLStateRestorer() 70 { 71 m_context->cleanupAfterGraphicsCall(m_changed); 72 } 73 74 private: 75 WebGLRenderingContext* m_context; 76 bool m_changed; 77 }; 78 79 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs) 80 { 81 OwnPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs->attributes())); 82 if (!context) 83 return 0; 84 85 return new WebGLRenderingContext(canvas, context.release()); 86 } 87 88 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<GraphicsContext3D> context) 89 : CanvasRenderingContext(passedCanvas) 90 , m_context(context) 91 , m_needsUpdate(true) 92 , m_markedCanvasDirty(false) 93 , m_activeTextureUnit(0) 94 { 95 ASSERT(m_context); 96 int numVertexAttribs = 0; 97 m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs); 98 m_maxVertexAttribs = numVertexAttribs; 99 m_context->reshape(canvas()->width(), canvas()->height()); 100 } 101 102 WebGLRenderingContext::~WebGLRenderingContext() 103 { 104 detachAndRemoveAllObjects(); 105 } 106 107 void WebGLRenderingContext::markContextChanged() 108 { 109 #if USE(ACCELERATED_COMPOSITING) 110 if (canvas()->renderBox() && canvas()->renderBox()->hasLayer()) { 111 canvas()->renderBox()->layer()->rendererContentChanged(); 112 } else { 113 #endif 114 if (!m_markedCanvasDirty) { 115 // Make sure the canvas's image buffer is allocated. 116 canvas()->buffer(); 117 canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height())); 118 m_markedCanvasDirty = true; 119 } 120 #if USE(ACCELERATED_COMPOSITING) 121 } 122 #endif 123 } 124 125 void WebGLRenderingContext::beginPaint() 126 { 127 if (m_markedCanvasDirty) { 128 m_context->beginPaint(this); 129 } 130 } 131 132 void WebGLRenderingContext::endPaint() 133 { 134 if (m_markedCanvasDirty) { 135 m_markedCanvasDirty = false; 136 m_context->endPaint(); 137 } 138 } 139 140 void WebGLRenderingContext::reshape(int width, int height) 141 { 142 if (m_needsUpdate) { 143 #if USE(ACCELERATED_COMPOSITING) 144 if (canvas()->renderBox() && canvas()->renderBox()->hasLayer()) 145 canvas()->renderBox()->layer()->rendererContentChanged(); 146 #endif 147 m_needsUpdate = false; 148 } 149 150 m_context->reshape(width, height); 151 } 152 153 int WebGLRenderingContext::sizeInBytes(int type, ExceptionCode& ec) 154 { 155 UNUSED_PARAM(ec); 156 int result = m_context->sizeInBytes(type); 157 if (result <= 0) 158 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 159 160 return result; 161 } 162 163 void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec) 164 { 165 UNUSED_PARAM(ec); 166 if ((texture - GraphicsContext3D::TEXTURE0) > sizeof(m_textureUnits) / sizeof(TextureUnitState)) { 167 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 168 return; 169 } 170 m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0; 171 m_context->activeTexture(texture); 172 cleanupAfterGraphicsCall(false); 173 } 174 175 void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) 176 { 177 UNUSED_PARAM(ec); 178 if (!program || program->context() != this || !shader || shader->context() != this) { 179 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 180 return; 181 } 182 m_context->attachShader(program, shader); 183 cleanupAfterGraphicsCall(false); 184 } 185 186 void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec) 187 { 188 UNUSED_PARAM(ec); 189 if (!program || program->context() != this) { 190 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 191 return; 192 } 193 m_context->bindAttribLocation(program, index, name); 194 cleanupAfterGraphicsCall(false); 195 } 196 197 void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec) 198 { 199 UNUSED_PARAM(ec); 200 if (buffer && buffer->context() != this) { 201 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 202 return; 203 } 204 205 if (target == GraphicsContext3D::ARRAY_BUFFER) 206 m_boundArrayBuffer = buffer; 207 else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER) 208 m_boundElementArrayBuffer = buffer; 209 else { 210 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 211 return; 212 } 213 214 m_context->bindBuffer(target, buffer); 215 cleanupAfterGraphicsCall(false); 216 } 217 218 219 void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec) 220 { 221 UNUSED_PARAM(ec); 222 if (buffer && buffer->context() != this) { 223 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 224 return; 225 } 226 if (target != GraphicsContext3D::FRAMEBUFFER) { 227 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 228 return; 229 } 230 m_framebufferBinding = buffer; 231 m_context->bindFramebuffer(target, buffer); 232 cleanupAfterGraphicsCall(false); 233 } 234 235 void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec) 236 { 237 UNUSED_PARAM(ec); 238 if (renderBuffer && renderBuffer->context() != this) { 239 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 240 return; 241 } 242 if (target != GraphicsContext3D::RENDERBUFFER) { 243 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 244 return; 245 } 246 m_renderbufferBinding = renderBuffer; 247 m_context->bindRenderbuffer(target, renderBuffer); 248 cleanupAfterGraphicsCall(false); 249 } 250 251 252 void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec) 253 { 254 UNUSED_PARAM(ec); 255 if (texture && texture->context() != this) { 256 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 257 return; 258 } 259 if (target == GraphicsContext3D::TEXTURE_2D) 260 m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture; 261 else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) 262 m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture; 263 else { 264 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 265 return; 266 } 267 m_context->bindTexture(target, texture); 268 cleanupAfterGraphicsCall(false); 269 } 270 271 void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha) 272 { 273 m_context->blendColor(red, green, blue, alpha); 274 cleanupAfterGraphicsCall(false); 275 } 276 277 void WebGLRenderingContext::blendEquation( unsigned long mode ) 278 { 279 m_context->blendEquation(mode); 280 cleanupAfterGraphicsCall(false); 281 } 282 283 void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha) 284 { 285 m_context->blendEquationSeparate(modeRGB, modeAlpha); 286 cleanupAfterGraphicsCall(false); 287 } 288 289 290 void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor) 291 { 292 m_context->blendFunc(sfactor, dfactor); 293 cleanupAfterGraphicsCall(false); 294 } 295 296 void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha) 297 { 298 m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); 299 cleanupAfterGraphicsCall(false); 300 } 301 302 void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec) 303 { 304 UNUSED_PARAM(ec); 305 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) { 306 if (!m_boundElementArrayBuffer->associateBufferData(target, size)) { 307 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 308 return; 309 } 310 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) { 311 if (!m_boundArrayBuffer->associateBufferData(target, size)) { 312 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 313 return; 314 } 315 } else { 316 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 317 return; 318 } 319 320 m_context->bufferData(target, size, usage); 321 cleanupAfterGraphicsCall(false); 322 } 323 324 void WebGLRenderingContext::bufferData(unsigned long target, WebGLArray* data, unsigned long usage, ExceptionCode& ec) 325 { 326 UNUSED_PARAM(ec); 327 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) { 328 if (!m_boundElementArrayBuffer->associateBufferData(target, data)) { 329 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 330 return; 331 } 332 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) { 333 if (!m_boundArrayBuffer->associateBufferData(target, data)) { 334 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 335 return; 336 } 337 } else { 338 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 339 return; 340 } 341 342 m_context->bufferData(target, data, usage); 343 cleanupAfterGraphicsCall(false); 344 } 345 346 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, WebGLArray* data, ExceptionCode& ec) 347 { 348 UNUSED_PARAM(ec); 349 if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && m_boundElementArrayBuffer) { 350 if (!m_boundElementArrayBuffer->associateBufferSubData(target, offset, data)) { 351 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 352 return; 353 } 354 } else if (target == GraphicsContext3D::ARRAY_BUFFER && m_boundArrayBuffer) { 355 if (!m_boundArrayBuffer->associateBufferSubData(target, offset, data)) { 356 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 357 return; 358 } 359 } else { 360 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 361 return; 362 } 363 364 m_context->bufferSubData(target, offset, data); 365 cleanupAfterGraphicsCall(false); 366 } 367 368 unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target) 369 { 370 return m_context->checkFramebufferStatus(target); 371 cleanupAfterGraphicsCall(false); 372 } 373 374 void WebGLRenderingContext::clear(unsigned long mask) 375 { 376 m_context->clear(mask); 377 cleanupAfterGraphicsCall(true); 378 } 379 380 void WebGLRenderingContext::clearColor(double r, double g, double b, double a) 381 { 382 if (isnan(r)) 383 r = 0; 384 if (isnan(g)) 385 g = 0; 386 if (isnan(b)) 387 b = 0; 388 if (isnan(a)) 389 a = 1; 390 m_context->clearColor(r, g, b, a); 391 cleanupAfterGraphicsCall(false); 392 } 393 394 void WebGLRenderingContext::clearDepth(double depth) 395 { 396 m_context->clearDepth(depth); 397 cleanupAfterGraphicsCall(false); 398 } 399 400 void WebGLRenderingContext::clearStencil(long s) 401 { 402 m_context->clearStencil(s); 403 cleanupAfterGraphicsCall(false); 404 } 405 406 void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha) 407 { 408 m_context->colorMask(red, green, blue, alpha); 409 cleanupAfterGraphicsCall(false); 410 } 411 412 void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec) 413 { 414 UNUSED_PARAM(ec); 415 if (!shader || shader->context() != this) { 416 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 417 return; 418 } 419 m_context->compileShader(shader); 420 cleanupAfterGraphicsCall(false); 421 } 422 423 void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) 424 { 425 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); 426 cleanupAfterGraphicsCall(false); 427 } 428 429 void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) 430 { 431 m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); 432 cleanupAfterGraphicsCall(false); 433 } 434 435 PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer() 436 { 437 RefPtr<WebGLBuffer> o = WebGLBuffer::create(this); 438 addObject(o.get()); 439 return o; 440 } 441 442 PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer() 443 { 444 RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this); 445 addObject(o.get()); 446 return o; 447 } 448 449 PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture() 450 { 451 RefPtr<WebGLTexture> o = WebGLTexture::create(this); 452 addObject(o.get()); 453 return o; 454 } 455 456 PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram() 457 { 458 RefPtr<WebGLProgram> o = WebGLProgram::create(this); 459 addObject(o.get()); 460 return o; 461 } 462 463 PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer() 464 { 465 RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this); 466 addObject(o.get()); 467 return o; 468 } 469 470 PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec) 471 { 472 UNUSED_PARAM(ec); 473 if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) { 474 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 475 return 0; 476 } 477 478 RefPtr<WebGLShader> o = WebGLShader::create(this, static_cast<GraphicsContext3D::WebGLEnumType>(type)); 479 addObject(o.get()); 480 return o; 481 } 482 483 void WebGLRenderingContext::cullFace(unsigned long mode) 484 { 485 m_context->cullFace(mode); 486 cleanupAfterGraphicsCall(false); 487 } 488 489 void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer) 490 { 491 if (!buffer) 492 return; 493 494 buffer->deleteObject(); 495 } 496 497 void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer) 498 { 499 if (!framebuffer) 500 return; 501 502 framebuffer->deleteObject(); 503 } 504 505 void WebGLRenderingContext::deleteProgram(WebGLProgram* program) 506 { 507 if (!program) 508 return; 509 510 program->deleteObject(); 511 } 512 513 void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer) 514 { 515 if (!renderbuffer) 516 return; 517 518 renderbuffer->deleteObject(); 519 } 520 521 void WebGLRenderingContext::deleteShader(WebGLShader* shader) 522 { 523 if (!shader) 524 return; 525 526 shader->deleteObject(); 527 } 528 529 void WebGLRenderingContext::deleteTexture(WebGLTexture* texture) 530 { 531 if (!texture) 532 return; 533 534 texture->deleteObject(); 535 } 536 537 void WebGLRenderingContext::depthFunc(unsigned long func) 538 { 539 m_context->depthFunc(func); 540 cleanupAfterGraphicsCall(false); 541 } 542 543 void WebGLRenderingContext::depthMask(bool flag) 544 { 545 m_context->depthMask(flag); 546 cleanupAfterGraphicsCall(false); 547 } 548 549 void WebGLRenderingContext::depthRange(double zNear, double zFar) 550 { 551 m_context->depthRange(zNear, zFar); 552 cleanupAfterGraphicsCall(false); 553 } 554 555 void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec) 556 { 557 UNUSED_PARAM(ec); 558 if (!program || program->context() != this || !shader || shader->context() != this) { 559 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 560 return; 561 } 562 m_context->detachShader(program, shader); 563 cleanupAfterGraphicsCall(false); 564 } 565 566 567 void WebGLRenderingContext::disable(unsigned long cap) 568 { 569 m_context->disable(cap); 570 cleanupAfterGraphicsCall(false); 571 } 572 573 void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec) 574 { 575 UNUSED_PARAM(ec); 576 if (index >= m_maxVertexAttribs) { 577 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 578 return; 579 } 580 581 if (index < m_vertexAttribState.size()) 582 m_vertexAttribState[index].enabled = false; 583 584 m_context->disableVertexAttribArray(index); 585 cleanupAfterGraphicsCall(false); 586 } 587 588 bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset) 589 { 590 if (!m_boundElementArrayBuffer) 591 return false; 592 593 if (offset < 0) 594 return false; 595 596 unsigned long uoffset = static_cast<unsigned long>(offset); 597 598 if (type == GraphicsContext3D::UNSIGNED_SHORT) { 599 // For an unsigned short array, offset must be divisible by 2 for alignment reasons. 600 if (uoffset & 1) 601 return false; 602 603 // Make uoffset an element offset. 604 uoffset /= 2; 605 606 unsigned long n = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER) / 2; 607 if (uoffset > n || count > n - uoffset) 608 return false; 609 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { 610 unsigned long n = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER); 611 if (uoffset > n || count > n - uoffset) 612 return false; 613 } 614 return true; 615 } 616 617 bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& numElementsRequired) 618 { 619 // Performs conservative validation by caching a maximum index of 620 // the given type per element array buffer. If all of the bound 621 // array buffers have enough elements to satisfy that maximum 622 // index, skips the expensive per-draw-call iteration in 623 // validateIndexArrayPrecise. 624 625 long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type); 626 if (maxIndex < 0) { 627 // Compute the maximum index in the entire buffer for the given type of index. 628 switch (type) { 629 case GraphicsContext3D::UNSIGNED_BYTE: { 630 unsigned numElements = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER); 631 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); 632 for (unsigned i = 0; i < numElements; i++) 633 maxIndex = max(maxIndex, static_cast<long>(p[i])); 634 break; 635 } 636 case GraphicsContext3D::UNSIGNED_SHORT: { 637 unsigned numElements = m_boundElementArrayBuffer->byteLength(GraphicsContext3D::ELEMENT_ARRAY_BUFFER) / sizeof(unsigned short); 638 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()); 639 for (unsigned i = 0; i < numElements; i++) 640 maxIndex = max(maxIndex, static_cast<long>(p[i])); 641 break; 642 } 643 default: 644 return false; 645 } 646 m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex); 647 } 648 649 if (maxIndex >= 0) { 650 // The number of required elements is one more than the maximum 651 // index that will be accessed. 652 numElementsRequired = maxIndex + 1; 653 return true; 654 } 655 656 return false; 657 } 658 659 bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired) 660 { 661 long lastIndex = -1; 662 663 if (!m_boundElementArrayBuffer) 664 return false; 665 666 unsigned long uoffset = static_cast<unsigned long>(offset); 667 unsigned long n = count; 668 669 if (type == GraphicsContext3D::UNSIGNED_SHORT) { 670 // Make uoffset an element offset. 671 uoffset /= 2; 672 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; 673 while (n-- > 0) { 674 if (*p > lastIndex) 675 lastIndex = *p; 676 ++p; 677 } 678 } else if (type == GraphicsContext3D::UNSIGNED_BYTE) { 679 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset; 680 while (n-- > 0) { 681 if (*p > lastIndex) 682 lastIndex = *p; 683 ++p; 684 } 685 } 686 687 // Then set the last index in the index array and make sure it is valid. 688 numElementsRequired = lastIndex + 1; 689 return numElementsRequired > 0; 690 } 691 692 bool WebGLRenderingContext::validateRenderingState(long numElementsRequired) 693 { 694 // Look in each enabled vertex attrib and find the smallest buffer size 695 long smallestNumElements = LONG_MAX; 696 for (unsigned i = 0; i < m_vertexAttribState.size(); ++i) { 697 const VertexAttribState& state = m_vertexAttribState[i]; 698 if (state.enabled && state.numElements < smallestNumElements) 699 smallestNumElements = state.numElements; 700 } 701 702 if (smallestNumElements == LONG_MAX) 703 smallestNumElements = 0; 704 705 return numElementsRequired <= smallestNumElements; 706 } 707 708 void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec) 709 { 710 UNUSED_PARAM(ec); 711 // Ensure we have a valid rendering state 712 if (first < 0 || count < 0 || !validateRenderingState(first + count)) { 713 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 714 return; 715 } 716 717 m_context->drawArrays(mode, first, count); 718 cleanupAfterGraphicsCall(true); 719 } 720 721 void WebGLRenderingContext::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset, ExceptionCode& ec) 722 { 723 UNUSED_PARAM(ec); 724 // Ensure we have a valid rendering state 725 long numElements; 726 727 if (offset < 0 || !validateElementArraySize(count, type, offset)) { 728 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 729 return; 730 } 731 732 if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) 733 if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) { 734 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 735 return; 736 } 737 738 m_context->drawElements(mode, count, type, offset); 739 cleanupAfterGraphicsCall(true); 740 } 741 742 void WebGLRenderingContext::enable(unsigned long cap) 743 { 744 m_context->enable(cap); 745 cleanupAfterGraphicsCall(false); 746 } 747 748 void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec) 749 { 750 UNUSED_PARAM(ec); 751 if (index >= m_maxVertexAttribs) { 752 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 753 return; 754 } 755 756 if (index >= m_vertexAttribState.size()) 757 m_vertexAttribState.resize(index + 1); 758 759 m_vertexAttribState[index].enabled = true; 760 761 m_context->enableVertexAttribArray(index); 762 cleanupAfterGraphicsCall(false); 763 } 764 765 void WebGLRenderingContext::finish() 766 { 767 m_context->finish(); 768 cleanupAfterGraphicsCall(true); 769 } 770 771 772 void WebGLRenderingContext::flush() 773 { 774 m_context->flush(); 775 cleanupAfterGraphicsCall(true); 776 } 777 778 void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec) 779 { 780 UNUSED_PARAM(ec); 781 if (buffer && buffer->context() != this) { 782 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 783 return; 784 } 785 // Don't allow the default framebuffer to be mutated; all current 786 // implementations use an FBO internally in place of the default 787 // FBO. 788 if (!m_framebufferBinding || !m_framebufferBinding->object()) { 789 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 790 return; 791 } 792 m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer); 793 cleanupAfterGraphicsCall(false); 794 } 795 796 void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec) 797 { 798 UNUSED_PARAM(ec); 799 if (texture && texture->context() != this) { 800 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 801 return; 802 } 803 // Don't allow the default framebuffer to be mutated; all current 804 // implementations use an FBO internally in place of the default 805 // FBO. 806 if (!m_framebufferBinding || !m_framebufferBinding->object()) { 807 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 808 return; 809 } 810 m_context->framebufferTexture2D(target, attachment, textarget, texture, level); 811 cleanupAfterGraphicsCall(false); 812 } 813 814 void WebGLRenderingContext::frontFace(unsigned long mode) 815 { 816 m_context->frontFace(mode); 817 cleanupAfterGraphicsCall(false); 818 } 819 820 void WebGLRenderingContext::generateMipmap(unsigned long target) 821 { 822 m_context->generateMipmap(target); 823 cleanupAfterGraphicsCall(false); 824 } 825 826 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec) 827 { 828 UNUSED_PARAM(ec); 829 ActiveInfo info; 830 if (!program || program->context() != this) { 831 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 832 return 0; 833 } 834 if (!m_context->getActiveAttrib(program, index, info)) { 835 return 0; 836 } 837 return WebGLActiveInfo::create(info.name, info.type, info.size); 838 } 839 840 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec) 841 { 842 UNUSED_PARAM(ec); 843 ActiveInfo info; 844 if (!program || program->context() != this) { 845 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 846 return 0; 847 } 848 if (!m_context->getActiveUniform(program, index, info)) { 849 return 0; 850 } 851 return WebGLActiveInfo::create(info.name, info.type, info.size); 852 } 853 854 int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name) 855 { 856 return m_context->getAttribLocation(program, name); 857 } 858 859 WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) 860 { 861 UNUSED_PARAM(ec); 862 if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) { 863 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 864 return WebGLGetInfo(); 865 } 866 867 if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) { 868 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 869 return WebGLGetInfo(); 870 } 871 872 WebGLStateRestorer(this, false); 873 int value; 874 m_context->getBufferParameteriv(target, pname, &value); 875 if (pname == GraphicsContext3D::BUFFER_SIZE) 876 return WebGLGetInfo(static_cast<long>(value)); 877 else 878 return WebGLGetInfo(static_cast<unsigned long>(value)); 879 } 880 881 PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes() 882 { 883 // We always need to return a new WebGLContextAttributes object to 884 // prevent the user from mutating any cached version. 885 return WebGLContextAttributes::create(m_context->getContextAttributes()); 886 } 887 888 unsigned long WebGLRenderingContext::getError() 889 { 890 return m_context->getError(); 891 } 892 893 WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec) 894 { 895 UNUSED_PARAM(ec); 896 if (target != GraphicsContext3D::FRAMEBUFFER 897 || (attachment != GraphicsContext3D::COLOR_ATTACHMENT0 898 && attachment != GraphicsContext3D::DEPTH_ATTACHMENT 899 && attachment != GraphicsContext3D::STENCIL_ATTACHMENT) 900 || (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 901 && pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 902 && pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 903 && pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE)) { 904 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 905 return WebGLGetInfo(); 906 } 907 908 if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { 909 WebGLStateRestorer(this, false); 910 int value; 911 m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value); 912 if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) 913 return WebGLGetInfo(static_cast<unsigned long>(value)); 914 else 915 return WebGLGetInfo(static_cast<long>(value)); 916 } else { 917 WebGLStateRestorer(this, false); 918 int type = 0; 919 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); 920 int value = 0; 921 m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value); 922 // FIXME: should consider canonicalizing these objects 923 switch (type) { 924 case GraphicsContext3D::RENDERBUFFER: { 925 RefPtr<WebGLRenderbuffer> tmp = WebGLRenderbuffer::create(this, value); 926 addObject(tmp.get()); 927 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(tmp)); 928 } 929 case GraphicsContext3D::TEXTURE: { 930 RefPtr<WebGLTexture> tmp = WebGLTexture::create(this, value); 931 addObject(tmp.get()); 932 return WebGLGetInfo(PassRefPtr<WebGLTexture>(tmp)); 933 } 934 default: 935 // FIXME: raise exception? 936 return WebGLGetInfo(); 937 } 938 } 939 } 940 941 WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec) 942 { 943 UNUSED_PARAM(ec); 944 WebGLStateRestorer(this, false); 945 switch (pname) { 946 case GraphicsContext3D::ACTIVE_TEXTURE: 947 return getUnsignedLongParameter(pname); 948 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE: 949 return getWebGLFloatArrayParameter(pname); 950 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE: 951 return getWebGLFloatArrayParameter(pname); 952 case GraphicsContext3D::ALPHA_BITS: 953 return getLongParameter(pname); 954 case GraphicsContext3D::ARRAY_BUFFER_BINDING: 955 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer)); 956 case GraphicsContext3D::BLEND: 957 return getBooleanParameter(pname); 958 case GraphicsContext3D::BLEND_COLOR: 959 return getWebGLFloatArrayParameter(pname); 960 case GraphicsContext3D::BLEND_DST_ALPHA: 961 return getUnsignedLongParameter(pname); 962 case GraphicsContext3D::BLEND_DST_RGB: 963 return getUnsignedLongParameter(pname); 964 case GraphicsContext3D::BLEND_EQUATION_ALPHA: 965 return getUnsignedLongParameter(pname); 966 case GraphicsContext3D::BLEND_EQUATION_RGB: 967 return getUnsignedLongParameter(pname); 968 case GraphicsContext3D::BLEND_SRC_ALPHA: 969 return getUnsignedLongParameter(pname); 970 case GraphicsContext3D::BLEND_SRC_RGB: 971 return getUnsignedLongParameter(pname); 972 case GraphicsContext3D::BLUE_BITS: 973 return getLongParameter(pname); 974 case GraphicsContext3D::COLOR_CLEAR_VALUE: 975 return getWebGLFloatArrayParameter(pname); 976 case GraphicsContext3D::COLOR_WRITEMASK: 977 return getWebGLUnsignedByteArrayParameter(pname); 978 case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS: 979 // Defined as null in the spec 980 return WebGLGetInfo(); 981 case GraphicsContext3D::CULL_FACE: 982 return getBooleanParameter(pname); 983 case GraphicsContext3D::CULL_FACE_MODE: 984 return getUnsignedLongParameter(pname); 985 case GraphicsContext3D::CURRENT_PROGRAM: 986 return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram)); 987 case GraphicsContext3D::DEPTH_BITS: 988 return getLongParameter(pname); 989 case GraphicsContext3D::DEPTH_CLEAR_VALUE: 990 return getFloatParameter(pname); 991 case GraphicsContext3D::DEPTH_FUNC: 992 return getUnsignedLongParameter(pname); 993 case GraphicsContext3D::DEPTH_RANGE: 994 return getWebGLFloatArrayParameter(pname); 995 case GraphicsContext3D::DEPTH_TEST: 996 return getBooleanParameter(pname); 997 case GraphicsContext3D::DEPTH_WRITEMASK: 998 return getBooleanParameter(pname); 999 case GraphicsContext3D::DITHER: 1000 return getBooleanParameter(pname); 1001 case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING: 1002 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundElementArrayBuffer)); 1003 case GraphicsContext3D::FRAMEBUFFER_BINDING: 1004 return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding)); 1005 case GraphicsContext3D::FRONT_FACE: 1006 return getUnsignedLongParameter(pname); 1007 case GraphicsContext3D::GENERATE_MIPMAP_HINT: 1008 return getUnsignedLongParameter(pname); 1009 case GraphicsContext3D::GREEN_BITS: 1010 return getLongParameter(pname); 1011 case GraphicsContext3D::LINE_WIDTH: 1012 return getFloatParameter(pname); 1013 case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS: 1014 return getLongParameter(pname); 1015 case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE: 1016 return getLongParameter(pname); 1017 case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS: 1018 return getLongParameter(pname); 1019 case GraphicsContext3D::MAX_RENDERBUFFER_SIZE: 1020 return getLongParameter(pname); 1021 case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS: 1022 return getLongParameter(pname); 1023 case GraphicsContext3D::MAX_TEXTURE_SIZE: 1024 return getLongParameter(pname); 1025 case GraphicsContext3D::MAX_VARYING_VECTORS: 1026 return getLongParameter(pname); 1027 case GraphicsContext3D::MAX_VERTEX_ATTRIBS: 1028 return getLongParameter(pname); 1029 case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS: 1030 return getLongParameter(pname); 1031 case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS: 1032 return getLongParameter(pname); 1033 case GraphicsContext3D::MAX_VIEWPORT_DIMS: 1034 return getWebGLIntArrayParameter(pname); 1035 case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS: 1036 return getLongParameter(pname); 1037 case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS: 1038 // FIXME: should we always return 0 for this? 1039 return getLongParameter(pname); 1040 case GraphicsContext3D::PACK_ALIGNMENT: 1041 return getLongParameter(pname); 1042 case GraphicsContext3D::POLYGON_OFFSET_FACTOR: 1043 return getFloatParameter(pname); 1044 case GraphicsContext3D::POLYGON_OFFSET_FILL: 1045 return getBooleanParameter(pname); 1046 case GraphicsContext3D::POLYGON_OFFSET_UNITS: 1047 return getFloatParameter(pname); 1048 case GraphicsContext3D::RED_BITS: 1049 return getLongParameter(pname); 1050 case GraphicsContext3D::RENDERBUFFER_BINDING: 1051 return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding)); 1052 case GraphicsContext3D::SAMPLE_BUFFERS: 1053 return getLongParameter(pname); 1054 case GraphicsContext3D::SAMPLE_COVERAGE_INVERT: 1055 return getBooleanParameter(pname); 1056 case GraphicsContext3D::SAMPLE_COVERAGE_VALUE: 1057 return getFloatParameter(pname); 1058 case GraphicsContext3D::SAMPLES: 1059 return getLongParameter(pname); 1060 case GraphicsContext3D::SCISSOR_BOX: 1061 return getWebGLIntArrayParameter(pname); 1062 case GraphicsContext3D::SCISSOR_TEST: 1063 return getBooleanParameter(pname); 1064 case GraphicsContext3D::STENCIL_BACK_FAIL: 1065 return getUnsignedLongParameter(pname); 1066 case GraphicsContext3D::STENCIL_BACK_FUNC: 1067 return getUnsignedLongParameter(pname); 1068 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL: 1069 return getUnsignedLongParameter(pname); 1070 case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS: 1071 return getUnsignedLongParameter(pname); 1072 case GraphicsContext3D::STENCIL_BACK_REF: 1073 return getLongParameter(pname); 1074 case GraphicsContext3D::STENCIL_BACK_VALUE_MASK: 1075 return getUnsignedLongParameter(pname); 1076 case GraphicsContext3D::STENCIL_BACK_WRITEMASK: 1077 return getUnsignedLongParameter(pname); 1078 case GraphicsContext3D::STENCIL_BITS: 1079 return getLongParameter(pname); 1080 case GraphicsContext3D::STENCIL_CLEAR_VALUE: 1081 return getLongParameter(pname); 1082 case GraphicsContext3D::STENCIL_FAIL: 1083 return getUnsignedLongParameter(pname); 1084 case GraphicsContext3D::STENCIL_FUNC: 1085 return getUnsignedLongParameter(pname); 1086 case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL: 1087 return getUnsignedLongParameter(pname); 1088 case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS: 1089 return getUnsignedLongParameter(pname); 1090 case GraphicsContext3D::STENCIL_REF: 1091 return getLongParameter(pname); 1092 case GraphicsContext3D::STENCIL_TEST: 1093 return getBooleanParameter(pname); 1094 case GraphicsContext3D::STENCIL_VALUE_MASK: 1095 return getUnsignedLongParameter(pname); 1096 case GraphicsContext3D::STENCIL_WRITEMASK: 1097 return getUnsignedLongParameter(pname); 1098 case GraphicsContext3D::SUBPIXEL_BITS: 1099 return getLongParameter(pname); 1100 case GraphicsContext3D::TEXTURE_BINDING_2D: 1101 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding)); 1102 case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP: 1103 return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding)); 1104 case GraphicsContext3D::UNPACK_ALIGNMENT: 1105 // FIXME: should this be "long" in the spec? 1106 return getIntParameter(pname); 1107 case GraphicsContext3D::VIEWPORT: 1108 return getWebGLIntArrayParameter(pname); 1109 default: 1110 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1111 return WebGLGetInfo(); 1112 } 1113 } 1114 1115 WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec) 1116 { 1117 UNUSED_PARAM(ec); 1118 if (!program || program->context() != this) { 1119 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1120 return WebGLGetInfo(); 1121 } 1122 1123 WebGLStateRestorer(this, false); 1124 int value = 0; 1125 switch (pname) { 1126 case GraphicsContext3D::DELETE_STATUS: 1127 case GraphicsContext3D::LINK_STATUS: 1128 case GraphicsContext3D::VALIDATE_STATUS: 1129 m_context->getProgramiv(program, pname, &value); 1130 return WebGLGetInfo(static_cast<bool>(value)); 1131 case GraphicsContext3D::INFO_LOG_LENGTH: 1132 case GraphicsContext3D::ATTACHED_SHADERS: 1133 case GraphicsContext3D::ACTIVE_ATTRIBUTES: 1134 case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH: 1135 case GraphicsContext3D::ACTIVE_UNIFORMS: 1136 case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH: 1137 m_context->getProgramiv(program, pname, &value); 1138 return WebGLGetInfo(static_cast<long>(value)); 1139 default: 1140 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1141 return WebGLGetInfo(); 1142 } 1143 } 1144 1145 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec) 1146 { 1147 UNUSED_PARAM(ec); 1148 if (!program || program->context() != this) { 1149 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1150 return ""; 1151 } 1152 WebGLStateRestorer(this, false); 1153 return m_context->getProgramInfoLog(program); 1154 } 1155 1156 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) 1157 { 1158 UNUSED_PARAM(ec); 1159 if (target != GraphicsContext3D::RENDERBUFFER) { 1160 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1161 return WebGLGetInfo(); 1162 } 1163 1164 WebGLStateRestorer(this, false); 1165 int value = 0; 1166 switch (pname) { 1167 case GraphicsContext3D::RENDERBUFFER_WIDTH: 1168 case GraphicsContext3D::RENDERBUFFER_HEIGHT: 1169 case GraphicsContext3D::RENDERBUFFER_RED_SIZE: 1170 case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE: 1171 case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE: 1172 case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE: 1173 case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE: 1174 case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE: 1175 m_context->getRenderbufferParameteriv(target, pname, &value); 1176 return WebGLGetInfo(static_cast<long>(value)); 1177 case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT: 1178 m_context->getRenderbufferParameteriv(target, pname, &value); 1179 return WebGLGetInfo(static_cast<unsigned long>(value)); 1180 default: 1181 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1182 return WebGLGetInfo(); 1183 } 1184 } 1185 1186 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec) 1187 { 1188 UNUSED_PARAM(ec); 1189 if (!shader || shader->context() != this) { 1190 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1191 return WebGLGetInfo(); 1192 } 1193 WebGLStateRestorer(this, false); 1194 int value = 0; 1195 switch (pname) { 1196 case GraphicsContext3D::DELETE_STATUS: 1197 case GraphicsContext3D::COMPILE_STATUS: 1198 m_context->getShaderiv(shader, pname, &value); 1199 return WebGLGetInfo(static_cast<bool>(value)); 1200 case GraphicsContext3D::SHADER_TYPE: 1201 m_context->getShaderiv(shader, pname, &value); 1202 return WebGLGetInfo(static_cast<unsigned long>(value)); 1203 case GraphicsContext3D::INFO_LOG_LENGTH: 1204 case GraphicsContext3D::SHADER_SOURCE_LENGTH: 1205 m_context->getShaderiv(shader, pname, &value); 1206 return WebGLGetInfo(static_cast<long>(value)); 1207 default: 1208 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1209 return WebGLGetInfo(); 1210 } 1211 } 1212 1213 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec) 1214 { 1215 UNUSED_PARAM(ec); 1216 if (!shader || shader->context() != this) { 1217 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1218 return ""; 1219 } 1220 WebGLStateRestorer(this, false); 1221 return m_context->getShaderInfoLog(shader); 1222 } 1223 1224 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec) 1225 { 1226 UNUSED_PARAM(ec); 1227 if (!shader || shader->context() != this) { 1228 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1229 return ""; 1230 } 1231 WebGLStateRestorer(this, false); 1232 return m_context->getShaderSource(shader); 1233 } 1234 1235 String WebGLRenderingContext::getString(unsigned long name) 1236 { 1237 WebGLStateRestorer(this, false); 1238 return m_context->getString(name); 1239 } 1240 1241 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec) 1242 { 1243 UNUSED_PARAM(ec); 1244 if (target != GraphicsContext3D::TEXTURE_2D 1245 && target != GraphicsContext3D::TEXTURE_CUBE_MAP) { 1246 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1247 return WebGLGetInfo(); 1248 } 1249 WebGLStateRestorer(this, false); 1250 int value = 0; 1251 switch (pname) { 1252 case GraphicsContext3D::TEXTURE_MAG_FILTER: 1253 case GraphicsContext3D::TEXTURE_MIN_FILTER: 1254 case GraphicsContext3D::TEXTURE_WRAP_S: 1255 case GraphicsContext3D::TEXTURE_WRAP_T: 1256 m_context->getTexParameteriv(target, pname, &value); 1257 return WebGLGetInfo(static_cast<unsigned long>(value)); 1258 default: 1259 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1260 return WebGLGetInfo(); 1261 } 1262 } 1263 1264 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec) 1265 { 1266 UNUSED_PARAM(ec); 1267 if (!program || uniformLocation->program() != program || program->context() != this) { 1268 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1269 return WebGLGetInfo(); 1270 } 1271 long location = uniformLocation->location(); 1272 1273 WebGLStateRestorer(this, false); 1274 // FIXME: make this more efficient using WebGLUniformLocation and caching types in it 1275 int activeUniforms = 0; 1276 m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms); 1277 for (int i = 0; i < activeUniforms; i++) { 1278 ActiveInfo info; 1279 if (!m_context->getActiveUniform(program, i, info)) 1280 return WebGLGetInfo(); 1281 // Now need to look this up by name again to find its location 1282 long loc = m_context->getUniformLocation(program, info.name); 1283 if (loc == location) { 1284 // Found it. Use the type in the ActiveInfo to determine the return type. 1285 GraphicsContext3D::WebGLEnumType baseType; 1286 unsigned length; 1287 switch (info.type) { 1288 case GraphicsContext3D::BOOL: 1289 baseType = GraphicsContext3D::BOOL; 1290 length = 1; 1291 break; 1292 case GraphicsContext3D::BOOL_VEC2: 1293 baseType = GraphicsContext3D::BOOL; 1294 length = 2; 1295 break; 1296 case GraphicsContext3D::BOOL_VEC3: 1297 baseType = GraphicsContext3D::BOOL; 1298 length = 3; 1299 break; 1300 case GraphicsContext3D::BOOL_VEC4: 1301 baseType = GraphicsContext3D::BOOL; 1302 length = 4; 1303 break; 1304 case GraphicsContext3D::INT: 1305 baseType = GraphicsContext3D::INT; 1306 length = 1; 1307 break; 1308 case GraphicsContext3D::INT_VEC2: 1309 baseType = GraphicsContext3D::INT; 1310 length = 2; 1311 break; 1312 case GraphicsContext3D::INT_VEC3: 1313 baseType = GraphicsContext3D::INT; 1314 length = 3; 1315 break; 1316 case GraphicsContext3D::INT_VEC4: 1317 baseType = GraphicsContext3D::INT; 1318 length = 4; 1319 break; 1320 case GraphicsContext3D::FLOAT: 1321 baseType = GraphicsContext3D::FLOAT; 1322 length = 1; 1323 break; 1324 case GraphicsContext3D::FLOAT_VEC2: 1325 baseType = GraphicsContext3D::FLOAT; 1326 length = 2; 1327 break; 1328 case GraphicsContext3D::FLOAT_VEC3: 1329 baseType = GraphicsContext3D::FLOAT; 1330 length = 3; 1331 break; 1332 case GraphicsContext3D::FLOAT_VEC4: 1333 baseType = GraphicsContext3D::FLOAT; 1334 length = 4; 1335 break; 1336 case GraphicsContext3D::FLOAT_MAT2: 1337 baseType = GraphicsContext3D::FLOAT; 1338 length = 4; 1339 break; 1340 case GraphicsContext3D::FLOAT_MAT3: 1341 baseType = GraphicsContext3D::FLOAT; 1342 length = 9; 1343 break; 1344 case GraphicsContext3D::FLOAT_MAT4: 1345 baseType = GraphicsContext3D::FLOAT; 1346 length = 16; 1347 break; 1348 default: 1349 // Can't handle this type 1350 // FIXME: what to do about samplers? 1351 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1352 return WebGLGetInfo(); 1353 } 1354 switch (baseType) { 1355 case GraphicsContext3D::FLOAT: { 1356 float value[16] = {0}; 1357 m_context->getUniformfv(program, location, value); 1358 if (length == 1) 1359 return WebGLGetInfo(value[0]); 1360 else 1361 return WebGLGetInfo(WebGLFloatArray::create(value, length)); 1362 } 1363 case GraphicsContext3D::INT: { 1364 int value[16] = {0}; 1365 m_context->getUniformiv(program, location, value); 1366 if (length == 1) 1367 return WebGLGetInfo(static_cast<long>(value[0])); 1368 else 1369 return WebGLGetInfo(WebGLIntArray::create(value, length)); 1370 } 1371 case GraphicsContext3D::BOOL: { 1372 int value[16] = {0}; 1373 m_context->getUniformiv(program, location, value); 1374 if (length == 1) 1375 return WebGLGetInfo(static_cast<bool>(value[0])); 1376 else { 1377 unsigned char boolValue[16] = {0}; 1378 for (unsigned j = 0; j < length; j++) 1379 boolValue[j] = static_cast<bool>(value[j]); 1380 return WebGLGetInfo(WebGLUnsignedByteArray::create(boolValue, length)); 1381 } 1382 } 1383 default: 1384 notImplemented(); 1385 } 1386 } 1387 } 1388 // If we get here, something went wrong in our unfortunately complex logic above 1389 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1390 return WebGLGetInfo(); 1391 } 1392 1393 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec) 1394 { 1395 UNUSED_PARAM(ec); 1396 if (!program || program->context() != this) { 1397 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1398 return 0; 1399 } 1400 WebGLStateRestorer(this, false); 1401 return WebGLUniformLocation::create(program, m_context->getUniformLocation(program, name)); 1402 } 1403 1404 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec) 1405 { 1406 UNUSED_PARAM(ec); 1407 WebGLStateRestorer(this, false); 1408 switch (pname) { 1409 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { 1410 int name = 0; 1411 m_context->getVertexAttribiv(index, pname, &name); 1412 if (name == 0) 1413 return WebGLGetInfo(); 1414 RefPtr<WebGLBuffer> tmp = WebGLBuffer::create(this, name); 1415 addObject(tmp.get()); 1416 return WebGLGetInfo(PassRefPtr<WebGLBuffer>(tmp)); 1417 } 1418 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED: 1419 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED: { 1420 int value = 0; 1421 m_context->getVertexAttribiv(index, pname, &value); 1422 return WebGLGetInfo(static_cast<bool>(value)); 1423 } 1424 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE: 1425 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE: { 1426 int value = 0; 1427 m_context->getVertexAttribiv(index, pname, &value); 1428 return WebGLGetInfo(static_cast<long>(value)); 1429 } 1430 case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE: { 1431 int value = 0; 1432 m_context->getVertexAttribiv(index, pname, &value); 1433 return WebGLGetInfo(static_cast<unsigned long>(value)); 1434 } 1435 case GraphicsContext3D::CURRENT_VERTEX_ATTRIB: { 1436 float value[4] = {0}; 1437 m_context->getVertexAttribfv(index, pname, value); 1438 return WebGLGetInfo(WebGLFloatArray::create(value, 4)); 1439 } 1440 default: { 1441 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM); 1442 return WebGLGetInfo(); 1443 } 1444 } 1445 } 1446 1447 long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname) 1448 { 1449 long result = m_context->getVertexAttribOffset(index, pname); 1450 cleanupAfterGraphicsCall(false); 1451 return result; 1452 } 1453 1454 void WebGLRenderingContext::hint(unsigned long target, unsigned long mode) 1455 { 1456 m_context->hint(target, mode); 1457 cleanupAfterGraphicsCall(false); 1458 } 1459 1460 bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer) 1461 { 1462 if (!buffer) 1463 return false; 1464 1465 return m_context->isBuffer(buffer); 1466 } 1467 1468 bool WebGLRenderingContext::isEnabled(unsigned long cap) 1469 { 1470 return m_context->isEnabled(cap); 1471 } 1472 1473 bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer) 1474 { 1475 if (!framebuffer) 1476 return false; 1477 1478 return m_context->isFramebuffer(framebuffer); 1479 } 1480 1481 bool WebGLRenderingContext::isProgram(WebGLProgram* program) 1482 { 1483 if (!program) 1484 return false; 1485 1486 return m_context->isProgram(program); 1487 } 1488 1489 bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer) 1490 { 1491 if (!renderbuffer) 1492 return false; 1493 1494 return m_context->isRenderbuffer(renderbuffer); 1495 } 1496 1497 bool WebGLRenderingContext::isShader(WebGLShader* shader) 1498 { 1499 if (!shader) 1500 return false; 1501 1502 return m_context->isShader(shader); 1503 } 1504 1505 bool WebGLRenderingContext::isTexture(WebGLTexture* texture) 1506 { 1507 if (!texture) 1508 return false; 1509 1510 return m_context->isTexture(texture); 1511 } 1512 1513 void WebGLRenderingContext::lineWidth(double width) 1514 { 1515 m_context->lineWidth((float) width); 1516 cleanupAfterGraphicsCall(false); 1517 } 1518 1519 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec) 1520 { 1521 UNUSED_PARAM(ec); 1522 if (!program || program->context() != this) { 1523 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1524 return; 1525 } 1526 1527 m_context->linkProgram(program); 1528 cleanupAfterGraphicsCall(false); 1529 } 1530 1531 void WebGLRenderingContext::pixelStorei(unsigned long pname, long param) 1532 { 1533 m_context->pixelStorei(pname, param); 1534 cleanupAfterGraphicsCall(false); 1535 } 1536 1537 void WebGLRenderingContext::polygonOffset(double factor, double units) 1538 { 1539 m_context->polygonOffset((float) factor, (float) units); 1540 cleanupAfterGraphicsCall(false); 1541 } 1542 1543 PassRefPtr<WebGLArray> WebGLRenderingContext::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type) 1544 { 1545 RefPtr<WebGLArray> array = m_context->readPixels(x, y, width, height, format, type); 1546 cleanupAfterGraphicsCall(false); 1547 return array; 1548 } 1549 1550 void WebGLRenderingContext::releaseShaderCompiler() 1551 { 1552 m_context->releaseShaderCompiler(); 1553 cleanupAfterGraphicsCall(false); 1554 } 1555 1556 void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) 1557 { 1558 m_context->renderbufferStorage(target, internalformat, width, height); 1559 cleanupAfterGraphicsCall(false); 1560 } 1561 1562 void WebGLRenderingContext::sampleCoverage(double value, bool invert) 1563 { 1564 m_context->sampleCoverage((float) value, invert); 1565 cleanupAfterGraphicsCall(false); 1566 } 1567 1568 void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height) 1569 { 1570 m_context->scissor(x, y, width, height); 1571 cleanupAfterGraphicsCall(false); 1572 } 1573 1574 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec) 1575 { 1576 UNUSED_PARAM(ec); 1577 if (!shader || shader->context() != this) { 1578 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1579 return; 1580 } 1581 m_context->shaderSource(shader, string); 1582 cleanupAfterGraphicsCall(false); 1583 } 1584 1585 void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask) 1586 { 1587 m_context->stencilFunc(func, ref, mask); 1588 cleanupAfterGraphicsCall(false); 1589 } 1590 1591 void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask) 1592 { 1593 m_context->stencilFuncSeparate(face, func, ref, mask); 1594 cleanupAfterGraphicsCall(false); 1595 } 1596 1597 void WebGLRenderingContext::stencilMask(unsigned long mask) 1598 { 1599 m_context->stencilMask(mask); 1600 cleanupAfterGraphicsCall(false); 1601 } 1602 1603 void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask) 1604 { 1605 m_context->stencilMaskSeparate(face, mask); 1606 cleanupAfterGraphicsCall(false); 1607 } 1608 1609 void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass) 1610 { 1611 m_context->stencilOp(fail, zfail, zpass); 1612 cleanupAfterGraphicsCall(false); 1613 } 1614 1615 void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass) 1616 { 1617 m_context->stencilOpSeparate(face, fail, zfail, zpass); 1618 cleanupAfterGraphicsCall(false); 1619 } 1620 1621 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat, 1622 unsigned width, unsigned height, unsigned border, 1623 unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode& ec) 1624 { 1625 // FIXME: For now we ignore any errors returned 1626 // FIXME: Need to make sure passed buffer has enough bytes to define the texture 1627 ec = 0; 1628 m_context->texImage2D(target, level, internalformat, width, height, 1629 border, format, type, pixels ? pixels->baseAddress() : 0); 1630 cleanupAfterGraphicsCall(false); 1631 } 1632 1633 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels, 1634 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1635 { 1636 // FIXME: For now we ignore any errors returned 1637 // FIXME: Need a form of this call that can take both a pixel buffer and flipY and premultiplyAlpha flags 1638 UNUSED_PARAM(flipY); 1639 UNUSED_PARAM(premultiplyAlpha); 1640 ec = 0; 1641 m_context->texImage2D(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels->data()->data()->data()); 1642 //RLP: m_context->texImage2D(target, level, pixels, flipY, premultiplyAlpha); 1643 cleanupAfterGraphicsCall(false); 1644 } 1645 1646 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image, 1647 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1648 { 1649 ec = 0; 1650 if (!image) { 1651 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1652 return; 1653 } 1654 1655 CachedImage* cachedImage = image->cachedImage(); 1656 if (!cachedImage) { 1657 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1658 return; 1659 } 1660 1661 // FIXME: For now we ignore any errors returned 1662 m_context->texImage2D(target, level, cachedImage->image(), flipY, premultiplyAlpha); 1663 cleanupAfterGraphicsCall(false); 1664 } 1665 1666 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas, 1667 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1668 { 1669 ec = 0; 1670 if (!canvas) { 1671 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1672 return; 1673 } 1674 1675 ImageBuffer* buffer = canvas->buffer(); 1676 if (!buffer) { 1677 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1678 return; 1679 } 1680 1681 // FIXME: For now we ignore any errors returned 1682 m_context->texImage2D(target, level, buffer->image(), flipY, premultiplyAlpha); 1683 cleanupAfterGraphicsCall(false); 1684 } 1685 1686 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video, 1687 bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1688 { 1689 // FIXME: Need implement this call 1690 UNUSED_PARAM(target); 1691 UNUSED_PARAM(level); 1692 UNUSED_PARAM(video); 1693 UNUSED_PARAM(flipY); 1694 UNUSED_PARAM(premultiplyAlpha); 1695 1696 ec = 0; 1697 cleanupAfterGraphicsCall(false); 1698 } 1699 1700 void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param) 1701 { 1702 m_context->texParameterf(target, pname, param); 1703 cleanupAfterGraphicsCall(false); 1704 } 1705 1706 void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param) 1707 { 1708 m_context->texParameteri(target, pname, param); 1709 cleanupAfterGraphicsCall(false); 1710 } 1711 1712 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, 1713 unsigned width, unsigned height, 1714 unsigned format, unsigned type, WebGLArray* pixels, ExceptionCode& ec) 1715 { 1716 // FIXME: For now we ignore any errors returned 1717 // FIXME: Need to make sure passed buffer has enough bytes to define the texture 1718 ec = 0; 1719 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels ? pixels->baseAddress() : 0); 1720 cleanupAfterGraphicsCall(false); 1721 } 1722 1723 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, 1724 ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1725 { 1726 // FIXME: For now we ignore any errors returned 1727 UNUSED_PARAM(flipY); 1728 UNUSED_PARAM(premultiplyAlpha); 1729 ec = 0; 1730 m_context->texSubImage2D(target, level, xoffset, yoffset, pixels->width(), pixels->height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels->data()->data()->data()); 1731 //RLP: m_context->texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, premultiplyAlpha); 1732 cleanupAfterGraphicsCall(false); 1733 } 1734 1735 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, 1736 HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1737 { 1738 // FIXME: For now we ignore any errors returned 1739 ec = 0; 1740 if (!image) { 1741 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1742 return; 1743 } 1744 1745 CachedImage* cachedImage = image->cachedImage(); 1746 if (!cachedImage) { 1747 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1748 return; 1749 } 1750 1751 m_context->texSubImage2D(target, level, xoffset, yoffset, cachedImage->image(), flipY, premultiplyAlpha); 1752 cleanupAfterGraphicsCall(false); 1753 } 1754 1755 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, 1756 HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1757 { 1758 ec = 0; 1759 if (!canvas) { 1760 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1761 return; 1762 } 1763 1764 ImageBuffer* buffer = canvas->buffer(); 1765 if (!buffer) { 1766 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1767 return; 1768 } 1769 1770 // FIXME: For now we ignore any errors returned 1771 m_context->texSubImage2D(target, level, xoffset, yoffset, buffer->image(), flipY, premultiplyAlpha); 1772 cleanupAfterGraphicsCall(false); 1773 } 1774 1775 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, 1776 HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 1777 { 1778 // FIXME: Need to implement this call 1779 UNUSED_PARAM(target); 1780 UNUSED_PARAM(level); 1781 UNUSED_PARAM(xoffset); 1782 UNUSED_PARAM(yoffset); 1783 UNUSED_PARAM(video); 1784 UNUSED_PARAM(flipY); 1785 UNUSED_PARAM(premultiplyAlpha); 1786 ec = 0; 1787 cleanupAfterGraphicsCall(false); 1788 } 1789 1790 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec) 1791 { 1792 UNUSED_PARAM(ec); 1793 if (!location || location->program() != m_currentProgram) { 1794 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1795 return; 1796 } 1797 1798 m_context->uniform1f(location->location(), x); 1799 cleanupAfterGraphicsCall(false); 1800 } 1801 1802 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec) 1803 { 1804 UNUSED_PARAM(ec); 1805 if (!location || location->program() != m_currentProgram) { 1806 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1807 return; 1808 } 1809 1810 if (!v) { 1811 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1812 return; 1813 } 1814 m_context->uniform1fv(location->location(), v->data(), v->length()); 1815 cleanupAfterGraphicsCall(false); 1816 } 1817 1818 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) 1819 { 1820 UNUSED_PARAM(ec); 1821 if (!location || location->program() != m_currentProgram) { 1822 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1823 return; 1824 } 1825 1826 if (!v) { 1827 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1828 return; 1829 } 1830 m_context->uniform1fv(location->location(), v, size); 1831 cleanupAfterGraphicsCall(false); 1832 } 1833 1834 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec) 1835 { 1836 UNUSED_PARAM(ec); 1837 if (!location || location->program() != m_currentProgram) { 1838 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1839 return; 1840 } 1841 1842 m_context->uniform1i(location->location(), x); 1843 cleanupAfterGraphicsCall(false); 1844 } 1845 1846 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec) 1847 { 1848 UNUSED_PARAM(ec); 1849 if (!location || location->program() != m_currentProgram) { 1850 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1851 return; 1852 } 1853 1854 if (!v) { 1855 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1856 return; 1857 } 1858 m_context->uniform1iv(location->location(), v->data(), v->length()); 1859 cleanupAfterGraphicsCall(false); 1860 } 1861 1862 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) 1863 { 1864 UNUSED_PARAM(ec); 1865 if (!location || location->program() != m_currentProgram) { 1866 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1867 return; 1868 } 1869 1870 if (!v) { 1871 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1872 return; 1873 } 1874 m_context->uniform1iv(location->location(), v, size); 1875 cleanupAfterGraphicsCall(false); 1876 } 1877 1878 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec) 1879 { 1880 UNUSED_PARAM(ec); 1881 if (!location || location->program() != m_currentProgram) { 1882 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1883 return; 1884 } 1885 1886 m_context->uniform2f(location->location(), x, y); 1887 cleanupAfterGraphicsCall(false); 1888 } 1889 1890 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec) 1891 { 1892 UNUSED_PARAM(ec); 1893 if (!location || location->program() != m_currentProgram) { 1894 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1895 return; 1896 } 1897 1898 if (!v) { 1899 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1900 return; 1901 } 1902 // FIXME: length needs to be a multiple of 2 1903 m_context->uniform2fv(location->location(), v->data(), v->length() / 2); 1904 cleanupAfterGraphicsCall(false); 1905 } 1906 1907 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) 1908 { 1909 UNUSED_PARAM(ec); 1910 if (!location || location->program() != m_currentProgram) { 1911 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1912 return; 1913 } 1914 1915 if (!v) { 1916 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1917 return; 1918 } 1919 // FIXME: length needs to be a multiple of 2 1920 m_context->uniform2fv(location->location(), v, size / 2); 1921 cleanupAfterGraphicsCall(false); 1922 } 1923 1924 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec) 1925 { 1926 UNUSED_PARAM(ec); 1927 if (!location || location->program() != m_currentProgram) { 1928 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1929 return; 1930 } 1931 1932 m_context->uniform2i(location->location(), x, y); 1933 cleanupAfterGraphicsCall(false); 1934 } 1935 1936 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec) 1937 { 1938 UNUSED_PARAM(ec); 1939 if (!location || location->program() != m_currentProgram) { 1940 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1941 return; 1942 } 1943 1944 if (!v) { 1945 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1946 return; 1947 } 1948 // FIXME: length needs to be a multiple of 2 1949 m_context->uniform2iv(location->location(), v->data(), v->length() / 2); 1950 cleanupAfterGraphicsCall(false); 1951 } 1952 1953 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) 1954 { 1955 UNUSED_PARAM(ec); 1956 if (!location || location->program() != m_currentProgram) { 1957 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1958 return; 1959 } 1960 1961 if (!v) { 1962 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1963 return; 1964 } 1965 // FIXME: length needs to be a multiple of 2 1966 m_context->uniform2iv(location->location(), v, size / 2); 1967 cleanupAfterGraphicsCall(false); 1968 } 1969 1970 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec) 1971 { 1972 UNUSED_PARAM(ec); 1973 if (!location || location->program() != m_currentProgram) { 1974 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1975 return; 1976 } 1977 1978 m_context->uniform3f(location->location(), x, y, z); 1979 cleanupAfterGraphicsCall(false); 1980 } 1981 1982 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec) 1983 { 1984 UNUSED_PARAM(ec); 1985 if (!location || location->program() != m_currentProgram) { 1986 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 1987 return; 1988 } 1989 1990 if (!v) { 1991 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 1992 return; 1993 } 1994 // FIXME: length needs to be a multiple of 3 1995 m_context->uniform3fv(location->location(), v->data(), v->length() / 3); 1996 cleanupAfterGraphicsCall(false); 1997 } 1998 1999 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) 2000 { 2001 UNUSED_PARAM(ec); 2002 if (!location || location->program() != m_currentProgram) { 2003 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2004 return; 2005 } 2006 2007 if (!v) { 2008 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2009 return; 2010 } 2011 // FIXME: length needs to be a multiple of 3 2012 m_context->uniform3fv(location->location(), v, size / 3); 2013 cleanupAfterGraphicsCall(false); 2014 } 2015 2016 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec) 2017 { 2018 UNUSED_PARAM(ec); 2019 if (!location || location->program() != m_currentProgram) { 2020 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2021 return; 2022 } 2023 2024 m_context->uniform3i(location->location(), x, y, z); 2025 cleanupAfterGraphicsCall(false); 2026 } 2027 2028 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec) 2029 { 2030 UNUSED_PARAM(ec); 2031 if (!location || location->program() != m_currentProgram) { 2032 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2033 return; 2034 } 2035 2036 if (!v) { 2037 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2038 return; 2039 } 2040 // FIXME: length needs to be a multiple of 3 2041 m_context->uniform3iv(location->location(), v->data(), v->length() / 3); 2042 cleanupAfterGraphicsCall(false); 2043 } 2044 2045 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) 2046 { 2047 UNUSED_PARAM(ec); 2048 if (!location || location->program() != m_currentProgram) { 2049 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2050 return; 2051 } 2052 2053 if (!v) { 2054 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2055 return; 2056 } 2057 // FIXME: length needs to be a multiple of 3 2058 m_context->uniform3iv(location->location(), v, size / 3); 2059 cleanupAfterGraphicsCall(false); 2060 } 2061 2062 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec) 2063 { 2064 UNUSED_PARAM(ec); 2065 if (!location || location->program() != m_currentProgram) { 2066 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2067 return; 2068 } 2069 2070 m_context->uniform4f(location->location(), x, y, z, w); 2071 cleanupAfterGraphicsCall(false); 2072 } 2073 2074 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, WebGLFloatArray* v, ExceptionCode& ec) 2075 { 2076 UNUSED_PARAM(ec); 2077 if (!location || location->program() != m_currentProgram) { 2078 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2079 return; 2080 } 2081 2082 if (!v) { 2083 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2084 return; 2085 } 2086 // FIXME: length needs to be a multiple of 4 2087 m_context->uniform4fv(location->location(), v->data(), v->length() / 4); 2088 cleanupAfterGraphicsCall(false); 2089 } 2090 2091 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec) 2092 { 2093 UNUSED_PARAM(ec); 2094 if (!location || location->program() != m_currentProgram) { 2095 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2096 return; 2097 } 2098 2099 if (!v) { 2100 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2101 return; 2102 } 2103 // FIXME: length needs to be a multiple of 4 2104 m_context->uniform4fv(location->location(), v, size / 4); 2105 cleanupAfterGraphicsCall(false); 2106 } 2107 2108 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec) 2109 { 2110 UNUSED_PARAM(ec); 2111 if (!location || location->program() != m_currentProgram) { 2112 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2113 return; 2114 } 2115 2116 m_context->uniform4i(location->location(), x, y, z, w); 2117 cleanupAfterGraphicsCall(false); 2118 } 2119 2120 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, WebGLIntArray* v, ExceptionCode& ec) 2121 { 2122 UNUSED_PARAM(ec); 2123 if (!location || location->program() != m_currentProgram) { 2124 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2125 return; 2126 } 2127 2128 if (!v) { 2129 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2130 return; 2131 } 2132 // FIXME: length needs to be a multiple of 4 2133 m_context->uniform4iv(location->location(), v->data(), v->length() / 4); 2134 cleanupAfterGraphicsCall(false); 2135 } 2136 2137 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec) 2138 { 2139 UNUSED_PARAM(ec); 2140 if (!location || location->program() != m_currentProgram) { 2141 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2142 return; 2143 } 2144 2145 if (!v) { 2146 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2147 return; 2148 } 2149 // FIXME: length needs to be a multiple of 4 2150 m_context->uniform4iv(location->location(), v, size / 4); 2151 cleanupAfterGraphicsCall(false); 2152 } 2153 2154 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* v, ExceptionCode& ec) 2155 { 2156 UNUSED_PARAM(ec); 2157 if (!location || location->program() != m_currentProgram) { 2158 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2159 return; 2160 } 2161 2162 if (!v) { 2163 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2164 return; 2165 } 2166 // FIXME: length needs to be a multiple of 4 2167 m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4); 2168 cleanupAfterGraphicsCall(false); 2169 } 2170 2171 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) 2172 { 2173 UNUSED_PARAM(ec); 2174 if (!location || location->program() != m_currentProgram) { 2175 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2176 return; 2177 } 2178 2179 if (!v) { 2180 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2181 return; 2182 } 2183 // FIXME: length needs to be a multiple of 4 2184 m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4); 2185 cleanupAfterGraphicsCall(false); 2186 } 2187 2188 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* v, ExceptionCode& ec) 2189 { 2190 UNUSED_PARAM(ec); 2191 if (!location || location->program() != m_currentProgram) { 2192 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2193 return; 2194 } 2195 2196 if (!v) { 2197 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2198 return; 2199 } 2200 // FIXME: length needs to be a multiple of 9 2201 m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9); 2202 cleanupAfterGraphicsCall(false); 2203 } 2204 2205 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) 2206 { 2207 UNUSED_PARAM(ec); 2208 if (!location || location->program() != m_currentProgram) { 2209 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2210 return; 2211 } 2212 2213 if (!v) { 2214 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2215 return; 2216 } 2217 // FIXME: length needs to be a multiple of 9 2218 m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9); 2219 cleanupAfterGraphicsCall(false); 2220 } 2221 2222 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, WebGLFloatArray* v, ExceptionCode& ec) 2223 { 2224 UNUSED_PARAM(ec); 2225 if (!location || location->program() != m_currentProgram) { 2226 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2227 return; 2228 } 2229 2230 if (!v) { 2231 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2232 return; 2233 } 2234 // FIXME: length needs to be a multiple of 16 2235 m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16); 2236 cleanupAfterGraphicsCall(false); 2237 } 2238 2239 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec) 2240 { 2241 UNUSED_PARAM(ec); 2242 if (!location || location->program() != m_currentProgram) { 2243 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2244 return; 2245 } 2246 2247 if (!v) { 2248 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2249 return; 2250 } 2251 // FIXME: length needs to be a multiple of 16 2252 m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16); 2253 cleanupAfterGraphicsCall(false); 2254 } 2255 2256 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec) 2257 { 2258 UNUSED_PARAM(ec); 2259 if (!program || program->context() != this) { 2260 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2261 return; 2262 } 2263 2264 m_currentProgram = program; 2265 m_context->useProgram(program); 2266 cleanupAfterGraphicsCall(false); 2267 } 2268 2269 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec) 2270 { 2271 UNUSED_PARAM(ec); 2272 if (!program || program->context() != this) { 2273 m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); 2274 return; 2275 } 2276 2277 m_context->validateProgram(program); 2278 cleanupAfterGraphicsCall(false); 2279 } 2280 2281 void WebGLRenderingContext::vertexAttrib1f(unsigned long indx, float v0) 2282 { 2283 m_context->vertexAttrib1f(indx, v0); 2284 cleanupAfterGraphicsCall(false); 2285 } 2286 2287 void WebGLRenderingContext::vertexAttrib1fv(unsigned long indx, WebGLFloatArray* v) 2288 { 2289 // FIXME: Need to make sure array is big enough for attribute being set 2290 m_context->vertexAttrib1fv(indx, v->data()); 2291 cleanupAfterGraphicsCall(false); 2292 } 2293 2294 void WebGLRenderingContext::vertexAttrib1fv(unsigned long indx, float* v, int size) 2295 { 2296 // FIXME: Need to make sure array is big enough for attribute being set 2297 UNUSED_PARAM(size); 2298 2299 m_context->vertexAttrib1fv(indx, v); 2300 cleanupAfterGraphicsCall(false); 2301 } 2302 2303 void WebGLRenderingContext::vertexAttrib2f(unsigned long indx, float v0, float v1) 2304 { 2305 m_context->vertexAttrib2f(indx, v0, v1); 2306 cleanupAfterGraphicsCall(false); 2307 } 2308 2309 void WebGLRenderingContext::vertexAttrib2fv(unsigned long indx, WebGLFloatArray* v) 2310 { 2311 // FIXME: Need to make sure array is big enough for attribute being set 2312 m_context->vertexAttrib2fv(indx, v->data()); 2313 cleanupAfterGraphicsCall(false); 2314 } 2315 2316 void WebGLRenderingContext::vertexAttrib2fv(unsigned long indx, float* v, int size) 2317 { 2318 // FIXME: Need to make sure array is big enough for attribute being set 2319 UNUSED_PARAM(size); 2320 2321 m_context->vertexAttrib2fv(indx, v); 2322 cleanupAfterGraphicsCall(false); 2323 } 2324 2325 void WebGLRenderingContext::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2) 2326 { 2327 m_context->vertexAttrib3f(indx, v0, v1, v2); 2328 cleanupAfterGraphicsCall(false); 2329 } 2330 2331 void WebGLRenderingContext::vertexAttrib3fv(unsigned long indx, WebGLFloatArray* v) 2332 { 2333 // FIXME: Need to make sure array is big enough for attribute being set 2334 m_context->vertexAttrib3fv(indx, v->data()); 2335 cleanupAfterGraphicsCall(false); 2336 } 2337 2338 void WebGLRenderingContext::vertexAttrib3fv(unsigned long indx, float* v, int size) 2339 { 2340 // FIXME: Need to make sure array is big enough for attribute being set 2341 UNUSED_PARAM(size); 2342 2343 m_context->vertexAttrib3fv(indx, v); 2344 cleanupAfterGraphicsCall(false); 2345 } 2346 2347 void WebGLRenderingContext::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3) 2348 { 2349 m_context->vertexAttrib4f(indx, v0, v1, v2, v3); 2350 cleanupAfterGraphicsCall(false); 2351 } 2352 2353 void WebGLRenderingContext::vertexAttrib4fv(unsigned long indx, WebGLFloatArray* v) 2354 { 2355 // FIXME: Need to make sure array is big enough for attribute being set 2356 m_context->vertexAttrib4fv(indx, v->data()); 2357 cleanupAfterGraphicsCall(false); 2358 } 2359 2360 void WebGLRenderingContext::vertexAttrib4fv(unsigned long indx, float* v, int size) 2361 { 2362 // FIXME: Need to make sure array is big enough for attribute being set 2363 UNUSED_PARAM(size); 2364 2365 m_context->vertexAttrib4fv(indx, v); 2366 cleanupAfterGraphicsCall(false); 2367 } 2368 2369 void WebGLRenderingContext::vertexAttribPointer(unsigned long indx, long size, unsigned long type, bool normalized, unsigned long stride, unsigned long offset, ExceptionCode& ec) 2370 { 2371 UNUSED_PARAM(ec); 2372 if (!m_boundArrayBuffer || indx >= m_maxVertexAttribs) { 2373 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2374 return; 2375 } 2376 2377 if (indx >= m_vertexAttribState.size()) 2378 m_vertexAttribState.resize(indx + 1); 2379 2380 // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride 2381 long bytesPerElement = size * sizeInBytes(type, ec); 2382 if (bytesPerElement <= 0) 2383 return; 2384 long validatedStride = bytesPerElement; 2385 if (stride != 0) { 2386 if ((long) stride < bytesPerElement) { 2387 m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE); 2388 return; 2389 } 2390 2391 validatedStride = stride; 2392 } 2393 2394 // Avoid off-by-one errors in numElements computation. 2395 // For the last element, we will only touch the data for the 2396 // element and nothing beyond it. 2397 long bytesRemaining = m_boundArrayBuffer->byteLength(GraphicsContext3D::ARRAY_BUFFER) - offset; 2398 if (bytesRemaining < bytesPerElement) 2399 m_vertexAttribState[indx].numElements = 0; 2400 else 2401 m_vertexAttribState[indx].numElements = 1 + (bytesRemaining - bytesPerElement) / validatedStride; 2402 2403 m_context->vertexAttribPointer(indx, size, type, normalized, stride, offset); 2404 cleanupAfterGraphicsCall(false); 2405 } 2406 2407 void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height) 2408 { 2409 if (isnan(x)) 2410 x = 0; 2411 if (isnan(y)) 2412 y = 0; 2413 if (isnan(width)) 2414 width = 100; 2415 if (isnan(height)) 2416 height = 100; 2417 m_context->viewport(x, y, width, height); 2418 cleanupAfterGraphicsCall(false); 2419 } 2420 2421 void WebGLRenderingContext::removeObject(CanvasObject* object) 2422 { 2423 m_canvasObjects.remove(object); 2424 } 2425 2426 void WebGLRenderingContext::addObject(CanvasObject* object) 2427 { 2428 removeObject(object); 2429 m_canvasObjects.add(object); 2430 } 2431 2432 void WebGLRenderingContext::detachAndRemoveAllObjects() 2433 { 2434 HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end(); 2435 for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) 2436 (*it)->detachContext(); 2437 2438 m_canvasObjects.clear(); 2439 } 2440 2441 WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname) 2442 { 2443 unsigned char value; 2444 m_context->getBooleanv(pname, &value); 2445 return WebGLGetInfo(static_cast<bool>(value)); 2446 } 2447 2448 WebGLGetInfo WebGLRenderingContext::getFloatParameter(unsigned long pname) 2449 { 2450 float value; 2451 m_context->getFloatv(pname, &value); 2452 return WebGLGetInfo(static_cast<float>(value)); 2453 } 2454 2455 WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname) 2456 { 2457 return getLongParameter(pname); 2458 } 2459 2460 WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname) 2461 { 2462 int value; 2463 m_context->getIntegerv(pname, &value); 2464 return WebGLGetInfo(static_cast<long>(value)); 2465 } 2466 2467 WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname) 2468 { 2469 int value; 2470 m_context->getIntegerv(pname, &value); 2471 return WebGLGetInfo(static_cast<unsigned long>(value)); 2472 } 2473 2474 WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname) 2475 { 2476 float value[4] = {0}; 2477 m_context->getFloatv(pname, value); 2478 unsigned length = 0; 2479 switch (pname) { 2480 case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE: 2481 case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE: 2482 case GraphicsContext3D::DEPTH_RANGE: 2483 length = 2; 2484 break; 2485 case GraphicsContext3D::BLEND_COLOR: 2486 case GraphicsContext3D::COLOR_CLEAR_VALUE: 2487 length = 4; 2488 break; 2489 default: 2490 notImplemented(); 2491 } 2492 return WebGLGetInfo(WebGLFloatArray::create(value, length)); 2493 } 2494 2495 WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(unsigned long pname) 2496 { 2497 int value[4] = {0}; 2498 m_context->getIntegerv(pname, value); 2499 unsigned length = 0; 2500 switch (pname) { 2501 case GraphicsContext3D::MAX_VIEWPORT_DIMS: 2502 length = 2; 2503 break; 2504 case GraphicsContext3D::SCISSOR_BOX: 2505 case GraphicsContext3D::VIEWPORT: 2506 length = 4; 2507 break; 2508 default: 2509 notImplemented(); 2510 } 2511 return WebGLGetInfo(WebGLIntArray::create(value, length)); 2512 } 2513 2514 WebGLGetInfo WebGLRenderingContext::getWebGLUnsignedByteArrayParameter(unsigned long pname) 2515 { 2516 unsigned char value[4] = {0}; 2517 m_context->getBooleanv(pname, value); 2518 unsigned length = 0; 2519 switch (pname) { 2520 case GraphicsContext3D::COLOR_WRITEMASK: 2521 length = 4; 2522 break; 2523 default: 2524 notImplemented(); 2525 } 2526 return WebGLGetInfo(WebGLUnsignedByteArray::create(value, length)); 2527 } 2528 2529 } // namespace WebCore 2530 2531 #endif // ENABLE(3D_CANVAS) 2532