1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 Google Inc. All rights reserved. 4 * Copyright (C) 2012 ChangSeok Oh <shivamidow@gmail.com> 5 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "config.h" 30 31#if USE(3D_GRAPHICS) 32 33#include "GraphicsContext3D.h" 34 35#include "CanvasRenderingContext.h" 36#if USE(OPENGL_ES_2) 37#include "Extensions3DOpenGLES.h" 38#else 39#include "Extensions3DOpenGL.h" 40#endif 41#include "GraphicsContext.h" 42#include "ImageBuffer.h" 43#include "ImageData.h" 44#include "IntRect.h" 45#include "IntSize.h" 46#include "NotImplemented.h" 47#include "WebGLObject.h" 48#include <cstring> 49#include <wtf/ArrayBuffer.h> 50#include <wtf/ArrayBufferView.h> 51#include <wtf/Float32Array.h> 52#include <wtf/Int32Array.h> 53#include <wtf/MainThread.h> 54#include <wtf/OwnArrayPtr.h> 55#include <wtf/Uint8Array.h> 56#include <wtf/text/CString.h> 57 58#if USE(OPENGL_ES_2) 59#include "OpenGLESShims.h" 60#elif PLATFORM(MAC) 61#include <OpenGL/gl.h> 62#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(QT) 63#include "OpenGLShims.h" 64#endif 65 66#if PLATFORM(BLACKBERRY) 67#include <BlackBerryPlatformLog.h> 68#endif 69 70namespace WebCore { 71 72PassRefPtr<GraphicsContext3D> GraphicsContext3D::createForCurrentGLContext() 73{ 74 RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(Attributes(), 0, GraphicsContext3D::RenderToCurrentGLContext)); 75 return context->m_private ? context.release() : 0; 76} 77 78void GraphicsContext3D::validateDepthStencil(const char* packedDepthStencilExtension) 79{ 80 Extensions3D* extensions = getExtensions(); 81 if (m_attrs.stencil) { 82 if (extensions->supports(packedDepthStencilExtension)) { 83 extensions->ensureEnabled(packedDepthStencilExtension); 84 // Force depth if stencil is true. 85 m_attrs.depth = true; 86 } else 87 m_attrs.stencil = false; 88 } 89 if (m_attrs.antialias) { 90 if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant()) 91 m_attrs.antialias = false; 92 else 93 extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); 94 } 95} 96 97bool GraphicsContext3D::isResourceSafe() 98{ 99 return false; 100} 101 102void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer* imageBuffer, DrawingBuffer*) 103{ 104 int rowBytes = m_currentWidth * 4; 105 int totalBytes = rowBytes * m_currentHeight; 106 107 OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]); 108 if (!pixels) 109 return; 110 111 readRenderingResults(pixels.get(), totalBytes); 112 113 if (!m_attrs.premultipliedAlpha) { 114 for (int i = 0; i < totalBytes; i += 4) { 115 // Premultiply alpha. 116 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); 117 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); 118 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); 119 } 120 } 121 122#if PLATFORM(BLACKBERRY) || USE(CG) 123 paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, 124 imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()); 125#else 126 paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, 127 imageBuffer->internalSize().width(), imageBuffer->internalSize().height(), imageBuffer->context()->platformContext()); 128#endif 129} 130 131bool GraphicsContext3D::paintCompositedResultsToCanvas(ImageBuffer*) 132{ 133 // Not needed at the moment, so return that nothing was done. 134 return false; 135} 136 137PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(DrawingBuffer*) 138{ 139 // Reading premultiplied alpha would involve unpremultiplying, which is 140 // lossy. 141 if (m_attrs.premultipliedAlpha) 142 return 0; 143 144 RefPtr<ImageData> imageData = ImageData::create(IntSize(m_currentWidth, m_currentHeight)); 145 unsigned char* pixels = imageData->data()->data(); 146 int totalBytes = 4 * m_currentWidth * m_currentHeight; 147 148 readRenderingResults(pixels, totalBytes); 149 150 // Convert to RGBA. 151 for (int i = 0; i < totalBytes; i += 4) 152 std::swap(pixels[i], pixels[i + 2]); 153 154 return imageData.release(); 155} 156 157#if !PLATFORM(BLACKBERRY) 158void GraphicsContext3D::prepareTexture() 159{ 160 if (m_layerComposited) 161 return; 162 163 makeContextCurrent(); 164 if (m_attrs.antialias) 165 resolveMultisamplingIfNecessary(); 166 167 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); 168 ::glActiveTexture(GL_TEXTURE0); 169 ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture); 170 ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0); 171 ::glBindTexture(GL_TEXTURE_2D, m_state.boundTexture0); 172 ::glActiveTexture(m_state.activeTexture); 173 if (m_state.boundFBO != m_fbo) 174 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO); 175 ::glFinish(); 176 m_layerComposited = true; 177} 178#endif 179 180void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize) 181{ 182 if (pixelsSize < m_currentWidth * m_currentHeight * 4) 183 return; 184 185 makeContextCurrent(); 186 187 bool mustRestoreFBO = false; 188 if (m_attrs.antialias) { 189 resolveMultisamplingIfNecessary(); 190 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); 191 mustRestoreFBO = true; 192 } else { 193 if (m_state.boundFBO != m_fbo) { 194 mustRestoreFBO = true; 195 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); 196 } 197 } 198 199 GLint packAlignment = 4; 200 bool mustRestorePackAlignment = false; 201 ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); 202 if (packAlignment > 4) { 203 ::glPixelStorei(GL_PACK_ALIGNMENT, 4); 204 mustRestorePackAlignment = true; 205 } 206 207 readPixelsAndConvertToBGRAIfNecessary(0, 0, m_currentWidth, m_currentHeight, pixels); 208 209 if (mustRestorePackAlignment) 210 ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); 211 212 if (mustRestoreFBO) 213 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO); 214} 215 216void GraphicsContext3D::reshape(int width, int height) 217{ 218 if (!platformGraphicsContext3D()) 219 return; 220 221 if (width == m_currentWidth && height == m_currentHeight) 222 return; 223 224#if (PLATFORM(QT) || PLATFORM(EFL)) && USE(GRAPHICS_SURFACE) 225 ::glFlush(); // Make sure all GL calls have been committed before resizing. 226 createGraphicsSurfaces(IntSize(width, height)); 227#endif 228 229 m_currentWidth = width; 230 m_currentHeight = height; 231 232 makeContextCurrent(); 233 validateAttributes(); 234 235 bool mustRestoreFBO = reshapeFBOs(IntSize(width, height)); 236 237 // Initialize renderbuffers to 0. 238 GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0; 239 GLint clearStencil = 0; 240 GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}, depthMask = GL_TRUE; 241 GLuint stencilMask = 0xffffffff; 242 GLboolean isScissorEnabled = GL_FALSE; 243 GLboolean isDitherEnabled = GL_FALSE; 244 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; 245 ::glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor); 246 ::glClearColor(0, 0, 0, 0); 247 ::glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); 248 ::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 249 if (m_attrs.depth) { 250 ::glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth); 251 GraphicsContext3D::clearDepth(1); 252 ::glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); 253 ::glDepthMask(GL_TRUE); 254 clearMask |= GL_DEPTH_BUFFER_BIT; 255 } 256 if (m_attrs.stencil) { 257 ::glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil); 258 ::glClearStencil(0); 259 ::glGetIntegerv(GL_STENCIL_WRITEMASK, reinterpret_cast<GLint*>(&stencilMask)); 260 ::glStencilMaskSeparate(GL_FRONT, 0xffffffff); 261 clearMask |= GL_STENCIL_BUFFER_BIT; 262 } 263 isScissorEnabled = ::glIsEnabled(GL_SCISSOR_TEST); 264 ::glDisable(GL_SCISSOR_TEST); 265 isDitherEnabled = ::glIsEnabled(GL_DITHER); 266 ::glDisable(GL_DITHER); 267 268 ::glClear(clearMask); 269 270 ::glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); 271 ::glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); 272 if (m_attrs.depth) { 273 GraphicsContext3D::clearDepth(clearDepth); 274 ::glDepthMask(depthMask); 275 } 276 if (m_attrs.stencil) { 277 ::glClearStencil(clearStencil); 278 ::glStencilMaskSeparate(GL_FRONT, stencilMask); 279 } 280 if (isScissorEnabled) 281 ::glEnable(GL_SCISSOR_TEST); 282 else 283 ::glDisable(GL_SCISSOR_TEST); 284 if (isDitherEnabled) 285 ::glEnable(GL_DITHER); 286 else 287 ::glDisable(GL_DITHER); 288 289 if (mustRestoreFBO) 290 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO); 291 292 ::glFlush(); 293} 294 295IntSize GraphicsContext3D::getInternalFramebufferSize() const 296{ 297 return IntSize(m_currentWidth, m_currentHeight); 298} 299 300void GraphicsContext3D::activeTexture(GC3Denum texture) 301{ 302 makeContextCurrent(); 303 m_state.activeTexture = texture; 304 ::glActiveTexture(texture); 305} 306 307void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader) 308{ 309 ASSERT(program); 310 ASSERT(shader); 311 makeContextCurrent(); 312 ::glAttachShader(program, shader); 313} 314 315void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name) 316{ 317 ASSERT(program); 318 makeContextCurrent(); 319 ::glBindAttribLocation(program, index, name.utf8().data()); 320} 321 322void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer) 323{ 324 makeContextCurrent(); 325 ::glBindBuffer(target, buffer); 326} 327 328void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer) 329{ 330 makeContextCurrent(); 331 GLuint fbo; 332 if (buffer) 333 fbo = buffer; 334 else 335#if PLATFORM(BLACKBERRY) 336 fbo = m_fbo; 337#else 338 fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo); 339#endif 340 if (fbo != m_state.boundFBO) { 341 ::glBindFramebufferEXT(target, fbo); 342 m_state.boundFBO = fbo; 343 } 344} 345 346void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer) 347{ 348 makeContextCurrent(); 349 ::glBindRenderbufferEXT(target, renderbuffer); 350} 351 352 353void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture) 354{ 355 makeContextCurrent(); 356 if (m_state.activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D) 357 m_state.boundTexture0 = texture; 358 ::glBindTexture(target, texture); 359} 360 361void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha) 362{ 363 makeContextCurrent(); 364 ::glBlendColor(red, green, blue, alpha); 365} 366 367void GraphicsContext3D::blendEquation(GC3Denum mode) 368{ 369 makeContextCurrent(); 370 ::glBlendEquation(mode); 371} 372 373void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha) 374{ 375 makeContextCurrent(); 376 ::glBlendEquationSeparate(modeRGB, modeAlpha); 377} 378 379 380void GraphicsContext3D::blendFunc(GC3Denum sfactor, GC3Denum dfactor) 381{ 382 makeContextCurrent(); 383 ::glBlendFunc(sfactor, dfactor); 384} 385 386void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha) 387{ 388 makeContextCurrent(); 389 ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); 390} 391 392void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage) 393{ 394 makeContextCurrent(); 395 ::glBufferData(target, size, 0, usage); 396} 397 398void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage) 399{ 400 makeContextCurrent(); 401 ::glBufferData(target, size, data, usage); 402} 403 404void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data) 405{ 406 makeContextCurrent(); 407 ::glBufferSubData(target, offset, size, data); 408} 409 410GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target) 411{ 412 makeContextCurrent(); 413 return ::glCheckFramebufferStatusEXT(target); 414} 415 416void GraphicsContext3D::clearColor(GC3Dclampf r, GC3Dclampf g, GC3Dclampf b, GC3Dclampf a) 417{ 418 makeContextCurrent(); 419 ::glClearColor(r, g, b, a); 420} 421 422void GraphicsContext3D::clear(GC3Dbitfield mask) 423{ 424 makeContextCurrent(); 425 ::glClear(mask); 426} 427 428void GraphicsContext3D::clearStencil(GC3Dint s) 429{ 430 makeContextCurrent(); 431 ::glClearStencil(s); 432} 433 434void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha) 435{ 436 makeContextCurrent(); 437 ::glColorMask(red, green, blue, alpha); 438} 439 440void GraphicsContext3D::compileShader(Platform3DObject shader) 441{ 442 ASSERT(shader); 443 makeContextCurrent(); 444 445 String translatedShaderSource = m_extensions->getTranslatedShaderSourceANGLE(shader); 446 447 if (!translatedShaderSource.length()) 448 return; 449 450 const CString& translatedShaderCString = translatedShaderSource.utf8(); 451 const char* translatedShaderPtr = translatedShaderCString.data(); 452 int translatedShaderLength = translatedShaderCString.length(); 453 454 ::glShaderSource(shader, 1, &translatedShaderPtr, &translatedShaderLength); 455 456 ::glCompileShader(shader); 457 458 int GLCompileSuccess; 459 460 ::glGetShaderiv(shader, COMPILE_STATUS, &GLCompileSuccess); 461 462 // Populate the shader log 463 GLint length = 0; 464 ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 465 466 if (length) { 467 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader); 468 GraphicsContext3D::ShaderSourceEntry& entry = result->value; 469 470 GLsizei size = 0; 471 OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]); 472 ::glGetShaderInfoLog(shader, length, &size, info.get()); 473 474 entry.log = info.get(); 475 } 476 477 // ASSERT that ANGLE generated GLSL will be accepted by OpenGL. 478 ASSERT(GLCompileSuccess == GL_TRUE); 479#if PLATFORM(BLACKBERRY) && !defined(NDEBUG) 480 if (GLCompileSuccess != GL_TRUE) 481 BBLOG(BlackBerry::Platform::LogLevelWarn, "The shader validated, but didn't compile.\n"); 482#endif 483} 484 485void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) 486{ 487 makeContextCurrent(); 488#if !PLATFORM(BLACKBERRY) 489 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) { 490 resolveMultisamplingIfNecessary(IntRect(x, y, width, height)); 491 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); 492 } 493#endif 494 ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); 495#if !PLATFORM(BLACKBERRY) 496 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) 497 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); 498#endif 499} 500 501void GraphicsContext3D::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) 502{ 503 makeContextCurrent(); 504#if !PLATFORM(BLACKBERRY) 505 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) { 506 resolveMultisamplingIfNecessary(IntRect(x, y, width, height)); 507 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo); 508 } 509#endif 510 ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); 511#if !PLATFORM(BLACKBERRY) 512 if (m_attrs.antialias && m_state.boundFBO == m_multisampleFBO) 513 ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); 514#endif 515} 516 517void GraphicsContext3D::cullFace(GC3Denum mode) 518{ 519 makeContextCurrent(); 520 ::glCullFace(mode); 521} 522 523void GraphicsContext3D::depthFunc(GC3Denum func) 524{ 525 makeContextCurrent(); 526 ::glDepthFunc(func); 527} 528 529void GraphicsContext3D::depthMask(GC3Dboolean flag) 530{ 531 makeContextCurrent(); 532 ::glDepthMask(flag); 533} 534 535void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader) 536{ 537 ASSERT(program); 538 ASSERT(shader); 539 makeContextCurrent(); 540 ::glDetachShader(program, shader); 541} 542 543void GraphicsContext3D::disable(GC3Denum cap) 544{ 545 makeContextCurrent(); 546 ::glDisable(cap); 547} 548 549void GraphicsContext3D::disableVertexAttribArray(GC3Duint index) 550{ 551 makeContextCurrent(); 552 ::glDisableVertexAttribArray(index); 553} 554 555void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count) 556{ 557 makeContextCurrent(); 558 ::glDrawArrays(mode, first, count); 559} 560 561void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset) 562{ 563 makeContextCurrent(); 564 ::glDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset))); 565} 566 567void GraphicsContext3D::enable(GC3Denum cap) 568{ 569 makeContextCurrent(); 570 ::glEnable(cap); 571} 572 573void GraphicsContext3D::enableVertexAttribArray(GC3Duint index) 574{ 575 makeContextCurrent(); 576 ::glEnableVertexAttribArray(index); 577} 578 579void GraphicsContext3D::finish() 580{ 581 makeContextCurrent(); 582 ::glFinish(); 583} 584 585void GraphicsContext3D::flush() 586{ 587 makeContextCurrent(); 588 ::glFlush(); 589} 590 591void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, Platform3DObject buffer) 592{ 593 makeContextCurrent(); 594 ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer); 595} 596 597void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, Platform3DObject texture, GC3Dint level) 598{ 599 makeContextCurrent(); 600 ::glFramebufferTexture2DEXT(target, attachment, textarget, texture, level); 601} 602 603void GraphicsContext3D::frontFace(GC3Denum mode) 604{ 605 makeContextCurrent(); 606 ::glFrontFace(mode); 607} 608 609void GraphicsContext3D::generateMipmap(GC3Denum target) 610{ 611 makeContextCurrent(); 612 ::glGenerateMipmapEXT(target); 613} 614 615bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info) 616{ 617 if (!program) { 618 synthesizeGLError(INVALID_VALUE); 619 return false; 620 } 621 makeContextCurrent(); 622 GLint maxAttributeSize = 0; 623 ::glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize); 624 OwnArrayPtr<GLchar> name = adoptArrayPtr(new GLchar[maxAttributeSize]); // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination. 625 GLsizei nameLength = 0; 626 GLint size = 0; 627 GLenum type = 0; 628 ::glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name.get()); 629 if (!nameLength) 630 return false; 631 632 String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, String(name.get(), nameLength)); 633 634 info.name = originalName; 635 info.type = type; 636 info.size = size; 637 return true; 638} 639 640bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info) 641{ 642 if (!program) { 643 synthesizeGLError(INVALID_VALUE); 644 return false; 645 } 646 647 makeContextCurrent(); 648 GLint maxUniformSize = 0; 649 ::glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize); 650 651 OwnArrayPtr<GLchar> name = adoptArrayPtr(new GLchar[maxUniformSize]); // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination. 652 GLsizei nameLength = 0; 653 GLint size = 0; 654 GLenum type = 0; 655 ::glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name.get()); 656 if (!nameLength) 657 return false; 658 659 String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, String(name.get(), nameLength)); 660 661 info.name = originalName; 662 info.type = type; 663 info.size = size; 664 return true; 665} 666 667void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders) 668{ 669 if (!program) { 670 synthesizeGLError(INVALID_VALUE); 671 return; 672 } 673 makeContextCurrent(); 674 ::glGetAttachedShaders(program, maxCount, count, shaders); 675} 676 677String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name) 678{ 679 GC3Dsizei count; 680 Platform3DObject shaders[2]; 681 getAttachedShaders(program, 2, &count, shaders); 682 683 for (GC3Dsizei i = 0; i < count; ++i) { 684 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]); 685 if (result == m_shaderSourceMap.end()) 686 continue; 687 688 const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType); 689 ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name); 690 if (symbolEntry != symbolMap.end()) 691 return symbolEntry->value.mappedName; 692 } 693 return name; 694} 695 696String GraphicsContext3D::originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name) 697{ 698 GC3Dsizei count; 699 Platform3DObject shaders[2]; 700 getAttachedShaders(program, 2, &count, shaders); 701 702 for (GC3Dsizei i = 0; i < count; ++i) { 703 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]); 704 if (result == m_shaderSourceMap.end()) 705 continue; 706 707 const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType); 708 ShaderSymbolMap::const_iterator symbolEntry; 709 for (symbolEntry = symbolMap.begin(); symbolEntry != symbolMap.end(); ++symbolEntry) { 710 if (symbolEntry->value.mappedName == name) 711 return symbolEntry->key; 712 } 713 } 714 return name; 715} 716 717int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name) 718{ 719 if (!program) 720 return -1; 721 722 makeContextCurrent(); 723 724 // The attribute name may have been translated during ANGLE compilation. 725 // Look through the corresponding ShaderSourceMap to make sure we 726 // reference the mapped name rather than the external name. 727 String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, name); 728 729 return ::glGetAttribLocation(program, mappedName.utf8().data()); 730} 731 732GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() 733{ 734 return m_attrs; 735} 736 737GC3Denum GraphicsContext3D::getError() 738{ 739 if (m_syntheticErrors.size() > 0) { 740 ListHashSet<GC3Denum>::iterator iter = m_syntheticErrors.begin(); 741 GC3Denum err = *iter; 742 m_syntheticErrors.remove(iter); 743 return err; 744 } 745 746 makeContextCurrent(); 747 return ::glGetError(); 748} 749 750String GraphicsContext3D::getString(GC3Denum name) 751{ 752 makeContextCurrent(); 753 return String(reinterpret_cast<const char*>(::glGetString(name))); 754} 755 756void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode) 757{ 758 makeContextCurrent(); 759 ::glHint(target, mode); 760} 761 762GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject buffer) 763{ 764 if (!buffer) 765 return GL_FALSE; 766 767 makeContextCurrent(); 768 return ::glIsBuffer(buffer); 769} 770 771GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap) 772{ 773 makeContextCurrent(); 774 return ::glIsEnabled(cap); 775} 776 777GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject framebuffer) 778{ 779 if (!framebuffer) 780 return GL_FALSE; 781 782 makeContextCurrent(); 783 return ::glIsFramebufferEXT(framebuffer); 784} 785 786GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject program) 787{ 788 if (!program) 789 return GL_FALSE; 790 791 makeContextCurrent(); 792 return ::glIsProgram(program); 793} 794 795GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject renderbuffer) 796{ 797 if (!renderbuffer) 798 return GL_FALSE; 799 800 makeContextCurrent(); 801 return ::glIsRenderbufferEXT(renderbuffer); 802} 803 804GC3Dboolean GraphicsContext3D::isShader(Platform3DObject shader) 805{ 806 if (!shader) 807 return GL_FALSE; 808 809 makeContextCurrent(); 810 return ::glIsShader(shader); 811} 812 813GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture) 814{ 815 if (!texture) 816 return GL_FALSE; 817 818 makeContextCurrent(); 819 return ::glIsTexture(texture); 820} 821 822void GraphicsContext3D::lineWidth(GC3Dfloat width) 823{ 824 makeContextCurrent(); 825 ::glLineWidth(width); 826} 827 828void GraphicsContext3D::linkProgram(Platform3DObject program) 829{ 830 ASSERT(program); 831 makeContextCurrent(); 832 ::glLinkProgram(program); 833} 834 835void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param) 836{ 837 makeContextCurrent(); 838 ::glPixelStorei(pname, param); 839} 840 841void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units) 842{ 843 makeContextCurrent(); 844 ::glPolygonOffset(factor, units); 845} 846 847void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert) 848{ 849 makeContextCurrent(); 850 ::glSampleCoverage(value, invert); 851} 852 853void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) 854{ 855 makeContextCurrent(); 856 ::glScissor(x, y, width, height); 857} 858 859void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& string) 860{ 861 ASSERT(shader); 862 863 makeContextCurrent(); 864 865 ShaderSourceEntry entry; 866 867 entry.source = string; 868 869 m_shaderSourceMap.set(shader, entry); 870} 871 872void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask) 873{ 874 makeContextCurrent(); 875 ::glStencilFunc(func, ref, mask); 876} 877 878void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask) 879{ 880 makeContextCurrent(); 881 ::glStencilFuncSeparate(face, func, ref, mask); 882} 883 884void GraphicsContext3D::stencilMask(GC3Duint mask) 885{ 886 makeContextCurrent(); 887 ::glStencilMask(mask); 888} 889 890void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask) 891{ 892 makeContextCurrent(); 893 ::glStencilMaskSeparate(face, mask); 894} 895 896void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass) 897{ 898 makeContextCurrent(); 899 ::glStencilOp(fail, zfail, zpass); 900} 901 902void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass) 903{ 904 makeContextCurrent(); 905 ::glStencilOpSeparate(face, fail, zfail, zpass); 906} 907 908void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat value) 909{ 910 makeContextCurrent(); 911 ::glTexParameterf(target, pname, value); 912} 913 914void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint value) 915{ 916 makeContextCurrent(); 917 ::glTexParameteri(target, pname, value); 918} 919 920void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat v0) 921{ 922 makeContextCurrent(); 923 ::glUniform1f(location, v0); 924} 925 926void GraphicsContext3D::uniform1fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array) 927{ 928 makeContextCurrent(); 929 ::glUniform1fv(location, size, array); 930} 931 932void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1) 933{ 934 makeContextCurrent(); 935 ::glUniform2f(location, v0, v1); 936} 937 938void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array) 939{ 940 // FIXME: length needs to be a multiple of 2. 941 makeContextCurrent(); 942 ::glUniform2fv(location, size, array); 943} 944 945void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2) 946{ 947 makeContextCurrent(); 948 ::glUniform3f(location, v0, v1, v2); 949} 950 951void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array) 952{ 953 // FIXME: length needs to be a multiple of 3. 954 makeContextCurrent(); 955 ::glUniform3fv(location, size, array); 956} 957 958void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3) 959{ 960 makeContextCurrent(); 961 ::glUniform4f(location, v0, v1, v2, v3); 962} 963 964void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array) 965{ 966 // FIXME: length needs to be a multiple of 4. 967 makeContextCurrent(); 968 ::glUniform4fv(location, size, array); 969} 970 971void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint v0) 972{ 973 makeContextCurrent(); 974 ::glUniform1i(location, v0); 975} 976 977void GraphicsContext3D::uniform1iv(GC3Dint location, GC3Dsizei size, GC3Dint* array) 978{ 979 makeContextCurrent(); 980 ::glUniform1iv(location, size, array); 981} 982 983void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint v0, GC3Dint v1) 984{ 985 makeContextCurrent(); 986 ::glUniform2i(location, v0, v1); 987} 988 989void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dsizei size, GC3Dint* array) 990{ 991 // FIXME: length needs to be a multiple of 2. 992 makeContextCurrent(); 993 ::glUniform2iv(location, size, array); 994} 995 996void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2) 997{ 998 makeContextCurrent(); 999 ::glUniform3i(location, v0, v1, v2); 1000} 1001 1002void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dsizei size, GC3Dint* array) 1003{ 1004 // FIXME: length needs to be a multiple of 3. 1005 makeContextCurrent(); 1006 ::glUniform3iv(location, size, array); 1007} 1008 1009void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint v0, GC3Dint v1, GC3Dint v2, GC3Dint v3) 1010{ 1011 makeContextCurrent(); 1012 ::glUniform4i(location, v0, v1, v2, v3); 1013} 1014 1015void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dsizei size, GC3Dint* array) 1016{ 1017 // FIXME: length needs to be a multiple of 4. 1018 makeContextCurrent(); 1019 ::glUniform4iv(location, size, array); 1020} 1021 1022void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array) 1023{ 1024 // FIXME: length needs to be a multiple of 4. 1025 makeContextCurrent(); 1026 ::glUniformMatrix2fv(location, size, transpose, array); 1027} 1028 1029void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array) 1030{ 1031 // FIXME: length needs to be a multiple of 9. 1032 makeContextCurrent(); 1033 ::glUniformMatrix3fv(location, size, transpose, array); 1034} 1035 1036void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* array) 1037{ 1038 // FIXME: length needs to be a multiple of 16. 1039 makeContextCurrent(); 1040 ::glUniformMatrix4fv(location, size, transpose, array); 1041} 1042 1043void GraphicsContext3D::useProgram(Platform3DObject program) 1044{ 1045 makeContextCurrent(); 1046 ::glUseProgram(program); 1047} 1048 1049void GraphicsContext3D::validateProgram(Platform3DObject program) 1050{ 1051 ASSERT(program); 1052 1053 makeContextCurrent(); 1054 ::glValidateProgram(program); 1055} 1056 1057void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat v0) 1058{ 1059 makeContextCurrent(); 1060 ::glVertexAttrib1f(index, v0); 1061} 1062 1063void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* array) 1064{ 1065 makeContextCurrent(); 1066 ::glVertexAttrib1fv(index, array); 1067} 1068 1069void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1) 1070{ 1071 makeContextCurrent(); 1072 ::glVertexAttrib2f(index, v0, v1); 1073} 1074 1075void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* array) 1076{ 1077 makeContextCurrent(); 1078 ::glVertexAttrib2fv(index, array); 1079} 1080 1081void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2) 1082{ 1083 makeContextCurrent(); 1084 ::glVertexAttrib3f(index, v0, v1, v2); 1085} 1086 1087void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* array) 1088{ 1089 makeContextCurrent(); 1090 ::glVertexAttrib3fv(index, array); 1091} 1092 1093void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3) 1094{ 1095 makeContextCurrent(); 1096 ::glVertexAttrib4f(index, v0, v1, v2, v3); 1097} 1098 1099void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* array) 1100{ 1101 makeContextCurrent(); 1102 ::glVertexAttrib4fv(index, array); 1103} 1104 1105void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset) 1106{ 1107 makeContextCurrent(); 1108 ::glVertexAttribPointer(index, size, type, normalized, stride, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset))); 1109} 1110 1111void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) 1112{ 1113 makeContextCurrent(); 1114 ::glViewport(x, y, width, height); 1115} 1116 1117void GraphicsContext3D::getBooleanv(GC3Denum pname, GC3Dboolean* value) 1118{ 1119 makeContextCurrent(); 1120 ::glGetBooleanv(pname, value); 1121} 1122 1123void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value) 1124{ 1125 makeContextCurrent(); 1126 ::glGetBufferParameteriv(target, pname, value); 1127} 1128 1129void GraphicsContext3D::getFloatv(GC3Denum pname, GC3Dfloat* value) 1130{ 1131 makeContextCurrent(); 1132 ::glGetFloatv(pname, value); 1133} 1134 1135void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum pname, GC3Dint* value) 1136{ 1137 makeContextCurrent(); 1138 if (attachment == DEPTH_STENCIL_ATTACHMENT) 1139 attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works. 1140 ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); 1141} 1142 1143void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum pname, GC3Dint* value) 1144{ 1145 makeContextCurrent(); 1146 ::glGetProgramiv(program, pname, value); 1147} 1148 1149String GraphicsContext3D::getProgramInfoLog(Platform3DObject program) 1150{ 1151 ASSERT(program); 1152 1153 makeContextCurrent(); 1154 GLint length = 0; 1155 ::glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 1156 if (!length) 1157 return String(); 1158 1159 GLsizei size = 0; 1160 OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]); 1161 ::glGetProgramInfoLog(program, length, &size, info.get()); 1162 1163 return String(info.get()); 1164} 1165 1166void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value) 1167{ 1168 makeContextCurrent(); 1169 ::glGetRenderbufferParameterivEXT(target, pname, value); 1170} 1171 1172void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3Dint* value) 1173{ 1174 ASSERT(shader); 1175 1176 makeContextCurrent(); 1177 1178 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader); 1179 1180 switch (pname) { 1181 case DELETE_STATUS: 1182 case SHADER_TYPE: 1183 ::glGetShaderiv(shader, pname, value); 1184 break; 1185 case COMPILE_STATUS: 1186 if (result == m_shaderSourceMap.end()) { 1187 *value = static_cast<int>(false); 1188 return; 1189 } 1190 *value = static_cast<int>(result->value.isValid); 1191 break; 1192 case INFO_LOG_LENGTH: 1193 if (result == m_shaderSourceMap.end()) { 1194 *value = 0; 1195 return; 1196 } 1197 *value = getShaderInfoLog(shader).length(); 1198 break; 1199 case SHADER_SOURCE_LENGTH: 1200 *value = getShaderSource(shader).length(); 1201 break; 1202 default: 1203 synthesizeGLError(INVALID_ENUM); 1204 } 1205} 1206 1207String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader) 1208{ 1209 ASSERT(shader); 1210 1211 makeContextCurrent(); 1212 1213 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader); 1214 if (result == m_shaderSourceMap.end()) 1215 return String(); 1216 1217 ShaderSourceEntry entry = result->value; 1218 if (!entry.isValid) 1219 return entry.log; 1220 1221 GLint length = 0; 1222 ::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 1223 if (!length) 1224 return String(); 1225 1226 GLsizei size = 0; 1227 OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]); 1228 ::glGetShaderInfoLog(shader, length, &size, info.get()); 1229 1230 return String(info.get()); 1231} 1232 1233String GraphicsContext3D::getShaderSource(Platform3DObject shader) 1234{ 1235 ASSERT(shader); 1236 1237 makeContextCurrent(); 1238 1239 ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader); 1240 if (result == m_shaderSourceMap.end()) 1241 return String(); 1242 1243 return result->value.source; 1244} 1245 1246 1247void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum pname, GC3Dfloat* value) 1248{ 1249 makeContextCurrent(); 1250 ::glGetTexParameterfv(target, pname, value); 1251} 1252 1253void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum pname, GC3Dint* value) 1254{ 1255 makeContextCurrent(); 1256 ::glGetTexParameteriv(target, pname, value); 1257} 1258 1259void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value) 1260{ 1261 makeContextCurrent(); 1262 ::glGetUniformfv(program, location, value); 1263} 1264 1265void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value) 1266{ 1267 makeContextCurrent(); 1268 ::glGetUniformiv(program, location, value); 1269} 1270 1271GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) 1272{ 1273 ASSERT(program); 1274 1275 makeContextCurrent(); 1276 1277 // The uniform name may have been translated during ANGLE compilation. 1278 // Look through the corresponding ShaderSourceMap to make sure we 1279 // reference the mapped name rather than the external name. 1280 String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, name); 1281 1282 return ::glGetUniformLocation(program, mappedName.utf8().data()); 1283} 1284 1285void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value) 1286{ 1287 makeContextCurrent(); 1288 ::glGetVertexAttribfv(index, pname, value); 1289} 1290 1291void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum pname, GC3Dint* value) 1292{ 1293 makeContextCurrent(); 1294 ::glGetVertexAttribiv(index, pname, value); 1295} 1296 1297GC3Dsizeiptr GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum pname) 1298{ 1299 makeContextCurrent(); 1300 1301 GLvoid* pointer = 0; 1302 ::glGetVertexAttribPointerv(index, pname, &pointer); 1303 return static_cast<GC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer)); 1304} 1305 1306void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoff, GC3Dint yoff, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels) 1307{ 1308 makeContextCurrent(); 1309 1310 // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size. 1311 ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels); 1312} 1313 1314void GraphicsContext3D::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data) 1315{ 1316 makeContextCurrent(); 1317 ::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); 1318} 1319 1320void GraphicsContext3D::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data) 1321{ 1322 makeContextCurrent(); 1323 ::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); 1324} 1325 1326Platform3DObject GraphicsContext3D::createBuffer() 1327{ 1328 makeContextCurrent(); 1329 GLuint o = 0; 1330 glGenBuffers(1, &o); 1331 return o; 1332} 1333 1334Platform3DObject GraphicsContext3D::createFramebuffer() 1335{ 1336 makeContextCurrent(); 1337 GLuint o = 0; 1338 glGenFramebuffersEXT(1, &o); 1339 return o; 1340} 1341 1342Platform3DObject GraphicsContext3D::createProgram() 1343{ 1344 makeContextCurrent(); 1345 return glCreateProgram(); 1346} 1347 1348Platform3DObject GraphicsContext3D::createRenderbuffer() 1349{ 1350 makeContextCurrent(); 1351 GLuint o = 0; 1352 glGenRenderbuffersEXT(1, &o); 1353 return o; 1354} 1355 1356Platform3DObject GraphicsContext3D::createShader(GC3Denum type) 1357{ 1358 makeContextCurrent(); 1359 return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER); 1360} 1361 1362Platform3DObject GraphicsContext3D::createTexture() 1363{ 1364 makeContextCurrent(); 1365 GLuint o = 0; 1366 glGenTextures(1, &o); 1367 return o; 1368} 1369 1370void GraphicsContext3D::deleteBuffer(Platform3DObject buffer) 1371{ 1372 makeContextCurrent(); 1373 glDeleteBuffers(1, &buffer); 1374} 1375 1376void GraphicsContext3D::deleteFramebuffer(Platform3DObject framebuffer) 1377{ 1378 makeContextCurrent(); 1379 if (framebuffer == m_state.boundFBO) { 1380 // Make sure the framebuffer is not going to be used for drawing 1381 // operations after it gets deleted. 1382 bindFramebuffer(FRAMEBUFFER, 0); 1383 } 1384 glDeleteFramebuffersEXT(1, &framebuffer); 1385} 1386 1387void GraphicsContext3D::deleteProgram(Platform3DObject program) 1388{ 1389 makeContextCurrent(); 1390 glDeleteProgram(program); 1391} 1392 1393void GraphicsContext3D::deleteRenderbuffer(Platform3DObject renderbuffer) 1394{ 1395 makeContextCurrent(); 1396 glDeleteRenderbuffersEXT(1, &renderbuffer); 1397} 1398 1399void GraphicsContext3D::deleteShader(Platform3DObject shader) 1400{ 1401 makeContextCurrent(); 1402 glDeleteShader(shader); 1403} 1404 1405void GraphicsContext3D::deleteTexture(Platform3DObject texture) 1406{ 1407 makeContextCurrent(); 1408 if (m_state.boundTexture0 == texture) 1409 m_state.boundTexture0 = 0; 1410 glDeleteTextures(1, &texture); 1411} 1412 1413void GraphicsContext3D::synthesizeGLError(GC3Denum error) 1414{ 1415 m_syntheticErrors.add(error); 1416} 1417 1418void GraphicsContext3D::markContextChanged() 1419{ 1420 m_layerComposited = false; 1421} 1422 1423void GraphicsContext3D::markLayerComposited() 1424{ 1425 m_layerComposited = true; 1426} 1427 1428bool GraphicsContext3D::layerComposited() const 1429{ 1430 return m_layerComposited; 1431} 1432 1433void GraphicsContext3D::texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels) 1434{ 1435 makeContextCurrent(); 1436 ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); 1437} 1438 1439} 1440 1441#endif // USE(3D_GRAPHICS) 1442