WebCore/html/canvas/WebGLRenderingContext.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
       
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
       
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
       
    24  */
       
    25 
       
    26 #include "config.h"
       
    27 
       
    28 #if ENABLE(3D_CANVAS)
       
    29 
       
    30 #include "WebGLRenderingContext.h"
       
    31 
       
    32 #include "CheckedInt.h"
       
    33 #include "CanvasPixelArray.h"
       
    34 #include "Console.h"
       
    35 #include "DOMWindow.h"
       
    36 #include "FrameView.h"
       
    37 #include "HTMLCanvasElement.h"
       
    38 #include "HTMLImageElement.h"
       
    39 #include "ImageBuffer.h"
       
    40 #include "ImageData.h"
       
    41 #include "NotImplemented.h"
       
    42 #include "RenderBox.h"
       
    43 #include "RenderLayer.h"
       
    44 #include "WebGLActiveInfo.h"
       
    45 #include "Uint16Array.h"
       
    46 #include "WebGLBuffer.h"
       
    47 #include "WebGLContextAttributes.h"
       
    48 #include "WebGLFramebuffer.h"
       
    49 #include "WebGLProgram.h"
       
    50 #include "WebGLRenderbuffer.h"
       
    51 #include "WebGLTexture.h"
       
    52 #include "WebGLShader.h"
       
    53 #include "WebGLUniformLocation.h"
       
    54 
       
    55 #include <wtf/ByteArray.h>
       
    56 #include <wtf/OwnArrayPtr.h>
       
    57 
       
    58 namespace WebCore {
       
    59 
       
    60 class WebGLStateRestorer {
       
    61 public:
       
    62     WebGLStateRestorer(WebGLRenderingContext* context,
       
    63                        bool changed)
       
    64         : m_context(context)
       
    65         , m_changed(changed)
       
    66     {
       
    67     }
       
    68 
       
    69     ~WebGLStateRestorer()
       
    70     {
       
    71         m_context->cleanupAfterGraphicsCall(m_changed);
       
    72     }
       
    73 
       
    74 private:
       
    75     WebGLRenderingContext* m_context;
       
    76     bool m_changed;
       
    77 };
       
    78 
       
    79 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
       
    80 {
       
    81     HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow();
       
    82     OwnPtr<GraphicsContext3D> context(GraphicsContext3D::create(attrs->attributes(), hostWindow));
       
    83 
       
    84     if (!context)
       
    85         return 0;
       
    86         
       
    87     return new WebGLRenderingContext(canvas, context.release());
       
    88 }
       
    89 
       
    90 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<GraphicsContext3D> context)
       
    91     : CanvasRenderingContext(passedCanvas)
       
    92     , m_context(context)
       
    93     , m_needsUpdate(true)
       
    94     , m_markedCanvasDirty(false)
       
    95     , m_activeTextureUnit(0)
       
    96     , m_packAlignment(4)
       
    97     , m_unpackAlignment(4)
       
    98     , m_unpackFlipY(false)
       
    99     , m_unpackPremultiplyAlpha(false)
       
   100 {
       
   101     ASSERT(m_context);
       
   102 
       
   103     int numCombinedTextureImageUnits = 0;
       
   104     m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
       
   105     m_textureUnits.resize(numCombinedTextureImageUnits);
       
   106 
       
   107     int numVertexAttribs = 0;
       
   108     m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
       
   109     m_maxVertexAttribs = numVertexAttribs;
       
   110 
       
   111     int implementationColorReadFormat = GraphicsContext3D::RGBA;
       
   112     m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT, &implementationColorReadFormat);
       
   113     m_implementationColorReadFormat = implementationColorReadFormat;
       
   114     int implementationColorReadType = GraphicsContext3D::UNSIGNED_BYTE;
       
   115     m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType);
       
   116     m_implementationColorReadType = implementationColorReadType;
       
   117 
       
   118     m_maxTextureSize = 0;
       
   119     m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
       
   120     m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
       
   121     m_maxCubeMapTextureSize = 0;
       
   122     m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
       
   123     m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
       
   124 
       
   125     if (!isGLES2Compliant()) {
       
   126         createFallbackBlackTextures1x1();
       
   127         initVertexAttrib0();
       
   128     }
       
   129     m_context->reshape(canvas()->width(), canvas()->height());
       
   130     m_context->viewport(0, 0, canvas()->width(), canvas()->height());
       
   131 }
       
   132 
       
   133 WebGLRenderingContext::~WebGLRenderingContext()
       
   134 {
       
   135     detachAndRemoveAllObjects();
       
   136 }
       
   137 
       
   138 void WebGLRenderingContext::markContextChanged()
       
   139 {
       
   140 #if USE(ACCELERATED_COMPOSITING)
       
   141     RenderBox* renderBox = canvas()->renderBox();
       
   142     if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
       
   143         renderBox->layer()->rendererContentChanged();
       
   144 #endif
       
   145     if (!m_markedCanvasDirty) {
       
   146         // Make sure the canvas's image buffer is allocated.
       
   147         canvas()->buffer();
       
   148         canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
       
   149         m_markedCanvasDirty = true;
       
   150     }
       
   151 }
       
   152 
       
   153 bool WebGLRenderingContext::paintRenderingResultsToCanvas()
       
   154 {
       
   155     if (m_markedCanvasDirty) {
       
   156         m_markedCanvasDirty = false;
       
   157         m_context->paintRenderingResultsToCanvas(this);
       
   158         return true;
       
   159     }
       
   160     return false;
       
   161 }
       
   162 
       
   163 void WebGLRenderingContext::beginPaint()
       
   164 {
       
   165     if (m_markedCanvasDirty) {
       
   166         m_context->beginPaint(this);
       
   167     }
       
   168 }
       
   169 
       
   170 void WebGLRenderingContext::endPaint()
       
   171 {
       
   172     if (m_markedCanvasDirty) {
       
   173         m_markedCanvasDirty = false;
       
   174         m_context->endPaint();
       
   175     }
       
   176 }
       
   177 
       
   178 void WebGLRenderingContext::reshape(int width, int height)
       
   179 {
       
   180     if (m_needsUpdate) {
       
   181 #if USE(ACCELERATED_COMPOSITING)
       
   182         RenderBox* renderBox = canvas()->renderBox();
       
   183         if (renderBox && renderBox->hasLayer())
       
   184             renderBox->layer()->rendererContentChanged();
       
   185 #endif
       
   186         m_needsUpdate = false;
       
   187     }
       
   188     
       
   189     m_context->reshape(width, height);
       
   190 }
       
   191 
       
   192 int WebGLRenderingContext::sizeInBytes(int type, ExceptionCode& ec)
       
   193 {
       
   194     UNUSED_PARAM(ec);
       
   195     int result = m_context->sizeInBytes(type);
       
   196     if (result <= 0)
       
   197         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   198 
       
   199     return result;
       
   200 }
       
   201 
       
   202 void WebGLRenderingContext::activeTexture(unsigned long texture, ExceptionCode& ec)
       
   203 {
       
   204     UNUSED_PARAM(ec);
       
   205     if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
       
   206         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   207         return;
       
   208     }
       
   209     m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
       
   210     m_context->activeTexture(texture);
       
   211     cleanupAfterGraphicsCall(false);
       
   212 }
       
   213 
       
   214 void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
       
   215 {
       
   216     UNUSED_PARAM(ec);
       
   217     if (!validateWebGLObject(program) || !validateWebGLObject(shader))
       
   218         return;
       
   219     m_context->attachShader(program, shader);
       
   220     cleanupAfterGraphicsCall(false);
       
   221 }
       
   222 
       
   223 void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name, ExceptionCode& ec)
       
   224 {
       
   225     UNUSED_PARAM(ec);
       
   226     if (!validateWebGLObject(program))
       
   227         return;
       
   228     m_context->bindAttribLocation(program, index, name);
       
   229     cleanupAfterGraphicsCall(false);
       
   230 }
       
   231 
       
   232 void WebGLRenderingContext::bindBuffer(unsigned long target, WebGLBuffer* buffer, ExceptionCode& ec)
       
   233 {
       
   234     UNUSED_PARAM(ec);
       
   235     if (buffer && buffer->context() != this) {
       
   236         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   237         return;
       
   238     }
       
   239     if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
       
   240         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   241         return;
       
   242     }
       
   243 
       
   244     if (target == GraphicsContext3D::ARRAY_BUFFER)
       
   245         m_boundArrayBuffer = buffer;
       
   246     else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
       
   247         m_boundElementArrayBuffer = buffer;
       
   248     else {
       
   249         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   250         return;
       
   251     }
       
   252 
       
   253     m_context->bindBuffer(target, buffer);
       
   254     if (buffer)
       
   255         buffer->setTarget(target);
       
   256     cleanupAfterGraphicsCall(false);
       
   257 }
       
   258 
       
   259 
       
   260 void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer, ExceptionCode& ec)
       
   261 {
       
   262     UNUSED_PARAM(ec);
       
   263     if (buffer && buffer->context() != this) {
       
   264         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   265         return;
       
   266     }
       
   267     if (target != GraphicsContext3D::FRAMEBUFFER) {
       
   268         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   269         return;
       
   270     }
       
   271     m_framebufferBinding = buffer;
       
   272     m_context->bindFramebuffer(target, buffer);
       
   273     if (m_framebufferBinding)
       
   274         m_framebufferBinding->onBind();
       
   275     cleanupAfterGraphicsCall(false);
       
   276 }
       
   277 
       
   278 void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderBuffer, ExceptionCode& ec)
       
   279 {
       
   280     UNUSED_PARAM(ec);
       
   281     if (renderBuffer && renderBuffer->context() != this) {
       
   282         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   283         return;
       
   284     }
       
   285     if (target != GraphicsContext3D::RENDERBUFFER) {
       
   286         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   287         return;
       
   288     }
       
   289     m_renderbufferBinding = renderBuffer;
       
   290     m_context->bindRenderbuffer(target, renderBuffer);
       
   291     cleanupAfterGraphicsCall(false);
       
   292 }
       
   293 
       
   294 
       
   295 void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* texture, ExceptionCode& ec)
       
   296 {
       
   297     UNUSED_PARAM(ec);
       
   298     if (texture && texture->context() != this) {
       
   299         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   300         return;
       
   301     }
       
   302     int maxLevel = 0;
       
   303     if (target == GraphicsContext3D::TEXTURE_2D) {
       
   304         m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
       
   305         maxLevel = m_maxTextureLevel;
       
   306     } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
       
   307         m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
       
   308         maxLevel = m_maxCubeMapTextureLevel;
       
   309     } else {
       
   310         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   311         return;
       
   312     }
       
   313     m_context->bindTexture(target, texture);
       
   314     if (!isGLES2Compliant() && texture)
       
   315         texture->setTarget(target, maxLevel);
       
   316     cleanupAfterGraphicsCall(false);
       
   317 }
       
   318 
       
   319 void WebGLRenderingContext::blendColor(double red, double green, double blue, double alpha)
       
   320 {
       
   321     m_context->blendColor(red, green, blue, alpha);
       
   322     cleanupAfterGraphicsCall(false);
       
   323 }
       
   324 
       
   325 void WebGLRenderingContext::blendEquation( unsigned long mode )
       
   326 {
       
   327     if (!isGLES2Compliant()) {
       
   328         if (!validateBlendEquation(mode))
       
   329             return;
       
   330     }
       
   331     m_context->blendEquation(mode);
       
   332     cleanupAfterGraphicsCall(false);
       
   333 }
       
   334 
       
   335 void WebGLRenderingContext::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
       
   336 {
       
   337     if (!isGLES2Compliant()) {
       
   338         if (!validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
       
   339             return;
       
   340     }
       
   341     m_context->blendEquationSeparate(modeRGB, modeAlpha);
       
   342     cleanupAfterGraphicsCall(false);
       
   343 }
       
   344 
       
   345 
       
   346 void WebGLRenderingContext::blendFunc(unsigned long sfactor, unsigned long dfactor)
       
   347 {
       
   348     m_context->blendFunc(sfactor, dfactor);
       
   349     cleanupAfterGraphicsCall(false);
       
   350 }       
       
   351 
       
   352 void WebGLRenderingContext::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
       
   353 {
       
   354     m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
       
   355     cleanupAfterGraphicsCall(false);
       
   356 }
       
   357 
       
   358 void WebGLRenderingContext::bufferData(unsigned long target, int size, unsigned long usage, ExceptionCode& ec)
       
   359 {
       
   360     UNUSED_PARAM(ec);
       
   361     WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
       
   362     if (!buffer)
       
   363         return;
       
   364     if (!buffer->associateBufferData(size)) {
       
   365         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   366         return;
       
   367     }
       
   368 
       
   369     m_context->bufferData(target, size, usage);
       
   370     cleanupAfterGraphicsCall(false);
       
   371 }
       
   372 
       
   373 void WebGLRenderingContext::bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage, ExceptionCode& ec)
       
   374 {
       
   375     UNUSED_PARAM(ec);
       
   376     WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
       
   377     if (!buffer)
       
   378         return;
       
   379     if (!buffer->associateBufferData(data)) {
       
   380         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   381         return;
       
   382     }
       
   383 
       
   384     m_context->bufferData(target, data, usage);
       
   385     cleanupAfterGraphicsCall(false);
       
   386 }
       
   387 
       
   388 void WebGLRenderingContext::bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage, ExceptionCode& ec)
       
   389 {
       
   390     UNUSED_PARAM(ec);
       
   391     WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
       
   392     if (!buffer)
       
   393         return;
       
   394     if (!buffer->associateBufferData(data)) {
       
   395         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   396         return;
       
   397     }
       
   398 
       
   399     m_context->bufferData(target, data, usage);
       
   400     cleanupAfterGraphicsCall(false);
       
   401 }
       
   402 
       
   403 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBuffer* data, ExceptionCode& ec)
       
   404 {
       
   405     UNUSED_PARAM(ec);
       
   406     WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
       
   407     if (!buffer)
       
   408         return;
       
   409     if (!buffer->associateBufferSubData(offset, data)) {
       
   410         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   411         return;
       
   412     }
       
   413 
       
   414     m_context->bufferSubData(target, offset, data);
       
   415     cleanupAfterGraphicsCall(false);
       
   416 }
       
   417 
       
   418 void WebGLRenderingContext::bufferSubData(unsigned long target, long offset, ArrayBufferView* data, ExceptionCode& ec)
       
   419 {
       
   420     UNUSED_PARAM(ec);
       
   421     WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
       
   422     if (!buffer)
       
   423         return;
       
   424     if (!buffer->associateBufferSubData(offset, data)) {
       
   425         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   426         return;
       
   427     }
       
   428 
       
   429     m_context->bufferSubData(target, offset, data);
       
   430     cleanupAfterGraphicsCall(false);
       
   431 }
       
   432 
       
   433 unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target)
       
   434 {
       
   435     if (!isGLES2Compliant()) {
       
   436         if (target != GraphicsContext3D::FRAMEBUFFER) {
       
   437             m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   438             return 0;
       
   439         }
       
   440     }
       
   441     if (!m_framebufferBinding || !m_framebufferBinding->object())
       
   442         return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
       
   443     return m_context->checkFramebufferStatus(target);
       
   444     cleanupAfterGraphicsCall(false);
       
   445 }
       
   446 
       
   447 void WebGLRenderingContext::clear(unsigned long mask)
       
   448 {
       
   449     if (!isGLES2Compliant()) {
       
   450         if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
       
   451             m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   452             return;
       
   453         }
       
   454     }
       
   455     m_context->clear(mask);
       
   456     cleanupAfterGraphicsCall(true);
       
   457 }
       
   458 
       
   459 void WebGLRenderingContext::clearColor(double r, double g, double b, double a)
       
   460 {
       
   461     if (isnan(r))
       
   462         r = 0;
       
   463     if (isnan(g))
       
   464         g = 0;
       
   465     if (isnan(b))
       
   466         b = 0;
       
   467     if (isnan(a))
       
   468         a = 1;
       
   469     m_context->clearColor(r, g, b, a);
       
   470     cleanupAfterGraphicsCall(false);
       
   471 }
       
   472 
       
   473 void WebGLRenderingContext::clearDepth(double depth)
       
   474 {
       
   475     m_context->clearDepth(depth);
       
   476     cleanupAfterGraphicsCall(false);
       
   477 }
       
   478 
       
   479 void WebGLRenderingContext::clearStencil(long s)
       
   480 {
       
   481     m_context->clearStencil(s);
       
   482     cleanupAfterGraphicsCall(false);
       
   483 }
       
   484 
       
   485 void WebGLRenderingContext::colorMask(bool red, bool green, bool blue, bool alpha)
       
   486 {
       
   487     m_context->colorMask(red, green, blue, alpha);
       
   488     cleanupAfterGraphicsCall(false);
       
   489 }
       
   490 
       
   491 void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
       
   492 {
       
   493     UNUSED_PARAM(ec);
       
   494     if (!validateWebGLObject(shader))
       
   495         return;
       
   496     m_context->compileShader(shader);
       
   497     cleanupAfterGraphicsCall(false);
       
   498 }
       
   499 
       
   500 void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
       
   501 {
       
   502     if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
       
   503         return;
       
   504     if (!isGLES2Compliant()) {
       
   505         if (m_framebufferBinding && m_framebufferBinding->object()
       
   506             && !isTexInternalFormatColorBufferCombinationValid(internalformat,
       
   507                                                                m_framebufferBinding->getColorBufferFormat())) {
       
   508             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   509             return;
       
   510         }
       
   511         if (level && WebGLTexture::isNPOT(width, height)) {
       
   512             m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   513             return;
       
   514         }
       
   515     }
       
   516     m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
       
   517     // FIXME: if the framebuffer is not complete, none of the below should be executed.
       
   518     WebGLTexture* tex = getTextureBinding(target);
       
   519     if (!isGLES2Compliant()) {
       
   520         if (tex)
       
   521             tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
       
   522     }
       
   523     if (m_framebufferBinding && tex)
       
   524         m_framebufferBinding->onAttachedObjectChange(tex);
       
   525     cleanupAfterGraphicsCall(false);
       
   526 }
       
   527 
       
   528 void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
       
   529 {
       
   530     if (!isGLES2Compliant()) {
       
   531         WebGLTexture* tex = getTextureBinding(target);
       
   532         if (m_framebufferBinding && m_framebufferBinding->object() && tex
       
   533             && !isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(),
       
   534                                                                m_framebufferBinding->getColorBufferFormat())) {
       
   535             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   536             return;
       
   537         }
       
   538     }
       
   539     m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
       
   540     cleanupAfterGraphicsCall(false);
       
   541 }
       
   542 
       
   543 PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
       
   544 {
       
   545     RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
       
   546     addObject(o.get());
       
   547     return o;
       
   548 }
       
   549         
       
   550 PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
       
   551 {
       
   552     RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
       
   553     addObject(o.get());
       
   554     return o;
       
   555 }
       
   556 
       
   557 PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
       
   558 {
       
   559     RefPtr<WebGLTexture> o = WebGLTexture::create(this);
       
   560     addObject(o.get());
       
   561     return o;
       
   562 }
       
   563 
       
   564 PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
       
   565 {
       
   566     RefPtr<WebGLProgram> o = WebGLProgram::create(this);
       
   567     addObject(o.get());
       
   568     return o;
       
   569 }
       
   570 
       
   571 PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
       
   572 {
       
   573     RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
       
   574     addObject(o.get());
       
   575     return o;
       
   576 }
       
   577 
       
   578 PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(unsigned long type, ExceptionCode& ec)
       
   579 {
       
   580     UNUSED_PARAM(ec);
       
   581     if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
       
   582         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   583         return 0;
       
   584     }
       
   585     
       
   586     RefPtr<WebGLShader> o = WebGLShader::create(this, static_cast<GraphicsContext3D::WebGLEnumType>(type));
       
   587     addObject(o.get());
       
   588     return o;
       
   589 }
       
   590 
       
   591 void WebGLRenderingContext::cullFace(unsigned long mode)
       
   592 {
       
   593     m_context->cullFace(mode);
       
   594     cleanupAfterGraphicsCall(false);
       
   595 }
       
   596 
       
   597 void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
       
   598 {
       
   599     if (!buffer)
       
   600         return;
       
   601     
       
   602     buffer->deleteObject();
       
   603 
       
   604     if (!isGLES2Compliant()) {
       
   605         VertexAttribState& state = m_vertexAttribState[0];
       
   606         if (buffer == state.bufferBinding) {
       
   607             state.bufferBinding = m_vertexAttrib0Buffer;
       
   608             state.bytesPerElement = 0;
       
   609             state.size = 4;
       
   610             state.type = GraphicsContext3D::FLOAT;
       
   611             state.normalized = false;
       
   612             state.stride = 16;
       
   613             state.originalStride = 0;
       
   614             state.offset = 0;
       
   615         }
       
   616     }
       
   617 }
       
   618 
       
   619 void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
       
   620 {
       
   621     if (!framebuffer)
       
   622         return;
       
   623     
       
   624     framebuffer->deleteObject();
       
   625 }
       
   626 
       
   627 void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
       
   628 {
       
   629     if (!program)
       
   630         return;
       
   631     
       
   632     program->deleteObject();
       
   633 }
       
   634 
       
   635 void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
       
   636 {
       
   637     if (!renderbuffer)
       
   638         return;
       
   639     
       
   640     renderbuffer->deleteObject();
       
   641     if (m_framebufferBinding)
       
   642         m_framebufferBinding->onAttachedObjectChange(renderbuffer);
       
   643 }
       
   644 
       
   645 void WebGLRenderingContext::deleteShader(WebGLShader* shader)
       
   646 {
       
   647     if (!shader)
       
   648         return;
       
   649     
       
   650     shader->deleteObject();
       
   651 }
       
   652 
       
   653 void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
       
   654 {
       
   655     if (!texture)
       
   656         return;
       
   657     
       
   658     texture->deleteObject();
       
   659     if (m_framebufferBinding)
       
   660         m_framebufferBinding->onAttachedObjectChange(texture);
       
   661 }
       
   662 
       
   663 void WebGLRenderingContext::depthFunc(unsigned long func)
       
   664 {
       
   665     m_context->depthFunc(func);
       
   666     cleanupAfterGraphicsCall(false);
       
   667 }
       
   668 
       
   669 void WebGLRenderingContext::depthMask(bool flag)
       
   670 {
       
   671     m_context->depthMask(flag);
       
   672     cleanupAfterGraphicsCall(false);
       
   673 }
       
   674 
       
   675 void WebGLRenderingContext::depthRange(double zNear, double zFar)
       
   676 {
       
   677     m_context->depthRange(zNear, zFar);
       
   678     cleanupAfterGraphicsCall(false);
       
   679 }
       
   680 
       
   681 void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
       
   682 {
       
   683     UNUSED_PARAM(ec);
       
   684     if (!validateWebGLObject(program) || !validateWebGLObject(shader))
       
   685         return;
       
   686     m_context->detachShader(program, shader);
       
   687     cleanupAfterGraphicsCall(false);
       
   688 }
       
   689 
       
   690 
       
   691 void WebGLRenderingContext::disable(unsigned long cap)
       
   692 {
       
   693     if (!isGLES2Compliant()) {
       
   694         if (!validateCapability(cap))
       
   695             return;
       
   696     }
       
   697     m_context->disable(cap);
       
   698     cleanupAfterGraphicsCall(false);
       
   699 }
       
   700 
       
   701 void WebGLRenderingContext::disableVertexAttribArray(unsigned long index, ExceptionCode& ec)
       
   702 {
       
   703     UNUSED_PARAM(ec);
       
   704     if (index >= m_maxVertexAttribs) {
       
   705         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   706         return;
       
   707     }
       
   708     
       
   709     if (index < m_vertexAttribState.size())
       
   710         m_vertexAttribState[index].enabled = false;
       
   711 
       
   712     if (index > 0 || isGLES2Compliant()) {
       
   713         m_context->disableVertexAttribArray(index);
       
   714         cleanupAfterGraphicsCall(false);
       
   715     }
       
   716 }
       
   717 
       
   718 bool WebGLRenderingContext::validateElementArraySize(unsigned long count, unsigned long type, long offset)
       
   719 {
       
   720     if (!m_boundElementArrayBuffer)
       
   721         return false;
       
   722 
       
   723     if (offset < 0)
       
   724         return false;
       
   725 
       
   726     unsigned long uoffset = static_cast<unsigned long>(offset);
       
   727 
       
   728     if (type == GraphicsContext3D::UNSIGNED_SHORT) {
       
   729         // For an unsigned short array, offset must be divisible by 2 for alignment reasons.
       
   730         if (uoffset & 1)
       
   731             return false;
       
   732 
       
   733         // Make uoffset an element offset.
       
   734         uoffset /= 2;
       
   735 
       
   736         unsigned long n = m_boundElementArrayBuffer->byteLength() / 2;
       
   737         if (uoffset > n || count > n - uoffset)
       
   738             return false;
       
   739     } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
       
   740         unsigned long n = m_boundElementArrayBuffer->byteLength();
       
   741         if (uoffset > n || count > n - uoffset)
       
   742             return false;
       
   743     }
       
   744     return true;
       
   745 }
       
   746 
       
   747 bool WebGLRenderingContext::validateIndexArrayConservative(unsigned long type, long& numElementsRequired)
       
   748 {
       
   749     // Performs conservative validation by caching a maximum index of
       
   750     // the given type per element array buffer. If all of the bound
       
   751     // array buffers have enough elements to satisfy that maximum
       
   752     // index, skips the expensive per-draw-call iteration in
       
   753     // validateIndexArrayPrecise.
       
   754 
       
   755     long maxIndex = m_boundElementArrayBuffer->getCachedMaxIndex(type);
       
   756     if (maxIndex < 0) {
       
   757         // Compute the maximum index in the entire buffer for the given type of index.
       
   758         switch (type) {
       
   759         case GraphicsContext3D::UNSIGNED_BYTE: {
       
   760             unsigned numElements = m_boundElementArrayBuffer->byteLength();
       
   761             if (!numElements)
       
   762                 maxIndex = 0;
       
   763             else {
       
   764                 const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
       
   765                 for (unsigned i = 0; i < numElements; i++)
       
   766                     maxIndex = max(maxIndex, static_cast<long>(p[i]));
       
   767             }
       
   768             break;
       
   769         }
       
   770         case GraphicsContext3D::UNSIGNED_SHORT: {
       
   771             unsigned numElements = m_boundElementArrayBuffer->byteLength() / sizeof(unsigned short);
       
   772             if (!numElements)
       
   773                 maxIndex = 0;
       
   774             else {
       
   775                 const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data());
       
   776                 for (unsigned i = 0; i < numElements; i++)
       
   777                     maxIndex = max(maxIndex, static_cast<long>(p[i]));
       
   778             }
       
   779             break;
       
   780         }
       
   781         default:
       
   782             return false;
       
   783         }
       
   784         m_boundElementArrayBuffer->setCachedMaxIndex(type, maxIndex);
       
   785     }
       
   786 
       
   787     if (maxIndex >= 0) {
       
   788         // The number of required elements is one more than the maximum
       
   789         // index that will be accessed.
       
   790         numElementsRequired = maxIndex + 1;
       
   791         return true;
       
   792     }
       
   793 
       
   794     return false;
       
   795 }
       
   796 
       
   797 bool WebGLRenderingContext::validateIndexArrayPrecise(unsigned long count, unsigned long type, long offset, long& numElementsRequired)
       
   798 {
       
   799     long lastIndex = -1;
       
   800 
       
   801     if (!m_boundElementArrayBuffer)
       
   802         return false;
       
   803 
       
   804     unsigned long uoffset = static_cast<unsigned long>(offset);
       
   805     unsigned long n = count;
       
   806 
       
   807     if (type == GraphicsContext3D::UNSIGNED_SHORT) {
       
   808         // Make uoffset an element offset.
       
   809         uoffset /= 2;
       
   810         const unsigned short* p = static_cast<const unsigned short*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
       
   811         while (n-- > 0) {
       
   812             if (*p > lastIndex)
       
   813                 lastIndex = *p;
       
   814             ++p;
       
   815         }
       
   816     } else if (type == GraphicsContext3D::UNSIGNED_BYTE) {
       
   817         const unsigned char* p = static_cast<const unsigned char*>(m_boundElementArrayBuffer->elementArrayBuffer()->data()) + uoffset;
       
   818         while (n-- > 0) {
       
   819             if (*p > lastIndex)
       
   820                 lastIndex = *p;
       
   821             ++p;
       
   822         }
       
   823     }    
       
   824         
       
   825     // Then set the last index in the index array and make sure it is valid.
       
   826     numElementsRequired = lastIndex + 1;
       
   827     return numElementsRequired > 0;
       
   828 }
       
   829 
       
   830 bool WebGLRenderingContext::validateRenderingState(long numElementsRequired)
       
   831 {
       
   832     if (!m_currentProgram)
       
   833         return false;
       
   834 
       
   835     int numAttribStates = static_cast<int>(m_vertexAttribState.size());
       
   836 
       
   837     // Look in each enabled vertex attrib and check if they've been bound to a buffer.
       
   838     for (int i = 0; i < numAttribStates; ++i) {
       
   839         if (m_vertexAttribState[i].enabled
       
   840             && (!m_vertexAttribState[i].bufferBinding || !m_vertexAttribState[i].bufferBinding->object()))
       
   841             return false;
       
   842     }
       
   843 
       
   844     // Look in each consumed vertex attrib (by the current program) and find the smallest buffer size
       
   845     long smallestNumElements = LONG_MAX;
       
   846     int numActiveAttribLocations = m_currentProgram->numActiveAttribLocations();
       
   847     for (int i = 0; i < numActiveAttribLocations; ++i) {
       
   848         int loc = m_currentProgram->getActiveAttribLocation(i);
       
   849         if (loc >=0 && loc < numAttribStates) {
       
   850             const VertexAttribState& state = m_vertexAttribState[loc];
       
   851             if (state.enabled) {
       
   852                 // Avoid off-by-one errors in numElements computation.
       
   853                 // For the last element, we will only touch the data for the
       
   854                 // element and nothing beyond it.
       
   855                 long bytesRemaining = state.bufferBinding->byteLength() - state.offset;
       
   856                 long numElements = 0;
       
   857                 if (bytesRemaining >= state.bytesPerElement)
       
   858                     numElements = 1 + (bytesRemaining - state.bytesPerElement) / state.stride;
       
   859                 if (numElements < smallestNumElements)
       
   860                     smallestNumElements = numElements;
       
   861             }
       
   862         }
       
   863     }
       
   864     
       
   865     if (smallestNumElements == LONG_MAX)
       
   866         smallestNumElements = 0;
       
   867     
       
   868     return numElementsRequired <= smallestNumElements;
       
   869 }
       
   870 
       
   871 bool WebGLRenderingContext::validateWebGLObject(CanvasObject* object)
       
   872 {
       
   873     if (!object) {
       
   874         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   875         return false;
       
   876     }
       
   877     if (object->context() != this) {
       
   878         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   879         return false;
       
   880     }
       
   881     return true;
       
   882 }
       
   883 
       
   884 void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long count, ExceptionCode& ec)
       
   885 {
       
   886     UNUSED_PARAM(ec);
       
   887 
       
   888     if (!validateDrawMode(mode))
       
   889         return;
       
   890 
       
   891     if (first < 0 || count < 0) {
       
   892         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   893         return;
       
   894     }
       
   895 
       
   896     // Ensure we have a valid rendering state
       
   897     CheckedInt<int32_t> checkedFirst(first);
       
   898     CheckedInt<int32_t> checkedCount(count);
       
   899     CheckedInt<int32_t> checkedSum = checkedFirst + checkedCount;
       
   900     if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) {
       
   901         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   902         return;
       
   903     }
       
   904 
       
   905     bool vertexAttrib0Simulated = false;
       
   906     if (!isGLES2Compliant()) {
       
   907         vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
       
   908         handleNPOTTextures(true);
       
   909     }
       
   910     m_context->drawArrays(mode, first, count);
       
   911     if (!isGLES2Compliant()) {
       
   912         handleNPOTTextures(false);
       
   913         if (vertexAttrib0Simulated)
       
   914             restoreStatesAfterVertexAttrib0Simulation();
       
   915     }
       
   916     cleanupAfterGraphicsCall(true);
       
   917 }
       
   918 
       
   919 void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigned long type, long offset, ExceptionCode& ec)
       
   920 {
       
   921     UNUSED_PARAM(ec);
       
   922 
       
   923     if (!validateDrawMode(mode))
       
   924         return;
       
   925 
       
   926     switch (type) {
       
   927     case GraphicsContext3D::UNSIGNED_BYTE:
       
   928     case GraphicsContext3D::UNSIGNED_SHORT:
       
   929         break;
       
   930     default:
       
   931         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
   932         return;
       
   933     }
       
   934 
       
   935     if (count < 0 || offset < 0) {
       
   936         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   937         return;
       
   938     }
       
   939 
       
   940     // Ensure we have a valid rendering state
       
   941     long numElements;
       
   942     
       
   943     if (!validateElementArraySize(count, type, offset)) {
       
   944         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   945         return;
       
   946     }
       
   947 
       
   948     if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements))
       
   949         if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
       
   950             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
   951             return;
       
   952         }
       
   953 
       
   954     bool vertexAttrib0Simulated = false;
       
   955     if (!isGLES2Compliant()) {
       
   956         vertexAttrib0Simulated = simulateVertexAttrib0(numElements);
       
   957         handleNPOTTextures(true);
       
   958     }
       
   959     m_context->drawElements(mode, count, type, offset);
       
   960     if (!isGLES2Compliant()) {
       
   961         handleNPOTTextures(false);
       
   962         if (vertexAttrib0Simulated)
       
   963             restoreStatesAfterVertexAttrib0Simulation();
       
   964     }
       
   965     cleanupAfterGraphicsCall(true);
       
   966 }
       
   967 
       
   968 void WebGLRenderingContext::enable(unsigned long cap)
       
   969 {
       
   970     if (!isGLES2Compliant()) {
       
   971         if (!validateCapability(cap))
       
   972             return;
       
   973     }
       
   974     m_context->enable(cap);
       
   975     cleanupAfterGraphicsCall(false);
       
   976 }
       
   977 
       
   978 void WebGLRenderingContext::enableVertexAttribArray(unsigned long index, ExceptionCode& ec)
       
   979 {
       
   980     UNUSED_PARAM(ec);
       
   981     if (index >= m_maxVertexAttribs) {
       
   982         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
   983         return;
       
   984     }
       
   985     
       
   986     if (index >= m_vertexAttribState.size())
       
   987         m_vertexAttribState.resize(index + 1);
       
   988         
       
   989     m_vertexAttribState[index].enabled = true;
       
   990     
       
   991     m_context->enableVertexAttribArray(index);
       
   992     cleanupAfterGraphicsCall(false);
       
   993 }
       
   994 
       
   995 void WebGLRenderingContext::finish()
       
   996 {
       
   997     m_context->finish();
       
   998     cleanupAfterGraphicsCall(true);
       
   999 }
       
  1000 
       
  1001 
       
  1002 void WebGLRenderingContext::flush()
       
  1003 {
       
  1004     m_context->flush();
       
  1005     cleanupAfterGraphicsCall(true);
       
  1006 }
       
  1007 
       
  1008 void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
       
  1009 {
       
  1010     UNUSED_PARAM(ec);
       
  1011     if (!validateFramebufferFuncParameters(target, attachment))
       
  1012         return;
       
  1013     if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
       
  1014         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1015         return;
       
  1016     }
       
  1017     if (buffer && buffer->context() != this) {
       
  1018         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1019         return;
       
  1020     }
       
  1021     // Don't allow the default framebuffer to be mutated; all current
       
  1022     // implementations use an FBO internally in place of the default
       
  1023     // FBO.
       
  1024     if (!m_framebufferBinding || !m_framebufferBinding->object()) {
       
  1025         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1026         return;
       
  1027     }
       
  1028     if (buffer && buffer->object()) {
       
  1029         bool isConflicted = false;
       
  1030         switch (attachment) {
       
  1031         case GraphicsContext3D::DEPTH_ATTACHMENT:
       
  1032             if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached())
       
  1033                 isConflicted = true;
       
  1034             if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
       
  1035                 isConflicted = true;
       
  1036             break;
       
  1037         case GraphicsContext3D::STENCIL_ATTACHMENT:
       
  1038             if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached())
       
  1039                 isConflicted = true;
       
  1040             if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
       
  1041                 isConflicted = true;
       
  1042             break;
       
  1043         case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
       
  1044             if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached())
       
  1045                 isConflicted = true;
       
  1046             if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
       
  1047                 isConflicted = true;
       
  1048             break;
       
  1049         }
       
  1050         if (isConflicted) {
       
  1051             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1052             return;
       
  1053         }
       
  1054     }
       
  1055     m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, buffer);
       
  1056     m_framebufferBinding->setAttachment(attachment, buffer);
       
  1057     cleanupAfterGraphicsCall(false);
       
  1058 }
       
  1059 
       
  1060 void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level, ExceptionCode& ec)
       
  1061 {
       
  1062     UNUSED_PARAM(ec);
       
  1063     if (!validateFramebufferFuncParameters(target, attachment))
       
  1064         return;
       
  1065     if (level) {
       
  1066         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1067         return;
       
  1068     }
       
  1069     if (texture && texture->context() != this) {
       
  1070         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1071         return;
       
  1072     }
       
  1073     // Don't allow the default framebuffer to be mutated; all current
       
  1074     // implementations use an FBO internally in place of the default
       
  1075     // FBO.
       
  1076     if (!m_framebufferBinding || !m_framebufferBinding->object()) {
       
  1077         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1078         return;
       
  1079     }
       
  1080     m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
       
  1081     m_framebufferBinding->setAttachment(attachment, texture);
       
  1082     cleanupAfterGraphicsCall(false);
       
  1083 }
       
  1084 
       
  1085 void WebGLRenderingContext::frontFace(unsigned long mode)
       
  1086 {
       
  1087     m_context->frontFace(mode);
       
  1088     cleanupAfterGraphicsCall(false);
       
  1089 }
       
  1090 
       
  1091 void WebGLRenderingContext::generateMipmap(unsigned long target)
       
  1092 {
       
  1093     RefPtr<WebGLTexture> tex;
       
  1094     if (!isGLES2Compliant()) {
       
  1095         if (target == GraphicsContext3D::TEXTURE_2D)
       
  1096             tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
       
  1097         else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
       
  1098             tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
       
  1099         if (tex && !tex->canGenerateMipmaps()) {
       
  1100             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1101             return;
       
  1102         }
       
  1103     }
       
  1104     m_context->generateMipmap(target);
       
  1105     if (!isGLES2Compliant()) {
       
  1106         if (tex)
       
  1107             tex->generateMipmapLevelInfo();
       
  1108     }
       
  1109     cleanupAfterGraphicsCall(false);
       
  1110 }
       
  1111 
       
  1112 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
       
  1113 {
       
  1114     UNUSED_PARAM(ec);
       
  1115     ActiveInfo info;
       
  1116     if (!validateWebGLObject(program))
       
  1117         return 0;
       
  1118     if (!m_context->getActiveAttrib(program, index, info)) {
       
  1119         return 0;
       
  1120     }
       
  1121     return WebGLActiveInfo::create(info.name, info.type, info.size);
       
  1122 }
       
  1123 
       
  1124 PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, unsigned long index, ExceptionCode& ec)
       
  1125 {
       
  1126     UNUSED_PARAM(ec);
       
  1127     ActiveInfo info;
       
  1128     if (!validateWebGLObject(program))
       
  1129         return 0;
       
  1130     if (!m_context->getActiveUniform(program, index, info)) {
       
  1131         return 0;
       
  1132     }
       
  1133     if (!isGLES2Compliant()) {
       
  1134         if (info.size > 1 && !info.name.endsWith("[0]"))
       
  1135             info.name.append("[0]");
       
  1136     }
       
  1137     return WebGLActiveInfo::create(info.name, info.type, info.size);
       
  1138 }
       
  1139 
       
  1140 bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<WebGLShader*>& shaderObjects, ExceptionCode& ec)
       
  1141 {
       
  1142     UNUSED_PARAM(ec);
       
  1143     shaderObjects.clear();
       
  1144     if (!validateWebGLObject(program))
       
  1145         return false;
       
  1146     int numShaders = 0;
       
  1147     m_context->getProgramiv(program, GraphicsContext3D::ATTACHED_SHADERS, &numShaders);
       
  1148     if (numShaders) {
       
  1149         OwnArrayPtr<unsigned int> shaders(new unsigned int[numShaders]);
       
  1150         int count;
       
  1151         m_context->getAttachedShaders(program, numShaders, &count, shaders.get());
       
  1152         if (count != numShaders)
       
  1153             return false;
       
  1154         shaderObjects.resize(numShaders);
       
  1155         for (int ii = 0; ii < numShaders; ++ii) {
       
  1156             WebGLShader* shader = findShader(shaders[ii]);
       
  1157             if (!shader) {
       
  1158                 shaderObjects.clear();
       
  1159                 return false;
       
  1160             }
       
  1161             shaderObjects[ii] = shader;
       
  1162         }
       
  1163     }
       
  1164     return true;
       
  1165 }
       
  1166 
       
  1167 int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
       
  1168 {
       
  1169     return m_context->getAttribLocation(program, name);
       
  1170 }
       
  1171 
       
  1172 WebGLGetInfo WebGLRenderingContext::getBufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
       
  1173 {
       
  1174     UNUSED_PARAM(ec);
       
  1175     if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
       
  1176         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1177         return WebGLGetInfo();
       
  1178     }
       
  1179 
       
  1180     if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
       
  1181         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1182         return WebGLGetInfo();
       
  1183     }
       
  1184 
       
  1185     WebGLStateRestorer(this, false);
       
  1186     int value;
       
  1187     m_context->getBufferParameteriv(target, pname, &value);
       
  1188     if (pname == GraphicsContext3D::BUFFER_SIZE)
       
  1189         return WebGLGetInfo(static_cast<long>(value));
       
  1190     else
       
  1191         return WebGLGetInfo(static_cast<unsigned long>(value));
       
  1192 }
       
  1193 
       
  1194 PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
       
  1195 {
       
  1196     // We always need to return a new WebGLContextAttributes object to
       
  1197     // prevent the user from mutating any cached version.
       
  1198     return WebGLContextAttributes::create(m_context->getContextAttributes());
       
  1199 }
       
  1200 
       
  1201 unsigned long WebGLRenderingContext::getError()
       
  1202 {
       
  1203     return m_context->getError();
       
  1204 }
       
  1205 
       
  1206 WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(unsigned long target, unsigned long attachment, unsigned long pname, ExceptionCode& ec)
       
  1207 {
       
  1208     UNUSED_PARAM(ec);
       
  1209     if (!validateFramebufferFuncParameters(target, attachment))
       
  1210         return WebGLGetInfo();
       
  1211     switch (pname) {
       
  1212     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
       
  1213     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
       
  1214     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
       
  1215     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
       
  1216         break;
       
  1217     default:
       
  1218         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1219         return WebGLGetInfo();
       
  1220     }
       
  1221 
       
  1222     if (!m_framebufferBinding || !m_framebufferBinding->object()) {
       
  1223         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1224         return WebGLGetInfo();
       
  1225     }
       
  1226 
       
  1227     if (pname != GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
       
  1228         WebGLStateRestorer(this, false);
       
  1229         int value;
       
  1230         m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
       
  1231         if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
       
  1232             return WebGLGetInfo(static_cast<unsigned long>(value));
       
  1233         else
       
  1234             return WebGLGetInfo(static_cast<long>(value));
       
  1235     } else {
       
  1236         WebGLStateRestorer(this, false);
       
  1237         int type = 0;
       
  1238         m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
       
  1239         int value = 0;
       
  1240         m_context->getFramebufferAttachmentParameteriv(target, attachment, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &value);
       
  1241         switch (type) {
       
  1242         case GraphicsContext3D::RENDERBUFFER:
       
  1243             return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(findRenderbuffer(static_cast<Platform3DObject>(value))));
       
  1244         case GraphicsContext3D::TEXTURE:
       
  1245             return WebGLGetInfo(PassRefPtr<WebGLTexture>(findTexture(static_cast<Platform3DObject>(value))));
       
  1246         default:
       
  1247             // FIXME: raise exception?
       
  1248             return WebGLGetInfo();
       
  1249         }
       
  1250     }
       
  1251 }
       
  1252 
       
  1253 WebGLGetInfo WebGLRenderingContext::getParameter(unsigned long pname, ExceptionCode& ec)
       
  1254 {
       
  1255     UNUSED_PARAM(ec);
       
  1256     WebGLStateRestorer(this, false);
       
  1257     switch (pname) {
       
  1258     case GraphicsContext3D::ACTIVE_TEXTURE:
       
  1259         return getUnsignedLongParameter(pname);
       
  1260     case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
       
  1261         return getWebGLFloatArrayParameter(pname);
       
  1262     case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
       
  1263         return getWebGLFloatArrayParameter(pname);
       
  1264     case GraphicsContext3D::ALPHA_BITS:
       
  1265         return getLongParameter(pname);
       
  1266     case GraphicsContext3D::ARRAY_BUFFER_BINDING:
       
  1267         return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
       
  1268     case GraphicsContext3D::BLEND:
       
  1269         return getBooleanParameter(pname);
       
  1270     case GraphicsContext3D::BLEND_COLOR:
       
  1271         return getWebGLFloatArrayParameter(pname);
       
  1272     case GraphicsContext3D::BLEND_DST_ALPHA:
       
  1273         return getUnsignedLongParameter(pname);
       
  1274     case GraphicsContext3D::BLEND_DST_RGB:
       
  1275         return getUnsignedLongParameter(pname);
       
  1276     case GraphicsContext3D::BLEND_EQUATION_ALPHA:
       
  1277         return getUnsignedLongParameter(pname);
       
  1278     case GraphicsContext3D::BLEND_EQUATION_RGB:
       
  1279         return getUnsignedLongParameter(pname);
       
  1280     case GraphicsContext3D::BLEND_SRC_ALPHA:
       
  1281         return getUnsignedLongParameter(pname);
       
  1282     case GraphicsContext3D::BLEND_SRC_RGB:
       
  1283         return getUnsignedLongParameter(pname);
       
  1284     case GraphicsContext3D::BLUE_BITS:
       
  1285         return getLongParameter(pname);
       
  1286     case GraphicsContext3D::COLOR_CLEAR_VALUE:
       
  1287         return getWebGLFloatArrayParameter(pname);
       
  1288     case GraphicsContext3D::COLOR_WRITEMASK:
       
  1289         return getBooleanArrayParameter(pname);
       
  1290     case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
       
  1291         // Defined as null in the spec
       
  1292         return WebGLGetInfo();
       
  1293     case GraphicsContext3D::CULL_FACE:
       
  1294         return getBooleanParameter(pname);
       
  1295     case GraphicsContext3D::CULL_FACE_MODE:
       
  1296         return getUnsignedLongParameter(pname);
       
  1297     case GraphicsContext3D::CURRENT_PROGRAM:
       
  1298         return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
       
  1299     case GraphicsContext3D::DEPTH_BITS:
       
  1300         return getLongParameter(pname);
       
  1301     case GraphicsContext3D::DEPTH_CLEAR_VALUE:
       
  1302         return getFloatParameter(pname);
       
  1303     case GraphicsContext3D::DEPTH_FUNC:
       
  1304         return getUnsignedLongParameter(pname);
       
  1305     case GraphicsContext3D::DEPTH_RANGE:
       
  1306         return getWebGLFloatArrayParameter(pname);
       
  1307     case GraphicsContext3D::DEPTH_TEST:
       
  1308         return getBooleanParameter(pname);
       
  1309     case GraphicsContext3D::DEPTH_WRITEMASK:
       
  1310         return getBooleanParameter(pname);
       
  1311     case GraphicsContext3D::DITHER:
       
  1312         return getBooleanParameter(pname);
       
  1313     case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
       
  1314         return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundElementArrayBuffer));
       
  1315     case GraphicsContext3D::FRAMEBUFFER_BINDING:
       
  1316         return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
       
  1317     case GraphicsContext3D::FRONT_FACE:
       
  1318         return getUnsignedLongParameter(pname);
       
  1319     case GraphicsContext3D::GENERATE_MIPMAP_HINT:
       
  1320         return getUnsignedLongParameter(pname);
       
  1321     case GraphicsContext3D::GREEN_BITS:
       
  1322         return getLongParameter(pname);
       
  1323     case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
       
  1324         return getLongParameter(pname);
       
  1325     case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
       
  1326         return getLongParameter(pname);
       
  1327     case GraphicsContext3D::LINE_WIDTH:
       
  1328         return getFloatParameter(pname);
       
  1329     case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
       
  1330         return getLongParameter(pname);
       
  1331     case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
       
  1332         return getLongParameter(pname);
       
  1333     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
       
  1334         return getLongParameter(pname);
       
  1335     case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
       
  1336         return getLongParameter(pname);
       
  1337     case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
       
  1338         return getLongParameter(pname);
       
  1339     case GraphicsContext3D::MAX_TEXTURE_SIZE:
       
  1340         return getLongParameter(pname);
       
  1341     case GraphicsContext3D::MAX_VARYING_VECTORS:
       
  1342         return getLongParameter(pname);
       
  1343     case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
       
  1344         return getLongParameter(pname);
       
  1345     case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
       
  1346         return getLongParameter(pname);
       
  1347     case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
       
  1348         return getLongParameter(pname);
       
  1349     case GraphicsContext3D::MAX_VIEWPORT_DIMS:
       
  1350         return getWebGLIntArrayParameter(pname);
       
  1351     case GraphicsContext3D::NUM_COMPRESSED_TEXTURE_FORMATS:
       
  1352         // WebGL 1.0 specifies that there are no compressed texture formats.
       
  1353         return WebGLGetInfo(static_cast<long>(0));
       
  1354     case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
       
  1355         // FIXME: should we always return 0 for this?
       
  1356         return getLongParameter(pname);
       
  1357     case GraphicsContext3D::PACK_ALIGNMENT:
       
  1358         return getLongParameter(pname);
       
  1359     case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
       
  1360         return getFloatParameter(pname);
       
  1361     case GraphicsContext3D::POLYGON_OFFSET_FILL:
       
  1362         return getBooleanParameter(pname);
       
  1363     case GraphicsContext3D::POLYGON_OFFSET_UNITS:
       
  1364         return getFloatParameter(pname);
       
  1365     case GraphicsContext3D::RED_BITS:
       
  1366         return getLongParameter(pname);
       
  1367     case GraphicsContext3D::RENDERBUFFER_BINDING:
       
  1368         return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
       
  1369     case GraphicsContext3D::SAMPLE_BUFFERS:
       
  1370         return getLongParameter(pname);
       
  1371     case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
       
  1372         return getBooleanParameter(pname);
       
  1373     case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
       
  1374         return getFloatParameter(pname);
       
  1375     case GraphicsContext3D::SAMPLES:
       
  1376         return getLongParameter(pname);
       
  1377     case GraphicsContext3D::SCISSOR_BOX:
       
  1378         return getWebGLIntArrayParameter(pname);
       
  1379     case GraphicsContext3D::SCISSOR_TEST:
       
  1380         return getBooleanParameter(pname);
       
  1381     case GraphicsContext3D::STENCIL_BACK_FAIL:
       
  1382         return getUnsignedLongParameter(pname);
       
  1383     case GraphicsContext3D::STENCIL_BACK_FUNC:
       
  1384         return getUnsignedLongParameter(pname);
       
  1385     case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
       
  1386         return getUnsignedLongParameter(pname);
       
  1387     case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
       
  1388         return getUnsignedLongParameter(pname);
       
  1389     case GraphicsContext3D::STENCIL_BACK_REF:
       
  1390         return getLongParameter(pname);
       
  1391     case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
       
  1392         return getUnsignedLongParameter(pname);
       
  1393     case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
       
  1394         return getUnsignedLongParameter(pname);
       
  1395     case GraphicsContext3D::STENCIL_BITS:
       
  1396         return getLongParameter(pname);
       
  1397     case GraphicsContext3D::STENCIL_CLEAR_VALUE:
       
  1398         return getLongParameter(pname);
       
  1399     case GraphicsContext3D::STENCIL_FAIL:
       
  1400         return getUnsignedLongParameter(pname);
       
  1401     case GraphicsContext3D::STENCIL_FUNC:
       
  1402         return getUnsignedLongParameter(pname);
       
  1403     case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
       
  1404         return getUnsignedLongParameter(pname);
       
  1405     case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
       
  1406         return getUnsignedLongParameter(pname);
       
  1407     case GraphicsContext3D::STENCIL_REF:
       
  1408         return getLongParameter(pname);
       
  1409     case GraphicsContext3D::STENCIL_TEST:
       
  1410         return getBooleanParameter(pname);
       
  1411     case GraphicsContext3D::STENCIL_VALUE_MASK:
       
  1412         return getUnsignedLongParameter(pname);
       
  1413     case GraphicsContext3D::STENCIL_WRITEMASK:
       
  1414         return getUnsignedLongParameter(pname);
       
  1415     case GraphicsContext3D::SUBPIXEL_BITS:
       
  1416         return getLongParameter(pname);
       
  1417     case GraphicsContext3D::TEXTURE_BINDING_2D:
       
  1418         return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
       
  1419     case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
       
  1420         return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
       
  1421     case GraphicsContext3D::UNPACK_ALIGNMENT:
       
  1422         // FIXME: should this be "long" in the spec?
       
  1423         return getIntParameter(pname);
       
  1424     case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
       
  1425         return WebGLGetInfo(m_unpackFlipY);
       
  1426     case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
       
  1427         return WebGLGetInfo(m_unpackPremultiplyAlpha);
       
  1428     case GraphicsContext3D::VIEWPORT:
       
  1429         return getWebGLIntArrayParameter(pname);
       
  1430     default:
       
  1431         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1432         return WebGLGetInfo();
       
  1433     }
       
  1434 }
       
  1435 
       
  1436 WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, unsigned long pname, ExceptionCode& ec)
       
  1437 {
       
  1438     UNUSED_PARAM(ec);
       
  1439     if (!validateWebGLObject(program))
       
  1440         return WebGLGetInfo();
       
  1441 
       
  1442     WebGLStateRestorer(this, false);
       
  1443     int value = 0;
       
  1444     switch (pname) {
       
  1445     case GraphicsContext3D::DELETE_STATUS:
       
  1446     case GraphicsContext3D::VALIDATE_STATUS:
       
  1447         m_context->getProgramiv(program, pname, &value);
       
  1448         return WebGLGetInfo(static_cast<bool>(value));
       
  1449     case GraphicsContext3D::LINK_STATUS:
       
  1450         if (program->isLinkFailureFlagSet())
       
  1451             return WebGLGetInfo(false);
       
  1452         m_context->getProgramiv(program, pname, &value);
       
  1453         return WebGLGetInfo(static_cast<bool>(value));
       
  1454     case GraphicsContext3D::INFO_LOG_LENGTH:
       
  1455     case GraphicsContext3D::ATTACHED_SHADERS:
       
  1456     case GraphicsContext3D::ACTIVE_ATTRIBUTES:
       
  1457     case GraphicsContext3D::ACTIVE_ATTRIBUTE_MAX_LENGTH:
       
  1458     case GraphicsContext3D::ACTIVE_UNIFORMS:
       
  1459     case GraphicsContext3D::ACTIVE_UNIFORM_MAX_LENGTH:
       
  1460         m_context->getProgramiv(program, pname, &value);
       
  1461         return WebGLGetInfo(static_cast<long>(value));
       
  1462     default:
       
  1463         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1464         return WebGLGetInfo();
       
  1465     }
       
  1466 }
       
  1467 
       
  1468 String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, ExceptionCode& ec)
       
  1469 {
       
  1470     UNUSED_PARAM(ec);
       
  1471     if (!validateWebGLObject(program))
       
  1472         return "";
       
  1473     WebGLStateRestorer(this, false);
       
  1474     return m_context->getProgramInfoLog(program);
       
  1475 }
       
  1476 
       
  1477 WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
       
  1478 {
       
  1479     UNUSED_PARAM(ec);
       
  1480     if (target != GraphicsContext3D::RENDERBUFFER) {
       
  1481         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1482         return WebGLGetInfo();
       
  1483     }
       
  1484 
       
  1485     WebGLStateRestorer(this, false);
       
  1486     int value = 0;
       
  1487     switch (pname) {
       
  1488     case GraphicsContext3D::RENDERBUFFER_WIDTH:
       
  1489     case GraphicsContext3D::RENDERBUFFER_HEIGHT:
       
  1490     case GraphicsContext3D::RENDERBUFFER_RED_SIZE:
       
  1491     case GraphicsContext3D::RENDERBUFFER_GREEN_SIZE:
       
  1492     case GraphicsContext3D::RENDERBUFFER_BLUE_SIZE:
       
  1493     case GraphicsContext3D::RENDERBUFFER_ALPHA_SIZE:
       
  1494     case GraphicsContext3D::RENDERBUFFER_DEPTH_SIZE:
       
  1495     case GraphicsContext3D::RENDERBUFFER_STENCIL_SIZE:
       
  1496         m_context->getRenderbufferParameteriv(target, pname, &value);
       
  1497         return WebGLGetInfo(static_cast<long>(value));
       
  1498     case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
       
  1499         if (!m_renderbufferBinding) {
       
  1500             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1501             return WebGLGetInfo();
       
  1502         }
       
  1503         return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
       
  1504     default:
       
  1505         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1506         return WebGLGetInfo();
       
  1507     }
       
  1508 }
       
  1509 
       
  1510 WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, unsigned long pname, ExceptionCode& ec)
       
  1511 {
       
  1512     UNUSED_PARAM(ec);
       
  1513     if (!validateWebGLObject(shader))
       
  1514         return WebGLGetInfo();
       
  1515     WebGLStateRestorer(this, false);
       
  1516     int value = 0;
       
  1517     switch (pname) {
       
  1518     case GraphicsContext3D::DELETE_STATUS:
       
  1519     case GraphicsContext3D::COMPILE_STATUS:
       
  1520         m_context->getShaderiv(shader, pname, &value);
       
  1521         return WebGLGetInfo(static_cast<bool>(value));
       
  1522     case GraphicsContext3D::SHADER_TYPE:
       
  1523         m_context->getShaderiv(shader, pname, &value);
       
  1524         return WebGLGetInfo(static_cast<unsigned long>(value));
       
  1525     case GraphicsContext3D::INFO_LOG_LENGTH:
       
  1526     case GraphicsContext3D::SHADER_SOURCE_LENGTH:
       
  1527         m_context->getShaderiv(shader, pname, &value);
       
  1528         return WebGLGetInfo(static_cast<long>(value));
       
  1529     default:
       
  1530         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1531         return WebGLGetInfo();
       
  1532     }
       
  1533 }
       
  1534 
       
  1535 String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCode& ec)
       
  1536 {
       
  1537     UNUSED_PARAM(ec);
       
  1538     if (!validateWebGLObject(shader))
       
  1539         return "";
       
  1540     WebGLStateRestorer(this, false);
       
  1541     return m_context->getShaderInfoLog(shader);
       
  1542 }
       
  1543 
       
  1544 String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode& ec)
       
  1545 {
       
  1546     UNUSED_PARAM(ec);
       
  1547     if (!validateWebGLObject(shader))
       
  1548         return "";
       
  1549     WebGLStateRestorer(this, false);
       
  1550     return m_context->getShaderSource(shader);
       
  1551 }
       
  1552 
       
  1553 String WebGLRenderingContext::getString(unsigned long name)
       
  1554 {
       
  1555     WebGLStateRestorer(this, false);
       
  1556     return m_context->getString(name);
       
  1557 }
       
  1558 
       
  1559 WebGLGetInfo WebGLRenderingContext::getTexParameter(unsigned long target, unsigned long pname, ExceptionCode& ec)
       
  1560 {
       
  1561     UNUSED_PARAM(ec);
       
  1562     if (target != GraphicsContext3D::TEXTURE_2D
       
  1563         && target != GraphicsContext3D::TEXTURE_CUBE_MAP) {
       
  1564         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1565         return WebGLGetInfo();
       
  1566     }
       
  1567     WebGLStateRestorer(this, false);
       
  1568     int value = 0;
       
  1569     switch (pname) {
       
  1570     case GraphicsContext3D::TEXTURE_MAG_FILTER:
       
  1571     case GraphicsContext3D::TEXTURE_MIN_FILTER:
       
  1572     case GraphicsContext3D::TEXTURE_WRAP_S:
       
  1573     case GraphicsContext3D::TEXTURE_WRAP_T:
       
  1574         m_context->getTexParameteriv(target, pname, &value);
       
  1575         return WebGLGetInfo(static_cast<unsigned long>(value));
       
  1576     default:
       
  1577         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1578         return WebGLGetInfo();
       
  1579     }
       
  1580 }
       
  1581 
       
  1582 WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
       
  1583 {
       
  1584     UNUSED_PARAM(ec);
       
  1585     if (!validateWebGLObject(program))
       
  1586         return WebGLGetInfo();
       
  1587     if (!uniformLocation) {
       
  1588         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1589         return WebGLGetInfo();
       
  1590     }
       
  1591     if (uniformLocation->program() != program) {
       
  1592         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1593         return WebGLGetInfo();
       
  1594     }
       
  1595     long location = uniformLocation->location();
       
  1596     
       
  1597     WebGLStateRestorer(this, false);
       
  1598     // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
       
  1599     int activeUniforms = 0;
       
  1600     m_context->getProgramiv(program, GraphicsContext3D::ACTIVE_UNIFORMS, &activeUniforms);
       
  1601     for (int i = 0; i < activeUniforms; i++) {
       
  1602         ActiveInfo info;
       
  1603         if (!m_context->getActiveUniform(program, i, info))
       
  1604             return WebGLGetInfo();
       
  1605         // Strip "[0]" from the name if it's an array.
       
  1606         if (info.size > 1)
       
  1607             info.name = info.name.left(info.name.length() - 3);
       
  1608         // If it's an array, we need to iterate through each element, appending "[index]" to the name.
       
  1609         for (int index = 0; index < info.size; ++index) {
       
  1610             String name = info.name;
       
  1611             if (info.size > 1 && index >= 1) {
       
  1612                 name.append('[');
       
  1613                 name.append(String::number(index));
       
  1614                 name.append(']');
       
  1615             }
       
  1616             // Now need to look this up by name again to find its location
       
  1617             long loc = m_context->getUniformLocation(program, name);
       
  1618             if (loc == location) {
       
  1619                 // Found it. Use the type in the ActiveInfo to determine the return type.
       
  1620                 GraphicsContext3D::WebGLEnumType baseType;
       
  1621                 unsigned length;
       
  1622                 switch (info.type) {
       
  1623                 case GraphicsContext3D::BOOL:
       
  1624                     baseType = GraphicsContext3D::BOOL;
       
  1625                     length = 1;
       
  1626                     break;
       
  1627                 case GraphicsContext3D::BOOL_VEC2:
       
  1628                     baseType = GraphicsContext3D::BOOL;
       
  1629                     length = 2;
       
  1630                     break;
       
  1631                 case GraphicsContext3D::BOOL_VEC3:
       
  1632                     baseType = GraphicsContext3D::BOOL;
       
  1633                     length = 3;
       
  1634                     break;
       
  1635                 case GraphicsContext3D::BOOL_VEC4:
       
  1636                     baseType = GraphicsContext3D::BOOL;
       
  1637                     length = 4;
       
  1638                     break;
       
  1639                 case GraphicsContext3D::INT:
       
  1640                     baseType = GraphicsContext3D::INT;
       
  1641                     length = 1;
       
  1642                     break;
       
  1643                 case GraphicsContext3D::INT_VEC2:
       
  1644                     baseType = GraphicsContext3D::INT;
       
  1645                     length = 2;
       
  1646                     break;
       
  1647                 case GraphicsContext3D::INT_VEC3:
       
  1648                     baseType = GraphicsContext3D::INT;
       
  1649                     length = 3;
       
  1650                     break;
       
  1651                 case GraphicsContext3D::INT_VEC4:
       
  1652                     baseType = GraphicsContext3D::INT;
       
  1653                     length = 4;
       
  1654                     break;
       
  1655                 case GraphicsContext3D::FLOAT:
       
  1656                     baseType = GraphicsContext3D::FLOAT;
       
  1657                     length = 1;
       
  1658                     break;
       
  1659                 case GraphicsContext3D::FLOAT_VEC2:
       
  1660                     baseType = GraphicsContext3D::FLOAT;
       
  1661                     length = 2;
       
  1662                     break;
       
  1663                 case GraphicsContext3D::FLOAT_VEC3:
       
  1664                     baseType = GraphicsContext3D::FLOAT;
       
  1665                     length = 3;
       
  1666                     break;
       
  1667                 case GraphicsContext3D::FLOAT_VEC4:
       
  1668                     baseType = GraphicsContext3D::FLOAT;
       
  1669                     length = 4;
       
  1670                     break;
       
  1671                 case GraphicsContext3D::FLOAT_MAT2:
       
  1672                     baseType = GraphicsContext3D::FLOAT;
       
  1673                     length = 4;
       
  1674                     break;
       
  1675                 case GraphicsContext3D::FLOAT_MAT3:
       
  1676                     baseType = GraphicsContext3D::FLOAT;
       
  1677                     length = 9;
       
  1678                     break;
       
  1679                 case GraphicsContext3D::FLOAT_MAT4:
       
  1680                     baseType = GraphicsContext3D::FLOAT;
       
  1681                     length = 16;
       
  1682                     break;
       
  1683                 default:
       
  1684                     // Can't handle this type
       
  1685                     // FIXME: what to do about samplers?
       
  1686                     m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1687                     return WebGLGetInfo();
       
  1688                 }
       
  1689                 switch (baseType) {
       
  1690                 case GraphicsContext3D::FLOAT: {
       
  1691                     float value[16] = {0};
       
  1692                     m_context->getUniformfv(program, location, value);
       
  1693                     if (length == 1)
       
  1694                         return WebGLGetInfo(value[0]);
       
  1695                     return WebGLGetInfo(Float32Array::create(value, length));
       
  1696                 }
       
  1697                 case GraphicsContext3D::INT: {
       
  1698                     int value[16] = {0};
       
  1699                     m_context->getUniformiv(program, location, value);
       
  1700                     if (length == 1)
       
  1701                         return WebGLGetInfo(static_cast<long>(value[0]));
       
  1702                     return WebGLGetInfo(Int32Array::create(value, length));
       
  1703                 }
       
  1704                 case GraphicsContext3D::BOOL: {
       
  1705                     int value[16] = {0};
       
  1706                     m_context->getUniformiv(program, location, value);
       
  1707                     if (length > 1) {
       
  1708                         unsigned char boolValue[16] = {0};
       
  1709                         for (unsigned j = 0; j < length; j++)
       
  1710                             boolValue[j] = static_cast<bool>(value[j]);
       
  1711                         return WebGLGetInfo(Uint8Array::create(boolValue, length));
       
  1712                     }
       
  1713                     return WebGLGetInfo(static_cast<bool>(value[0]));
       
  1714                 }
       
  1715                 default:
       
  1716                     notImplemented();
       
  1717                 }
       
  1718             }
       
  1719         }
       
  1720     }
       
  1721     // If we get here, something went wrong in our unfortunately complex logic above
       
  1722     m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1723     return WebGLGetInfo();
       
  1724 }
       
  1725 
       
  1726 PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
       
  1727 {
       
  1728     UNUSED_PARAM(ec);
       
  1729     if (!validateWebGLObject(program))
       
  1730         return 0;
       
  1731     WebGLStateRestorer(this, false);
       
  1732     long uniformLocation = m_context->getUniformLocation(program, name);
       
  1733     if (uniformLocation == -1)
       
  1734         return 0;
       
  1735     return WebGLUniformLocation::create(program, uniformLocation);
       
  1736 }
       
  1737 
       
  1738 WebGLGetInfo WebGLRenderingContext::getVertexAttrib(unsigned long index, unsigned long pname, ExceptionCode& ec)
       
  1739 {
       
  1740     UNUSED_PARAM(ec);
       
  1741     WebGLStateRestorer(this, false);
       
  1742     if (index >= m_maxVertexAttribs) {
       
  1743         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1744         return WebGLGetInfo();
       
  1745     }
       
  1746     switch (pname) {
       
  1747     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
       
  1748         if (!isGLES2Compliant() && !index && m_vertexAttribState[0].bufferBinding == m_vertexAttrib0Buffer
       
  1749             || index >= m_vertexAttribState.size()
       
  1750             || !m_vertexAttribState[index].bufferBinding
       
  1751             || !m_vertexAttribState[index].bufferBinding->object())
       
  1752             return WebGLGetInfo();
       
  1753         return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_vertexAttribState[index].bufferBinding));
       
  1754     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_ENABLED:
       
  1755         if (index >= m_vertexAttribState.size())
       
  1756             return WebGLGetInfo(false);
       
  1757         return WebGLGetInfo(m_vertexAttribState[index].enabled);
       
  1758     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_NORMALIZED:
       
  1759         if (index >= m_vertexAttribState.size())
       
  1760             return WebGLGetInfo(false);
       
  1761         return WebGLGetInfo(m_vertexAttribState[index].normalized);
       
  1762     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_SIZE:
       
  1763         if (index >= m_vertexAttribState.size())
       
  1764             return WebGLGetInfo(static_cast<long>(4));
       
  1765         return WebGLGetInfo(m_vertexAttribState[index].size);
       
  1766     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_STRIDE:
       
  1767         if (index >= m_vertexAttribState.size())
       
  1768             return WebGLGetInfo(static_cast<long>(0));
       
  1769         return WebGLGetInfo(m_vertexAttribState[index].originalStride);
       
  1770     case GraphicsContext3D::VERTEX_ATTRIB_ARRAY_TYPE:
       
  1771         if (index >= m_vertexAttribState.size())
       
  1772             return WebGLGetInfo(static_cast<unsigned long>(GraphicsContext3D::FLOAT));
       
  1773         return WebGLGetInfo(m_vertexAttribState[index].type);
       
  1774     case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
       
  1775         if (index >= m_vertexAttribState.size()) {
       
  1776             float value[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
       
  1777             return WebGLGetInfo(Float32Array::create(value, 4));
       
  1778         }
       
  1779         return WebGLGetInfo(Float32Array::create(m_vertexAttribState[index].value, 4));
       
  1780     default:
       
  1781         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1782         return WebGLGetInfo();
       
  1783     }
       
  1784 }
       
  1785 
       
  1786 long WebGLRenderingContext::getVertexAttribOffset(unsigned long index, unsigned long pname)
       
  1787 {
       
  1788     long result = m_context->getVertexAttribOffset(index, pname);
       
  1789     cleanupAfterGraphicsCall(false);
       
  1790     return result;
       
  1791 }
       
  1792 
       
  1793 void WebGLRenderingContext::hint(unsigned long target, unsigned long mode)
       
  1794 {
       
  1795     if (!isGLES2Compliant()) {
       
  1796         if (target != GraphicsContext3D::GENERATE_MIPMAP_HINT) {
       
  1797             m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1798             return;
       
  1799         }
       
  1800     }
       
  1801     m_context->hint(target, mode);
       
  1802     cleanupAfterGraphicsCall(false);
       
  1803 }
       
  1804 
       
  1805 bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
       
  1806 {
       
  1807     if (!buffer)
       
  1808         return false;
       
  1809 
       
  1810     return m_context->isBuffer(buffer);
       
  1811 }
       
  1812 
       
  1813 bool WebGLRenderingContext::isEnabled(unsigned long cap)
       
  1814 {
       
  1815     if (!isGLES2Compliant()) {
       
  1816         if (!validateCapability(cap))
       
  1817             return false;
       
  1818     }
       
  1819     return m_context->isEnabled(cap);
       
  1820 }
       
  1821 
       
  1822 bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
       
  1823 {
       
  1824     if (!framebuffer)
       
  1825         return false;
       
  1826 
       
  1827     return m_context->isFramebuffer(framebuffer);
       
  1828 }
       
  1829 
       
  1830 bool WebGLRenderingContext::isProgram(WebGLProgram* program)
       
  1831 {
       
  1832     if (!program)
       
  1833         return false;
       
  1834 
       
  1835     return m_context->isProgram(program);
       
  1836 }
       
  1837 
       
  1838 bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
       
  1839 {
       
  1840     if (!renderbuffer)
       
  1841         return false;
       
  1842 
       
  1843     return m_context->isRenderbuffer(renderbuffer);
       
  1844 }
       
  1845 
       
  1846 bool WebGLRenderingContext::isShader(WebGLShader* shader)
       
  1847 {
       
  1848     if (!shader)
       
  1849         return false;
       
  1850 
       
  1851     return m_context->isShader(shader);
       
  1852 }
       
  1853 
       
  1854 bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
       
  1855 {
       
  1856     if (!texture)
       
  1857         return false;
       
  1858 
       
  1859     return m_context->isTexture(texture);
       
  1860 }
       
  1861 
       
  1862 void WebGLRenderingContext::lineWidth(double width)
       
  1863 {
       
  1864     m_context->lineWidth((float) width);
       
  1865     cleanupAfterGraphicsCall(false);
       
  1866 }
       
  1867 
       
  1868 void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
       
  1869 {
       
  1870     UNUSED_PARAM(ec);
       
  1871     if (!validateWebGLObject(program))
       
  1872         return;
       
  1873     if (!isGLES2Compliant()) {
       
  1874         Vector<WebGLShader*> shaders;
       
  1875         bool succeed = getAttachedShaders(program, shaders, ec);
       
  1876         if (succeed) {
       
  1877             bool vShader = false;
       
  1878             bool fShader = false;
       
  1879             for (size_t ii = 0; ii < shaders.size() && (!vShader || !fShader); ++ii) {
       
  1880                 if (shaders[ii]->getType() == GraphicsContext3D::VERTEX_SHADER)
       
  1881                     vShader = true;
       
  1882                 else if (shaders[ii]->getType() == GraphicsContext3D::FRAGMENT_SHADER)
       
  1883                     fShader = true;
       
  1884             }
       
  1885             if (!vShader || !fShader)
       
  1886                 succeed = false;
       
  1887         }
       
  1888         if (!succeed) {
       
  1889             program->setLinkFailureFlag(true);
       
  1890             return;
       
  1891         }
       
  1892         program->setLinkFailureFlag(false);
       
  1893     }
       
  1894 
       
  1895     m_context->linkProgram(program);
       
  1896     program->cacheActiveAttribLocations();
       
  1897     cleanupAfterGraphicsCall(false);
       
  1898 }
       
  1899 
       
  1900 void WebGLRenderingContext::pixelStorei(unsigned long pname, long param)
       
  1901 {
       
  1902     switch (pname) {
       
  1903     case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
       
  1904         m_unpackFlipY = param;
       
  1905         break;
       
  1906     case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
       
  1907         m_unpackPremultiplyAlpha = param;
       
  1908         break;
       
  1909     case GraphicsContext3D::PACK_ALIGNMENT:
       
  1910     case GraphicsContext3D::UNPACK_ALIGNMENT:
       
  1911         m_context->pixelStorei(pname, param);
       
  1912         if (param == 1 || param == 2 || param == 4 || param == 8) {
       
  1913             if (pname == GraphicsContext3D::PACK_ALIGNMENT)
       
  1914                 m_packAlignment = static_cast<int>(param);
       
  1915             else // GraphicsContext3D::UNPACK_ALIGNMENT:
       
  1916                 m_unpackAlignment = static_cast<int>(param);
       
  1917         }
       
  1918         break;
       
  1919     default:
       
  1920         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1921         return;
       
  1922     }
       
  1923     cleanupAfterGraphicsCall(false);
       
  1924 }
       
  1925 
       
  1926 void WebGLRenderingContext::polygonOffset(double factor, double units)
       
  1927 {
       
  1928     m_context->polygonOffset((float) factor, (float) units);
       
  1929     cleanupAfterGraphicsCall(false);
       
  1930 }
       
  1931 
       
  1932 void WebGLRenderingContext::readPixels(long x, long y, long width, long height, unsigned long format, unsigned long type, ArrayBufferView* pixels)
       
  1933 {
       
  1934     // Validate input parameters.
       
  1935     unsigned long componentsPerPixel, bytesPerComponent;
       
  1936     if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
       
  1937         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  1938         return;
       
  1939     }
       
  1940     if (!pixels) {
       
  1941         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1942         return;
       
  1943     }
       
  1944     if (width < 0 || height < 0) {
       
  1945         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  1946         return;
       
  1947     }
       
  1948     if (!((format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE) || (format == m_implementationColorReadFormat && type == m_implementationColorReadType))) {
       
  1949         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1950         return;
       
  1951     }
       
  1952     // Validate array type against pixel type.
       
  1953     if (type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray()
       
  1954         || type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray()) {
       
  1955         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1956         return;
       
  1957     }
       
  1958     // Calculate array size, taking into consideration of PACK_ALIGNMENT.
       
  1959     unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
       
  1960     unsigned long padding = 0;
       
  1961     unsigned long residualBytes = bytesPerRow % m_packAlignment;
       
  1962     if (residualBytes) {
       
  1963         padding = m_packAlignment - residualBytes;
       
  1964         bytesPerRow += padding;
       
  1965     }
       
  1966     // The last row needs no padding.
       
  1967     unsigned long totalBytes = bytesPerRow * height - padding;
       
  1968     unsigned long num = totalBytes / bytesPerComponent;
       
  1969     if (pixels->length() < num) {
       
  1970         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  1971         return;
       
  1972     }
       
  1973     void* data = pixels->baseAddress();
       
  1974     m_context->readPixels(x, y, width, height, format, type, data);
       
  1975 #if PLATFORM(CG)
       
  1976     // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
       
  1977     // when alpha is off, readPixels should set alpha to 255 instead of 0.
       
  1978     if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) {
       
  1979         if (type == GraphicsContext3D::UNSIGNED_BYTE) {
       
  1980             unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
       
  1981             for (long iy = 0; iy < height; ++iy) {
       
  1982                 for (long ix = 0; ix < width; ++ix) {
       
  1983                     pixels[componentsPerPixel - 1] = 255;
       
  1984                     pixels += componentsPerPixel;
       
  1985                 }
       
  1986                 pixels += padding;
       
  1987             }
       
  1988         }
       
  1989         // FIXME: check whether we need to do the same with UNSIGNED_SHORT.
       
  1990     }
       
  1991 #endif
       
  1992     cleanupAfterGraphicsCall(false);
       
  1993 }
       
  1994 
       
  1995 void WebGLRenderingContext::releaseShaderCompiler()
       
  1996 {
       
  1997     m_context->releaseShaderCompiler();
       
  1998     cleanupAfterGraphicsCall(false);
       
  1999 }
       
  2000 
       
  2001 void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
       
  2002 {
       
  2003     switch (internalformat) {
       
  2004     case GraphicsContext3D::DEPTH_COMPONENT16:
       
  2005     case GraphicsContext3D::RGBA4:
       
  2006     case GraphicsContext3D::RGB5_A1:
       
  2007     case GraphicsContext3D::RGB565:
       
  2008     case GraphicsContext3D::STENCIL_INDEX8:
       
  2009     case GraphicsContext3D::DEPTH_STENCIL:
       
  2010         m_context->renderbufferStorage(target, internalformat, width, height);
       
  2011         if (m_renderbufferBinding) {
       
  2012             m_renderbufferBinding->setInternalFormat(internalformat);
       
  2013             if (m_framebufferBinding)
       
  2014                 m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get());
       
  2015         }
       
  2016         cleanupAfterGraphicsCall(false);
       
  2017         break;
       
  2018     default:
       
  2019         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  2020     }
       
  2021 }
       
  2022 
       
  2023 void WebGLRenderingContext::sampleCoverage(double value, bool invert)
       
  2024 {
       
  2025     m_context->sampleCoverage((float) value, invert);
       
  2026     cleanupAfterGraphicsCall(false);
       
  2027 }
       
  2028 
       
  2029 void WebGLRenderingContext::scissor(long x, long y, unsigned long width, unsigned long height)
       
  2030 {
       
  2031     m_context->scissor(x, y, width, height);
       
  2032     cleanupAfterGraphicsCall(false);
       
  2033 }
       
  2034 
       
  2035 void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
       
  2036 {
       
  2037     UNUSED_PARAM(ec);
       
  2038     if (!validateWebGLObject(shader))
       
  2039         return;
       
  2040     m_context->shaderSource(shader, string);
       
  2041     cleanupAfterGraphicsCall(false);
       
  2042 }
       
  2043 
       
  2044 void WebGLRenderingContext::stencilFunc(unsigned long func, long ref, unsigned long mask)
       
  2045 {
       
  2046     m_context->stencilFunc(func, ref, mask);
       
  2047     cleanupAfterGraphicsCall(false);
       
  2048 }
       
  2049 
       
  2050 void WebGLRenderingContext::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
       
  2051 {
       
  2052     m_context->stencilFuncSeparate(face, func, ref, mask);
       
  2053     cleanupAfterGraphicsCall(false);
       
  2054 }
       
  2055 
       
  2056 void WebGLRenderingContext::stencilMask(unsigned long mask)
       
  2057 {
       
  2058     m_context->stencilMask(mask);
       
  2059     cleanupAfterGraphicsCall(false);
       
  2060 }
       
  2061 
       
  2062 void WebGLRenderingContext::stencilMaskSeparate(unsigned long face, unsigned long mask)
       
  2063 {
       
  2064     m_context->stencilMaskSeparate(face, mask);
       
  2065     cleanupAfterGraphicsCall(false);
       
  2066 }
       
  2067 
       
  2068 void WebGLRenderingContext::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
       
  2069 {
       
  2070     m_context->stencilOp(fail, zfail, zpass);
       
  2071     cleanupAfterGraphicsCall(false);
       
  2072 }
       
  2073 
       
  2074 void WebGLRenderingContext::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
       
  2075 {
       
  2076     m_context->stencilOpSeparate(face, fail, zfail, zpass);
       
  2077     cleanupAfterGraphicsCall(false);
       
  2078 }
       
  2079 
       
  2080 void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsigned internalformat,
       
  2081                                            unsigned width, unsigned height, unsigned border,
       
  2082                                            unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
       
  2083 {
       
  2084     // FIXME: For now we ignore any errors returned
       
  2085     ec = 0;
       
  2086     if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
       
  2087         return;
       
  2088     if (!isGLES2Compliant()) {
       
  2089         if (level && WebGLTexture::isNPOT(width, height)) {
       
  2090             m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2091             return;
       
  2092         }
       
  2093     }
       
  2094     m_context->texImage2D(target, level, internalformat, width, height,
       
  2095                           border, format, type, pixels);
       
  2096     WebGLTexture* tex = getTextureBinding(target);
       
  2097     if (!isGLES2Compliant()) {
       
  2098         if (tex)
       
  2099             tex->setLevelInfo(target, level, internalformat, width, height, type);
       
  2100     }
       
  2101     if (m_framebufferBinding && tex)
       
  2102         m_framebufferBinding->onAttachedObjectChange(tex);
       
  2103     cleanupAfterGraphicsCall(false);
       
  2104 }
       
  2105 
       
  2106 void WebGLRenderingContext::texImage2DImpl(unsigned target, unsigned level, unsigned internalformat,
       
  2107                                            unsigned format, unsigned type, Image* image,
       
  2108                                            bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2109 {
       
  2110     ec = 0;
       
  2111     Vector<uint8_t> data;
       
  2112     if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
       
  2113         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2114         return;
       
  2115     }
       
  2116     if (m_unpackAlignment != 1)
       
  2117         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
       
  2118     texImage2DBase(target, level, internalformat, image->width(), image->height(), 0,
       
  2119                    format, type, data.data(), ec);
       
  2120     if (m_unpackAlignment != 1)
       
  2121         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
       
  2122 }
       
  2123 
       
  2124 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
       
  2125                                        unsigned width, unsigned height, unsigned border,
       
  2126                                        unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
       
  2127 {
       
  2128     if (!validateTexFuncData(width, height, format, type, pixels))
       
  2129         return;
       
  2130     void* data = pixels ? pixels->baseAddress() : 0;
       
  2131     Vector<uint8_t> tempData;
       
  2132     bool changeUnpackAlignment = false;
       
  2133     if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
       
  2134         if (!m_context->extractTextureData(width, height, format, type,
       
  2135                                            m_unpackAlignment,
       
  2136                                            m_unpackFlipY, m_unpackPremultiplyAlpha,
       
  2137                                            pixels,
       
  2138                                            tempData))
       
  2139             return;
       
  2140         data = tempData.data();
       
  2141         changeUnpackAlignment = true;
       
  2142     }
       
  2143     if (changeUnpackAlignment)
       
  2144         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
       
  2145     texImage2DBase(target, level, internalformat, width, height, border,
       
  2146                    format, type, data, ec);
       
  2147     if (changeUnpackAlignment)
       
  2148         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
       
  2149 }
       
  2150 
       
  2151 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
       
  2152                                        unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
       
  2153 {
       
  2154     ec = 0;
       
  2155     Vector<uint8_t> data;
       
  2156     if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
       
  2157         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2158         return;
       
  2159     }
       
  2160     if (m_unpackAlignment != 1)
       
  2161         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
       
  2162     texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0,
       
  2163                    format, type, data.data(), ec);
       
  2164     if (m_unpackAlignment != 1)
       
  2165         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
       
  2166 }
       
  2167 
       
  2168 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
       
  2169                                        unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
       
  2170 {
       
  2171     ec = 0;
       
  2172     if (!image || !image->cachedImage()) {
       
  2173         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2174         return;
       
  2175     }
       
  2176     texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
       
  2177                    m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
       
  2178 }
       
  2179 
       
  2180 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
       
  2181                                        unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
       
  2182 {
       
  2183     ec = 0;
       
  2184     if (!canvas || !canvas->buffer()) {
       
  2185         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2186         return;
       
  2187     }
       
  2188     texImage2DImpl(target, level, internalformat, format, type, canvas->buffer()->image(),
       
  2189                    m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
       
  2190 }
       
  2191 
       
  2192 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned internalformat,
       
  2193                                        unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
       
  2194 {
       
  2195     // FIXME: Need to implement this call
       
  2196     UNUSED_PARAM(target);
       
  2197     UNUSED_PARAM(level);
       
  2198     UNUSED_PARAM(internalformat);
       
  2199     UNUSED_PARAM(format);
       
  2200     UNUSED_PARAM(type);
       
  2201     UNUSED_PARAM(video);
       
  2202 
       
  2203     ec = 0;
       
  2204     cleanupAfterGraphicsCall(false);
       
  2205 }
       
  2206 
       
  2207 // Obsolete texImage2D entry points -- to be removed shortly. (FIXME)
       
  2208 
       
  2209 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
       
  2210                                        ExceptionCode& ec)
       
  2211 {
       
  2212     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels)");
       
  2213     texImage2D(target, level, pixels, 0, 0, ec);
       
  2214 }
       
  2215 
       
  2216 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
       
  2217                                        bool flipY, ExceptionCode& ec)
       
  2218 {
       
  2219     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY)");
       
  2220     texImage2D(target, level, pixels, flipY, 0, ec);
       
  2221 }
       
  2222 
       
  2223 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, ImageData* pixels,
       
  2224                                        bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2225 {
       
  2226     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
       
  2227     ec = 0;
       
  2228     Vector<uint8_t> data;
       
  2229     if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
       
  2230         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2231         return;
       
  2232     }
       
  2233     texImage2DBase(target, level, GraphicsContext3D::RGBA, pixels->width(), pixels->height(), 0,
       
  2234                    GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
       
  2235 }
       
  2236 
       
  2237 
       
  2238 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
       
  2239                                        ExceptionCode& ec)
       
  2240 {
       
  2241     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image)");
       
  2242     texImage2D(target, level, image, 0, 0, ec);
       
  2243 }
       
  2244 
       
  2245 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
       
  2246                                        bool flipY, ExceptionCode& ec)
       
  2247 {
       
  2248     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY)");
       
  2249     texImage2D(target, level, image, flipY, 0, ec);
       
  2250 }
       
  2251 
       
  2252 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
       
  2253                                        bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2254 {
       
  2255     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
       
  2256     ec = 0;
       
  2257     if (!image || !image->cachedImage()) {
       
  2258         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2259         return;
       
  2260     }
       
  2261     texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(), flipY, premultiplyAlpha, ec);
       
  2262 }
       
  2263 
       
  2264 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
       
  2265                                        ExceptionCode& ec)
       
  2266 {
       
  2267     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas)");
       
  2268     texImage2D(target, level, canvas, 0, 0, ec);
       
  2269 }
       
  2270 
       
  2271 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
       
  2272                                        bool flipY, ExceptionCode& ec)
       
  2273 {
       
  2274     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY)");
       
  2275     texImage2D(target, level, canvas, flipY, 0, ec);
       
  2276 }
       
  2277 
       
  2278 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
       
  2279                                        bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2280 {
       
  2281     printWarningToConsole("Calling obsolete texImage2D(GLenum target, GLint level, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
       
  2282     ec = 0;
       
  2283     if (!canvas || !canvas->buffer()) {
       
  2284         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2285         return;
       
  2286     }
       
  2287     texImage2DImpl(target, level, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(), flipY, premultiplyAlpha, ec);
       
  2288 }
       
  2289 
       
  2290 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
       
  2291                                        ExceptionCode& ec)
       
  2292 {
       
  2293     texImage2D(target, level, video, 0, 0, ec);
       
  2294 }
       
  2295 
       
  2296 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
       
  2297                                        bool flipY, ExceptionCode& ec)
       
  2298 {
       
  2299     texImage2D(target, level, video, flipY, 0, ec);
       
  2300 }
       
  2301 
       
  2302 void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
       
  2303                                        bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2304 {
       
  2305     // FIXME: Need implement this call
       
  2306     UNUSED_PARAM(target);
       
  2307     UNUSED_PARAM(level);
       
  2308     UNUSED_PARAM(video);
       
  2309     UNUSED_PARAM(flipY);
       
  2310     UNUSED_PARAM(premultiplyAlpha);
       
  2311     
       
  2312     ec = 0;
       
  2313     cleanupAfterGraphicsCall(false);
       
  2314 }
       
  2315 
       
  2316 void WebGLRenderingContext::texParameter(unsigned long target, unsigned long pname, float paramf, int parami, bool isFloat)
       
  2317 {
       
  2318     if (!isGLES2Compliant()) {
       
  2319         RefPtr<WebGLTexture> tex = 0;
       
  2320         switch (target) {
       
  2321         case GraphicsContext3D::TEXTURE_2D:
       
  2322             tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
       
  2323             break;
       
  2324         case GraphicsContext3D::TEXTURE_CUBE_MAP:
       
  2325             tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
       
  2326             break;
       
  2327         default:
       
  2328             m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  2329             return;
       
  2330         }
       
  2331         switch (pname) {
       
  2332         case GraphicsContext3D::TEXTURE_MIN_FILTER:
       
  2333         case GraphicsContext3D::TEXTURE_MAG_FILTER:
       
  2334             break;
       
  2335         case GraphicsContext3D::TEXTURE_WRAP_S:
       
  2336         case GraphicsContext3D::TEXTURE_WRAP_T:
       
  2337             if (isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT
       
  2338                 || !isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT) {
       
  2339                 m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  2340                 return;
       
  2341             }
       
  2342             break;
       
  2343         default:
       
  2344             m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  2345             return;
       
  2346         }
       
  2347         if (tex) {
       
  2348             if (isFloat)
       
  2349                 tex->setParameterf(pname, paramf);
       
  2350             else
       
  2351                 tex->setParameteri(pname, parami);
       
  2352         }
       
  2353     }
       
  2354     if (isFloat)
       
  2355         m_context->texParameterf(target, pname, paramf);
       
  2356     else
       
  2357         m_context->texParameteri(target, pname, parami);
       
  2358     cleanupAfterGraphicsCall(false);
       
  2359 }
       
  2360 
       
  2361 void WebGLRenderingContext::texParameterf(unsigned target, unsigned pname, float param)
       
  2362 {
       
  2363     texParameter(target, pname, param, 0, true);
       
  2364 }
       
  2365 
       
  2366 void WebGLRenderingContext::texParameteri(unsigned target, unsigned pname, int param)
       
  2367 {
       
  2368     texParameter(target, pname, 0, param, false);
       
  2369 }
       
  2370 
       
  2371 void WebGLRenderingContext::texSubImage2DBase(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2372                                               unsigned width, unsigned height,
       
  2373                                               unsigned format, unsigned type, void* pixels, ExceptionCode& ec)
       
  2374 {
       
  2375     // FIXME: For now we ignore any errors returned
       
  2376     ec = 0;
       
  2377     if (!validateTexFuncFormatAndType(format, type))
       
  2378         return;
       
  2379 
       
  2380     m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
       
  2381     cleanupAfterGraphicsCall(false);
       
  2382 }
       
  2383 
       
  2384 void WebGLRenderingContext::texSubImage2DImpl(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2385                                               unsigned format, unsigned type,
       
  2386                                               Image* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2387 {
       
  2388     ec = 0;
       
  2389     Vector<uint8_t> data;
       
  2390     if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, data)) {
       
  2391         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2392         return;
       
  2393     }
       
  2394     texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
       
  2395                       format, type, data.data(), ec);
       
  2396 }
       
  2397 
       
  2398 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2399                                           unsigned width, unsigned height,
       
  2400                                           unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
       
  2401 {
       
  2402     if (!validateTexFuncData(width, height, format, type, pixels))
       
  2403         return;
       
  2404     void* data = pixels ? pixels->baseAddress() : 0;
       
  2405     Vector<uint8_t> tempData;
       
  2406     bool changeUnpackAlignment = false;
       
  2407     if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
       
  2408         if (!m_context->extractTextureData(width, height, format, type,
       
  2409                                            m_unpackAlignment,
       
  2410                                            m_unpackFlipY, m_unpackPremultiplyAlpha,
       
  2411                                            pixels,
       
  2412                                            tempData))
       
  2413             return;
       
  2414         data = tempData.data();
       
  2415         changeUnpackAlignment = true;
       
  2416     }
       
  2417     if (changeUnpackAlignment)
       
  2418         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
       
  2419     texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
       
  2420     if (changeUnpackAlignment)
       
  2421         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
       
  2422 }
       
  2423 
       
  2424 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2425                                           unsigned format, unsigned type, ImageData* pixels, ExceptionCode& ec)
       
  2426 {
       
  2427     ec = 0;
       
  2428     Vector<uint8_t> data;
       
  2429     if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
       
  2430         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2431         return;
       
  2432     }
       
  2433     texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
       
  2434                       format, type, data.data(), ec);
       
  2435 }
       
  2436 
       
  2437 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2438                                           unsigned format, unsigned type, HTMLImageElement* image, ExceptionCode& ec)
       
  2439 {
       
  2440     ec = 0;
       
  2441     if (!image || !image->cachedImage()) {
       
  2442         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2443         return;
       
  2444     }
       
  2445     texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
       
  2446                       m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
       
  2447 }
       
  2448 
       
  2449 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2450                                           unsigned format, unsigned type, HTMLCanvasElement* canvas, ExceptionCode& ec)
       
  2451 {
       
  2452     ec = 0;
       
  2453     if (!canvas || !canvas->buffer()) {
       
  2454         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2455         return;
       
  2456     }
       
  2457     texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->buffer()->image(),
       
  2458                       m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
       
  2459 }
       
  2460 
       
  2461 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2462                                           unsigned format, unsigned type, HTMLVideoElement* video, ExceptionCode& ec)
       
  2463 {
       
  2464     // FIXME: Need to implement this call
       
  2465     UNUSED_PARAM(target);
       
  2466     UNUSED_PARAM(level);
       
  2467     UNUSED_PARAM(xoffset);
       
  2468     UNUSED_PARAM(yoffset);
       
  2469     UNUSED_PARAM(format);
       
  2470     UNUSED_PARAM(type);
       
  2471     UNUSED_PARAM(video);
       
  2472     ec = 0;
       
  2473     cleanupAfterGraphicsCall(false);
       
  2474 }
       
  2475 
       
  2476 // Obsolete texSubImage2D entry points -- to be removed shortly. (FIXME)
       
  2477 
       
  2478 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2479                                           ImageData* pixels, ExceptionCode& ec)
       
  2480 {
       
  2481     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels)");
       
  2482     texSubImage2D(target, level, xoffset, yoffset, pixels, 0, 0, ec);
       
  2483 }
       
  2484 
       
  2485 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2486                                           ImageData* pixels, bool flipY, ExceptionCode& ec)
       
  2487 {
       
  2488     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY)");
       
  2489     texSubImage2D(target, level, xoffset, yoffset, pixels, flipY, 0, ec);
       
  2490 }
       
  2491 
       
  2492 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2493                                           ImageData* pixels, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2494 {
       
  2495     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ImageData pixels, GLboolean flipY, GLboolean premultiplyAlpha)");
       
  2496     ec = 0;
       
  2497     Vector<uint8_t> data;
       
  2498     if (!m_context->extractImageData(pixels, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, flipY, premultiplyAlpha, data)) {
       
  2499         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2500         return;
       
  2501     }
       
  2502     texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
       
  2503                       GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, data.data(), ec);
       
  2504 }
       
  2505 
       
  2506 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2507                                           HTMLImageElement* image, ExceptionCode& ec)
       
  2508 {
       
  2509     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image)");
       
  2510     texSubImage2D(target, level, xoffset, yoffset, image, 0, 0, ec);
       
  2511 }
       
  2512 
       
  2513 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2514                                           HTMLImageElement* image, bool flipY, ExceptionCode& ec)
       
  2515 {
       
  2516     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY)");
       
  2517     texSubImage2D(target, level, xoffset, yoffset, image, flipY, 0, ec);
       
  2518 }
       
  2519 
       
  2520 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2521                                           HTMLImageElement* image, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2522 {
       
  2523     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLImageElement image, GLboolean flipY, GLboolean premultiplyAlpha)");
       
  2524     ec = 0;
       
  2525     if (!image || !image->cachedImage()) {
       
  2526         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2527         return;
       
  2528     }
       
  2529     texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, image->cachedImage()->image(),
       
  2530                       flipY, premultiplyAlpha, ec);
       
  2531 }
       
  2532 
       
  2533 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2534                                           HTMLCanvasElement* canvas, ExceptionCode& ec)
       
  2535 {
       
  2536     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas)");
       
  2537     texSubImage2D(target, level, xoffset, yoffset, canvas, 0, 0, ec);
       
  2538 }
       
  2539 
       
  2540 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2541                                           HTMLCanvasElement* canvas, bool flipY, ExceptionCode& ec)
       
  2542 {
       
  2543     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY)");
       
  2544     texSubImage2D(target, level, xoffset, yoffset, canvas, flipY, 0, ec);
       
  2545 }
       
  2546 
       
  2547 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2548                                           HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2549 {
       
  2550     printWarningToConsole("Calling obsolete texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, HTMLCanvasElement canvas, GLboolean flipY, GLboolean premultiplyAlpha)");
       
  2551     ec = 0;
       
  2552     if (!canvas || !canvas->buffer()) {
       
  2553         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  2554         return;
       
  2555     }
       
  2556     texSubImage2DImpl(target, level, xoffset, yoffset, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, canvas->buffer()->image(),
       
  2557                       flipY, premultiplyAlpha, ec);
       
  2558 }
       
  2559 
       
  2560 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2561                                           HTMLVideoElement* video, ExceptionCode& ec)
       
  2562 {
       
  2563     texSubImage2D(target, level, xoffset, yoffset, video, 0, 0, ec);
       
  2564 }
       
  2565 
       
  2566 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2567                                           HTMLVideoElement* video, bool flipY, ExceptionCode& ec)
       
  2568 {
       
  2569     texSubImage2D(target, level, xoffset, yoffset, video, flipY, 0, ec);
       
  2570 }
       
  2571 
       
  2572 void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
       
  2573                                           HTMLVideoElement* video, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
       
  2574 {
       
  2575     // FIXME: Need to implement this call
       
  2576     UNUSED_PARAM(target);
       
  2577     UNUSED_PARAM(level);
       
  2578     UNUSED_PARAM(xoffset);
       
  2579     UNUSED_PARAM(yoffset);
       
  2580     UNUSED_PARAM(video);
       
  2581     UNUSED_PARAM(flipY);
       
  2582     UNUSED_PARAM(premultiplyAlpha);
       
  2583     ec = 0;
       
  2584     cleanupAfterGraphicsCall(false);
       
  2585 }
       
  2586 
       
  2587 void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, float x, ExceptionCode& ec)
       
  2588 {
       
  2589     UNUSED_PARAM(ec);
       
  2590     if (!location)
       
  2591         return;
       
  2592 
       
  2593     if (location->program() != m_currentProgram) {
       
  2594         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2595         return;
       
  2596     }
       
  2597 
       
  2598     m_context->uniform1f(location->location(), x);
       
  2599     cleanupAfterGraphicsCall(false);
       
  2600 }
       
  2601 
       
  2602 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
       
  2603 {
       
  2604     UNUSED_PARAM(ec);
       
  2605     if (!validateUniformParameters(location, v, 1))
       
  2606         return;
       
  2607 
       
  2608     m_context->uniform1fv(location->location(), v->data(), v->length());
       
  2609     cleanupAfterGraphicsCall(false);
       
  2610 }
       
  2611 
       
  2612 void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
       
  2613 {
       
  2614     UNUSED_PARAM(ec);
       
  2615     if (!validateUniformParameters(location, v, size, 1))
       
  2616         return;
       
  2617 
       
  2618     m_context->uniform1fv(location->location(), v, size);
       
  2619     cleanupAfterGraphicsCall(false);
       
  2620 }
       
  2621 
       
  2622 void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, int x, ExceptionCode& ec)
       
  2623 {
       
  2624     UNUSED_PARAM(ec);
       
  2625     if (!location)
       
  2626         return;
       
  2627 
       
  2628     if (location->program() != m_currentProgram) {
       
  2629         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2630         return;
       
  2631     }
       
  2632 
       
  2633     m_context->uniform1i(location->location(), x);
       
  2634     cleanupAfterGraphicsCall(false);
       
  2635 }
       
  2636 
       
  2637 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
       
  2638 {
       
  2639     UNUSED_PARAM(ec);
       
  2640     if (!validateUniformParameters(location, v, 1))
       
  2641         return;
       
  2642 
       
  2643     m_context->uniform1iv(location->location(), v->data(), v->length());
       
  2644     cleanupAfterGraphicsCall(false);
       
  2645 }
       
  2646 
       
  2647 void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
       
  2648 {
       
  2649     UNUSED_PARAM(ec);
       
  2650     if (!validateUniformParameters(location, v, size, 1))
       
  2651         return;
       
  2652 
       
  2653     m_context->uniform1iv(location->location(), v, size);
       
  2654     cleanupAfterGraphicsCall(false);
       
  2655 }
       
  2656 
       
  2657 void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, float x, float y, ExceptionCode& ec)
       
  2658 {
       
  2659     UNUSED_PARAM(ec);
       
  2660     if (!location)
       
  2661         return;
       
  2662 
       
  2663     if (location->program() != m_currentProgram) {
       
  2664         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2665         return;
       
  2666     }
       
  2667 
       
  2668     m_context->uniform2f(location->location(), x, y);
       
  2669     cleanupAfterGraphicsCall(false);
       
  2670 }
       
  2671 
       
  2672 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
       
  2673 {
       
  2674     UNUSED_PARAM(ec);
       
  2675     if (!validateUniformParameters(location, v, 2))
       
  2676         return;
       
  2677 
       
  2678     m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
       
  2679     cleanupAfterGraphicsCall(false);
       
  2680 }
       
  2681 
       
  2682 void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
       
  2683 {
       
  2684     UNUSED_PARAM(ec);
       
  2685     if (!validateUniformParameters(location, v, size, 2))
       
  2686         return;
       
  2687 
       
  2688     m_context->uniform2fv(location->location(), v, size / 2);
       
  2689     cleanupAfterGraphicsCall(false);
       
  2690 }
       
  2691 
       
  2692 void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, int x, int y, ExceptionCode& ec)
       
  2693 {
       
  2694     UNUSED_PARAM(ec);
       
  2695     if (!location)
       
  2696         return;
       
  2697 
       
  2698     if (location->program() != m_currentProgram) {
       
  2699         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2700         return;
       
  2701     }
       
  2702 
       
  2703     m_context->uniform2i(location->location(), x, y);
       
  2704     cleanupAfterGraphicsCall(false);
       
  2705 }
       
  2706 
       
  2707 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
       
  2708 {
       
  2709     UNUSED_PARAM(ec);
       
  2710     if (!validateUniformParameters(location, v, 2))
       
  2711         return;
       
  2712 
       
  2713     m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
       
  2714     cleanupAfterGraphicsCall(false);
       
  2715 }
       
  2716 
       
  2717 void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
       
  2718 {
       
  2719     UNUSED_PARAM(ec);
       
  2720     if (!validateUniformParameters(location, v, size, 2))
       
  2721         return;
       
  2722 
       
  2723     m_context->uniform2iv(location->location(), v, size / 2);
       
  2724     cleanupAfterGraphicsCall(false);
       
  2725 }
       
  2726 
       
  2727 void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, float x, float y, float z, ExceptionCode& ec)
       
  2728 {
       
  2729     UNUSED_PARAM(ec);
       
  2730     if (!location)
       
  2731         return;
       
  2732 
       
  2733     if (location->program() != m_currentProgram) {
       
  2734         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2735         return;
       
  2736     }
       
  2737 
       
  2738     m_context->uniform3f(location->location(), x, y, z);
       
  2739     cleanupAfterGraphicsCall(false);
       
  2740 }
       
  2741 
       
  2742 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
       
  2743 {
       
  2744     UNUSED_PARAM(ec);
       
  2745     if (!validateUniformParameters(location, v, 3))
       
  2746         return;
       
  2747 
       
  2748     m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
       
  2749     cleanupAfterGraphicsCall(false);
       
  2750 }
       
  2751 
       
  2752 void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
       
  2753 {
       
  2754     UNUSED_PARAM(ec);
       
  2755     if (!validateUniformParameters(location, v, size, 3))
       
  2756         return;
       
  2757 
       
  2758     m_context->uniform3fv(location->location(), v, size / 3);
       
  2759     cleanupAfterGraphicsCall(false);
       
  2760 }
       
  2761 
       
  2762 void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, int x, int y, int z, ExceptionCode& ec)
       
  2763 {
       
  2764     UNUSED_PARAM(ec);
       
  2765     if (!location)
       
  2766         return;
       
  2767 
       
  2768     if (location->program() != m_currentProgram) {
       
  2769         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2770         return;
       
  2771     }
       
  2772 
       
  2773     m_context->uniform3i(location->location(), x, y, z);
       
  2774     cleanupAfterGraphicsCall(false);
       
  2775 }
       
  2776 
       
  2777 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
       
  2778 {
       
  2779     UNUSED_PARAM(ec);
       
  2780     if (!validateUniformParameters(location, v, 3))
       
  2781         return;
       
  2782 
       
  2783     m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
       
  2784     cleanupAfterGraphicsCall(false);
       
  2785 }
       
  2786 
       
  2787 void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
       
  2788 {
       
  2789     UNUSED_PARAM(ec);
       
  2790     if (!validateUniformParameters(location, v, size, 3))
       
  2791         return;
       
  2792 
       
  2793     m_context->uniform3iv(location->location(), v, size / 3);
       
  2794     cleanupAfterGraphicsCall(false);
       
  2795 }
       
  2796 
       
  2797 void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, float x, float y, float z, float w, ExceptionCode& ec)
       
  2798 {
       
  2799     UNUSED_PARAM(ec);
       
  2800     if (!location)
       
  2801         return;
       
  2802 
       
  2803     if (location->program() != m_currentProgram) {
       
  2804         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2805         return;
       
  2806     }
       
  2807 
       
  2808     m_context->uniform4f(location->location(), x, y, z, w);
       
  2809     cleanupAfterGraphicsCall(false);
       
  2810 }
       
  2811 
       
  2812 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
       
  2813 {
       
  2814     UNUSED_PARAM(ec);
       
  2815     if (!validateUniformParameters(location, v, 4))
       
  2816         return;
       
  2817 
       
  2818     m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
       
  2819     cleanupAfterGraphicsCall(false);
       
  2820 }
       
  2821 
       
  2822 void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, float* v, int size, ExceptionCode& ec)
       
  2823 {
       
  2824     UNUSED_PARAM(ec);
       
  2825     if (!validateUniformParameters(location, v, size, 4))
       
  2826         return;
       
  2827 
       
  2828     m_context->uniform4fv(location->location(), v, size / 4);
       
  2829     cleanupAfterGraphicsCall(false);
       
  2830 }
       
  2831 
       
  2832 void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, int x, int y, int z, int w, ExceptionCode& ec)
       
  2833 {
       
  2834     UNUSED_PARAM(ec);
       
  2835     if (!location)
       
  2836         return;
       
  2837 
       
  2838     if (location->program() != m_currentProgram) {
       
  2839         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2840         return;
       
  2841     }
       
  2842 
       
  2843     m_context->uniform4i(location->location(), x, y, z, w);
       
  2844     cleanupAfterGraphicsCall(false);
       
  2845 }
       
  2846 
       
  2847 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
       
  2848 {
       
  2849     UNUSED_PARAM(ec);
       
  2850     if (!validateUniformParameters(location, v, 4))
       
  2851         return;
       
  2852 
       
  2853     m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
       
  2854     cleanupAfterGraphicsCall(false);
       
  2855 }
       
  2856 
       
  2857 void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, int* v, int size, ExceptionCode& ec)
       
  2858 {
       
  2859     UNUSED_PARAM(ec);
       
  2860     if (!validateUniformParameters(location, v, size, 4))
       
  2861         return;
       
  2862 
       
  2863     m_context->uniform4iv(location->location(), v, size / 4);
       
  2864     cleanupAfterGraphicsCall(false);
       
  2865 }
       
  2866 
       
  2867 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
       
  2868 {
       
  2869     UNUSED_PARAM(ec);
       
  2870     if (!validateUniformMatrixParameters(location, transpose, v, 4))
       
  2871         return;
       
  2872     m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
       
  2873     cleanupAfterGraphicsCall(false);
       
  2874 }
       
  2875 
       
  2876 void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
       
  2877 {
       
  2878     UNUSED_PARAM(ec);
       
  2879     if (!validateUniformMatrixParameters(location, transpose, v, size, 4))
       
  2880         return;
       
  2881     m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
       
  2882     cleanupAfterGraphicsCall(false);
       
  2883 }
       
  2884 
       
  2885 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
       
  2886 {
       
  2887     UNUSED_PARAM(ec);
       
  2888     if (!validateUniformMatrixParameters(location, transpose, v, 9))
       
  2889         return;
       
  2890     m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
       
  2891     cleanupAfterGraphicsCall(false);
       
  2892 }
       
  2893 
       
  2894 void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
       
  2895 {
       
  2896     UNUSED_PARAM(ec);
       
  2897     if (!validateUniformMatrixParameters(location, transpose, v, size, 9))
       
  2898         return;
       
  2899     m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
       
  2900     cleanupAfterGraphicsCall(false);
       
  2901 }
       
  2902 
       
  2903 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, Float32Array* v, ExceptionCode& ec)
       
  2904 {
       
  2905     UNUSED_PARAM(ec);
       
  2906     if (!validateUniformMatrixParameters(location, transpose, v, 16))
       
  2907         return;
       
  2908     m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
       
  2909     cleanupAfterGraphicsCall(false);
       
  2910 }
       
  2911 
       
  2912 void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, bool transpose, float* v, int size, ExceptionCode& ec)
       
  2913 {
       
  2914     UNUSED_PARAM(ec);
       
  2915     if (!validateUniformMatrixParameters(location, transpose, v, size, 16))
       
  2916         return;
       
  2917     m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
       
  2918     cleanupAfterGraphicsCall(false);
       
  2919 }
       
  2920 
       
  2921 void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
       
  2922 {
       
  2923     UNUSED_PARAM(ec);
       
  2924     if (program && program->context() != this) {
       
  2925         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  2926         return;
       
  2927     }
       
  2928     m_currentProgram = program;
       
  2929     m_context->useProgram(program);
       
  2930     cleanupAfterGraphicsCall(false);
       
  2931 }
       
  2932 
       
  2933 void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
       
  2934 {
       
  2935     UNUSED_PARAM(ec);
       
  2936     if (!validateWebGLObject(program))
       
  2937         return;
       
  2938     m_context->validateProgram(program);
       
  2939     cleanupAfterGraphicsCall(false);
       
  2940 }
       
  2941 
       
  2942 void WebGLRenderingContext::vertexAttrib1f(unsigned long index, float v0)
       
  2943 {
       
  2944     vertexAttribfImpl(index, 1, v0, 0.0f, 0.0f, 1.0f);
       
  2945 }
       
  2946 
       
  2947 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, Float32Array* v)
       
  2948 {
       
  2949     vertexAttribfvImpl(index, v, 1);
       
  2950 }
       
  2951 
       
  2952 void WebGLRenderingContext::vertexAttrib1fv(unsigned long index, float* v, int size)
       
  2953 {
       
  2954     vertexAttribfvImpl(index, v, size, 1);
       
  2955 }
       
  2956 
       
  2957 void WebGLRenderingContext::vertexAttrib2f(unsigned long index, float v0, float v1)
       
  2958 {
       
  2959     vertexAttribfImpl(index, 2, v0, v1, 0.0f, 1.0f);
       
  2960 }
       
  2961 
       
  2962 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, Float32Array* v)
       
  2963 {
       
  2964     vertexAttribfvImpl(index, v, 2);
       
  2965 }
       
  2966 
       
  2967 void WebGLRenderingContext::vertexAttrib2fv(unsigned long index, float* v, int size)
       
  2968 {
       
  2969     vertexAttribfvImpl(index, v, size, 2);
       
  2970 }
       
  2971 
       
  2972 void WebGLRenderingContext::vertexAttrib3f(unsigned long index, float v0, float v1, float v2)
       
  2973 {
       
  2974     vertexAttribfImpl(index, 3, v0, v1, v2, 1.0f);
       
  2975 }
       
  2976 
       
  2977 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, Float32Array* v)
       
  2978 {
       
  2979     vertexAttribfvImpl(index, v, 3);
       
  2980 }
       
  2981 
       
  2982 void WebGLRenderingContext::vertexAttrib3fv(unsigned long index, float* v, int size)
       
  2983 {
       
  2984     vertexAttribfvImpl(index, v, size, 3);
       
  2985 }
       
  2986 
       
  2987 void WebGLRenderingContext::vertexAttrib4f(unsigned long index, float v0, float v1, float v2, float v3)
       
  2988 {
       
  2989     vertexAttribfImpl(index, 4, v0, v1, v2, v3);
       
  2990 }
       
  2991 
       
  2992 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, Float32Array* v)
       
  2993 {
       
  2994     vertexAttribfvImpl(index, v, 4);
       
  2995 }
       
  2996 
       
  2997 void WebGLRenderingContext::vertexAttrib4fv(unsigned long index, float* v, int size)
       
  2998 {
       
  2999     vertexAttribfvImpl(index, v, size, 4);
       
  3000 }
       
  3001 
       
  3002 void WebGLRenderingContext::vertexAttribPointer(unsigned long index, long size, unsigned long type, bool normalized, long stride, long offset, ExceptionCode& ec)
       
  3003 {
       
  3004     if (index >= m_maxVertexAttribs) {
       
  3005         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3006         return;
       
  3007     }
       
  3008     if (size < 1 || size > 4 || stride < 0 || offset < 0) {
       
  3009         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3010         return;
       
  3011     }
       
  3012     if (!m_boundArrayBuffer) {
       
  3013         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3014         return;
       
  3015     }
       
  3016     // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
       
  3017     long bytesPerElement = size * sizeInBytes(type, ec);
       
  3018     if (bytesPerElement <= 0)
       
  3019         return;
       
  3020 
       
  3021     if (index >= m_vertexAttribState.size())
       
  3022         m_vertexAttribState.resize(index + 1);
       
  3023 
       
  3024     long validatedStride = bytesPerElement;
       
  3025     if (stride != 0) {
       
  3026         if ((long) stride < bytesPerElement) {
       
  3027             m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3028             return;
       
  3029         }
       
  3030         validatedStride = stride;
       
  3031     }
       
  3032     m_vertexAttribState[index].bufferBinding = m_boundArrayBuffer;
       
  3033     m_vertexAttribState[index].bytesPerElement = bytesPerElement;
       
  3034     m_vertexAttribState[index].size = size;
       
  3035     m_vertexAttribState[index].type = type;
       
  3036     m_vertexAttribState[index].normalized = normalized;
       
  3037     m_vertexAttribState[index].stride = validatedStride;
       
  3038     m_vertexAttribState[index].originalStride = stride;
       
  3039     m_vertexAttribState[index].offset = offset;
       
  3040     m_context->vertexAttribPointer(index, size, type, normalized, stride, offset);
       
  3041     cleanupAfterGraphicsCall(false);
       
  3042 }
       
  3043 
       
  3044 void WebGLRenderingContext::viewport(long x, long y, unsigned long width, unsigned long height)
       
  3045 {
       
  3046     if (isnan(x))
       
  3047         x = 0;
       
  3048     if (isnan(y))
       
  3049         y = 0;
       
  3050     if (isnan(width))
       
  3051         width = 100;
       
  3052     if (isnan(height))
       
  3053         height = 100;
       
  3054     m_context->viewport(x, y, width, height);
       
  3055     cleanupAfterGraphicsCall(false);
       
  3056 }
       
  3057 
       
  3058 void WebGLRenderingContext::removeObject(CanvasObject* object)
       
  3059 {
       
  3060     m_canvasObjects.remove(object);
       
  3061 }
       
  3062 
       
  3063 void WebGLRenderingContext::addObject(CanvasObject* object)
       
  3064 {
       
  3065     removeObject(object);
       
  3066     m_canvasObjects.add(object);
       
  3067 }
       
  3068 
       
  3069 void WebGLRenderingContext::detachAndRemoveAllObjects()
       
  3070 {
       
  3071     HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
       
  3072     for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it)
       
  3073         (*it)->detachContext();
       
  3074         
       
  3075     m_canvasObjects.clear();
       
  3076 }
       
  3077 
       
  3078 WebGLTexture* WebGLRenderingContext::findTexture(Platform3DObject obj)
       
  3079 {
       
  3080     if (!obj)
       
  3081         return 0;
       
  3082     HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
       
  3083     for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
       
  3084         if ((*it)->isTexture() && (*it)->object() == obj)
       
  3085             return reinterpret_cast<WebGLTexture*>((*it).get());
       
  3086     }
       
  3087     return 0;
       
  3088 }
       
  3089 
       
  3090 WebGLRenderbuffer* WebGLRenderingContext::findRenderbuffer(Platform3DObject obj)
       
  3091 {
       
  3092     if (!obj)
       
  3093         return 0;
       
  3094     HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
       
  3095     for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
       
  3096         if ((*it)->isRenderbuffer() && (*it)->object() == obj)
       
  3097             return reinterpret_cast<WebGLRenderbuffer*>((*it).get());
       
  3098     }
       
  3099     return 0;
       
  3100 }
       
  3101 
       
  3102 WebGLBuffer* WebGLRenderingContext::findBuffer(Platform3DObject obj)
       
  3103 {
       
  3104     if (!obj)
       
  3105         return 0;
       
  3106     HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
       
  3107     for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
       
  3108         if ((*it)->isBuffer() && (*it)->object() == obj)
       
  3109             return reinterpret_cast<WebGLBuffer*>((*it).get());
       
  3110     }
       
  3111     return 0;
       
  3112 }
       
  3113 
       
  3114 WebGLShader* WebGLRenderingContext::findShader(Platform3DObject obj)
       
  3115 {
       
  3116     if (!obj)
       
  3117         return 0;
       
  3118     HashSet<RefPtr<CanvasObject> >::iterator pend = m_canvasObjects.end();
       
  3119     for (HashSet<RefPtr<CanvasObject> >::iterator it = m_canvasObjects.begin(); it != pend; ++it) {
       
  3120         if ((*it)->isShader() && (*it)->object() == obj)
       
  3121             return reinterpret_cast<WebGLShader*>((*it).get());
       
  3122     }
       
  3123     return 0;
       
  3124 }
       
  3125 
       
  3126 WebGLGetInfo WebGLRenderingContext::getBooleanParameter(unsigned long pname)
       
  3127 {
       
  3128     unsigned char value;
       
  3129     m_context->getBooleanv(pname, &value);
       
  3130     return WebGLGetInfo(static_cast<bool>(value));
       
  3131 }
       
  3132 
       
  3133 WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(unsigned long pname)
       
  3134 {
       
  3135     if (pname != GraphicsContext3D::COLOR_WRITEMASK) {
       
  3136         notImplemented();
       
  3137         return WebGLGetInfo(0, 0);
       
  3138     }
       
  3139     unsigned char value[4] = {0};
       
  3140     m_context->getBooleanv(pname, value);
       
  3141     bool boolValue[4];
       
  3142     for (int ii = 0; ii < 4; ++ii)
       
  3143         boolValue[ii] = static_cast<bool>(value[ii]);
       
  3144     return WebGLGetInfo(boolValue, 4);
       
  3145 }
       
  3146 
       
  3147 WebGLGetInfo WebGLRenderingContext::getFloatParameter(unsigned long pname)
       
  3148 {
       
  3149     float value;
       
  3150     m_context->getFloatv(pname, &value);
       
  3151     return WebGLGetInfo(static_cast<float>(value));
       
  3152 }
       
  3153 
       
  3154 WebGLGetInfo WebGLRenderingContext::getIntParameter(unsigned long pname)
       
  3155 {
       
  3156     return getLongParameter(pname);
       
  3157 }
       
  3158 
       
  3159 WebGLGetInfo WebGLRenderingContext::getLongParameter(unsigned long pname)
       
  3160 {
       
  3161     int value;
       
  3162     m_context->getIntegerv(pname, &value);
       
  3163     return WebGLGetInfo(static_cast<long>(value));
       
  3164 }
       
  3165 
       
  3166 WebGLGetInfo WebGLRenderingContext::getUnsignedLongParameter(unsigned long pname)
       
  3167 {
       
  3168     int value;
       
  3169     m_context->getIntegerv(pname, &value);
       
  3170     return WebGLGetInfo(static_cast<unsigned long>(value));
       
  3171 }
       
  3172 
       
  3173 WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(unsigned long pname)
       
  3174 {
       
  3175     float value[4] = {0};
       
  3176     m_context->getFloatv(pname, value);
       
  3177     unsigned length = 0;
       
  3178     switch (pname) {
       
  3179     case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
       
  3180     case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
       
  3181     case GraphicsContext3D::DEPTH_RANGE:
       
  3182         length = 2;
       
  3183         break;
       
  3184     case GraphicsContext3D::BLEND_COLOR:
       
  3185     case GraphicsContext3D::COLOR_CLEAR_VALUE:
       
  3186         length = 4;
       
  3187         break;
       
  3188     default:
       
  3189         notImplemented();
       
  3190     }
       
  3191     return WebGLGetInfo(Float32Array::create(value, length));
       
  3192 }
       
  3193 
       
  3194 WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(unsigned long pname)
       
  3195 {
       
  3196     int value[4] = {0};
       
  3197     m_context->getIntegerv(pname, value);
       
  3198     unsigned length = 0;
       
  3199     switch (pname) {
       
  3200     case GraphicsContext3D::MAX_VIEWPORT_DIMS:
       
  3201         length = 2;
       
  3202         break;
       
  3203     case GraphicsContext3D::SCISSOR_BOX:
       
  3204     case GraphicsContext3D::VIEWPORT:
       
  3205         length = 4;
       
  3206         break;
       
  3207     default:
       
  3208         notImplemented();
       
  3209     }
       
  3210     return WebGLGetInfo(Int32Array::create(value, length));
       
  3211 }
       
  3212 
       
  3213 bool WebGLRenderingContext::isGLES2Compliant()
       
  3214 {
       
  3215     return m_context->isGLES2Compliant();
       
  3216 }
       
  3217 
       
  3218 void WebGLRenderingContext::handleNPOTTextures(bool prepareToDraw)
       
  3219 {
       
  3220     bool resetActiveUnit = false;
       
  3221     for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
       
  3222         if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture()
       
  3223             || m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture()) {
       
  3224             if (ii != m_activeTextureUnit) {
       
  3225                 m_context->activeTexture(ii);
       
  3226                 resetActiveUnit = true;
       
  3227             } else if (resetActiveUnit) {
       
  3228                 m_context->activeTexture(ii);
       
  3229                 resetActiveUnit = false;
       
  3230             }
       
  3231             WebGLTexture* tex2D;
       
  3232             WebGLTexture* texCubeMap;
       
  3233             if (prepareToDraw) {
       
  3234                 tex2D = m_blackTexture2D.get();
       
  3235                 texCubeMap = m_blackTextureCubeMap.get();
       
  3236             } else {
       
  3237                 tex2D = m_textureUnits[ii].m_texture2DBinding.get();
       
  3238                 texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
       
  3239             }
       
  3240             if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture())
       
  3241                 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, tex2D);
       
  3242             if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture())
       
  3243                 m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, texCubeMap);
       
  3244         }
       
  3245     }
       
  3246     if (resetActiveUnit)
       
  3247         m_context->activeTexture(m_activeTextureUnit);
       
  3248 }
       
  3249 
       
  3250 void WebGLRenderingContext::createFallbackBlackTextures1x1()
       
  3251 {
       
  3252     unsigned char black[] = {0, 0, 0, 255};
       
  3253     m_blackTexture2D = createTexture();
       
  3254     m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_blackTexture2D.get());
       
  3255     m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3256                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3257     m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
       
  3258     m_blackTextureCubeMap = createTexture();
       
  3259     m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, m_blackTextureCubeMap.get());
       
  3260     m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3261                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3262     m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3263                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3264     m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3265                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3266     m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3267                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3268     m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3269                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3270     m_context->texImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GraphicsContext3D::RGBA, 1, 1,
       
  3271                           0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, black);
       
  3272     m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, 0);
       
  3273 }
       
  3274 
       
  3275 bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(unsigned long texInternalFormat,
       
  3276                                                                            unsigned long colorBufferFormat)
       
  3277 {
       
  3278     switch (colorBufferFormat) {
       
  3279     case GraphicsContext3D::ALPHA:
       
  3280         if (texInternalFormat == GraphicsContext3D::ALPHA)
       
  3281             return true;
       
  3282         break;
       
  3283     case GraphicsContext3D::RGB:
       
  3284         if (texInternalFormat == GraphicsContext3D::LUMINANCE
       
  3285             || texInternalFormat == GraphicsContext3D::RGB)
       
  3286             return true;
       
  3287         break;
       
  3288     case GraphicsContext3D::RGBA:
       
  3289         return true;
       
  3290     }
       
  3291     return false;
       
  3292 }
       
  3293 
       
  3294 WebGLTexture* WebGLRenderingContext::getTextureBinding(unsigned long target)
       
  3295 {
       
  3296     RefPtr<WebGLTexture> tex = 0;
       
  3297     switch (target) {
       
  3298     case GraphicsContext3D::TEXTURE_2D:
       
  3299         tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
       
  3300         break;
       
  3301     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
       
  3302     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
       
  3303     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
       
  3304     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
       
  3305     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
       
  3306     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
       
  3307         tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
       
  3308         break;
       
  3309     }
       
  3310     if (tex && tex->object())
       
  3311         return tex.get();
       
  3312     return 0;
       
  3313 }
       
  3314 
       
  3315 bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type)
       
  3316 {
       
  3317     switch (format) {
       
  3318     case GraphicsContext3D::ALPHA:
       
  3319     case GraphicsContext3D::LUMINANCE:
       
  3320     case GraphicsContext3D::LUMINANCE_ALPHA:
       
  3321     case GraphicsContext3D::RGB:
       
  3322     case GraphicsContext3D::RGBA:
       
  3323         break;
       
  3324     default:
       
  3325         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3326         return false;
       
  3327     }
       
  3328 
       
  3329     switch (type) {
       
  3330     case GraphicsContext3D::UNSIGNED_BYTE:
       
  3331     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
       
  3332     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
       
  3333     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
       
  3334         break;
       
  3335     default:
       
  3336         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3337         return false;
       
  3338     }
       
  3339 
       
  3340     // Verify that the combination of format and type is supported.
       
  3341     switch (format) {
       
  3342     case GraphicsContext3D::ALPHA:
       
  3343     case GraphicsContext3D::LUMINANCE:
       
  3344     case GraphicsContext3D::LUMINANCE_ALPHA:
       
  3345         if (type != GraphicsContext3D::UNSIGNED_BYTE) {
       
  3346             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3347             return false;
       
  3348         }
       
  3349         break;
       
  3350     case GraphicsContext3D::RGB:
       
  3351         if (type != GraphicsContext3D::UNSIGNED_BYTE
       
  3352             && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5) {
       
  3353             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3354             return false;
       
  3355         }
       
  3356         break;
       
  3357     case GraphicsContext3D::RGBA:
       
  3358         if (type != GraphicsContext3D::UNSIGNED_BYTE
       
  3359             && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
       
  3360             && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1) {
       
  3361             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3362             return false;
       
  3363         }
       
  3364         break;
       
  3365     default:
       
  3366         ASSERT_NOT_REACHED();
       
  3367     }
       
  3368 
       
  3369     return true;
       
  3370 }
       
  3371 
       
  3372 bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long level,
       
  3373                                                       unsigned long internalformat,
       
  3374                                                       long width, long height, long border,
       
  3375                                                       unsigned long format, unsigned long type)
       
  3376 {
       
  3377     // We absolutely have to validate the format and type combination.
       
  3378     // The texImage2D entry points taking HTMLImage, etc. will produce
       
  3379     // temporary data based on this combination, so it must be legal.
       
  3380     if (!validateTexFuncFormatAndType(format, type))
       
  3381         return false;
       
  3382 
       
  3383     if (width < 0 || height < 0 || level < 0) {
       
  3384         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3385         return false;
       
  3386     }
       
  3387 
       
  3388     switch (target) {
       
  3389     case GraphicsContext3D::TEXTURE_2D:
       
  3390         if (width > m_maxTextureSize || height > m_maxTextureSize || level > m_maxTextureLevel) {
       
  3391             m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3392             return false;
       
  3393         }
       
  3394         break;
       
  3395     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
       
  3396     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
       
  3397     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
       
  3398     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
       
  3399     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
       
  3400     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
       
  3401         if (width != height || width > m_maxCubeMapTextureSize || level > m_maxCubeMapTextureLevel) {
       
  3402             m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3403             return false;
       
  3404         }
       
  3405         break;
       
  3406     default:
       
  3407         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3408         return false;
       
  3409     }
       
  3410 
       
  3411     if (format != internalformat) {
       
  3412         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3413         return false;
       
  3414     }
       
  3415 
       
  3416     if (border) {
       
  3417         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3418         return false;
       
  3419     }
       
  3420 
       
  3421     return true;
       
  3422 }
       
  3423 
       
  3424 bool WebGLRenderingContext::validateTexFuncData(long width, long height,
       
  3425                                                 unsigned long format, unsigned long type,
       
  3426                                                 ArrayBufferView* pixels)
       
  3427 {
       
  3428     if (!pixels)
       
  3429         return true;
       
  3430 
       
  3431     if (!validateTexFuncFormatAndType(format, type))
       
  3432         return false;
       
  3433 
       
  3434     switch (type) {
       
  3435     case GraphicsContext3D::UNSIGNED_BYTE:
       
  3436         if (!pixels->isUnsignedByteArray()) {
       
  3437             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3438             return false;
       
  3439         }
       
  3440         break;
       
  3441     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
       
  3442     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
       
  3443     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
       
  3444         if (!pixels->isUnsignedShortArray()) {
       
  3445             m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3446             return false;
       
  3447         }
       
  3448         break;
       
  3449     default:
       
  3450         ASSERT_NOT_REACHED();
       
  3451     }
       
  3452 
       
  3453     unsigned long componentsPerPixel, bytesPerComponent;
       
  3454     if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
       
  3455         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3456         return false;
       
  3457     }
       
  3458 
       
  3459     if (!width || !height)
       
  3460         return true;
       
  3461     unsigned int validRowBytes = width * componentsPerPixel * bytesPerComponent;
       
  3462     unsigned int totalRowBytes = validRowBytes;
       
  3463     unsigned int remainder = validRowBytes % m_unpackAlignment;
       
  3464     if (remainder)
       
  3465         totalRowBytes += (m_unpackAlignment - remainder);
       
  3466     unsigned int totalBytesRequired = (height - 1) * totalRowBytes + validRowBytes;
       
  3467     if (pixels->byteLength() < totalBytesRequired) {
       
  3468         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3469         return false;
       
  3470     }
       
  3471     return true;
       
  3472 }
       
  3473 
       
  3474 bool WebGLRenderingContext::validateDrawMode(unsigned long mode)
       
  3475 {
       
  3476     switch (mode) {
       
  3477     case GraphicsContext3D::POINTS:
       
  3478     case GraphicsContext3D::LINE_STRIP:
       
  3479     case GraphicsContext3D::LINE_LOOP:
       
  3480     case GraphicsContext3D::LINES:
       
  3481     case GraphicsContext3D::TRIANGLE_STRIP:
       
  3482     case GraphicsContext3D::TRIANGLE_FAN:
       
  3483     case GraphicsContext3D::TRIANGLES:
       
  3484         return true;
       
  3485     default:
       
  3486         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3487         return false;
       
  3488     }
       
  3489 }
       
  3490 
       
  3491 void WebGLRenderingContext::printWarningToConsole(const String& message)
       
  3492 {
       
  3493     canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel,
       
  3494                                                                       message, 0, canvas()->document()->url().string());
       
  3495 }
       
  3496 
       
  3497 bool WebGLRenderingContext::validateFramebufferFuncParameters(unsigned long target, unsigned long attachment)
       
  3498 {
       
  3499     if (target != GraphicsContext3D::FRAMEBUFFER) {
       
  3500         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3501         return false;
       
  3502     }
       
  3503     switch (attachment) {
       
  3504     case GraphicsContext3D::COLOR_ATTACHMENT0:
       
  3505     case GraphicsContext3D::DEPTH_ATTACHMENT:
       
  3506     case GraphicsContext3D::STENCIL_ATTACHMENT:
       
  3507     case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
       
  3508         break;
       
  3509     default:
       
  3510         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3511         return false;
       
  3512     }
       
  3513     return true;
       
  3514 }
       
  3515 
       
  3516 bool WebGLRenderingContext::validateBlendEquation(unsigned long mode)
       
  3517 {
       
  3518     switch (mode) {
       
  3519     case GraphicsContext3D::FUNC_ADD:
       
  3520     case GraphicsContext3D::FUNC_SUBTRACT:
       
  3521     case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
       
  3522         return true;
       
  3523     default:
       
  3524         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3525         return false;
       
  3526     }
       
  3527 }
       
  3528 
       
  3529 bool WebGLRenderingContext::validateCapability(unsigned long cap)
       
  3530 {
       
  3531     switch (cap) {
       
  3532     case GraphicsContext3D::BLEND:
       
  3533     case GraphicsContext3D::CULL_FACE:
       
  3534     case GraphicsContext3D::DEPTH_TEST:
       
  3535     case GraphicsContext3D::DITHER:
       
  3536     case GraphicsContext3D::POLYGON_OFFSET_FILL:
       
  3537     case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
       
  3538     case GraphicsContext3D::SAMPLE_COVERAGE:
       
  3539     case GraphicsContext3D::SCISSOR_TEST:
       
  3540     case GraphicsContext3D::STENCIL_TEST:
       
  3541         return true;
       
  3542     default:
       
  3543         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3544         return false;
       
  3545     }
       
  3546 }
       
  3547 
       
  3548 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, int requiredMinSize)
       
  3549 {
       
  3550     if (!v) {
       
  3551         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3552         return false;
       
  3553     }
       
  3554     return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
       
  3555 }
       
  3556 
       
  3557 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, int requiredMinSize)
       
  3558 {
       
  3559     if (!v) {
       
  3560         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3561         return false;
       
  3562     }
       
  3563     return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
       
  3564 }
       
  3565 
       
  3566 bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, int size, int requiredMinSize)
       
  3567 {
       
  3568     return validateUniformMatrixParameters(location, false, v, size, requiredMinSize);
       
  3569 }
       
  3570 
       
  3571 bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, Float32Array* v, int requiredMinSize)
       
  3572 {
       
  3573     if (!v) {
       
  3574         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3575         return false;
       
  3576     }
       
  3577     return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize);
       
  3578 }
       
  3579 
       
  3580 bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, bool transpose, void* v, int size, int requiredMinSize)
       
  3581 {
       
  3582     if (!location)
       
  3583         return false;
       
  3584     if (location->program() != m_currentProgram) {
       
  3585         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3586         return false;
       
  3587     }
       
  3588     if (!v) {
       
  3589         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3590         return false;
       
  3591     }
       
  3592     if (transpose) {
       
  3593         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3594         return false;
       
  3595     }
       
  3596     if (size < requiredMinSize) {
       
  3597         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3598         return false;
       
  3599     }
       
  3600     return true;
       
  3601 }
       
  3602 
       
  3603 WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(unsigned long target, unsigned long usage)
       
  3604 {
       
  3605     WebGLBuffer* buffer = 0;
       
  3606     switch (target) {
       
  3607     case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
       
  3608         buffer = m_boundElementArrayBuffer.get();
       
  3609         break;
       
  3610     case GraphicsContext3D::ARRAY_BUFFER:
       
  3611         buffer = m_boundArrayBuffer.get();
       
  3612         break;
       
  3613     default:
       
  3614         m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3615         return 0;
       
  3616     }
       
  3617     if (!buffer) {
       
  3618         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
       
  3619         return 0;
       
  3620     }
       
  3621     switch (usage) {
       
  3622     case GraphicsContext3D::STREAM_DRAW:
       
  3623     case GraphicsContext3D::STATIC_DRAW:
       
  3624     case GraphicsContext3D::DYNAMIC_DRAW:
       
  3625         return buffer;
       
  3626     }
       
  3627     m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
       
  3628     return 0;
       
  3629 }
       
  3630 
       
  3631 void WebGLRenderingContext::vertexAttribfImpl(unsigned long index, int expectedSize, float v0, float v1, float v2, float v3)
       
  3632 {
       
  3633     if (index >= m_maxVertexAttribs) {
       
  3634         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3635         return;
       
  3636     }
       
  3637     // In GL, we skip setting vertexAttrib0 values.
       
  3638     if (index || isGLES2Compliant()) {
       
  3639         switch (expectedSize) {
       
  3640         case 1:
       
  3641             m_context->vertexAttrib1f(index, v0);
       
  3642             break;
       
  3643         case 2:
       
  3644             m_context->vertexAttrib2f(index, v0, v1);
       
  3645             break;
       
  3646         case 3:
       
  3647             m_context->vertexAttrib3f(index, v0, v1, v2);
       
  3648             break;
       
  3649         case 4:
       
  3650             m_context->vertexAttrib4f(index, v0, v1, v2, v3);
       
  3651             break;
       
  3652         }
       
  3653         cleanupAfterGraphicsCall(false);
       
  3654     }
       
  3655     if (index >= m_vertexAttribState.size())
       
  3656         m_vertexAttribState.resize(index + 1);
       
  3657     m_vertexAttribState[index].value[0] = v0;
       
  3658     m_vertexAttribState[index].value[1] = v1;
       
  3659     m_vertexAttribState[index].value[2] = v2;
       
  3660     m_vertexAttribState[index].value[3] = v3;
       
  3661 }
       
  3662 
       
  3663 void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, Float32Array* v, int expectedSize)
       
  3664 {
       
  3665     if (!v) {
       
  3666         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3667         return;
       
  3668     }
       
  3669     vertexAttribfvImpl(index, v->data(), v->length(), expectedSize);
       
  3670 }
       
  3671 
       
  3672 void WebGLRenderingContext::vertexAttribfvImpl(unsigned long index, float* v, int size, int expectedSize)
       
  3673 {
       
  3674     if (!v) {
       
  3675         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3676         return;
       
  3677     }
       
  3678     if (size < expectedSize) {
       
  3679         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3680         return;
       
  3681     }
       
  3682     if (index >= m_maxVertexAttribs) {
       
  3683         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
       
  3684         return;
       
  3685     }
       
  3686     // In GL, we skip setting vertexAttrib0 values.
       
  3687     if (index || isGLES2Compliant()) {
       
  3688         switch (expectedSize) {
       
  3689         case 1:
       
  3690             m_context->vertexAttrib1fv(index, v);
       
  3691             break;
       
  3692         case 2:
       
  3693             m_context->vertexAttrib2fv(index, v);
       
  3694             break;
       
  3695         case 3:
       
  3696             m_context->vertexAttrib3fv(index, v);
       
  3697             break;
       
  3698         case 4:
       
  3699             m_context->vertexAttrib4fv(index, v);
       
  3700             break;
       
  3701         }
       
  3702         cleanupAfterGraphicsCall(false);
       
  3703     }
       
  3704     if (index >= m_vertexAttribState.size())
       
  3705         m_vertexAttribState.resize(index + 1);
       
  3706     m_vertexAttribState[index].initValue();
       
  3707     for (int ii = 0; ii < expectedSize; ++ii)
       
  3708         m_vertexAttribState[index].value[ii] = v[ii];
       
  3709 }
       
  3710 
       
  3711 void WebGLRenderingContext::initVertexAttrib0()
       
  3712 {
       
  3713     m_vertexAttribState.resize(1);
       
  3714     m_vertexAttrib0Buffer = createBuffer();
       
  3715     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer.get());
       
  3716     m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, 0, GraphicsContext3D::DYNAMIC_DRAW);
       
  3717     m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
       
  3718     m_vertexAttribState[0].bufferBinding = m_vertexAttrib0Buffer;
       
  3719     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
       
  3720     m_context->enableVertexAttribArray(0);
       
  3721     m_vertexAttrib0BufferSize = 0;
       
  3722     m_vertexAttrib0BufferValue[0] = 0.0f;
       
  3723     m_vertexAttrib0BufferValue[1] = 0.0f;
       
  3724     m_vertexAttrib0BufferValue[2] = 0.0f;
       
  3725     m_vertexAttrib0BufferValue[3] = 1.0f;
       
  3726 }
       
  3727 
       
  3728 bool WebGLRenderingContext::simulateVertexAttrib0(long numVertex)
       
  3729 {
       
  3730     const VertexAttribState& state = m_vertexAttribState[0];
       
  3731     if (state.enabled || !m_currentProgram || !m_currentProgram->object()
       
  3732         || !m_currentProgram->isUsingVertexAttrib0())
       
  3733         return false;
       
  3734     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexAttrib0Buffer.get());
       
  3735     long bufferDataSize = (numVertex + 1) * 4 * sizeof(float);
       
  3736     if (bufferDataSize > m_vertexAttrib0BufferSize
       
  3737         || state.value[0] != m_vertexAttrib0BufferValue[0]
       
  3738         || state.value[1] != m_vertexAttrib0BufferValue[1]
       
  3739         || state.value[2] != m_vertexAttrib0BufferValue[2]
       
  3740         || state.value[3] != m_vertexAttrib0BufferValue[3]) {
       
  3741         RefPtr<Float32Array> bufferData = Float32Array::create((numVertex + 1) * 4);
       
  3742         for (long ii = 0; ii < numVertex + 1; ++ii) {
       
  3743             bufferData->set(ii * 4, state.value[0]);
       
  3744             bufferData->set(ii * 4 + 1, state.value[1]);
       
  3745             bufferData->set(ii * 4 + 2, state.value[2]);
       
  3746             bufferData->set(ii * 4 + 3, state.value[3]);
       
  3747         }
       
  3748         m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, bufferData.get(), GraphicsContext3D::DYNAMIC_DRAW);
       
  3749         m_vertexAttrib0BufferSize = bufferDataSize;
       
  3750         m_vertexAttrib0BufferValue[0] = state.value[0];
       
  3751         m_vertexAttrib0BufferValue[1] = state.value[1];
       
  3752         m_vertexAttrib0BufferValue[2] = state.value[2];
       
  3753         m_vertexAttrib0BufferValue[3] = state.value[3];
       
  3754     }
       
  3755     m_context->vertexAttribPointer(0, 4, GraphicsContext3D::FLOAT, false, 0, 0);
       
  3756     return true;
       
  3757 }
       
  3758 
       
  3759 void WebGLRenderingContext::restoreStatesAfterVertexAttrib0Simulation()
       
  3760 {
       
  3761     const VertexAttribState& state = m_vertexAttribState[0];
       
  3762     if (state.bufferBinding != m_vertexAttrib0Buffer) {
       
  3763         m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, state.bufferBinding.get());
       
  3764         m_context->vertexAttribPointer(0, state.size, state.type, state.normalized, state.originalStride, state.offset);
       
  3765     }
       
  3766     m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_boundArrayBuffer.get());
       
  3767 }
       
  3768 
       
  3769 } // namespace WebCore
       
  3770 
       
  3771 #endif // ENABLE(3D_CANVAS)