Home | History | Annotate | Download | only in mac
      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