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 "GraphicsContext3D.h" 31 32 #include "CanvasObject.h" 33 #include "CString.h" 34 #include "ImageBuffer.h" 35 #include "NotImplemented.h" 36 #include "WebGLActiveInfo.h" 37 #include "WebGLArray.h" 38 #include "WebGLBuffer.h" 39 #include "WebGLFramebuffer.h" 40 #include "WebGLFloatArray.h" 41 #include "WebGLIntArray.h" 42 #include "WebGLProgram.h" 43 #include "WebGLRenderbuffer.h" 44 #include "WebGLShader.h" 45 #include "WebGLTexture.h" 46 #include "WebGLUnsignedByteArray.h" 47 #include <CoreGraphics/CGBitmapContext.h> 48 #include <OpenGL/CGLRenderers.h> 49 #include <wtf/UnusedParam.h> 50 51 namespace WebCore { 52 53 static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest) 54 { 55 attribs.clear(); 56 57 attribs.append(kCGLPFAColorSize); 58 attribs.append(static_cast<CGLPixelFormatAttribute>(colorBits)); 59 attribs.append(kCGLPFADepthSize); 60 attribs.append(static_cast<CGLPixelFormatAttribute>(depthBits)); 61 62 if (accelerated) 63 attribs.append(kCGLPFAAccelerated); 64 else { 65 attribs.append(kCGLPFARendererID); 66 attribs.append(static_cast<CGLPixelFormatAttribute>(kCGLRendererGenericFloatID)); 67 } 68 69 if (supersample) 70 attribs.append(kCGLPFASupersample); 71 72 if (closest) 73 attribs.append(kCGLPFAClosestPolicy); 74 75 attribs.append(static_cast<CGLPixelFormatAttribute>(0)); 76 } 77 78 PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs) 79 { 80 OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs)); 81 return context->m_contextObj ? context.release() : 0; 82 } 83 84 GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs) 85 : m_attrs(attrs) 86 , m_contextObj(0) 87 , m_texture(0) 88 , m_fbo(0) 89 , m_depthBuffer(0) 90 { 91 // FIXME: we need to take into account the user's requested 92 // context creation attributes, in particular stencil and 93 // antialias, and determine which could and could not be honored 94 // based on the capabilities of the OpenGL implementation. 95 m_attrs.alpha = true; 96 m_attrs.depth = true; 97 m_attrs.stencil = false; 98 m_attrs.antialias = false; 99 m_attrs.premultipliedAlpha = true; 100 101 Vector<CGLPixelFormatAttribute> attribs; 102 CGLPixelFormatObj pixelFormatObj = 0; 103 GLint numPixelFormats = 0; 104 105 // We will try: 106 // 107 // 1) 32 bit RGBA/32 bit depth/accelerated/supersampled 108 // 2) 32 bit RGBA/32 bit depth/accelerated 109 // 3) 32 bit RGBA/16 bit depth/accelerated 110 // 4) closest to 32 bit RGBA/16 bit depth/software renderer 111 // 112 // If none of that works, we simply fail and set m_contextObj to 0. 113 114 setPixelFormat(attribs, 32, 32, true, true, false); 115 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats); 116 if (numPixelFormats == 0) { 117 setPixelFormat(attribs, 32, 32, true, false, false); 118 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats); 119 120 if (numPixelFormats == 0) { 121 setPixelFormat(attribs, 32, 16, true, false, false); 122 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats); 123 124 if (numPixelFormats == 0) { 125 setPixelFormat(attribs, 32, 16, false, false, true); 126 CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats); 127 128 if (numPixelFormats == 0) { 129 // Could not find an acceptable renderer - fail 130 return; 131 } 132 } 133 } 134 } 135 136 CGLError err = CGLCreateContext(pixelFormatObj, 0, &m_contextObj); 137 CGLDestroyPixelFormat(pixelFormatObj); 138 139 if (err != kCGLNoError || !m_contextObj) { 140 // Could not create the context - fail 141 m_contextObj = 0; 142 return; 143 } 144 145 // Set the current context to the one given to us. 146 CGLSetCurrentContext(m_contextObj); 147 148 // create a texture to render into 149 ::glGenTextures(1, &m_texture); 150 ::glBindTexture(GL_TEXTURE_2D, m_texture); 151 ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 152 ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 153 ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 154 ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 155 ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 156 ::glBindTexture(GL_TEXTURE_2D, 0); 157 158 // create an FBO 159 ::glGenFramebuffersEXT(1, &m_fbo); 160 ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); 161 162 ::glGenRenderbuffersEXT(1, &m_depthBuffer); 163 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); 164 ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 1, 1); 165 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); 166 167 ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); 168 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); 169 170 ::glClearColor(0, 0, 0, 0); 171 } 172 173 GraphicsContext3D::~GraphicsContext3D() 174 { 175 if (m_contextObj) { 176 CGLSetCurrentContext(m_contextObj); 177 ::glDeleteRenderbuffersEXT(1, & m_depthBuffer); 178 ::glDeleteTextures(1, &m_texture); 179 ::glDeleteFramebuffersEXT(1, &m_fbo); 180 CGLSetCurrentContext(0); 181 CGLDestroyContext(m_contextObj); 182 } 183 } 184 185 void GraphicsContext3D::makeContextCurrent() 186 { 187 CGLSetCurrentContext(m_contextObj); 188 } 189 190 void GraphicsContext3D::beginPaint(WebGLRenderingContext* context) 191 { 192 UNUSED_PARAM(context); 193 } 194 195 void GraphicsContext3D::endPaint() 196 { 197 } 198 199 void GraphicsContext3D::reshape(int width, int height) 200 { 201 if (width == m_currentWidth && height == m_currentHeight || !m_contextObj) 202 return; 203 204 m_currentWidth = width; 205 m_currentHeight = height; 206 207 CGLSetCurrentContext(m_contextObj); 208 209 ::glBindTexture(GL_TEXTURE_2D, m_texture); 210 ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 211 ::glBindTexture(GL_TEXTURE_2D, 0); 212 213 ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); 214 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); 215 ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); 216 ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); 217 218 ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); 219 ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); 220 GLenum status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 221 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 222 // FIXME: cleanup 223 notImplemented(); 224 } 225 226 ::glClear(GL_COLOR_BUFFER_BIT); 227 ::glFlush(); 228 } 229 230 static inline void ensureContext(CGLContextObj context) 231 { 232 if (!context) 233 return; 234 235 CGLContextObj currentContext = CGLGetCurrentContext(); 236 if (currentContext != context) 237 CGLSetCurrentContext(context); 238 } 239 240 void GraphicsContext3D::activeTexture(unsigned long texture) 241 { 242 ensureContext(m_contextObj); 243 ::glActiveTexture(texture); 244 } 245 246 void GraphicsContext3D::attachShader(WebGLProgram* program, WebGLShader* shader) 247 { 248 ASSERT(program); 249 ASSERT(shader); 250 ensureContext(m_contextObj); 251 ::glAttachShader((GLuint) program->object(), (GLuint) shader->object()); 252 } 253 254 void GraphicsContext3D::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name) 255 { 256 ASSERT(program); 257 ensureContext(m_contextObj); 258 ::glBindAttribLocation((GLuint) program->object(), index, name.utf8().data()); 259 } 260 261 void GraphicsContext3D::bindBuffer(unsigned long target, WebGLBuffer* buffer) 262 { 263 ensureContext(m_contextObj); 264 ::glBindBuffer(target, buffer ? (GLuint) buffer->object() : 0); 265 } 266 267 268 void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer) 269 { 270 ensureContext(m_contextObj); 271 ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo); 272 } 273 274 void GraphicsContext3D::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderbuffer) 275 { 276 ensureContext(m_contextObj); 277 ::glBindRenderbufferEXT(target, renderbuffer ? (GLuint) renderbuffer->object() : 0); 278 } 279 280 281 void GraphicsContext3D::bindTexture(unsigned long target, WebGLTexture* texture) 282 { 283 ensureContext(m_contextObj); 284 ::glBindTexture(target, texture ? (GLuint) texture->object() : 0); 285 } 286 287 void GraphicsContext3D::blendColor(double red, double green, double blue, double alpha) 288 { 289 ensureContext(m_contextObj); 290 ::glBlendColor(static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue), static_cast<float>(alpha)); 291 } 292 293 void GraphicsContext3D::blendEquation( unsigned long mode ) 294 { 295 ensureContext(m_contextObj); 296 ::glBlendEquation(mode); 297 } 298 299 void GraphicsContext3D::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha) 300 { 301 ensureContext(m_contextObj); 302 ::glBlendEquationSeparate(modeRGB, modeAlpha); 303 } 304 305 306 void GraphicsContext3D::blendFunc(unsigned long sfactor, unsigned long dfactor) 307 { 308 ensureContext(m_contextObj); 309 ::glBlendFunc(sfactor, dfactor); 310 } 311 312 void GraphicsContext3D::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha) 313 { 314 ensureContext(m_contextObj); 315 ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); 316 } 317 318 void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage) 319 { 320 ensureContext(m_contextObj); 321 ::glBufferData(target, size, 0, usage); 322 } 323 void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage) 324 { 325 if (!array || !array->length()) 326 return; 327 328 ensureContext(m_contextObj); 329 ::glBufferData(target, array->byteLength(), array->baseAddress(), usage); 330 } 331 332 void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array) 333 { 334 if (!array || !array->length()) 335 return; 336 337 ensureContext(m_contextObj); 338 ::glBufferSubData(target, offset, array->byteLength(), array->baseAddress()); 339 } 340 341 unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target) 342 { 343 ensureContext(m_contextObj); 344 return ::glCheckFramebufferStatusEXT(target); 345 } 346 347 void GraphicsContext3D::clearColor(double r, double g, double b, double a) 348 { 349 ensureContext(m_contextObj); 350 ::glClearColor(static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)); 351 } 352 353 void GraphicsContext3D::clear(unsigned long mask) 354 { 355 ensureContext(m_contextObj); 356 ::glClear(mask); 357 } 358 359 void GraphicsContext3D::clearDepth(double depth) 360 { 361 ensureContext(m_contextObj); 362 ::glClearDepth(depth); 363 } 364 365 void GraphicsContext3D::clearStencil(long s) 366 { 367 ensureContext(m_contextObj); 368 ::glClearStencil(s); 369 } 370 371 void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha) 372 { 373 ensureContext(m_contextObj); 374 ::glColorMask(red, green, blue, alpha); 375 } 376 377 void GraphicsContext3D::compileShader(WebGLShader* shader) 378 { 379 ASSERT(shader); 380 ensureContext(m_contextObj); 381 ::glCompileShader((GLuint) shader->object()); 382 } 383 384 void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) 385 { 386 ensureContext(m_contextObj); 387 ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); 388 } 389 390 void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) 391 { 392 ensureContext(m_contextObj); 393 ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); 394 } 395 396 void GraphicsContext3D::cullFace(unsigned long mode) 397 { 398 ensureContext(m_contextObj); 399 ::glCullFace(mode); 400 } 401 402 void GraphicsContext3D::depthFunc(unsigned long func) 403 { 404 ensureContext(m_contextObj); 405 ::glDepthFunc(func); 406 } 407 408 void GraphicsContext3D::depthMask(bool flag) 409 { 410 ensureContext(m_contextObj); 411 ::glDepthMask(flag); 412 } 413 414 void GraphicsContext3D::depthRange(double zNear, double zFar) 415 { 416 ensureContext(m_contextObj); 417 ::glDepthRange(zNear, zFar); 418 } 419 420 void GraphicsContext3D::detachShader(WebGLProgram* program, WebGLShader* shader) 421 { 422 ASSERT(program); 423 ASSERT(shader); 424 ensureContext(m_contextObj); 425 ::glDetachShader((GLuint) program->object(), (GLuint) shader->object()); 426 } 427 428 void GraphicsContext3D::disable(unsigned long cap) 429 { 430 ensureContext(m_contextObj); 431 ::glDisable(cap); 432 } 433 434 void GraphicsContext3D::disableVertexAttribArray(unsigned long index) 435 { 436 ensureContext(m_contextObj); 437 ::glDisableVertexAttribArray(index); 438 } 439 440 void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count) 441 { 442 ensureContext(m_contextObj); 443 ::glDrawArrays(mode, first, count); 444 } 445 446 void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) 447 { 448 ensureContext(m_contextObj); 449 ::glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 450 } 451 452 void GraphicsContext3D::enable(unsigned long cap) 453 { 454 ensureContext(m_contextObj); 455 ::glEnable(cap); 456 } 457 458 void GraphicsContext3D::enableVertexAttribArray(unsigned long index) 459 { 460 ensureContext(m_contextObj); 461 ::glEnableVertexAttribArray(index); 462 } 463 464 void GraphicsContext3D::finish() 465 { 466 ensureContext(m_contextObj); 467 ::glFinish(); 468 } 469 470 void GraphicsContext3D::flush() 471 { 472 ensureContext(m_contextObj); 473 ::glFlush(); 474 } 475 476 void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer) 477 { 478 ensureContext(m_contextObj); 479 ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer ? (GLuint) buffer->object() : 0); 480 } 481 482 void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level) 483 { 484 ensureContext(m_contextObj); 485 ::glFramebufferTexture2DEXT(target, attachment, textarget, texture ? (GLuint) texture->object() : 0, level); 486 } 487 488 void GraphicsContext3D::frontFace(unsigned long mode) 489 { 490 ensureContext(m_contextObj); 491 ::glFrontFace(mode); 492 } 493 494 void GraphicsContext3D::generateMipmap(unsigned long target) 495 { 496 ensureContext(m_contextObj); 497 ::glGenerateMipmapEXT(target); 498 } 499 500 bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info) 501 { 502 if (!program->object()) { 503 synthesizeGLError(INVALID_VALUE); 504 return false; 505 } 506 ensureContext(m_contextObj); 507 GLint maxAttributeSize = 0; 508 ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize); 509 GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination 510 GLsizei nameLength = 0; 511 GLint size = 0; 512 GLenum type = 0; 513 ::glGetActiveAttrib(static_cast<GLuint>(program->object()), index, maxAttributeSize, &nameLength, &size, &type, name); 514 if (!nameLength) 515 return false; 516 info.name = String(name, nameLength); 517 info.type = type; 518 info.size = size; 519 return true; 520 } 521 522 bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info) 523 { 524 if (!program->object()) { 525 synthesizeGLError(INVALID_VALUE); 526 return false; 527 } 528 ensureContext(m_contextObj); 529 GLint maxUniformSize = 0; 530 ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize); 531 GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination 532 GLsizei nameLength = 0; 533 GLint size = 0; 534 GLenum type = 0; 535 ::glGetActiveUniform(static_cast<GLuint>(program->object()), index, maxUniformSize, &nameLength, &size, &type, name); 536 if (!nameLength) 537 return false; 538 info.name = String(name, nameLength); 539 info.type = type; 540 info.size = size; 541 return true; 542 } 543 544 int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& name) 545 { 546 if (!program) 547 return -1; 548 549 ensureContext(m_contextObj); 550 return ::glGetAttribLocation((GLuint) program->object(), name.utf8().data()); 551 } 552 553 GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() 554 { 555 return m_attrs; 556 } 557 558 unsigned long GraphicsContext3D::getError() 559 { 560 if (m_syntheticErrors.size() > 0) { 561 ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); 562 unsigned long err = *iter; 563 m_syntheticErrors.remove(iter); 564 return err; 565 } 566 567 ensureContext(m_contextObj); 568 return ::glGetError(); 569 } 570 571 String GraphicsContext3D::getString(unsigned long name) 572 { 573 ensureContext(m_contextObj); 574 return String((const char*) ::glGetString(name)); 575 } 576 577 void GraphicsContext3D::hint(unsigned long target, unsigned long mode) 578 { 579 ensureContext(m_contextObj); 580 ::glHint(target, mode); 581 } 582 583 bool GraphicsContext3D::isBuffer(WebGLBuffer* buffer) 584 { 585 if (!buffer) 586 return false; 587 588 ensureContext(m_contextObj); 589 return ::glIsBuffer((GLuint) buffer->object()); 590 } 591 592 bool GraphicsContext3D::isEnabled(unsigned long cap) 593 { 594 ensureContext(m_contextObj); 595 return ::glIsEnabled(cap); 596 } 597 598 bool GraphicsContext3D::isFramebuffer(WebGLFramebuffer* framebuffer) 599 { 600 if (!framebuffer) 601 return false; 602 603 ensureContext(m_contextObj); 604 return ::glIsFramebufferEXT((GLuint) framebuffer->object()); 605 } 606 607 bool GraphicsContext3D::isProgram(WebGLProgram* program) 608 { 609 if (!program) 610 return false; 611 612 ensureContext(m_contextObj); 613 return ::glIsProgram((GLuint) program->object()); 614 } 615 616 bool GraphicsContext3D::isRenderbuffer(WebGLRenderbuffer* renderbuffer) 617 { 618 if (!renderbuffer) 619 return false; 620 621 ensureContext(m_contextObj); 622 return ::glIsRenderbufferEXT((GLuint) renderbuffer->object()); 623 } 624 625 bool GraphicsContext3D::isShader(WebGLShader* shader) 626 { 627 if (!shader) 628 return false; 629 630 ensureContext(m_contextObj); 631 return ::glIsShader((GLuint) shader->object()); 632 } 633 634 bool GraphicsContext3D::isTexture(WebGLTexture* texture) 635 { 636 if (!texture) 637 return false; 638 639 ensureContext(m_contextObj); 640 return ::glIsTexture((GLuint) texture->object()); 641 } 642 643 void GraphicsContext3D::lineWidth(double width) 644 { 645 ensureContext(m_contextObj); 646 ::glLineWidth(static_cast<float>(width)); 647 } 648 649 void GraphicsContext3D::linkProgram(WebGLProgram* program) 650 { 651 ASSERT(program); 652 ensureContext(m_contextObj); 653 ::glLinkProgram((GLuint) program->object()); 654 } 655 656 void GraphicsContext3D::pixelStorei(unsigned long pname, long param) 657 { 658 ensureContext(m_contextObj); 659 ::glPixelStorei(pname, param); 660 } 661 662 void GraphicsContext3D::polygonOffset(double factor, double units) 663 { 664 ensureContext(m_contextObj); 665 ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units)); 666 } 667 668 PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type) 669 { 670 ensureContext(m_contextObj); 671 672 // FIXME: For now we only accept GL_UNSIGNED_BYTE/GL_RGBA. In reality OpenGL ES 2.0 accepts that pair and one other 673 // as specified by GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE. But for now we will 674 // not accept those. 675 // FIXME: Also, we should throw when an unacceptable value is passed 676 if (type != GL_UNSIGNED_BYTE || format != GL_RGBA) 677 return 0; 678 679 RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4); 680 ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data()); 681 return array; 682 } 683 684 void GraphicsContext3D::releaseShaderCompiler() 685 { 686 // FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants 687 ensureContext(m_contextObj); 688 //::glReleaseShaderCompiler(); 689 } 690 691 void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) 692 { 693 ensureContext(m_contextObj); 694 ::glRenderbufferStorageEXT(target, internalformat, width, height); 695 } 696 697 void GraphicsContext3D::sampleCoverage(double value, bool invert) 698 { 699 ensureContext(m_contextObj); 700 ::glSampleCoverage(static_cast<float>(value), invert); 701 } 702 703 void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned long height) 704 { 705 ensureContext(m_contextObj); 706 ::glScissor(x, y, width, height); 707 } 708 709 void GraphicsContext3D::shaderSource(WebGLShader* shader, const String& string) 710 { 711 ASSERT(shader); 712 713 ensureContext(m_contextObj); 714 const CString& cs = string.utf8(); 715 const char* s = cs.data(); 716 717 int length = string.length(); 718 ::glShaderSource((GLuint) shader->object(), 1, &s, &length); 719 } 720 721 void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask) 722 { 723 ensureContext(m_contextObj); 724 ::glStencilFunc(func, ref, mask); 725 } 726 727 void GraphicsContext3D::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask) 728 { 729 ensureContext(m_contextObj); 730 ::glStencilFuncSeparate(face, func, ref, mask); 731 } 732 733 void GraphicsContext3D::stencilMask(unsigned long mask) 734 { 735 ensureContext(m_contextObj); 736 ::glStencilMask(mask); 737 } 738 739 void GraphicsContext3D::stencilMaskSeparate(unsigned long face, unsigned long mask) 740 { 741 ensureContext(m_contextObj); 742 ::glStencilMaskSeparate(face, mask); 743 } 744 745 void GraphicsContext3D::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass) 746 { 747 ensureContext(m_contextObj); 748 ::glStencilOp(fail, zfail, zpass); 749 } 750 751 void GraphicsContext3D::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass) 752 { 753 ensureContext(m_contextObj); 754 ::glStencilOpSeparate(face, fail, zfail, zpass); 755 } 756 757 void GraphicsContext3D::texParameterf(unsigned target, unsigned pname, float value) 758 { 759 ensureContext(m_contextObj); 760 ::glTexParameterf(target, pname, static_cast<float>(value)); 761 } 762 763 void GraphicsContext3D::texParameteri(unsigned target, unsigned pname, int value) 764 { 765 ensureContext(m_contextObj); 766 ::glTexParameteri(target, pname, static_cast<float>(value)); 767 } 768 769 void GraphicsContext3D::uniform1f(long location, float v0) 770 { 771 ensureContext(m_contextObj); 772 ::glUniform1f(location, v0); 773 } 774 775 void GraphicsContext3D::uniform1fv(long location, float* array, int size) 776 { 777 ensureContext(m_contextObj); 778 ::glUniform1fv(location, size, array); 779 } 780 781 void GraphicsContext3D::uniform2f(long location, float v0, float v1) 782 { 783 ensureContext(m_contextObj); 784 ::glUniform2f(location, v0, v1); 785 } 786 787 void GraphicsContext3D::uniform2fv(long location, float* array, int size) 788 { 789 // FIXME: length needs to be a multiple of 2 790 ensureContext(m_contextObj); 791 ::glUniform2fv(location, size, array); 792 } 793 794 void GraphicsContext3D::uniform3f(long location, float v0, float v1, float v2) 795 { 796 ensureContext(m_contextObj); 797 ::glUniform3f(location, v0, v1, v2); 798 } 799 800 void GraphicsContext3D::uniform3fv(long location, float* array, int size) 801 { 802 // FIXME: length needs to be a multiple of 3 803 ensureContext(m_contextObj); 804 ::glUniform3fv(location, size, array); 805 } 806 807 void GraphicsContext3D::uniform4f(long location, float v0, float v1, float v2, float v3) 808 { 809 ensureContext(m_contextObj); 810 ::glUniform4f(location, v0, v1, v2, v3); 811 } 812 813 void GraphicsContext3D::uniform4fv(long location, float* array, int size) 814 { 815 // FIXME: length needs to be a multiple of 4 816 ensureContext(m_contextObj); 817 ::glUniform4fv(location, size, array); 818 } 819 820 void GraphicsContext3D::uniform1i(long location, int v0) 821 { 822 ensureContext(m_contextObj); 823 ::glUniform1i(location, v0); 824 } 825 826 void GraphicsContext3D::uniform1iv(long location, int* array, int size) 827 { 828 ensureContext(m_contextObj); 829 ::glUniform1iv(location, size, array); 830 } 831 832 void GraphicsContext3D::uniform2i(long location, int v0, int v1) 833 { 834 ensureContext(m_contextObj); 835 ::glUniform2i(location, v0, v1); 836 } 837 838 void GraphicsContext3D::uniform2iv(long location, int* array, int size) 839 { 840 // FIXME: length needs to be a multiple of 2 841 ensureContext(m_contextObj); 842 ::glUniform2iv(location, size, array); 843 } 844 845 void GraphicsContext3D::uniform3i(long location, int v0, int v1, int v2) 846 { 847 ensureContext(m_contextObj); 848 ::glUniform3i(location, v0, v1, v2); 849 } 850 851 void GraphicsContext3D::uniform3iv(long location, int* array, int size) 852 { 853 // FIXME: length needs to be a multiple of 3 854 ensureContext(m_contextObj); 855 ::glUniform3iv(location, size, array); 856 } 857 858 void GraphicsContext3D::uniform4i(long location, int v0, int v1, int v2, int v3) 859 { 860 ensureContext(m_contextObj); 861 ::glUniform4i(location, v0, v1, v2, v3); 862 } 863 864 void GraphicsContext3D::uniform4iv(long location, int* array, int size) 865 { 866 // FIXME: length needs to be a multiple of 4 867 ensureContext(m_contextObj); 868 ::glUniform4iv(location, size, array); 869 } 870 871 void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* array, int size) 872 { 873 // FIXME: length needs to be a multiple of 4 874 ensureContext(m_contextObj); 875 ::glUniformMatrix2fv(location, size, transpose, array); 876 } 877 878 void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* array, int size) 879 { 880 // FIXME: length needs to be a multiple of 9 881 ensureContext(m_contextObj); 882 ::glUniformMatrix3fv(location, size, transpose, array); 883 } 884 885 void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* array, int size) 886 { 887 // FIXME: length needs to be a multiple of 16 888 ensureContext(m_contextObj); 889 ::glUniformMatrix4fv(location, size, transpose, array); 890 } 891 892 void GraphicsContext3D::useProgram(WebGLProgram* program) 893 { 894 ASSERT(program); 895 896 ensureContext(m_contextObj); 897 ::glUseProgram((GLuint) program->object()); 898 } 899 900 void GraphicsContext3D::validateProgram(WebGLProgram* program) 901 { 902 ASSERT(program); 903 904 ensureContext(m_contextObj); 905 ::glValidateProgram((GLuint) program->object()); 906 } 907 908 void GraphicsContext3D::vertexAttrib1f(unsigned long indx, float v0) 909 { 910 ensureContext(m_contextObj); 911 ::glVertexAttrib1f(indx, v0); 912 } 913 914 void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* array) 915 { 916 ensureContext(m_contextObj); 917 ::glVertexAttrib1fv(indx, array); 918 } 919 920 void GraphicsContext3D::vertexAttrib2f(unsigned long indx, float v0, float v1) 921 { 922 ensureContext(m_contextObj); 923 ::glVertexAttrib2f(indx, v0, v1); 924 } 925 926 void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* array) 927 { 928 ensureContext(m_contextObj); 929 ::glVertexAttrib2fv(indx, array); 930 } 931 932 void GraphicsContext3D::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2) 933 { 934 ensureContext(m_contextObj); 935 ::glVertexAttrib3f(indx, v0, v1, v2); 936 } 937 938 void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* array) 939 { 940 ensureContext(m_contextObj); 941 ::glVertexAttrib3fv(indx, array); 942 } 943 944 void GraphicsContext3D::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3) 945 { 946 ensureContext(m_contextObj); 947 ::glVertexAttrib4f(indx, v0, v1, v2, v3); 948 } 949 950 void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* array) 951 { 952 ensureContext(m_contextObj); 953 ::glVertexAttrib4fv(indx, array); 954 } 955 956 void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset) 957 { 958 ensureContext(m_contextObj); 959 ::glVertexAttribPointer(indx, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 960 } 961 962 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) 963 { 964 ensureContext(m_contextObj); 965 ::glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height)); 966 } 967 968 void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value) 969 { 970 ensureContext(m_contextObj); 971 ::glGetBooleanv(pname, value); 972 } 973 974 void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value) 975 { 976 ensureContext(m_contextObj); 977 ::glGetBufferParameteriv(target, pname, value); 978 } 979 980 void GraphicsContext3D::getFloatv(unsigned long pname, float* value) 981 { 982 ensureContext(m_contextObj); 983 ::glGetFloatv(pname, value); 984 } 985 986 void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value) 987 { 988 ensureContext(m_contextObj); 989 ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); 990 } 991 992 void GraphicsContext3D::getIntegerv(unsigned long pname, int* value) 993 { 994 ensureContext(m_contextObj); 995 ::glGetIntegerv(pname, value); 996 } 997 998 void GraphicsContext3D::getProgramiv(WebGLProgram* program, unsigned long pname, int* value) 999 { 1000 ensureContext(m_contextObj); 1001 ::glGetProgramiv((GLuint) program->object(), pname, value); 1002 } 1003 1004 String GraphicsContext3D::getProgramInfoLog(WebGLProgram* program) 1005 { 1006 ASSERT(program); 1007 1008 ensureContext(m_contextObj); 1009 GLint length; 1010 ::glGetProgramiv((GLuint) program->object(), GL_INFO_LOG_LENGTH, &length); 1011 1012 GLsizei size; 1013 GLchar* info = (GLchar*) fastMalloc(length); 1014 if (!info) 1015 return ""; 1016 1017 ::glGetProgramInfoLog((GLuint) program->object(), length, &size, info); 1018 String s(info); 1019 fastFree(info); 1020 return s; 1021 } 1022 1023 void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value) 1024 { 1025 ensureContext(m_contextObj); 1026 ::glGetRenderbufferParameterivEXT(target, pname, value); 1027 } 1028 1029 void GraphicsContext3D::getShaderiv(WebGLShader* shader, unsigned long pname, int* value) 1030 { 1031 ASSERT(shader); 1032 1033 ensureContext(m_contextObj); 1034 ::glGetShaderiv((GLuint) shader->object(), pname, value); 1035 } 1036 1037 String GraphicsContext3D::getShaderInfoLog(WebGLShader* shader) 1038 { 1039 ASSERT(shader); 1040 1041 ensureContext(m_contextObj); 1042 GLint length; 1043 ::glGetShaderiv((GLuint) shader->object(), GL_INFO_LOG_LENGTH, &length); 1044 1045 GLsizei size; 1046 GLchar* info = (GLchar*) fastMalloc(length); 1047 if (!info) 1048 return ""; 1049 1050 ::glGetShaderInfoLog((GLuint) shader->object(), length, &size, info); 1051 String s(info); 1052 fastFree(info); 1053 return s; 1054 } 1055 1056 String GraphicsContext3D::getShaderSource(WebGLShader* shader) 1057 { 1058 ASSERT(shader); 1059 1060 ensureContext(m_contextObj); 1061 GLint length; 1062 ::glGetShaderiv((GLuint) shader->object(), GL_SHADER_SOURCE_LENGTH, &length); 1063 1064 GLsizei size; 1065 GLchar* info = (GLchar*) fastMalloc(length); 1066 if (!info) 1067 return ""; 1068 1069 ::glGetShaderSource((GLuint) shader->object(), length, &size, info); 1070 String s(info); 1071 fastFree(info); 1072 return s; 1073 } 1074 1075 1076 void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value) 1077 { 1078 ensureContext(m_contextObj); 1079 ::glGetTexParameterfv(target, pname, value); 1080 } 1081 1082 void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value) 1083 { 1084 ensureContext(m_contextObj); 1085 ::glGetTexParameteriv(target, pname, value); 1086 } 1087 1088 void GraphicsContext3D::getUniformfv(WebGLProgram* program, long location, float* value) 1089 { 1090 ensureContext(m_contextObj); 1091 ::glGetUniformfv((GLuint) program->object(), location, value); 1092 } 1093 1094 void GraphicsContext3D::getUniformiv(WebGLProgram* program, long location, int* value) 1095 { 1096 ensureContext(m_contextObj); 1097 ::glGetUniformiv((GLuint) program->object(), location, value); 1098 } 1099 1100 long GraphicsContext3D::getUniformLocation(WebGLProgram* program, const String& name) 1101 { 1102 ASSERT(program); 1103 1104 ensureContext(m_contextObj); 1105 return ::glGetUniformLocation((GLuint) program->object(), name.utf8().data()); 1106 } 1107 1108 void GraphicsContext3D::getVertexAttribfv(unsigned long index, unsigned long pname, float* value) 1109 { 1110 ensureContext(m_contextObj); 1111 ::glGetVertexAttribfv(index, pname, value); 1112 } 1113 1114 void GraphicsContext3D::getVertexAttribiv(unsigned long index, unsigned long pname, int* value) 1115 { 1116 ensureContext(m_contextObj); 1117 ::glGetVertexAttribiv(index, pname, value); 1118 } 1119 1120 long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname) 1121 { 1122 ensureContext(m_contextObj); 1123 1124 void* pointer; 1125 ::glGetVertexAttribPointerv(index, pname, &pointer); 1126 return reinterpret_cast<long>(pointer); 1127 } 1128 1129 // Returned pointer must be freed by fastFree() 1130 static bool imageToTexture(Image* image, GLubyte*& buffer, size_t& width, size_t& height) 1131 { 1132 if (!image) 1133 return false; 1134 1135 CGImageRef textureImage = image->getCGImageRef(); 1136 if (!textureImage) 1137 return false; 1138 1139 width = CGImageGetWidth(textureImage); 1140 height = CGImageGetHeight(textureImage); 1141 1142 buffer = (GLubyte*) fastMalloc(width * height * 4); 1143 if (!buffer) 1144 return false; 1145 1146 CGContextRef textureContext = CGBitmapContextCreate(buffer, width, height, 8, width * 4, 1147 CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast); 1148 CGContextSetBlendMode(textureContext, kCGBlendModeCopy); 1149 CGContextDrawImage(textureContext, CGRectMake(0, 0, (CGFloat)width, (CGFloat)height), textureImage); 1150 CGContextRelease(textureContext); 1151 return true; 1152 } 1153 1154 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels) 1155 { 1156 // FIXME: Need to do bounds checking on the buffer here. 1157 ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); 1158 return 0; 1159 } 1160 1161 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, bool flipY, bool premultiplyAlpha) 1162 { 1163 // FIXME: need to support flipY and premultiplyAlpha 1164 UNUSED_PARAM(flipY); 1165 UNUSED_PARAM(premultiplyAlpha); 1166 ASSERT(image); 1167 1168 ensureContext(m_contextObj); 1169 GLubyte* buffer; 1170 size_t width; 1171 size_t height; 1172 if (!imageToTexture(image, buffer, width, height)) 1173 return -1; 1174 1175 ::glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 1176 fastFree(buffer); 1177 return 0; 1178 } 1179 1180 int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels) 1181 { 1182 // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size 1183 // FIXME: Need to do bounds checking on the buffer here. 1184 ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels); 1185 return 0; 1186 } 1187 1188 int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, Image* image, bool flipY, bool premultiplyAlpha) 1189 { 1190 // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size 1191 // FIXME: need to support flipY and premultiplyAlpha 1192 UNUSED_PARAM(flipY); 1193 UNUSED_PARAM(premultiplyAlpha); 1194 ASSERT(image); 1195 1196 ensureContext(m_contextObj); 1197 GLubyte* buffer; 1198 size_t width; 1199 size_t height; 1200 if (!imageToTexture(image, buffer, width, height)) 1201 return -1; 1202 1203 ::glTexSubImage2D(target, level, xoff, yoff, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 1204 fastFree(buffer); 1205 return 0; 1206 } 1207 1208 unsigned GraphicsContext3D::createBuffer() 1209 { 1210 ensureContext(m_contextObj); 1211 GLuint o; 1212 glGenBuffers(1, &o); 1213 return o; 1214 } 1215 1216 unsigned GraphicsContext3D::createFramebuffer() 1217 { 1218 ensureContext(m_contextObj); 1219 GLuint o; 1220 glGenFramebuffersEXT(1, &o); 1221 return o; 1222 } 1223 1224 unsigned GraphicsContext3D::createProgram() 1225 { 1226 ensureContext(m_contextObj); 1227 return glCreateProgram(); 1228 } 1229 1230 unsigned GraphicsContext3D::createRenderbuffer() 1231 { 1232 ensureContext(m_contextObj); 1233 GLuint o; 1234 glGenRenderbuffersEXT(1, &o); 1235 return o; 1236 } 1237 1238 unsigned GraphicsContext3D::createShader(unsigned long type) 1239 { 1240 ensureContext(m_contextObj); 1241 return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER); 1242 } 1243 1244 unsigned GraphicsContext3D::createTexture() 1245 { 1246 ensureContext(m_contextObj); 1247 GLuint o; 1248 glGenTextures(1, &o); 1249 return o; 1250 } 1251 1252 void GraphicsContext3D::deleteBuffer(unsigned buffer) 1253 { 1254 ensureContext(m_contextObj); 1255 glDeleteBuffers(1, &buffer); 1256 } 1257 1258 void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer) 1259 { 1260 ensureContext(m_contextObj); 1261 glDeleteFramebuffersEXT(1, &framebuffer); 1262 } 1263 1264 void GraphicsContext3D::deleteProgram(unsigned program) 1265 { 1266 ensureContext(m_contextObj); 1267 glDeleteProgram(program); 1268 } 1269 1270 void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer) 1271 { 1272 ensureContext(m_contextObj); 1273 glDeleteRenderbuffersEXT(1, &renderbuffer); 1274 } 1275 1276 void GraphicsContext3D::deleteShader(unsigned shader) 1277 { 1278 ensureContext(m_contextObj); 1279 glDeleteShader(shader); 1280 } 1281 1282 void GraphicsContext3D::deleteTexture(unsigned texture) 1283 { 1284 ensureContext(m_contextObj); 1285 glDeleteTextures(1, &texture); 1286 } 1287 1288 int GraphicsContext3D::sizeInBytes(int type) 1289 { 1290 switch (type) { 1291 case GL_BYTE: 1292 return sizeof(GLbyte); 1293 case GL_UNSIGNED_BYTE: 1294 return sizeof(GLubyte); 1295 case GL_SHORT: 1296 return sizeof(GLshort); 1297 case GL_UNSIGNED_SHORT: 1298 return sizeof(GLushort); 1299 case GL_INT: 1300 return sizeof(GLint); 1301 case GL_UNSIGNED_INT: 1302 return sizeof(GLuint); 1303 case GL_FLOAT: 1304 return sizeof(GLfloat); 1305 default: 1306 return 0; 1307 } 1308 } 1309 1310 void GraphicsContext3D::synthesizeGLError(unsigned long error) 1311 { 1312 m_syntheticErrors.add(error); 1313 } 1314 1315 } 1316 1317 #endif // ENABLE(3D_CANVAS) 1318