Home | History | Annotate | Download | only in libGLESv2
      1 //
      2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
      8 
      9 #define GL_APICALL
     10 #include <GLES2/gl2.h>
     11 #include <GLES2/gl2ext.h>
     12 
     13 #include <exception>
     14 #include <limits>
     15 
     16 #include "common/debug.h"
     17 
     18 #include "libGLESv2/main.h"
     19 #include "libGLESv2/mathutil.h"
     20 #include "libGLESv2/utilities.h"
     21 #include "libGLESv2/Buffer.h"
     22 #include "libGLESv2/Context.h"
     23 #include "libGLESv2/Fence.h"
     24 #include "libGLESv2/Framebuffer.h"
     25 #include "libGLESv2/Program.h"
     26 #include "libGLESv2/Renderbuffer.h"
     27 #include "libGLESv2/Shader.h"
     28 #include "libGLESv2/Texture.h"
     29 
     30 extern "C"
     31 {
     32 
     33 void __stdcall glActiveTexture(GLenum texture)
     34 {
     35     TRACE("(GLenum texture = 0x%X)", texture);
     36 
     37     try
     38     {
     39         if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
     40         {
     41             return error(GL_INVALID_ENUM);
     42         }
     43 
     44         gl::Context *context = gl::getContext();
     45 
     46         if (context)
     47         {
     48             context->setActiveSampler(texture - GL_TEXTURE0);
     49         }
     50     }
     51     catch(std::bad_alloc&)
     52     {
     53         return error(GL_OUT_OF_MEMORY);
     54     }
     55 }
     56 
     57 void __stdcall glAttachShader(GLuint program, GLuint shader)
     58 {
     59     TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
     60 
     61     try
     62     {
     63         gl::Context *context = gl::getContext();
     64 
     65         if (context)
     66         {
     67             gl::Program *programObject = context->getProgram(program);
     68             gl::Shader *shaderObject = context->getShader(shader);
     69 
     70             if (!programObject)
     71             {
     72                 if (context->getShader(program))
     73                 {
     74                     return error(GL_INVALID_OPERATION);
     75                 }
     76                 else
     77                 {
     78                     return error(GL_INVALID_VALUE);
     79                 }
     80             }
     81 
     82             if (!shaderObject)
     83             {
     84                 if (context->getProgram(shader))
     85                 {
     86                     return error(GL_INVALID_OPERATION);
     87                 }
     88                 else
     89                 {
     90                     return error(GL_INVALID_VALUE);
     91                 }
     92             }
     93 
     94             if (!programObject->attachShader(shaderObject))
     95             {
     96                 return error(GL_INVALID_OPERATION);
     97             }
     98         }
     99     }
    100     catch(std::bad_alloc&)
    101     {
    102         return error(GL_OUT_OF_MEMORY);
    103     }
    104 }
    105 
    106 void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
    107 {
    108     TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
    109 
    110     try
    111     {
    112         if (index >= gl::MAX_VERTEX_ATTRIBS)
    113         {
    114             return error(GL_INVALID_VALUE);
    115         }
    116 
    117         gl::Context *context = gl::getContext();
    118 
    119         if (context)
    120         {
    121             gl::Program *programObject = context->getProgram(program);
    122 
    123             if (!programObject)
    124             {
    125                 if (context->getShader(program))
    126                 {
    127                     return error(GL_INVALID_OPERATION);
    128                 }
    129                 else
    130                 {
    131                     return error(GL_INVALID_VALUE);
    132                 }
    133             }
    134 
    135             if (strncmp(name, "gl_", 3) == 0)
    136             {
    137                 return error(GL_INVALID_OPERATION);
    138             }
    139 
    140             programObject->bindAttributeLocation(index, name);
    141         }
    142     }
    143     catch(std::bad_alloc&)
    144     {
    145         return error(GL_OUT_OF_MEMORY);
    146     }
    147 }
    148 
    149 void __stdcall glBindBuffer(GLenum target, GLuint buffer)
    150 {
    151     TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
    152 
    153     try
    154     {
    155         gl::Context *context = gl::getContext();
    156 
    157         if (context)
    158         {
    159             switch (target)
    160             {
    161               case GL_ARRAY_BUFFER:
    162                 context->bindArrayBuffer(buffer);
    163                 return;
    164               case GL_ELEMENT_ARRAY_BUFFER:
    165                 context->bindElementArrayBuffer(buffer);
    166                 return;
    167               default:
    168                 return error(GL_INVALID_ENUM);
    169             }
    170         }
    171     }
    172     catch(std::bad_alloc&)
    173     {
    174         return error(GL_OUT_OF_MEMORY);
    175     }
    176 }
    177 
    178 void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
    179 {
    180     TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
    181 
    182     try
    183     {
    184         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
    185         {
    186             return error(GL_INVALID_ENUM);
    187         }
    188 
    189         gl::Context *context = gl::getContext();
    190 
    191         if (context)
    192         {
    193             if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
    194             {
    195                 context->bindReadFramebuffer(framebuffer);
    196             }
    197 
    198             if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
    199             {
    200                 context->bindDrawFramebuffer(framebuffer);
    201             }
    202         }
    203     }
    204     catch(std::bad_alloc&)
    205     {
    206         return error(GL_OUT_OF_MEMORY);
    207     }
    208 }
    209 
    210 void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
    211 {
    212     TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
    213 
    214     try
    215     {
    216         if (target != GL_RENDERBUFFER)
    217         {
    218             return error(GL_INVALID_ENUM);
    219         }
    220 
    221         gl::Context *context = gl::getContext();
    222 
    223         if (context)
    224         {
    225             context->bindRenderbuffer(renderbuffer);
    226         }
    227     }
    228     catch(std::bad_alloc&)
    229     {
    230         return error(GL_OUT_OF_MEMORY);
    231     }
    232 }
    233 
    234 void __stdcall glBindTexture(GLenum target, GLuint texture)
    235 {
    236     TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
    237 
    238     try
    239     {
    240         gl::Context *context = gl::getContext();
    241 
    242         if (context)
    243         {
    244             gl::Texture *textureObject = context->getTexture(texture);
    245 
    246             if (textureObject && textureObject->getTarget() != target && texture != 0)
    247             {
    248                 return error(GL_INVALID_OPERATION);
    249             }
    250 
    251             switch (target)
    252             {
    253               case GL_TEXTURE_2D:
    254                 context->bindTexture2D(texture);
    255                 return;
    256               case GL_TEXTURE_CUBE_MAP:
    257                 context->bindTextureCubeMap(texture);
    258                 return;
    259               default:
    260                 return error(GL_INVALID_ENUM);
    261             }
    262         }
    263     }
    264     catch(std::bad_alloc&)
    265     {
    266         return error(GL_OUT_OF_MEMORY);
    267     }
    268 }
    269 
    270 void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
    271 {
    272     TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
    273           red, green, blue, alpha);
    274 
    275     try
    276     {
    277         gl::Context* context = gl::getContext();
    278 
    279         if (context)
    280         {
    281             context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
    282         }
    283     }
    284     catch(std::bad_alloc&)
    285     {
    286         return error(GL_OUT_OF_MEMORY);
    287     }
    288 }
    289 
    290 void __stdcall glBlendEquation(GLenum mode)
    291 {
    292     glBlendEquationSeparate(mode, mode);
    293 }
    294 
    295 void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
    296 {
    297     TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
    298 
    299     try
    300     {
    301         switch (modeRGB)
    302         {
    303           case GL_FUNC_ADD:
    304           case GL_FUNC_SUBTRACT:
    305           case GL_FUNC_REVERSE_SUBTRACT:
    306             break;
    307           default:
    308             return error(GL_INVALID_ENUM);
    309         }
    310 
    311         switch (modeAlpha)
    312         {
    313           case GL_FUNC_ADD:
    314           case GL_FUNC_SUBTRACT:
    315           case GL_FUNC_REVERSE_SUBTRACT:
    316             break;
    317           default:
    318             return error(GL_INVALID_ENUM);
    319         }
    320 
    321         gl::Context *context = gl::getContext();
    322 
    323         if (context)
    324         {
    325             context->setBlendEquation(modeRGB, modeAlpha);
    326         }
    327     }
    328     catch(std::bad_alloc&)
    329     {
    330         return error(GL_OUT_OF_MEMORY);
    331     }
    332 }
    333 
    334 void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
    335 {
    336     glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
    337 }
    338 
    339 void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
    340 {
    341     TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
    342           srcRGB, dstRGB, srcAlpha, dstAlpha);
    343 
    344     try
    345     {
    346         switch (srcRGB)
    347         {
    348           case GL_ZERO:
    349           case GL_ONE:
    350           case GL_SRC_COLOR:
    351           case GL_ONE_MINUS_SRC_COLOR:
    352           case GL_DST_COLOR:
    353           case GL_ONE_MINUS_DST_COLOR:
    354           case GL_SRC_ALPHA:
    355           case GL_ONE_MINUS_SRC_ALPHA:
    356           case GL_DST_ALPHA:
    357           case GL_ONE_MINUS_DST_ALPHA:
    358           case GL_CONSTANT_COLOR:
    359           case GL_ONE_MINUS_CONSTANT_COLOR:
    360           case GL_CONSTANT_ALPHA:
    361           case GL_ONE_MINUS_CONSTANT_ALPHA:
    362           case GL_SRC_ALPHA_SATURATE:
    363             break;
    364           default:
    365             return error(GL_INVALID_ENUM);
    366         }
    367 
    368         switch (dstRGB)
    369         {
    370           case GL_ZERO:
    371           case GL_ONE:
    372           case GL_SRC_COLOR:
    373           case GL_ONE_MINUS_SRC_COLOR:
    374           case GL_DST_COLOR:
    375           case GL_ONE_MINUS_DST_COLOR:
    376           case GL_SRC_ALPHA:
    377           case GL_ONE_MINUS_SRC_ALPHA:
    378           case GL_DST_ALPHA:
    379           case GL_ONE_MINUS_DST_ALPHA:
    380           case GL_CONSTANT_COLOR:
    381           case GL_ONE_MINUS_CONSTANT_COLOR:
    382           case GL_CONSTANT_ALPHA:
    383           case GL_ONE_MINUS_CONSTANT_ALPHA:
    384             break;
    385           default:
    386             return error(GL_INVALID_ENUM);
    387         }
    388 
    389         switch (srcAlpha)
    390         {
    391           case GL_ZERO:
    392           case GL_ONE:
    393           case GL_SRC_COLOR:
    394           case GL_ONE_MINUS_SRC_COLOR:
    395           case GL_DST_COLOR:
    396           case GL_ONE_MINUS_DST_COLOR:
    397           case GL_SRC_ALPHA:
    398           case GL_ONE_MINUS_SRC_ALPHA:
    399           case GL_DST_ALPHA:
    400           case GL_ONE_MINUS_DST_ALPHA:
    401           case GL_CONSTANT_COLOR:
    402           case GL_ONE_MINUS_CONSTANT_COLOR:
    403           case GL_CONSTANT_ALPHA:
    404           case GL_ONE_MINUS_CONSTANT_ALPHA:
    405           case GL_SRC_ALPHA_SATURATE:
    406             break;
    407           default:
    408             return error(GL_INVALID_ENUM);
    409         }
    410 
    411         switch (dstAlpha)
    412         {
    413           case GL_ZERO:
    414           case GL_ONE:
    415           case GL_SRC_COLOR:
    416           case GL_ONE_MINUS_SRC_COLOR:
    417           case GL_DST_COLOR:
    418           case GL_ONE_MINUS_DST_COLOR:
    419           case GL_SRC_ALPHA:
    420           case GL_ONE_MINUS_SRC_ALPHA:
    421           case GL_DST_ALPHA:
    422           case GL_ONE_MINUS_DST_ALPHA:
    423           case GL_CONSTANT_COLOR:
    424           case GL_ONE_MINUS_CONSTANT_COLOR:
    425           case GL_CONSTANT_ALPHA:
    426           case GL_ONE_MINUS_CONSTANT_ALPHA:
    427             break;
    428           default:
    429             return error(GL_INVALID_ENUM);
    430         }
    431 
    432         bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
    433                                   dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
    434 
    435         bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
    436                                   dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
    437 
    438         if (constantColorUsed && constantAlphaUsed)
    439         {
    440             ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
    441             return error(GL_INVALID_OPERATION);
    442         }
    443 
    444         gl::Context *context = gl::getContext();
    445 
    446         if (context)
    447         {
    448             context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
    449         }
    450     }
    451     catch(std::bad_alloc&)
    452     {
    453         return error(GL_OUT_OF_MEMORY);
    454     }
    455 }
    456 
    457 void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
    458 {
    459     TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
    460           target, size, data, usage);
    461 
    462     try
    463     {
    464         if (size < 0)
    465         {
    466             return error(GL_INVALID_VALUE);
    467         }
    468 
    469         switch (usage)
    470         {
    471           case GL_STREAM_DRAW:
    472           case GL_STATIC_DRAW:
    473           case GL_DYNAMIC_DRAW:
    474             break;
    475           default:
    476             return error(GL_INVALID_ENUM);
    477         }
    478 
    479         gl::Context *context = gl::getContext();
    480 
    481         if (context)
    482         {
    483             gl::Buffer *buffer;
    484 
    485             switch (target)
    486             {
    487               case GL_ARRAY_BUFFER:
    488                 buffer = context->getArrayBuffer();
    489                 break;
    490               case GL_ELEMENT_ARRAY_BUFFER:
    491                 buffer = context->getElementArrayBuffer();
    492                 break;
    493               default:
    494                 return error(GL_INVALID_ENUM);
    495             }
    496 
    497             if (!buffer)
    498             {
    499                 return error(GL_INVALID_OPERATION);
    500             }
    501 
    502             buffer->bufferData(data, size, usage);
    503         }
    504     }
    505     catch(std::bad_alloc&)
    506     {
    507         return error(GL_OUT_OF_MEMORY);
    508     }
    509 }
    510 
    511 void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
    512 {
    513     TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
    514           target, offset, size, data);
    515 
    516     try
    517     {
    518         if (size < 0 || offset < 0)
    519         {
    520             return error(GL_INVALID_VALUE);
    521         }
    522 
    523         if (data == NULL)
    524         {
    525             return;
    526         }
    527 
    528         gl::Context *context = gl::getContext();
    529 
    530         if (context)
    531         {
    532             gl::Buffer *buffer;
    533 
    534             switch (target)
    535             {
    536               case GL_ARRAY_BUFFER:
    537                 buffer = context->getArrayBuffer();
    538                 break;
    539               case GL_ELEMENT_ARRAY_BUFFER:
    540                 buffer = context->getElementArrayBuffer();
    541                 break;
    542               default:
    543                 return error(GL_INVALID_ENUM);
    544             }
    545 
    546             if (!buffer)
    547             {
    548                 return error(GL_INVALID_OPERATION);
    549             }
    550 
    551             if ((size_t)size + offset > buffer->size())
    552             {
    553                 return error(GL_INVALID_VALUE);
    554             }
    555 
    556             buffer->bufferSubData(data, size, offset);
    557         }
    558     }
    559     catch(std::bad_alloc&)
    560     {
    561         return error(GL_OUT_OF_MEMORY);
    562     }
    563 }
    564 
    565 GLenum __stdcall glCheckFramebufferStatus(GLenum target)
    566 {
    567     TRACE("(GLenum target = 0x%X)", target);
    568 
    569     try
    570     {
    571         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
    572         {
    573             return error(GL_INVALID_ENUM, 0);
    574         }
    575 
    576         gl::Context *context = gl::getContext();
    577 
    578         if (context)
    579         {
    580             gl::Framebuffer *framebuffer = NULL;
    581             if (target == GL_READ_FRAMEBUFFER_ANGLE)
    582             {
    583                 framebuffer = context->getReadFramebuffer();
    584             }
    585             else
    586             {
    587                 framebuffer = context->getDrawFramebuffer();
    588             }
    589 
    590             return framebuffer->completeness();
    591         }
    592     }
    593     catch(std::bad_alloc&)
    594     {
    595         return error(GL_OUT_OF_MEMORY, 0);
    596     }
    597 
    598     return 0;
    599 }
    600 
    601 void __stdcall glClear(GLbitfield mask)
    602 {
    603     TRACE("(GLbitfield mask = %X)", mask);
    604 
    605     try
    606     {
    607         gl::Context *context = gl::getContext();
    608 
    609         if (context)
    610         {
    611             context->clear(mask);
    612         }
    613     }
    614     catch(std::bad_alloc&)
    615     {
    616         return error(GL_OUT_OF_MEMORY);
    617     }
    618 }
    619 
    620 void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
    621 {
    622     TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
    623           red, green, blue, alpha);
    624 
    625     try
    626     {
    627         gl::Context *context = gl::getContext();
    628 
    629         if (context)
    630         {
    631             context->setClearColor(red, green, blue, alpha);
    632         }
    633     }
    634     catch(std::bad_alloc&)
    635     {
    636         return error(GL_OUT_OF_MEMORY);
    637     }
    638 }
    639 
    640 void __stdcall glClearDepthf(GLclampf depth)
    641 {
    642     TRACE("(GLclampf depth = %f)", depth);
    643 
    644     try
    645     {
    646         gl::Context *context = gl::getContext();
    647 
    648         if (context)
    649         {
    650             context->setClearDepth(depth);
    651         }
    652     }
    653     catch(std::bad_alloc&)
    654     {
    655         return error(GL_OUT_OF_MEMORY);
    656     }
    657 }
    658 
    659 void __stdcall glClearStencil(GLint s)
    660 {
    661     TRACE("(GLint s = %d)", s);
    662 
    663     try
    664     {
    665         gl::Context *context = gl::getContext();
    666 
    667         if (context)
    668         {
    669             context->setClearStencil(s);
    670         }
    671     }
    672     catch(std::bad_alloc&)
    673     {
    674         return error(GL_OUT_OF_MEMORY);
    675     }
    676 }
    677 
    678 void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
    679 {
    680     TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
    681           red, green, blue, alpha);
    682 
    683     try
    684     {
    685         gl::Context *context = gl::getContext();
    686 
    687         if (context)
    688         {
    689             context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
    690         }
    691     }
    692     catch(std::bad_alloc&)
    693     {
    694         return error(GL_OUT_OF_MEMORY);
    695     }
    696 }
    697 
    698 void __stdcall glCompileShader(GLuint shader)
    699 {
    700     TRACE("(GLuint shader = %d)", shader);
    701 
    702     try
    703     {
    704         gl::Context *context = gl::getContext();
    705 
    706         if (context)
    707         {
    708             gl::Shader *shaderObject = context->getShader(shader);
    709 
    710             if (!shaderObject)
    711             {
    712                 if (context->getProgram(shader))
    713                 {
    714                     return error(GL_INVALID_OPERATION);
    715                 }
    716                 else
    717                 {
    718                     return error(GL_INVALID_VALUE);
    719                 }
    720             }
    721 
    722             shaderObject->compile();
    723         }
    724     }
    725     catch(std::bad_alloc&)
    726     {
    727         return error(GL_OUT_OF_MEMORY);
    728     }
    729 }
    730 
    731 void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
    732                                       GLint border, GLsizei imageSize, const GLvoid* data)
    733 {
    734     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
    735           "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
    736           target, level, internalformat, width, height, border, imageSize, data);
    737 
    738     try
    739     {
    740         if (level < 0)
    741         {
    742             return error(GL_INVALID_VALUE);
    743         }
    744 
    745         if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
    746         {
    747             return error(GL_INVALID_VALUE);
    748         }
    749 
    750         switch (internalformat)
    751         {
    752           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    753           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    754             break;
    755           default:
    756             return error(GL_INVALID_ENUM);
    757         }
    758 
    759         if (border != 0)
    760         {
    761             return error(GL_INVALID_VALUE);
    762         }
    763 
    764         gl::Context *context = gl::getContext();
    765 
    766         if (context)
    767         {
    768             if (level > context->getMaximumTextureLevel())
    769             {
    770                 return error(GL_INVALID_VALUE);
    771             }
    772 
    773             switch (target)
    774             {
    775               case GL_TEXTURE_2D:
    776                 if (width > (context->getMaximumTextureDimension() >> level) ||
    777                     height > (context->getMaximumTextureDimension() >> level))
    778                 {
    779                     return error(GL_INVALID_VALUE);
    780                 }
    781                 break;
    782               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    783               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    784               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    785               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    786               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    787               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
    788                 if (width != height)
    789                 {
    790                     return error(GL_INVALID_VALUE);
    791                 }
    792 
    793                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
    794                     height > (context->getMaximumCubeTextureDimension() >> level))
    795                 {
    796                     return error(GL_INVALID_VALUE);
    797                 }
    798                 break;
    799               default:
    800                 return error(GL_INVALID_ENUM);
    801             }
    802 
    803             if (!context->supportsCompressedTextures())
    804             {
    805                 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
    806             }
    807 
    808             if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
    809             {
    810                 return error(GL_INVALID_VALUE);
    811             }
    812 
    813             if (target == GL_TEXTURE_2D)
    814             {
    815                 gl::Texture2D *texture = context->getTexture2D();
    816 
    817                 if (!texture)
    818                 {
    819                     return error(GL_INVALID_OPERATION);
    820                 }
    821 
    822                 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
    823             }
    824             else
    825             {
    826                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
    827 
    828                 if (!texture)
    829                 {
    830                     return error(GL_INVALID_OPERATION);
    831                 }
    832 
    833                 switch (target)
    834                 {
    835                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
    836                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    837                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    838                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    839                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    840                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
    841                     texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
    842                     break;
    843                   default: UNREACHABLE();
    844                 }
    845             }
    846         }
    847 
    848     }
    849     catch(std::bad_alloc&)
    850     {
    851         return error(GL_OUT_OF_MEMORY);
    852     }
    853 }
    854 
    855 void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
    856                                          GLenum format, GLsizei imageSize, const GLvoid* data)
    857 {
    858     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
    859           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
    860           "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
    861           target, level, xoffset, yoffset, width, height, format, imageSize, data);
    862 
    863     try
    864     {
    865         if (!gl::IsTextureTarget(target))
    866         {
    867             return error(GL_INVALID_ENUM);
    868         }
    869 
    870         if (level < 0)
    871         {
    872             return error(GL_INVALID_VALUE);
    873         }
    874 
    875         if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
    876             (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
    877         {
    878             return error(GL_INVALID_VALUE);
    879         }
    880 
    881         switch (format)
    882         {
    883           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    884           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    885             break;
    886           default:
    887             return error(GL_INVALID_ENUM);
    888         }
    889 
    890         if (width == 0 || height == 0 || data == NULL)
    891         {
    892             return;
    893         }
    894 
    895         gl::Context *context = gl::getContext();
    896 
    897         if (context)
    898         {
    899             if (level > context->getMaximumTextureLevel())
    900             {
    901                 return error(GL_INVALID_VALUE);
    902             }
    903 
    904             if (!context->supportsCompressedTextures())
    905             {
    906                 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
    907             }
    908 
    909             if (imageSize != gl::ComputeCompressedSize(width, height, format))
    910             {
    911                 return error(GL_INVALID_VALUE);
    912             }
    913 
    914             if (xoffset % 4 != 0 || yoffset % 4 != 0)
    915             {
    916                 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
    917                                                     // does not exist unless DXT1 textures are supported.
    918             }
    919 
    920             if (target == GL_TEXTURE_2D)
    921             {
    922                 gl::Texture2D *texture = context->getTexture2D();
    923 
    924                 if (!texture)
    925                 {
    926                     return error(GL_INVALID_OPERATION);
    927                 }
    928 
    929                 if (!texture->isCompressed())
    930                 {
    931                     return error(GL_INVALID_OPERATION);
    932                 }
    933 
    934                 if ((width % 4 != 0 && width != texture->getWidth()) ||
    935                     (height % 4 != 0 && height != texture->getHeight()))
    936                 {
    937                     return error(GL_INVALID_OPERATION);
    938                 }
    939 
    940                 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
    941             }
    942             else if (gl::IsCubemapTextureTarget(target))
    943             {
    944                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
    945 
    946                 if (!texture)
    947                 {
    948                     return error(GL_INVALID_OPERATION);
    949                 }
    950 
    951                 if (!texture->isCompressed())
    952                 {
    953                     return error(GL_INVALID_OPERATION);
    954                 }
    955 
    956                 if ((width % 4 != 0 && width != texture->getWidth()) ||
    957                     (height % 4 != 0 && height != texture->getHeight()))
    958                 {
    959                     return error(GL_INVALID_OPERATION);
    960                 }
    961 
    962                 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
    963             }
    964             else
    965             {
    966                 UNREACHABLE();
    967             }
    968         }
    969     }
    970     catch(std::bad_alloc&)
    971     {
    972         return error(GL_OUT_OF_MEMORY);
    973     }
    974 }
    975 
    976 void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
    977 {
    978     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
    979           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
    980           target, level, internalformat, x, y, width, height, border);
    981 
    982     try
    983     {
    984         if (level < 0 || width < 0 || height < 0)
    985         {
    986             return error(GL_INVALID_VALUE);
    987         }
    988 
    989         if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
    990         {
    991             return error(GL_INVALID_VALUE);
    992         }
    993 
    994         if (border != 0)
    995         {
    996             return error(GL_INVALID_VALUE);
    997         }
    998 
    999         gl::Context *context = gl::getContext();
   1000 
   1001         if (context)
   1002         {
   1003             switch (target)
   1004             {
   1005               case GL_TEXTURE_2D:
   1006                 if (width > (context->getMaximumTextureDimension() >> level) ||
   1007                     height > (context->getMaximumTextureDimension() >> level))
   1008                 {
   1009                     return error(GL_INVALID_VALUE);
   1010                 }
   1011                 break;
   1012               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   1013               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   1014               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   1015               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   1016               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   1017               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   1018                 if (width != height)
   1019                 {
   1020                     return error(GL_INVALID_VALUE);
   1021                 }
   1022 
   1023                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
   1024                     height > (context->getMaximumCubeTextureDimension() >> level))
   1025                 {
   1026                     return error(GL_INVALID_VALUE);
   1027                 }
   1028                 break;
   1029               default:
   1030                 return error(GL_INVALID_ENUM);
   1031             }
   1032 
   1033             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
   1034 
   1035             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1036             {
   1037                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
   1038             }
   1039 
   1040             if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
   1041             {
   1042                 return error(GL_INVALID_OPERATION);
   1043             }
   1044 
   1045             gl::Colorbuffer *source = framebuffer->getColorbuffer();
   1046             GLenum colorbufferFormat = source->getFormat();
   1047 
   1048             // [OpenGL ES 2.0.24] table 3.9
   1049             switch (internalformat)
   1050             {
   1051               case GL_ALPHA:
   1052                 if (colorbufferFormat != GL_ALPHA &&
   1053                     colorbufferFormat != GL_RGBA &&
   1054                     colorbufferFormat != GL_RGBA4 &&
   1055                     colorbufferFormat != GL_RGB5_A1 &&
   1056                     colorbufferFormat != GL_RGBA8_OES)
   1057                 {
   1058                     return error(GL_INVALID_OPERATION);
   1059                 }
   1060                 break;
   1061               case GL_LUMINANCE:
   1062               case GL_RGB:
   1063                 if (colorbufferFormat != GL_RGB &&
   1064                     colorbufferFormat != GL_RGB565 &&
   1065                     colorbufferFormat != GL_RGB8_OES &&
   1066                     colorbufferFormat != GL_RGBA &&
   1067                     colorbufferFormat != GL_RGBA4 &&
   1068                     colorbufferFormat != GL_RGB5_A1 &&
   1069                     colorbufferFormat != GL_RGBA8_OES)
   1070                 {
   1071                     return error(GL_INVALID_OPERATION);
   1072                 }
   1073                 break;
   1074               case GL_LUMINANCE_ALPHA:
   1075               case GL_RGBA:
   1076                 if (colorbufferFormat != GL_RGBA &&
   1077                     colorbufferFormat != GL_RGBA4 &&
   1078                     colorbufferFormat != GL_RGB5_A1 &&
   1079                     colorbufferFormat != GL_RGBA8_OES)
   1080                  {
   1081                      return error(GL_INVALID_OPERATION);
   1082                  }
   1083                  break;
   1084               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   1085               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
   1086                 if (context->supportsCompressedTextures())
   1087                 {
   1088                     return error(GL_INVALID_OPERATION);
   1089                 }
   1090                 else
   1091                 {
   1092                     return error(GL_INVALID_ENUM);
   1093                 }
   1094                 break;
   1095               default:
   1096                 return error(GL_INVALID_ENUM);
   1097             }
   1098 
   1099             if (target == GL_TEXTURE_2D)
   1100             {
   1101                 gl::Texture2D *texture = context->getTexture2D();
   1102 
   1103                 if (!texture)
   1104                 {
   1105                     return error(GL_INVALID_OPERATION);
   1106                 }
   1107 
   1108                 texture->copyImage(level, internalformat, x, y, width, height, source);
   1109             }
   1110             else if (gl::IsCubemapTextureTarget(target))
   1111             {
   1112                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
   1113 
   1114                 if (!texture)
   1115                 {
   1116                     return error(GL_INVALID_OPERATION);
   1117                 }
   1118 
   1119                 texture->copyImage(target, level, internalformat, x, y, width, height, source);
   1120             }
   1121             else UNREACHABLE();
   1122         }
   1123     }
   1124     catch(std::bad_alloc&)
   1125     {
   1126         return error(GL_OUT_OF_MEMORY);
   1127     }
   1128 }
   1129 
   1130 void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
   1131 {
   1132     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   1133           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
   1134           target, level, xoffset, yoffset, x, y, width, height);
   1135 
   1136     try
   1137     {
   1138         if (!gl::IsTextureTarget(target))
   1139         {
   1140             return error(GL_INVALID_ENUM);
   1141         }
   1142 
   1143         if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
   1144         {
   1145             return error(GL_INVALID_VALUE);
   1146         }
   1147 
   1148         if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
   1149         {
   1150             return error(GL_INVALID_VALUE);
   1151         }
   1152 
   1153         if (width == 0 || height == 0)
   1154         {
   1155             return;
   1156         }
   1157 
   1158         gl::Context *context = gl::getContext();
   1159 
   1160         if (context)
   1161         {
   1162             if (level > context->getMaximumTextureLevel())
   1163             {
   1164                 return error(GL_INVALID_VALUE);
   1165             }
   1166 
   1167             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
   1168 
   1169             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1170             {
   1171                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
   1172             }
   1173 
   1174             if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
   1175             {
   1176                 return error(GL_INVALID_OPERATION);
   1177             }
   1178 
   1179             gl::Colorbuffer *source = framebuffer->getColorbuffer();
   1180             GLenum colorbufferFormat = source->getFormat();
   1181             gl::Texture *texture = NULL;
   1182 
   1183             if (target == GL_TEXTURE_2D)
   1184             {
   1185                 texture = context->getTexture2D();
   1186             }
   1187             else if (gl::IsCubemapTextureTarget(target))
   1188             {
   1189                 texture = context->getTextureCubeMap();
   1190             }
   1191             else UNREACHABLE();
   1192 
   1193             if (!texture)
   1194             {
   1195                 return error(GL_INVALID_OPERATION);
   1196             }
   1197 
   1198             GLenum textureFormat = texture->getFormat();
   1199 
   1200             // [OpenGL ES 2.0.24] table 3.9
   1201             switch (textureFormat)
   1202             {
   1203               case GL_ALPHA:
   1204                 if (colorbufferFormat != GL_ALPHA &&
   1205                     colorbufferFormat != GL_RGBA &&
   1206                     colorbufferFormat != GL_RGBA4 &&
   1207                     colorbufferFormat != GL_RGB5_A1 &&
   1208                     colorbufferFormat != GL_RGBA8_OES)
   1209                 {
   1210                     return error(GL_INVALID_OPERATION);
   1211                 }
   1212                 break;
   1213               case GL_LUMINANCE:
   1214               case GL_RGB:
   1215                 if (colorbufferFormat != GL_RGB &&
   1216                     colorbufferFormat != GL_RGB565 &&
   1217                     colorbufferFormat != GL_RGB8_OES &&
   1218                     colorbufferFormat != GL_RGBA &&
   1219                     colorbufferFormat != GL_RGBA4 &&
   1220                     colorbufferFormat != GL_RGB5_A1 &&
   1221                     colorbufferFormat != GL_RGBA8_OES)
   1222                 {
   1223                     return error(GL_INVALID_OPERATION);
   1224                 }
   1225                 break;
   1226               case GL_LUMINANCE_ALPHA:
   1227               case GL_RGBA:
   1228                 if (colorbufferFormat != GL_RGBA &&
   1229                     colorbufferFormat != GL_RGBA4 &&
   1230                     colorbufferFormat != GL_RGB5_A1 &&
   1231                     colorbufferFormat != GL_RGBA8_OES)
   1232                 {
   1233                     return error(GL_INVALID_OPERATION);
   1234                 }
   1235                 break;
   1236               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   1237               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
   1238                 return error(GL_INVALID_OPERATION);
   1239               default:
   1240                 return error(GL_INVALID_OPERATION);
   1241             }
   1242 
   1243             texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
   1244         }
   1245     }
   1246 
   1247     catch(std::bad_alloc&)
   1248     {
   1249         return error(GL_OUT_OF_MEMORY);
   1250     }
   1251 }
   1252 
   1253 GLuint __stdcall glCreateProgram(void)
   1254 {
   1255     TRACE("()");
   1256 
   1257     try
   1258     {
   1259         gl::Context *context = gl::getContext();
   1260 
   1261         if (context)
   1262         {
   1263             return context->createProgram();
   1264         }
   1265     }
   1266     catch(std::bad_alloc&)
   1267     {
   1268         return error(GL_OUT_OF_MEMORY, 0);
   1269     }
   1270 
   1271     return 0;
   1272 }
   1273 
   1274 GLuint __stdcall glCreateShader(GLenum type)
   1275 {
   1276     TRACE("(GLenum type = 0x%X)", type);
   1277 
   1278     try
   1279     {
   1280         gl::Context *context = gl::getContext();
   1281 
   1282         if (context)
   1283         {
   1284             switch (type)
   1285             {
   1286               case GL_FRAGMENT_SHADER:
   1287               case GL_VERTEX_SHADER:
   1288                 return context->createShader(type);
   1289               default:
   1290                 return error(GL_INVALID_ENUM, 0);
   1291             }
   1292         }
   1293     }
   1294     catch(std::bad_alloc&)
   1295     {
   1296         return error(GL_OUT_OF_MEMORY, 0);
   1297     }
   1298 
   1299     return 0;
   1300 }
   1301 
   1302 void __stdcall glCullFace(GLenum mode)
   1303 {
   1304     TRACE("(GLenum mode = 0x%X)", mode);
   1305 
   1306     try
   1307     {
   1308         switch (mode)
   1309         {
   1310           case GL_FRONT:
   1311           case GL_BACK:
   1312           case GL_FRONT_AND_BACK:
   1313             {
   1314                 gl::Context *context = gl::getContext();
   1315 
   1316                 if (context)
   1317                 {
   1318                     context->setCullMode(mode);
   1319                 }
   1320             }
   1321             break;
   1322           default:
   1323             return error(GL_INVALID_ENUM);
   1324         }
   1325     }
   1326     catch(std::bad_alloc&)
   1327     {
   1328         return error(GL_OUT_OF_MEMORY);
   1329     }
   1330 }
   1331 
   1332 void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
   1333 {
   1334     TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
   1335 
   1336     try
   1337     {
   1338         if (n < 0)
   1339         {
   1340             return error(GL_INVALID_VALUE);
   1341         }
   1342 
   1343         gl::Context *context = gl::getContext();
   1344 
   1345         if (context)
   1346         {
   1347             for (int i = 0; i < n; i++)
   1348             {
   1349                 context->deleteBuffer(buffers[i]);
   1350             }
   1351         }
   1352     }
   1353     catch(std::bad_alloc&)
   1354     {
   1355         return error(GL_OUT_OF_MEMORY);
   1356     }
   1357 }
   1358 
   1359 void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
   1360 {
   1361     TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
   1362 
   1363     try
   1364     {
   1365         if (n < 0)
   1366         {
   1367             return error(GL_INVALID_VALUE);
   1368         }
   1369 
   1370         gl::Context *context = gl::getContext();
   1371 
   1372         if (context)
   1373         {
   1374             for (int i = 0; i < n; i++)
   1375             {
   1376                 context->deleteFence(fences[i]);
   1377             }
   1378         }
   1379     }
   1380     catch(std::bad_alloc&)
   1381     {
   1382         return error(GL_OUT_OF_MEMORY);
   1383     }
   1384 }
   1385 
   1386 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
   1387 {
   1388     TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
   1389 
   1390     try
   1391     {
   1392         if (n < 0)
   1393         {
   1394             return error(GL_INVALID_VALUE);
   1395         }
   1396 
   1397         gl::Context *context = gl::getContext();
   1398 
   1399         if (context)
   1400         {
   1401             for (int i = 0; i < n; i++)
   1402             {
   1403                 if (framebuffers[i] != 0)
   1404                 {
   1405                     context->deleteFramebuffer(framebuffers[i]);
   1406                 }
   1407             }
   1408         }
   1409     }
   1410     catch(std::bad_alloc&)
   1411     {
   1412         return error(GL_OUT_OF_MEMORY);
   1413     }
   1414 }
   1415 
   1416 void __stdcall glDeleteProgram(GLuint program)
   1417 {
   1418     TRACE("(GLuint program = %d)", program);
   1419 
   1420     try
   1421     {
   1422         if (program == 0)
   1423         {
   1424             return;
   1425         }
   1426 
   1427         gl::Context *context = gl::getContext();
   1428 
   1429         if (context)
   1430         {
   1431             if (!context->getProgram(program))
   1432             {
   1433                 if(context->getShader(program))
   1434                 {
   1435                     return error(GL_INVALID_OPERATION);
   1436                 }
   1437                 else
   1438                 {
   1439                     return error(GL_INVALID_VALUE);
   1440                 }
   1441             }
   1442 
   1443             context->deleteProgram(program);
   1444         }
   1445     }
   1446     catch(std::bad_alloc&)
   1447     {
   1448         return error(GL_OUT_OF_MEMORY);
   1449     }
   1450 }
   1451 
   1452 void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
   1453 {
   1454     TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
   1455 
   1456     try
   1457     {
   1458         if (n < 0)
   1459         {
   1460             return error(GL_INVALID_VALUE);
   1461         }
   1462 
   1463         gl::Context *context = gl::getContext();
   1464 
   1465         if (context)
   1466         {
   1467             for (int i = 0; i < n; i++)
   1468             {
   1469                 context->deleteRenderbuffer(renderbuffers[i]);
   1470             }
   1471         }
   1472     }
   1473     catch(std::bad_alloc&)
   1474     {
   1475         return error(GL_OUT_OF_MEMORY);
   1476     }
   1477 }
   1478 
   1479 void __stdcall glDeleteShader(GLuint shader)
   1480 {
   1481     TRACE("(GLuint shader = %d)", shader);
   1482 
   1483     try
   1484     {
   1485         if (shader == 0)
   1486         {
   1487             return;
   1488         }
   1489 
   1490         gl::Context *context = gl::getContext();
   1491 
   1492         if (context)
   1493         {
   1494             if (!context->getShader(shader))
   1495             {
   1496                 if(context->getProgram(shader))
   1497                 {
   1498                     return error(GL_INVALID_OPERATION);
   1499                 }
   1500                 else
   1501                 {
   1502                     return error(GL_INVALID_VALUE);
   1503                 }
   1504             }
   1505 
   1506             context->deleteShader(shader);
   1507         }
   1508     }
   1509     catch(std::bad_alloc&)
   1510     {
   1511         return error(GL_OUT_OF_MEMORY);
   1512     }
   1513 }
   1514 
   1515 void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
   1516 {
   1517     TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
   1518 
   1519     try
   1520     {
   1521         if (n < 0)
   1522         {
   1523             return error(GL_INVALID_VALUE);
   1524         }
   1525 
   1526         gl::Context *context = gl::getContext();
   1527 
   1528         if (context)
   1529         {
   1530             for (int i = 0; i < n; i++)
   1531             {
   1532                 if (textures[i] != 0)
   1533                 {
   1534                     context->deleteTexture(textures[i]);
   1535                 }
   1536             }
   1537         }
   1538     }
   1539     catch(std::bad_alloc&)
   1540     {
   1541         return error(GL_OUT_OF_MEMORY);
   1542     }
   1543 }
   1544 
   1545 void __stdcall glDepthFunc(GLenum func)
   1546 {
   1547     TRACE("(GLenum func = 0x%X)", func);
   1548 
   1549     try
   1550     {
   1551         switch (func)
   1552         {
   1553           case GL_NEVER:
   1554           case GL_ALWAYS:
   1555           case GL_LESS:
   1556           case GL_LEQUAL:
   1557           case GL_EQUAL:
   1558           case GL_GREATER:
   1559           case GL_GEQUAL:
   1560           case GL_NOTEQUAL:
   1561             break;
   1562           default:
   1563             return error(GL_INVALID_ENUM);
   1564         }
   1565 
   1566         gl::Context *context = gl::getContext();
   1567 
   1568         if (context)
   1569         {
   1570             context->setDepthFunc(func);
   1571         }
   1572     }
   1573     catch(std::bad_alloc&)
   1574     {
   1575         return error(GL_OUT_OF_MEMORY);
   1576     }
   1577 }
   1578 
   1579 void __stdcall glDepthMask(GLboolean flag)
   1580 {
   1581     TRACE("(GLboolean flag = %d)", flag);
   1582 
   1583     try
   1584     {
   1585         gl::Context *context = gl::getContext();
   1586 
   1587         if (context)
   1588         {
   1589             context->setDepthMask(flag != GL_FALSE);
   1590         }
   1591     }
   1592     catch(std::bad_alloc&)
   1593     {
   1594         return error(GL_OUT_OF_MEMORY);
   1595     }
   1596 }
   1597 
   1598 void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
   1599 {
   1600     TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
   1601 
   1602     try
   1603     {
   1604         gl::Context *context = gl::getContext();
   1605 
   1606         if (context)
   1607         {
   1608             context->setDepthRange(zNear, zFar);
   1609         }
   1610     }
   1611     catch(std::bad_alloc&)
   1612     {
   1613         return error(GL_OUT_OF_MEMORY);
   1614     }
   1615 }
   1616 
   1617 void __stdcall glDetachShader(GLuint program, GLuint shader)
   1618 {
   1619     TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
   1620 
   1621     try
   1622     {
   1623         gl::Context *context = gl::getContext();
   1624 
   1625         if (context)
   1626         {
   1627 
   1628             gl::Program *programObject = context->getProgram(program);
   1629             gl::Shader *shaderObject = context->getShader(shader);
   1630 
   1631             if (!programObject)
   1632             {
   1633                 gl::Shader *shaderByProgramHandle;
   1634                 shaderByProgramHandle = context->getShader(program);
   1635                 if (!shaderByProgramHandle)
   1636                 {
   1637                     return error(GL_INVALID_VALUE);
   1638                 }
   1639                 else
   1640                 {
   1641                     return error(GL_INVALID_OPERATION);
   1642                 }
   1643             }
   1644 
   1645             if (!shaderObject)
   1646             {
   1647                 gl::Program *programByShaderHandle = context->getProgram(shader);
   1648                 if (!programByShaderHandle)
   1649                 {
   1650                     return error(GL_INVALID_VALUE);
   1651                 }
   1652                 else
   1653                 {
   1654                     return error(GL_INVALID_OPERATION);
   1655                 }
   1656             }
   1657 
   1658             if (!programObject->detachShader(shaderObject))
   1659             {
   1660                 return error(GL_INVALID_OPERATION);
   1661             }
   1662         }
   1663     }
   1664     catch(std::bad_alloc&)
   1665     {
   1666         return error(GL_OUT_OF_MEMORY);
   1667     }
   1668 }
   1669 
   1670 void __stdcall glDisable(GLenum cap)
   1671 {
   1672     TRACE("(GLenum cap = 0x%X)", cap);
   1673 
   1674     try
   1675     {
   1676         gl::Context *context = gl::getContext();
   1677 
   1678         if (context)
   1679         {
   1680             switch (cap)
   1681             {
   1682               case GL_CULL_FACE:                context->setCullFace(false);              break;
   1683               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(false);     break;
   1684               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
   1685               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(false);        break;
   1686               case GL_SCISSOR_TEST:             context->setScissorTest(false);           break;
   1687               case GL_STENCIL_TEST:             context->setStencilTest(false);           break;
   1688               case GL_DEPTH_TEST:               context->setDepthTest(false);             break;
   1689               case GL_BLEND:                    context->setBlend(false);                 break;
   1690               case GL_DITHER:                   context->setDither(false);                break;
   1691               default:
   1692                 return error(GL_INVALID_ENUM);
   1693             }
   1694         }
   1695     }
   1696     catch(std::bad_alloc&)
   1697     {
   1698         return error(GL_OUT_OF_MEMORY);
   1699     }
   1700 }
   1701 
   1702 void __stdcall glDisableVertexAttribArray(GLuint index)
   1703 {
   1704     TRACE("(GLuint index = %d)", index);
   1705 
   1706     try
   1707     {
   1708         if (index >= gl::MAX_VERTEX_ATTRIBS)
   1709         {
   1710             return error(GL_INVALID_VALUE);
   1711         }
   1712 
   1713         gl::Context *context = gl::getContext();
   1714 
   1715         if (context)
   1716         {
   1717             context->setEnableVertexAttribArray(index, false);
   1718         }
   1719     }
   1720     catch(std::bad_alloc&)
   1721     {
   1722         return error(GL_OUT_OF_MEMORY);
   1723     }
   1724 }
   1725 
   1726 void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
   1727 {
   1728     TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
   1729 
   1730     try
   1731     {
   1732         if (count < 0 || first < 0)
   1733         {
   1734             return error(GL_INVALID_VALUE);
   1735         }
   1736 
   1737         gl::Context *context = gl::getContext();
   1738 
   1739         if (context)
   1740         {
   1741             context->drawArrays(mode, first, count);
   1742         }
   1743     }
   1744     catch(std::bad_alloc&)
   1745     {
   1746         return error(GL_OUT_OF_MEMORY);
   1747     }
   1748 }
   1749 
   1750 void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
   1751 {
   1752     TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
   1753           mode, count, type, indices);
   1754 
   1755     try
   1756     {
   1757         if (count < 0)
   1758         {
   1759             return error(GL_INVALID_VALUE);
   1760         }
   1761 
   1762         gl::Context *context = gl::getContext();
   1763 
   1764         if (context)
   1765         {
   1766             switch (type)
   1767             {
   1768               case GL_UNSIGNED_BYTE:
   1769               case GL_UNSIGNED_SHORT:
   1770                 break;
   1771               case GL_UNSIGNED_INT:
   1772                 if (!context->supports32bitIndices())
   1773                 {
   1774                     return error(GL_INVALID_ENUM);
   1775                 }
   1776                 break;
   1777               default:
   1778                 return error(GL_INVALID_ENUM);
   1779             }
   1780 
   1781             context->drawElements(mode, count, type, indices);
   1782         }
   1783     }
   1784     catch(std::bad_alloc&)
   1785     {
   1786         return error(GL_OUT_OF_MEMORY);
   1787     }
   1788 }
   1789 
   1790 void __stdcall glEnable(GLenum cap)
   1791 {
   1792     TRACE("(GLenum cap = 0x%X)", cap);
   1793 
   1794     try
   1795     {
   1796         gl::Context *context = gl::getContext();
   1797 
   1798         if (context)
   1799         {
   1800             switch (cap)
   1801             {
   1802               case GL_CULL_FACE:                context->setCullFace(true);              break;
   1803               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(true);     break;
   1804               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
   1805               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(true);        break;
   1806               case GL_SCISSOR_TEST:             context->setScissorTest(true);           break;
   1807               case GL_STENCIL_TEST:             context->setStencilTest(true);           break;
   1808               case GL_DEPTH_TEST:               context->setDepthTest(true);             break;
   1809               case GL_BLEND:                    context->setBlend(true);                 break;
   1810               case GL_DITHER:                   context->setDither(true);                break;
   1811               default:
   1812                 return error(GL_INVALID_ENUM);
   1813             }
   1814         }
   1815     }
   1816     catch(std::bad_alloc&)
   1817     {
   1818         return error(GL_OUT_OF_MEMORY);
   1819     }
   1820 }
   1821 
   1822 void __stdcall glEnableVertexAttribArray(GLuint index)
   1823 {
   1824     TRACE("(GLuint index = %d)", index);
   1825 
   1826     try
   1827     {
   1828         if (index >= gl::MAX_VERTEX_ATTRIBS)
   1829         {
   1830             return error(GL_INVALID_VALUE);
   1831         }
   1832 
   1833         gl::Context *context = gl::getContext();
   1834 
   1835         if (context)
   1836         {
   1837             context->setEnableVertexAttribArray(index, true);
   1838         }
   1839     }
   1840     catch(std::bad_alloc&)
   1841     {
   1842         return error(GL_OUT_OF_MEMORY);
   1843     }
   1844 }
   1845 
   1846 void __stdcall glFinishFenceNV(GLuint fence)
   1847 {
   1848     TRACE("(GLuint fence = %d)", fence);
   1849 
   1850     try
   1851     {
   1852         gl::Context *context = gl::getContext();
   1853 
   1854         if (context)
   1855         {
   1856             gl::Fence* fenceObject = context->getFence(fence);
   1857 
   1858             if (fenceObject == NULL)
   1859             {
   1860                 return error(GL_INVALID_OPERATION);
   1861             }
   1862 
   1863             fenceObject->finishFence();
   1864         }
   1865     }
   1866     catch(std::bad_alloc&)
   1867     {
   1868         return error(GL_OUT_OF_MEMORY);
   1869     }
   1870 }
   1871 
   1872 void __stdcall glFinish(void)
   1873 {
   1874     TRACE("()");
   1875 
   1876     try
   1877     {
   1878         gl::Context *context = gl::getContext();
   1879 
   1880         if (context)
   1881         {
   1882             context->finish();
   1883         }
   1884     }
   1885     catch(std::bad_alloc&)
   1886     {
   1887         return error(GL_OUT_OF_MEMORY);
   1888     }
   1889 }
   1890 
   1891 void __stdcall glFlush(void)
   1892 {
   1893     TRACE("()");
   1894 
   1895     try
   1896     {
   1897         gl::Context *context = gl::getContext();
   1898 
   1899         if (context)
   1900         {
   1901             context->flush();
   1902         }
   1903     }
   1904     catch(std::bad_alloc&)
   1905     {
   1906         return error(GL_OUT_OF_MEMORY);
   1907     }
   1908 }
   1909 
   1910 void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
   1911 {
   1912     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
   1913           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
   1914 
   1915     try
   1916     {
   1917         if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
   1918             || renderbuffertarget != GL_RENDERBUFFER)
   1919         {
   1920             return error(GL_INVALID_ENUM);
   1921         }
   1922 
   1923         gl::Context *context = gl::getContext();
   1924 
   1925         if (context)
   1926         {
   1927             gl::Framebuffer *framebuffer = NULL;
   1928             GLuint framebufferHandle = 0;
   1929             if (target == GL_READ_FRAMEBUFFER_ANGLE)
   1930             {
   1931                 framebuffer = context->getReadFramebuffer();
   1932                 framebufferHandle = context->getReadFramebufferHandle();
   1933             }
   1934             else
   1935             {
   1936                 framebuffer = context->getDrawFramebuffer();
   1937                 framebufferHandle = context->getDrawFramebufferHandle();
   1938             }
   1939 
   1940             if (framebufferHandle == 0 || !framebuffer)
   1941             {
   1942                 return error(GL_INVALID_OPERATION);
   1943             }
   1944 
   1945             switch (attachment)
   1946             {
   1947               case GL_COLOR_ATTACHMENT0:
   1948                 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
   1949                 break;
   1950               case GL_DEPTH_ATTACHMENT:
   1951                 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
   1952                 break;
   1953               case GL_STENCIL_ATTACHMENT:
   1954                 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
   1955                 break;
   1956               default:
   1957                 return error(GL_INVALID_ENUM);
   1958             }
   1959         }
   1960     }
   1961     catch(std::bad_alloc&)
   1962     {
   1963         return error(GL_OUT_OF_MEMORY);
   1964     }
   1965 }
   1966 
   1967 void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
   1968 {
   1969     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
   1970           "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
   1971 
   1972     try
   1973     {
   1974         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
   1975         {
   1976             return error(GL_INVALID_ENUM);
   1977         }
   1978 
   1979         switch (attachment)
   1980         {
   1981           case GL_COLOR_ATTACHMENT0:
   1982           case GL_DEPTH_ATTACHMENT:
   1983           case GL_STENCIL_ATTACHMENT:
   1984             break;
   1985           default:
   1986             return error(GL_INVALID_ENUM);
   1987         }
   1988 
   1989         gl::Context *context = gl::getContext();
   1990 
   1991         if (context)
   1992         {
   1993             if (texture == 0)
   1994             {
   1995                 textarget = GL_NONE;
   1996             }
   1997             else
   1998             {
   1999                 gl::Texture *tex = context->getTexture(texture);
   2000 
   2001                 if (tex == NULL)
   2002                 {
   2003                     return error(GL_INVALID_OPERATION);
   2004                 }
   2005 
   2006                 if (tex->isCompressed())
   2007                 {
   2008                     return error(GL_INVALID_OPERATION);
   2009                 }
   2010 
   2011                 switch (textarget)
   2012                 {
   2013                   case GL_TEXTURE_2D:
   2014                     if (tex->getTarget() != GL_TEXTURE_2D)
   2015                     {
   2016                         return error(GL_INVALID_OPERATION);
   2017                     }
   2018                     break;
   2019 
   2020                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   2021                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   2022                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   2023                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   2024                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   2025                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   2026                     if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
   2027                     {
   2028                         return error(GL_INVALID_OPERATION);
   2029                     }
   2030                     break;
   2031 
   2032                   default:
   2033                     return error(GL_INVALID_ENUM);
   2034                 }
   2035 
   2036                 if (level != 0)
   2037                 {
   2038                     return error(GL_INVALID_VALUE);
   2039                 }
   2040             }
   2041 
   2042             gl::Framebuffer *framebuffer = NULL;
   2043             GLuint framebufferHandle = 0;
   2044             if (target == GL_READ_FRAMEBUFFER_ANGLE)
   2045             {
   2046                 framebuffer = context->getReadFramebuffer();
   2047                 framebufferHandle = context->getReadFramebufferHandle();
   2048             }
   2049             else
   2050             {
   2051                 framebuffer = context->getDrawFramebuffer();
   2052                 framebufferHandle = context->getDrawFramebufferHandle();
   2053             }
   2054 
   2055             if (framebufferHandle == 0 || !framebuffer)
   2056             {
   2057                 return error(GL_INVALID_OPERATION);
   2058             }
   2059 
   2060             switch (attachment)
   2061             {
   2062               case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;
   2063               case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
   2064               case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
   2065             }
   2066         }
   2067     }
   2068     catch(std::bad_alloc&)
   2069     {
   2070         return error(GL_OUT_OF_MEMORY);
   2071     }
   2072 }
   2073 
   2074 void __stdcall glFrontFace(GLenum mode)
   2075 {
   2076     TRACE("(GLenum mode = 0x%X)", mode);
   2077 
   2078     try
   2079     {
   2080         switch (mode)
   2081         {
   2082           case GL_CW:
   2083           case GL_CCW:
   2084             {
   2085                 gl::Context *context = gl::getContext();
   2086 
   2087                 if (context)
   2088                 {
   2089                     context->setFrontFace(mode);
   2090                 }
   2091             }
   2092             break;
   2093           default:
   2094             return error(GL_INVALID_ENUM);
   2095         }
   2096     }
   2097     catch(std::bad_alloc&)
   2098     {
   2099         return error(GL_OUT_OF_MEMORY);
   2100     }
   2101 }
   2102 
   2103 void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
   2104 {
   2105     TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
   2106 
   2107     try
   2108     {
   2109         if (n < 0)
   2110         {
   2111             return error(GL_INVALID_VALUE);
   2112         }
   2113 
   2114         gl::Context *context = gl::getContext();
   2115 
   2116         if (context)
   2117         {
   2118             for (int i = 0; i < n; i++)
   2119             {
   2120                 buffers[i] = context->createBuffer();
   2121             }
   2122         }
   2123     }
   2124     catch(std::bad_alloc&)
   2125     {
   2126         return error(GL_OUT_OF_MEMORY);
   2127     }
   2128 }
   2129 
   2130 void __stdcall glGenerateMipmap(GLenum target)
   2131 {
   2132     TRACE("(GLenum target = 0x%X)", target);
   2133 
   2134     try
   2135     {
   2136         gl::Context *context = gl::getContext();
   2137 
   2138         if (context)
   2139         {
   2140             gl::Texture *texture;
   2141 
   2142             switch (target)
   2143             {
   2144               case GL_TEXTURE_2D:
   2145                 texture = context->getTexture2D();
   2146                 break;
   2147 
   2148               case GL_TEXTURE_CUBE_MAP:
   2149                 texture = context->getTextureCubeMap();
   2150                 break;
   2151 
   2152               default:
   2153                 return error(GL_INVALID_ENUM);
   2154             }
   2155 
   2156             if (texture->isCompressed())
   2157             {
   2158                 return error(GL_INVALID_OPERATION);
   2159             }
   2160 
   2161             texture->generateMipmaps();
   2162         }
   2163     }
   2164     catch(std::bad_alloc&)
   2165     {
   2166         return error(GL_OUT_OF_MEMORY);
   2167     }
   2168 }
   2169 
   2170 void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
   2171 {
   2172     TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
   2173 
   2174     try
   2175     {
   2176         if (n < 0)
   2177         {
   2178             return error(GL_INVALID_VALUE);
   2179         }
   2180 
   2181         gl::Context *context = gl::getContext();
   2182 
   2183         if (context)
   2184         {
   2185             for (int i = 0; i < n; i++)
   2186             {
   2187                 fences[i] = context->createFence();
   2188             }
   2189         }
   2190     }
   2191     catch(std::bad_alloc&)
   2192     {
   2193         return error(GL_OUT_OF_MEMORY);
   2194     }
   2195 }
   2196 
   2197 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
   2198 {
   2199     TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
   2200 
   2201     try
   2202     {
   2203         if (n < 0)
   2204         {
   2205             return error(GL_INVALID_VALUE);
   2206         }
   2207 
   2208         gl::Context *context = gl::getContext();
   2209 
   2210         if (context)
   2211         {
   2212             for (int i = 0; i < n; i++)
   2213             {
   2214                 framebuffers[i] = context->createFramebuffer();
   2215             }
   2216         }
   2217     }
   2218     catch(std::bad_alloc&)
   2219     {
   2220         return error(GL_OUT_OF_MEMORY);
   2221     }
   2222 }
   2223 
   2224 void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
   2225 {
   2226     TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
   2227 
   2228     try
   2229     {
   2230         if (n < 0)
   2231         {
   2232             return error(GL_INVALID_VALUE);
   2233         }
   2234 
   2235         gl::Context *context = gl::getContext();
   2236 
   2237         if (context)
   2238         {
   2239             for (int i = 0; i < n; i++)
   2240             {
   2241                 renderbuffers[i] = context->createRenderbuffer();
   2242             }
   2243         }
   2244     }
   2245     catch(std::bad_alloc&)
   2246     {
   2247         return error(GL_OUT_OF_MEMORY);
   2248     }
   2249 }
   2250 
   2251 void __stdcall glGenTextures(GLsizei n, GLuint* textures)
   2252 {
   2253     TRACE("(GLsizei n = %d, GLuint* textures =  0x%0.8p)", n, textures);
   2254 
   2255     try
   2256     {
   2257         if (n < 0)
   2258         {
   2259             return error(GL_INVALID_VALUE);
   2260         }
   2261 
   2262         gl::Context *context = gl::getContext();
   2263 
   2264         if (context)
   2265         {
   2266             for (int i = 0; i < n; i++)
   2267             {
   2268                 textures[i] = context->createTexture();
   2269             }
   2270         }
   2271     }
   2272     catch(std::bad_alloc&)
   2273     {
   2274         return error(GL_OUT_OF_MEMORY);
   2275     }
   2276 }
   2277 
   2278 void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
   2279 {
   2280     TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
   2281           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
   2282           program, index, bufsize, length, size, type, name);
   2283 
   2284     try
   2285     {
   2286         if (bufsize < 0)
   2287         {
   2288             return error(GL_INVALID_VALUE);
   2289         }
   2290 
   2291         gl::Context *context = gl::getContext();
   2292 
   2293         if (context)
   2294         {
   2295             gl::Program *programObject = context->getProgram(program);
   2296 
   2297             if (!programObject)
   2298             {
   2299                 if (context->getShader(program))
   2300                 {
   2301                     return error(GL_INVALID_OPERATION);
   2302                 }
   2303                 else
   2304                 {
   2305                     return error(GL_INVALID_VALUE);
   2306                 }
   2307             }
   2308 
   2309             if (index >= (GLuint)programObject->getActiveAttributeCount())
   2310             {
   2311                 return error(GL_INVALID_VALUE);
   2312             }
   2313 
   2314             programObject->getActiveAttribute(index, bufsize, length, size, type, name);
   2315         }
   2316     }
   2317     catch(std::bad_alloc&)
   2318     {
   2319         return error(GL_OUT_OF_MEMORY);
   2320     }
   2321 }
   2322 
   2323 void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
   2324 {
   2325     TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
   2326           "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
   2327           program, index, bufsize, length, size, type, name);
   2328 
   2329     try
   2330     {
   2331         if (bufsize < 0)
   2332         {
   2333             return error(GL_INVALID_VALUE);
   2334         }
   2335 
   2336         gl::Context *context = gl::getContext();
   2337 
   2338         if (context)
   2339         {
   2340             gl::Program *programObject = context->getProgram(program);
   2341 
   2342             if (!programObject)
   2343             {
   2344                 if (context->getShader(program))
   2345                 {
   2346                     return error(GL_INVALID_OPERATION);
   2347                 }
   2348                 else
   2349                 {
   2350                     return error(GL_INVALID_VALUE);
   2351                 }
   2352             }
   2353 
   2354             if (index >= (GLuint)programObject->getActiveUniformCount())
   2355             {
   2356                 return error(GL_INVALID_VALUE);
   2357             }
   2358 
   2359             programObject->getActiveUniform(index, bufsize, length, size, type, name);
   2360         }
   2361     }
   2362     catch(std::bad_alloc&)
   2363     {
   2364         return error(GL_OUT_OF_MEMORY);
   2365     }
   2366 }
   2367 
   2368 void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
   2369 {
   2370     TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
   2371           program, maxcount, count, shaders);
   2372 
   2373     try
   2374     {
   2375         if (maxcount < 0)
   2376         {
   2377             return error(GL_INVALID_VALUE);
   2378         }
   2379 
   2380         gl::Context *context = gl::getContext();
   2381 
   2382         if (context)
   2383         {
   2384             gl::Program *programObject = context->getProgram(program);
   2385 
   2386             if (!programObject)
   2387             {
   2388                 if (context->getShader(program))
   2389                 {
   2390                     return error(GL_INVALID_OPERATION);
   2391                 }
   2392                 else
   2393                 {
   2394                     return error(GL_INVALID_VALUE);
   2395                 }
   2396             }
   2397 
   2398             return programObject->getAttachedShaders(maxcount, count, shaders);
   2399         }
   2400     }
   2401     catch(std::bad_alloc&)
   2402     {
   2403         return error(GL_OUT_OF_MEMORY);
   2404     }
   2405 }
   2406 
   2407 int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
   2408 {
   2409     TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
   2410 
   2411     try
   2412     {
   2413         gl::Context *context = gl::getContext();
   2414 
   2415         if (context)
   2416         {
   2417 
   2418             gl::Program *programObject = context->getProgram(program);
   2419 
   2420             if (!programObject)
   2421             {
   2422                 if (context->getShader(program))
   2423                 {
   2424                     return error(GL_INVALID_OPERATION, -1);
   2425                 }
   2426                 else
   2427                 {
   2428                     return error(GL_INVALID_VALUE, -1);
   2429                 }
   2430             }
   2431 
   2432             if (!programObject->isLinked())
   2433             {
   2434                 return error(GL_INVALID_OPERATION, -1);
   2435             }
   2436 
   2437             return programObject->getAttributeLocation(name);
   2438         }
   2439     }
   2440     catch(std::bad_alloc&)
   2441     {
   2442         return error(GL_OUT_OF_MEMORY, -1);
   2443     }
   2444 
   2445     return -1;
   2446 }
   2447 
   2448 void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
   2449 {
   2450     TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);
   2451 
   2452     try
   2453     {
   2454         gl::Context *context = gl::getContext();
   2455 
   2456         if (context)
   2457         {
   2458             if (!(context->getBooleanv(pname, params)))
   2459             {
   2460                 GLenum nativeType;
   2461                 unsigned int numParams = 0;
   2462                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
   2463                     return error(GL_INVALID_ENUM);
   2464 
   2465                 if (numParams == 0)
   2466                     return; // it is known that the pname is valid, but there are no parameters to return
   2467 
   2468                 if (nativeType == GL_FLOAT)
   2469                 {
   2470                     GLfloat *floatParams = NULL;
   2471                     floatParams = new GLfloat[numParams];
   2472 
   2473                     context->getFloatv(pname, floatParams);
   2474 
   2475                     for (unsigned int i = 0; i < numParams; ++i)
   2476                     {
   2477                         if (floatParams[i] == 0.0f)
   2478                             params[i] = GL_FALSE;
   2479                         else
   2480                             params[i] = GL_TRUE;
   2481                     }
   2482 
   2483                     delete [] floatParams;
   2484                 }
   2485                 else if (nativeType == GL_INT)
   2486                 {
   2487                     GLint *intParams = NULL;
   2488                     intParams = new GLint[numParams];
   2489 
   2490                     context->getIntegerv(pname, intParams);
   2491 
   2492                     for (unsigned int i = 0; i < numParams; ++i)
   2493                     {
   2494                         if (intParams[i] == 0)
   2495                             params[i] = GL_FALSE;
   2496                         else
   2497                             params[i] = GL_TRUE;
   2498                     }
   2499 
   2500                     delete [] intParams;
   2501                 }
   2502             }
   2503         }
   2504     }
   2505     catch(std::bad_alloc&)
   2506     {
   2507         return error(GL_OUT_OF_MEMORY);
   2508     }
   2509 }
   2510 
   2511 void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
   2512 {
   2513     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   2514 
   2515     try
   2516     {
   2517         gl::Context *context = gl::getContext();
   2518 
   2519         if (context)
   2520         {
   2521             gl::Buffer *buffer;
   2522 
   2523             switch (target)
   2524             {
   2525               case GL_ARRAY_BUFFER:
   2526                 buffer = context->getArrayBuffer();
   2527                 break;
   2528               case GL_ELEMENT_ARRAY_BUFFER:
   2529                 buffer = context->getElementArrayBuffer();
   2530                 break;
   2531               default: return error(GL_INVALID_ENUM);
   2532             }
   2533 
   2534             if (!buffer)
   2535             {
   2536                 // A null buffer means that "0" is bound to the requested buffer target
   2537                 return error(GL_INVALID_OPERATION);
   2538             }
   2539 
   2540             switch (pname)
   2541             {
   2542               case GL_BUFFER_USAGE:
   2543                 *params = buffer->usage();
   2544                 break;
   2545               case GL_BUFFER_SIZE:
   2546                 *params = buffer->size();
   2547                 break;
   2548               default: return error(GL_INVALID_ENUM);
   2549             }
   2550         }
   2551     }
   2552     catch(std::bad_alloc&)
   2553     {
   2554         return error(GL_OUT_OF_MEMORY);
   2555     }
   2556 }
   2557 
   2558 GLenum __stdcall glGetError(void)
   2559 {
   2560     TRACE("()");
   2561 
   2562     gl::Context *context = gl::getContext();
   2563 
   2564     if (context)
   2565     {
   2566         return context->getError();
   2567     }
   2568 
   2569     return GL_NO_ERROR;
   2570 }
   2571 
   2572 void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
   2573 {
   2574     TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
   2575 
   2576     try
   2577     {
   2578 
   2579         gl::Context *context = gl::getContext();
   2580 
   2581         if (context)
   2582         {
   2583             gl::Fence *fenceObject = context->getFence(fence);
   2584 
   2585             if (fenceObject == NULL)
   2586             {
   2587                 return error(GL_INVALID_OPERATION);
   2588             }
   2589 
   2590             fenceObject->getFenceiv(pname, params);
   2591         }
   2592     }
   2593     catch(std::bad_alloc&)
   2594     {
   2595         return error(GL_OUT_OF_MEMORY);
   2596     }
   2597 }
   2598 
   2599 void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
   2600 {
   2601     TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
   2602 
   2603     try
   2604     {
   2605         gl::Context *context = gl::getContext();
   2606 
   2607         if (context)
   2608         {
   2609             if (!(context->getFloatv(pname, params)))
   2610             {
   2611                 GLenum nativeType;
   2612                 unsigned int numParams = 0;
   2613                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
   2614                     return error(GL_INVALID_ENUM);
   2615 
   2616                 if (numParams == 0)
   2617                     return; // it is known that the pname is valid, but that there are no parameters to return.
   2618 
   2619                 if (nativeType == GL_BOOL)
   2620                 {
   2621                     GLboolean *boolParams = NULL;
   2622                     boolParams = new GLboolean[numParams];
   2623 
   2624                     context->getBooleanv(pname, boolParams);
   2625 
   2626                     for (unsigned int i = 0; i < numParams; ++i)
   2627                     {
   2628                         if (boolParams[i] == GL_FALSE)
   2629                             params[i] = 0.0f;
   2630                         else
   2631                             params[i] = 1.0f;
   2632                     }
   2633 
   2634                     delete [] boolParams;
   2635                 }
   2636                 else if (nativeType == GL_INT)
   2637                 {
   2638                     GLint *intParams = NULL;
   2639                     intParams = new GLint[numParams];
   2640 
   2641                     context->getIntegerv(pname, intParams);
   2642 
   2643                     for (unsigned int i = 0; i < numParams; ++i)
   2644                     {
   2645                         params[i] = (GLfloat)intParams[i];
   2646                     }
   2647 
   2648                     delete [] intParams;
   2649                 }
   2650             }
   2651         }
   2652     }
   2653     catch(std::bad_alloc&)
   2654     {
   2655         return error(GL_OUT_OF_MEMORY);
   2656     }
   2657 }
   2658 
   2659 void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
   2660 {
   2661     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
   2662           target, attachment, pname, params);
   2663 
   2664     try
   2665     {
   2666         gl::Context *context = gl::getContext();
   2667 
   2668         if (context)
   2669         {
   2670             if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
   2671             {
   2672                 return error(GL_INVALID_ENUM);
   2673             }
   2674 
   2675             gl::Framebuffer *framebuffer = NULL;
   2676             if (target == GL_READ_FRAMEBUFFER_ANGLE)
   2677             {
   2678                 if(context->getReadFramebufferHandle() == 0)
   2679                 {
   2680                     return error(GL_INVALID_OPERATION);
   2681                 }
   2682 
   2683                 framebuffer = context->getReadFramebuffer();
   2684             }
   2685             else
   2686             {
   2687                 if (context->getDrawFramebufferHandle() == 0)
   2688                 {
   2689                     return error(GL_INVALID_OPERATION);
   2690                 }
   2691 
   2692                 framebuffer = context->getDrawFramebuffer();
   2693             }
   2694 
   2695             GLenum attachmentType;
   2696             GLuint attachmentHandle;
   2697             switch (attachment)
   2698             {
   2699               case GL_COLOR_ATTACHMENT0:
   2700                 attachmentType = framebuffer->getColorbufferType();
   2701                 attachmentHandle = framebuffer->getColorbufferHandle();
   2702                 break;
   2703               case GL_DEPTH_ATTACHMENT:
   2704                 attachmentType = framebuffer->getDepthbufferType();
   2705                 attachmentHandle = framebuffer->getDepthbufferHandle();
   2706                 break;
   2707               case GL_STENCIL_ATTACHMENT:
   2708                 attachmentType = framebuffer->getStencilbufferType();
   2709                 attachmentHandle = framebuffer->getStencilbufferHandle();
   2710                 break;
   2711               default: return error(GL_INVALID_ENUM);
   2712             }
   2713 
   2714             GLenum attachmentObjectType;   // Type category
   2715             if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
   2716             {
   2717                 attachmentObjectType = attachmentType;
   2718             }
   2719             else if (gl::IsTextureTarget(attachmentType))
   2720             {
   2721                 attachmentObjectType = GL_TEXTURE;
   2722             }
   2723             else UNREACHABLE();
   2724 
   2725             switch (pname)
   2726             {
   2727               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
   2728                 *params = attachmentObjectType;
   2729                 break;
   2730               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
   2731                 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
   2732                 {
   2733                     *params = attachmentHandle;
   2734                 }
   2735                 else
   2736                 {
   2737                     return error(GL_INVALID_ENUM);
   2738                 }
   2739                 break;
   2740               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
   2741                 if (attachmentObjectType == GL_TEXTURE)
   2742                 {
   2743                     *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
   2744                 }
   2745                 else
   2746                 {
   2747                     return error(GL_INVALID_ENUM);
   2748                 }
   2749                 break;
   2750               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
   2751                 if (attachmentObjectType == GL_TEXTURE)
   2752                 {
   2753                     if (gl::IsCubemapTextureTarget(attachmentType))
   2754                     {
   2755                         *params = attachmentType;
   2756                     }
   2757                     else
   2758                     {
   2759                         *params = 0;
   2760                     }
   2761                 }
   2762                 else
   2763                 {
   2764                     return error(GL_INVALID_ENUM);
   2765                 }
   2766                 break;
   2767               default:
   2768                 return error(GL_INVALID_ENUM);
   2769             }
   2770         }
   2771     }
   2772     catch(std::bad_alloc&)
   2773     {
   2774         return error(GL_OUT_OF_MEMORY);
   2775     }
   2776 }
   2777 
   2778 void __stdcall glGetIntegerv(GLenum pname, GLint* params)
   2779 {
   2780     TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
   2781 
   2782     try
   2783     {
   2784         gl::Context *context = gl::getContext();
   2785 
   2786         if (context)
   2787         {
   2788             if (!(context->getIntegerv(pname, params)))
   2789             {
   2790                 GLenum nativeType;
   2791                 unsigned int numParams = 0;
   2792                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
   2793                     return error(GL_INVALID_ENUM);
   2794 
   2795                 if (numParams == 0)
   2796                     return; // it is known that pname is valid, but there are no parameters to return
   2797 
   2798                 if (nativeType == GL_BOOL)
   2799                 {
   2800                     GLboolean *boolParams = NULL;
   2801                     boolParams = new GLboolean[numParams];
   2802 
   2803                     context->getBooleanv(pname, boolParams);
   2804 
   2805                     for (unsigned int i = 0; i < numParams; ++i)
   2806                     {
   2807                         if (boolParams[i] == GL_FALSE)
   2808                             params[i] = 0;
   2809                         else
   2810                             params[i] = 1;
   2811                     }
   2812 
   2813                     delete [] boolParams;
   2814                 }
   2815                 else if (nativeType == GL_FLOAT)
   2816                 {
   2817                     GLfloat *floatParams = NULL;
   2818                     floatParams = new GLfloat[numParams];
   2819 
   2820                     context->getFloatv(pname, floatParams);
   2821 
   2822                     for (unsigned int i = 0; i < numParams; ++i)
   2823                     {
   2824                         if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
   2825                         {
   2826                             params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
   2827                         }
   2828                         else
   2829                             params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
   2830                     }
   2831 
   2832                     delete [] floatParams;
   2833                 }
   2834             }
   2835         }
   2836     }
   2837     catch(std::bad_alloc&)
   2838     {
   2839         return error(GL_OUT_OF_MEMORY);
   2840     }
   2841 }
   2842 
   2843 void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
   2844 {
   2845     TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
   2846 
   2847     try
   2848     {
   2849         gl::Context *context = gl::getContext();
   2850 
   2851         if (context)
   2852         {
   2853             gl::Program *programObject = context->getProgram(program);
   2854 
   2855             if (!programObject)
   2856             {
   2857                 return error(GL_INVALID_VALUE);
   2858             }
   2859 
   2860             switch (pname)
   2861             {
   2862               case GL_DELETE_STATUS:
   2863                 *params = programObject->isFlaggedForDeletion();
   2864                 return;
   2865               case GL_LINK_STATUS:
   2866                 *params = programObject->isLinked();
   2867                 return;
   2868               case GL_VALIDATE_STATUS:
   2869                 *params = programObject->isValidated();
   2870                 return;
   2871               case GL_INFO_LOG_LENGTH:
   2872                 *params = programObject->getInfoLogLength();
   2873                 return;
   2874               case GL_ATTACHED_SHADERS:
   2875                 *params = programObject->getAttachedShadersCount();
   2876                 return;
   2877               case GL_ACTIVE_ATTRIBUTES:
   2878                 *params = programObject->getActiveAttributeCount();
   2879                 return;
   2880               case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
   2881                 *params = programObject->getActiveAttributeMaxLength();
   2882                 return;
   2883               case GL_ACTIVE_UNIFORMS:
   2884                 *params = programObject->getActiveUniformCount();
   2885                 return;
   2886               case GL_ACTIVE_UNIFORM_MAX_LENGTH:
   2887                 *params = programObject->getActiveUniformMaxLength();
   2888                 return;
   2889               default:
   2890                 return error(GL_INVALID_ENUM);
   2891             }
   2892         }
   2893     }
   2894     catch(std::bad_alloc&)
   2895     {
   2896         return error(GL_OUT_OF_MEMORY);
   2897     }
   2898 }
   2899 
   2900 void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
   2901 {
   2902     TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
   2903           program, bufsize, length, infolog);
   2904 
   2905     try
   2906     {
   2907         if (bufsize < 0)
   2908         {
   2909             return error(GL_INVALID_VALUE);
   2910         }
   2911 
   2912         gl::Context *context = gl::getContext();
   2913 
   2914         if (context)
   2915         {
   2916             gl::Program *programObject = context->getProgram(program);
   2917 
   2918             if (!programObject)
   2919             {
   2920                 return error(GL_INVALID_VALUE);
   2921             }
   2922 
   2923             programObject->getInfoLog(bufsize, length, infolog);
   2924         }
   2925     }
   2926     catch(std::bad_alloc&)
   2927     {
   2928         return error(GL_OUT_OF_MEMORY);
   2929     }
   2930 }
   2931 
   2932 void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
   2933 {
   2934     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   2935 
   2936     try
   2937     {
   2938         gl::Context *context = gl::getContext();
   2939 
   2940         if (context)
   2941         {
   2942             if (target != GL_RENDERBUFFER)
   2943             {
   2944                 return error(GL_INVALID_ENUM);
   2945             }
   2946 
   2947             if (context->getRenderbufferHandle() == 0)
   2948             {
   2949                 return error(GL_INVALID_OPERATION);
   2950             }
   2951 
   2952             gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
   2953 
   2954             switch (pname)
   2955             {
   2956               case GL_RENDERBUFFER_WIDTH:
   2957                 *params = renderbuffer->getWidth();
   2958                 break;
   2959               case GL_RENDERBUFFER_HEIGHT:
   2960                 *params = renderbuffer->getHeight();
   2961                 break;
   2962               case GL_RENDERBUFFER_INTERNAL_FORMAT:
   2963                 *params = renderbuffer->getFormat();
   2964                 break;
   2965               case GL_RENDERBUFFER_RED_SIZE:
   2966                 if (renderbuffer->isColorbuffer())
   2967                 {
   2968                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
   2969                 }
   2970                 else
   2971                 {
   2972                     *params = 0;
   2973                 }
   2974                 break;
   2975               case GL_RENDERBUFFER_GREEN_SIZE:
   2976                 if (renderbuffer->isColorbuffer())
   2977                 {
   2978                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
   2979                 }
   2980                 else
   2981                 {
   2982                     *params = 0;
   2983                 }
   2984                 break;
   2985               case GL_RENDERBUFFER_BLUE_SIZE:
   2986                 if (renderbuffer->isColorbuffer())
   2987                 {
   2988                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
   2989                 }
   2990                 else
   2991                 {
   2992                     *params = 0;
   2993                 }
   2994                 break;
   2995               case GL_RENDERBUFFER_ALPHA_SIZE:
   2996                 if (renderbuffer->isColorbuffer())
   2997                 {
   2998                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
   2999                 }
   3000                 else
   3001                 {
   3002                     *params = 0;
   3003                 }
   3004                 break;
   3005               case GL_RENDERBUFFER_DEPTH_SIZE:
   3006                 if (renderbuffer->isDepthbuffer())
   3007                 {
   3008                     *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
   3009                 }
   3010                 else
   3011                 {
   3012                     *params = 0;
   3013                 }
   3014                 break;
   3015               case GL_RENDERBUFFER_STENCIL_SIZE:
   3016                 if (renderbuffer->isStencilbuffer())
   3017                 {
   3018                     *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
   3019                 }
   3020                 else
   3021                 {
   3022                     *params = 0;
   3023                 }
   3024                 break;
   3025               case GL_RENDERBUFFER_SAMPLES_ANGLE:
   3026                 {
   3027                     if (context->getMaxSupportedSamples() != 0)
   3028                     {
   3029                         *params = renderbuffer->getStorage()->getSamples();
   3030                     }
   3031                     else
   3032                     {
   3033                         return error(GL_INVALID_ENUM);
   3034                     }
   3035                 }
   3036                 break;
   3037               default:
   3038                 return error(GL_INVALID_ENUM);
   3039             }
   3040         }
   3041     }
   3042     catch(std::bad_alloc&)
   3043     {
   3044         return error(GL_OUT_OF_MEMORY);
   3045     }
   3046 }
   3047 
   3048 void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
   3049 {
   3050     TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
   3051 
   3052     try
   3053     {
   3054         gl::Context *context = gl::getContext();
   3055 
   3056         if (context)
   3057         {
   3058             gl::Shader *shaderObject = context->getShader(shader);
   3059 
   3060             if (!shaderObject)
   3061             {
   3062                 return error(GL_INVALID_VALUE);
   3063             }
   3064 
   3065             switch (pname)
   3066             {
   3067               case GL_SHADER_TYPE:
   3068                 *params = shaderObject->getType();
   3069                 return;
   3070               case GL_DELETE_STATUS:
   3071                 *params = shaderObject->isFlaggedForDeletion();
   3072                 return;
   3073               case GL_COMPILE_STATUS:
   3074                 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
   3075                 return;
   3076               case GL_INFO_LOG_LENGTH:
   3077                 *params = shaderObject->getInfoLogLength();
   3078                 return;
   3079               case GL_SHADER_SOURCE_LENGTH:
   3080                 *params = shaderObject->getSourceLength();
   3081                 return;
   3082               default:
   3083                 return error(GL_INVALID_ENUM);
   3084             }
   3085         }
   3086     }
   3087     catch(std::bad_alloc&)
   3088     {
   3089         return error(GL_OUT_OF_MEMORY);
   3090     }
   3091 }
   3092 
   3093 void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
   3094 {
   3095     TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
   3096           shader, bufsize, length, infolog);
   3097 
   3098     try
   3099     {
   3100         if (bufsize < 0)
   3101         {
   3102             return error(GL_INVALID_VALUE);
   3103         }
   3104 
   3105         gl::Context *context = gl::getContext();
   3106 
   3107         if (context)
   3108         {
   3109             gl::Shader *shaderObject = context->getShader(shader);
   3110 
   3111             if (!shaderObject)
   3112             {
   3113                 return error(GL_INVALID_VALUE);
   3114             }
   3115 
   3116             shaderObject->getInfoLog(bufsize, length, infolog);
   3117         }
   3118     }
   3119     catch(std::bad_alloc&)
   3120     {
   3121         return error(GL_OUT_OF_MEMORY);
   3122     }
   3123 }
   3124 
   3125 void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
   3126 {
   3127     TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
   3128           shadertype, precisiontype, range, precision);
   3129 
   3130     try
   3131     {
   3132         switch (shadertype)
   3133         {
   3134           case GL_VERTEX_SHADER:
   3135           case GL_FRAGMENT_SHADER:
   3136             break;
   3137           default:
   3138             return error(GL_INVALID_ENUM);
   3139         }
   3140 
   3141         switch (precisiontype)
   3142         {
   3143           case GL_LOW_FLOAT:
   3144           case GL_MEDIUM_FLOAT:
   3145           case GL_HIGH_FLOAT:
   3146             // Assume IEEE 754 precision
   3147             range[0] = 127;
   3148             range[1] = 127;
   3149             *precision = 23;
   3150             break;
   3151           case GL_LOW_INT:
   3152           case GL_MEDIUM_INT:
   3153           case GL_HIGH_INT:
   3154             // Some (most) hardware only supports single-precision floating-point numbers,
   3155             // which can accurately represent integers up to +/-16777216
   3156             range[0] = 24;
   3157             range[1] = 24;
   3158             *precision = 0;
   3159             break;
   3160           default:
   3161             return error(GL_INVALID_ENUM);
   3162         }
   3163     }
   3164     catch(std::bad_alloc&)
   3165     {
   3166         return error(GL_OUT_OF_MEMORY);
   3167     }
   3168 }
   3169 
   3170 void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
   3171 {
   3172     TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
   3173           shader, bufsize, length, source);
   3174 
   3175     try
   3176     {
   3177         if (bufsize < 0)
   3178         {
   3179             return error(GL_INVALID_VALUE);
   3180         }
   3181 
   3182         gl::Context *context = gl::getContext();
   3183 
   3184         if (context)
   3185         {
   3186             gl::Shader *shaderObject = context->getShader(shader);
   3187 
   3188             if (!shaderObject)
   3189             {
   3190                 return error(GL_INVALID_OPERATION);
   3191             }
   3192 
   3193             shaderObject->getSource(bufsize, length, source);
   3194         }
   3195     }
   3196     catch(std::bad_alloc&)
   3197     {
   3198         return error(GL_OUT_OF_MEMORY);
   3199     }
   3200 }
   3201 
   3202 const GLubyte* __stdcall glGetString(GLenum name)
   3203 {
   3204     TRACE("(GLenum name = 0x%X)", name);
   3205 
   3206     try
   3207     {
   3208         gl::Context *context = gl::getContext();
   3209 
   3210         switch (name)
   3211         {
   3212           case GL_VENDOR:
   3213             return (GLubyte*)"TransGaming Inc.";
   3214           case GL_RENDERER:
   3215             return (GLubyte*)"ANGLE";
   3216           case GL_VERSION:
   3217             return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
   3218           case GL_SHADING_LANGUAGE_VERSION:
   3219             return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
   3220           case GL_EXTENSIONS:
   3221             return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
   3222           default:
   3223             return error(GL_INVALID_ENUM, (GLubyte*)NULL);
   3224         }
   3225     }
   3226     catch(std::bad_alloc&)
   3227     {
   3228         return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
   3229     }
   3230 
   3231     return NULL;
   3232 }
   3233 
   3234 void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
   3235 {
   3236     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
   3237 
   3238     try
   3239     {
   3240         gl::Context *context = gl::getContext();
   3241 
   3242         if (context)
   3243         {
   3244             gl::Texture *texture;
   3245 
   3246             switch (target)
   3247             {
   3248               case GL_TEXTURE_2D:
   3249                 texture = context->getTexture2D();
   3250                 break;
   3251               case GL_TEXTURE_CUBE_MAP:
   3252                 texture = context->getTextureCubeMap();
   3253                 break;
   3254               default:
   3255                 return error(GL_INVALID_ENUM);
   3256             }
   3257 
   3258             switch (pname)
   3259             {
   3260               case GL_TEXTURE_MAG_FILTER:
   3261                 *params = (GLfloat)texture->getMagFilter();
   3262                 break;
   3263               case GL_TEXTURE_MIN_FILTER:
   3264                 *params = (GLfloat)texture->getMinFilter();
   3265                 break;
   3266               case GL_TEXTURE_WRAP_S:
   3267                 *params = (GLfloat)texture->getWrapS();
   3268                 break;
   3269               case GL_TEXTURE_WRAP_T:
   3270                 *params = (GLfloat)texture->getWrapT();
   3271                 break;
   3272               default:
   3273                 return error(GL_INVALID_ENUM);
   3274             }
   3275         }
   3276     }
   3277     catch(std::bad_alloc&)
   3278     {
   3279         return error(GL_OUT_OF_MEMORY);
   3280     }
   3281 }
   3282 
   3283 void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
   3284 {
   3285     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
   3286 
   3287     try
   3288     {
   3289         gl::Context *context = gl::getContext();
   3290 
   3291         if (context)
   3292         {
   3293             gl::Texture *texture;
   3294 
   3295             switch (target)
   3296             {
   3297               case GL_TEXTURE_2D:
   3298                 texture = context->getTexture2D();
   3299                 break;
   3300               case GL_TEXTURE_CUBE_MAP:
   3301                 texture = context->getTextureCubeMap();
   3302                 break;
   3303               default:
   3304                 return error(GL_INVALID_ENUM);
   3305             }
   3306 
   3307             switch (pname)
   3308             {
   3309               case GL_TEXTURE_MAG_FILTER:
   3310                 *params = texture->getMagFilter();
   3311                 break;
   3312               case GL_TEXTURE_MIN_FILTER:
   3313                 *params = texture->getMinFilter();
   3314                 break;
   3315               case GL_TEXTURE_WRAP_S:
   3316                 *params = texture->getWrapS();
   3317                 break;
   3318               case GL_TEXTURE_WRAP_T:
   3319                 *params = texture->getWrapT();
   3320                 break;
   3321               default:
   3322                 return error(GL_INVALID_ENUM);
   3323             }
   3324         }
   3325     }
   3326     catch(std::bad_alloc&)
   3327     {
   3328         return error(GL_OUT_OF_MEMORY);
   3329     }
   3330 }
   3331 
   3332 void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
   3333 {
   3334     TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
   3335 
   3336     try
   3337     {
   3338         gl::Context *context = gl::getContext();
   3339 
   3340         if (context)
   3341         {
   3342             if (program == 0)
   3343             {
   3344                 return error(GL_INVALID_VALUE);
   3345             }
   3346 
   3347             gl::Program *programObject = context->getProgram(program);
   3348 
   3349             if (!programObject || !programObject->isLinked())
   3350             {
   3351                 return error(GL_INVALID_OPERATION);
   3352             }
   3353 
   3354             if (!programObject->getUniformfv(location, params))
   3355             {
   3356                 return error(GL_INVALID_OPERATION);
   3357             }
   3358         }
   3359     }
   3360     catch(std::bad_alloc&)
   3361     {
   3362         return error(GL_OUT_OF_MEMORY);
   3363     }
   3364 }
   3365 
   3366 void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
   3367 {
   3368     TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
   3369 
   3370     try
   3371     {
   3372         gl::Context *context = gl::getContext();
   3373 
   3374         if (context)
   3375         {
   3376             if (program == 0)
   3377             {
   3378                 return error(GL_INVALID_VALUE);
   3379             }
   3380 
   3381             gl::Program *programObject = context->getProgram(program);
   3382 
   3383             if (!programObject || !programObject->isLinked())
   3384             {
   3385                 return error(GL_INVALID_OPERATION);
   3386             }
   3387 
   3388             if (!programObject)
   3389             {
   3390                 return error(GL_INVALID_OPERATION);
   3391             }
   3392 
   3393             if (!programObject->getUniformiv(location, params))
   3394             {
   3395                 return error(GL_INVALID_OPERATION);
   3396             }
   3397         }
   3398     }
   3399     catch(std::bad_alloc&)
   3400     {
   3401         return error(GL_OUT_OF_MEMORY);
   3402     }
   3403 }
   3404 
   3405 int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
   3406 {
   3407     TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
   3408 
   3409     try
   3410     {
   3411         gl::Context *context = gl::getContext();
   3412 
   3413         if (strstr(name, "gl_") == name)
   3414         {
   3415             return -1;
   3416         }
   3417 
   3418         if (context)
   3419         {
   3420             gl::Program *programObject = context->getProgram(program);
   3421 
   3422             if (!programObject)
   3423             {
   3424                 if (context->getShader(program))
   3425                 {
   3426                     return error(GL_INVALID_OPERATION, -1);
   3427                 }
   3428                 else
   3429                 {
   3430                     return error(GL_INVALID_VALUE, -1);
   3431                 }
   3432             }
   3433 
   3434             if (!programObject->isLinked())
   3435             {
   3436                 return error(GL_INVALID_OPERATION, -1);
   3437             }
   3438 
   3439             return programObject->getUniformLocation(name, false);
   3440         }
   3441     }
   3442     catch(std::bad_alloc&)
   3443     {
   3444         return error(GL_OUT_OF_MEMORY, -1);
   3445     }
   3446 
   3447     return -1;
   3448 }
   3449 
   3450 void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
   3451 {
   3452     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
   3453 
   3454     try
   3455     {
   3456         gl::Context *context = gl::getContext();
   3457 
   3458         if (context)
   3459         {
   3460             if (index >= gl::MAX_VERTEX_ATTRIBS)
   3461             {
   3462                 return error(GL_INVALID_VALUE);
   3463             }
   3464 
   3465             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
   3466 
   3467             switch (pname)
   3468             {
   3469               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
   3470                 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
   3471                 break;
   3472               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
   3473                 *params = (GLfloat)attribState.mSize;
   3474                 break;
   3475               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
   3476                 *params = (GLfloat)attribState.mStride;
   3477                 break;
   3478               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
   3479                 *params = (GLfloat)attribState.mType;
   3480                 break;
   3481               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
   3482                 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
   3483                 break;
   3484               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
   3485                 *params = (GLfloat)attribState.mBoundBuffer.id();
   3486                 break;
   3487               case GL_CURRENT_VERTEX_ATTRIB:
   3488                 for (int i = 0; i < 4; ++i)
   3489                 {
   3490                     params[i] = attribState.mCurrentValue[i];
   3491                 }
   3492                 break;
   3493               default: return error(GL_INVALID_ENUM);
   3494             }
   3495         }
   3496     }
   3497     catch(std::bad_alloc&)
   3498     {
   3499         return error(GL_OUT_OF_MEMORY);
   3500     }
   3501 }
   3502 
   3503 void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
   3504 {
   3505     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
   3506 
   3507     try
   3508     {
   3509         gl::Context *context = gl::getContext();
   3510 
   3511         if (context)
   3512         {
   3513             if (index >= gl::MAX_VERTEX_ATTRIBS)
   3514             {
   3515                 return error(GL_INVALID_VALUE);
   3516             }
   3517 
   3518             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
   3519 
   3520             switch (pname)
   3521             {
   3522               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
   3523                 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
   3524                 break;
   3525               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
   3526                 *params = attribState.mSize;
   3527                 break;
   3528               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
   3529                 *params = attribState.mStride;
   3530                 break;
   3531               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
   3532                 *params = attribState.mType;
   3533                 break;
   3534               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
   3535                 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
   3536                 break;
   3537               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
   3538                 *params = attribState.mBoundBuffer.id();
   3539                 break;
   3540               case GL_CURRENT_VERTEX_ATTRIB:
   3541                 for (int i = 0; i < 4; ++i)
   3542                 {
   3543                     float currentValue = attribState.mCurrentValue[i];
   3544                     params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
   3545                 }
   3546                 break;
   3547               default: return error(GL_INVALID_ENUM);
   3548             }
   3549         }
   3550     }
   3551     catch(std::bad_alloc&)
   3552     {
   3553         return error(GL_OUT_OF_MEMORY);
   3554     }
   3555 }
   3556 
   3557 void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
   3558 {
   3559     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
   3560 
   3561     try
   3562     {
   3563         gl::Context *context = gl::getContext();
   3564 
   3565         if (context)
   3566         {
   3567             if (index >= gl::MAX_VERTEX_ATTRIBS)
   3568             {
   3569                 return error(GL_INVALID_VALUE);
   3570             }
   3571 
   3572             if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
   3573             {
   3574                 return error(GL_INVALID_ENUM);
   3575             }
   3576 
   3577             *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
   3578         }
   3579     }
   3580     catch(std::bad_alloc&)
   3581     {
   3582         return error(GL_OUT_OF_MEMORY);
   3583     }
   3584 }
   3585 
   3586 void __stdcall glHint(GLenum target, GLenum mode)
   3587 {
   3588     TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
   3589 
   3590     try
   3591     {
   3592         switch (mode)
   3593         {
   3594           case GL_FASTEST:
   3595           case GL_NICEST:
   3596           case GL_DONT_CARE:
   3597             break;
   3598           default:
   3599             return error(GL_INVALID_ENUM);
   3600         }
   3601 
   3602         gl::Context *context = gl::getContext();
   3603         switch (target)
   3604         {
   3605           case GL_GENERATE_MIPMAP_HINT:
   3606             if (context) context->setGenerateMipmapHint(mode);
   3607             break;
   3608           case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   3609             if (context) context->setFragmentShaderDerivativeHint(mode);
   3610             break;
   3611           default:
   3612             return error(GL_INVALID_ENUM);
   3613         }
   3614     }
   3615     catch(std::bad_alloc&)
   3616     {
   3617         return error(GL_OUT_OF_MEMORY);
   3618     }
   3619 }
   3620 
   3621 GLboolean __stdcall glIsBuffer(GLuint buffer)
   3622 {
   3623     TRACE("(GLuint buffer = %d)", buffer);
   3624 
   3625     try
   3626     {
   3627         gl::Context *context = gl::getContext();
   3628 
   3629         if (context && buffer)
   3630         {
   3631             gl::Buffer *bufferObject = context->getBuffer(buffer);
   3632 
   3633             if (bufferObject)
   3634             {
   3635                 return GL_TRUE;
   3636             }
   3637         }
   3638     }
   3639     catch(std::bad_alloc&)
   3640     {
   3641         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3642     }
   3643 
   3644     return GL_FALSE;
   3645 }
   3646 
   3647 GLboolean __stdcall glIsEnabled(GLenum cap)
   3648 {
   3649     TRACE("(GLenum cap = 0x%X)", cap);
   3650 
   3651     try
   3652     {
   3653         gl::Context *context = gl::getContext();
   3654 
   3655         if (context)
   3656         {
   3657             switch (cap)
   3658             {
   3659               case GL_CULL_FACE:                return context->isCullFaceEnabled();
   3660               case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
   3661               case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
   3662               case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
   3663               case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
   3664               case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
   3665               case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
   3666               case GL_BLEND:                    return context->isBlendEnabled();
   3667               case GL_DITHER:                   return context->isDitherEnabled();
   3668               default:
   3669                 return error(GL_INVALID_ENUM, false);
   3670             }
   3671         }
   3672     }
   3673     catch(std::bad_alloc&)
   3674     {
   3675         return error(GL_OUT_OF_MEMORY, false);
   3676     }
   3677 
   3678     return false;
   3679 }
   3680 
   3681 GLboolean __stdcall glIsFenceNV(GLuint fence)
   3682 {
   3683     TRACE("(GLuint fence = %d)", fence);
   3684 
   3685     try
   3686     {
   3687         gl::Context *context = gl::getContext();
   3688 
   3689         if (context)
   3690         {
   3691             gl::Fence *fenceObject = context->getFence(fence);
   3692 
   3693             if (fenceObject == NULL)
   3694             {
   3695                 return GL_FALSE;
   3696             }
   3697 
   3698             return fenceObject->isFence();
   3699         }
   3700     }
   3701     catch(std::bad_alloc&)
   3702     {
   3703         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3704     }
   3705 
   3706     return GL_FALSE;
   3707 }
   3708 
   3709 GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
   3710 {
   3711     TRACE("(GLuint framebuffer = %d)", framebuffer);
   3712 
   3713     try
   3714     {
   3715         gl::Context *context = gl::getContext();
   3716 
   3717         if (context && framebuffer)
   3718         {
   3719             gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
   3720 
   3721             if (framebufferObject)
   3722             {
   3723                 return GL_TRUE;
   3724             }
   3725         }
   3726     }
   3727     catch(std::bad_alloc&)
   3728     {
   3729         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3730     }
   3731 
   3732     return GL_FALSE;
   3733 }
   3734 
   3735 GLboolean __stdcall glIsProgram(GLuint program)
   3736 {
   3737     TRACE("(GLuint program = %d)", program);
   3738 
   3739     try
   3740     {
   3741         gl::Context *context = gl::getContext();
   3742 
   3743         if (context && program)
   3744         {
   3745             gl::Program *programObject = context->getProgram(program);
   3746 
   3747             if (programObject)
   3748             {
   3749                 return GL_TRUE;
   3750             }
   3751         }
   3752     }
   3753     catch(std::bad_alloc&)
   3754     {
   3755         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3756     }
   3757 
   3758     return GL_FALSE;
   3759 }
   3760 
   3761 GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
   3762 {
   3763     TRACE("(GLuint renderbuffer = %d)", renderbuffer);
   3764 
   3765     try
   3766     {
   3767         gl::Context *context = gl::getContext();
   3768 
   3769         if (context && renderbuffer)
   3770         {
   3771             gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
   3772 
   3773             if (renderbufferObject)
   3774             {
   3775                 return GL_TRUE;
   3776             }
   3777         }
   3778     }
   3779     catch(std::bad_alloc&)
   3780     {
   3781         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3782     }
   3783 
   3784     return GL_FALSE;
   3785 }
   3786 
   3787 GLboolean __stdcall glIsShader(GLuint shader)
   3788 {
   3789     TRACE("(GLuint shader = %d)", shader);
   3790 
   3791     try
   3792     {
   3793         gl::Context *context = gl::getContext();
   3794 
   3795         if (context && shader)
   3796         {
   3797             gl::Shader *shaderObject = context->getShader(shader);
   3798 
   3799             if (shaderObject)
   3800             {
   3801                 return GL_TRUE;
   3802             }
   3803         }
   3804     }
   3805     catch(std::bad_alloc&)
   3806     {
   3807         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3808     }
   3809 
   3810     return GL_FALSE;
   3811 }
   3812 
   3813 GLboolean __stdcall glIsTexture(GLuint texture)
   3814 {
   3815     TRACE("(GLuint texture = %d)", texture);
   3816 
   3817     try
   3818     {
   3819         gl::Context *context = gl::getContext();
   3820 
   3821         if (context && texture)
   3822         {
   3823             gl::Texture *textureObject = context->getTexture(texture);
   3824 
   3825             if (textureObject)
   3826             {
   3827                 return GL_TRUE;
   3828             }
   3829         }
   3830     }
   3831     catch(std::bad_alloc&)
   3832     {
   3833         return error(GL_OUT_OF_MEMORY, GL_FALSE);
   3834     }
   3835 
   3836     return GL_FALSE;
   3837 }
   3838 
   3839 void __stdcall glLineWidth(GLfloat width)
   3840 {
   3841     TRACE("(GLfloat width = %f)", width);
   3842 
   3843     try
   3844     {
   3845         if (width <= 0.0f)
   3846         {
   3847             return error(GL_INVALID_VALUE);
   3848         }
   3849 
   3850         gl::Context *context = gl::getContext();
   3851 
   3852         if (context)
   3853         {
   3854             context->setLineWidth(width);
   3855         }
   3856     }
   3857     catch(std::bad_alloc&)
   3858     {
   3859         return error(GL_OUT_OF_MEMORY);
   3860     }
   3861 }
   3862 
   3863 void __stdcall glLinkProgram(GLuint program)
   3864 {
   3865     TRACE("(GLuint program = %d)", program);
   3866 
   3867     try
   3868     {
   3869         gl::Context *context = gl::getContext();
   3870 
   3871         if (context)
   3872         {
   3873             gl::Program *programObject = context->getProgram(program);
   3874 
   3875             if (!programObject)
   3876             {
   3877                 if (context->getShader(program))
   3878                 {
   3879                     return error(GL_INVALID_OPERATION);
   3880                 }
   3881                 else
   3882                 {
   3883                     return error(GL_INVALID_VALUE);
   3884                 }
   3885             }
   3886 
   3887             programObject->link();
   3888         }
   3889     }
   3890     catch(std::bad_alloc&)
   3891     {
   3892         return error(GL_OUT_OF_MEMORY);
   3893     }
   3894 }
   3895 
   3896 void __stdcall glPixelStorei(GLenum pname, GLint param)
   3897 {
   3898     TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
   3899 
   3900     try
   3901     {
   3902         gl::Context *context = gl::getContext();
   3903 
   3904         if (context)
   3905         {
   3906             switch (pname)
   3907             {
   3908               case GL_UNPACK_ALIGNMENT:
   3909                 if (param != 1 && param != 2 && param != 4 && param != 8)
   3910                 {
   3911                     return error(GL_INVALID_VALUE);
   3912                 }
   3913 
   3914                 context->setUnpackAlignment(param);
   3915                 break;
   3916 
   3917               case GL_PACK_ALIGNMENT:
   3918                 if (param != 1 && param != 2 && param != 4 && param != 8)
   3919                 {
   3920                     return error(GL_INVALID_VALUE);
   3921                 }
   3922 
   3923                 context->setPackAlignment(param);
   3924                 break;
   3925 
   3926               default:
   3927                 return error(GL_INVALID_ENUM);
   3928             }
   3929         }
   3930     }
   3931     catch(std::bad_alloc&)
   3932     {
   3933         return error(GL_OUT_OF_MEMORY);
   3934     }
   3935 }
   3936 
   3937 void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
   3938 {
   3939     TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
   3940 
   3941     try
   3942     {
   3943         gl::Context *context = gl::getContext();
   3944 
   3945         if (context)
   3946         {
   3947             context->setPolygonOffsetParams(factor, units);
   3948         }
   3949     }
   3950     catch(std::bad_alloc&)
   3951     {
   3952         return error(GL_OUT_OF_MEMORY);
   3953     }
   3954 }
   3955 
   3956 void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
   3957 {
   3958     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
   3959           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
   3960           x, y, width, height, format, type,  pixels);
   3961 
   3962     try
   3963     {
   3964         if (width < 0 || height < 0)
   3965         {
   3966             return error(GL_INVALID_VALUE);
   3967         }
   3968 
   3969         switch (format)
   3970         {
   3971           case GL_RGBA:
   3972             switch (type)
   3973             {
   3974               case GL_UNSIGNED_BYTE:
   3975                 break;
   3976               default:
   3977                 return error(GL_INVALID_OPERATION);
   3978             }
   3979             break;
   3980           case GL_BGRA_EXT:
   3981             switch (type)
   3982             {
   3983               case GL_UNSIGNED_BYTE:
   3984               case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
   3985               case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
   3986                 break;
   3987               default:
   3988                 return error(GL_INVALID_OPERATION);
   3989             }
   3990             break;
   3991           case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
   3992             switch (type)
   3993             {
   3994               case gl::IMPLEMENTATION_COLOR_READ_TYPE:
   3995                 break;
   3996               default:
   3997                 return error(GL_INVALID_OPERATION);
   3998             }
   3999             break;
   4000           default:
   4001             return error(GL_INVALID_OPERATION);
   4002         }
   4003 
   4004         gl::Context *context = gl::getContext();
   4005 
   4006         if (context)
   4007         {
   4008             context->readPixels(x, y, width, height, format, type, pixels);
   4009         }
   4010     }
   4011     catch(std::bad_alloc&)
   4012     {
   4013         return error(GL_OUT_OF_MEMORY);
   4014     }
   4015 }
   4016 
   4017 void __stdcall glReleaseShaderCompiler(void)
   4018 {
   4019     TRACE("()");
   4020 
   4021     try
   4022     {
   4023         gl::Shader::releaseCompiler();
   4024     }
   4025     catch(std::bad_alloc&)
   4026     {
   4027         return error(GL_OUT_OF_MEMORY);
   4028     }
   4029 }
   4030 
   4031 void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
   4032 {
   4033     TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
   4034           target, samples, internalformat, width, height);
   4035 
   4036     try
   4037     {
   4038         switch (target)
   4039         {
   4040           case GL_RENDERBUFFER:
   4041             break;
   4042           default:
   4043             return error(GL_INVALID_ENUM);
   4044         }
   4045 
   4046         if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
   4047         {
   4048             return error(GL_INVALID_ENUM);
   4049         }
   4050 
   4051         if (width < 0 || height < 0 || samples < 0)
   4052         {
   4053             return error(GL_INVALID_VALUE);
   4054         }
   4055 
   4056         gl::Context *context = gl::getContext();
   4057 
   4058         if (context)
   4059         {
   4060             if (width > context->getMaximumRenderbufferDimension() ||
   4061                 height > context->getMaximumRenderbufferDimension() ||
   4062                 samples > context->getMaxSupportedSamples())
   4063             {
   4064                 return error(GL_INVALID_VALUE);
   4065             }
   4066 
   4067             GLuint handle = context->getRenderbufferHandle();
   4068             if (handle == 0)
   4069             {
   4070                 return error(GL_INVALID_OPERATION);
   4071             }
   4072 
   4073             switch (internalformat)
   4074             {
   4075               case GL_DEPTH_COMPONENT16:
   4076                 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
   4077                 break;
   4078               case GL_RGBA4:
   4079               case GL_RGB5_A1:
   4080               case GL_RGB565:
   4081               case GL_RGB8_OES:
   4082               case GL_RGBA8_OES:
   4083                 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
   4084                 break;
   4085               case GL_STENCIL_INDEX8:
   4086                 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
   4087                 break;
   4088               case GL_DEPTH24_STENCIL8_OES:
   4089                 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
   4090                 break;
   4091               default:
   4092                 return error(GL_INVALID_ENUM);
   4093             }
   4094         }
   4095     }
   4096     catch(std::bad_alloc&)
   4097     {
   4098         return error(GL_OUT_OF_MEMORY);
   4099     }
   4100 }
   4101 
   4102 void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
   4103 {
   4104     glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
   4105 }
   4106 
   4107 void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
   4108 {
   4109     TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
   4110 
   4111     try
   4112     {
   4113         gl::Context* context = gl::getContext();
   4114 
   4115         if (context)
   4116         {
   4117             context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
   4118         }
   4119     }
   4120     catch(std::bad_alloc&)
   4121     {
   4122         return error(GL_OUT_OF_MEMORY);
   4123     }
   4124 }
   4125 
   4126 void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
   4127 {
   4128     TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
   4129 
   4130     try
   4131     {
   4132         if (condition != GL_ALL_COMPLETED_NV)
   4133         {
   4134             return error(GL_INVALID_ENUM);
   4135         }
   4136 
   4137         gl::Context *context = gl::getContext();
   4138 
   4139         if (context)
   4140         {
   4141             gl::Fence *fenceObject = context->getFence(fence);
   4142 
   4143             if (fenceObject == NULL)
   4144             {
   4145                 return error(GL_INVALID_OPERATION);
   4146             }
   4147 
   4148             fenceObject->setFence(condition);
   4149         }
   4150     }
   4151     catch(std::bad_alloc&)
   4152     {
   4153         return error(GL_OUT_OF_MEMORY);
   4154     }
   4155 }
   4156 
   4157 void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
   4158 {
   4159     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
   4160 
   4161     try
   4162     {
   4163         if (width < 0 || height < 0)
   4164         {
   4165             return error(GL_INVALID_VALUE);
   4166         }
   4167 
   4168         gl::Context* context = gl::getContext();
   4169 
   4170         if (context)
   4171         {
   4172             context->setScissorParams(x, y, width, height);
   4173         }
   4174     }
   4175     catch(std::bad_alloc&)
   4176     {
   4177         return error(GL_OUT_OF_MEMORY);
   4178     }
   4179 }
   4180 
   4181 void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
   4182 {
   4183     TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
   4184           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
   4185           n, shaders, binaryformat, binary, length);
   4186 
   4187     try
   4188     {
   4189         // No binary shader formats are supported.
   4190         return error(GL_INVALID_ENUM);
   4191     }
   4192     catch(std::bad_alloc&)
   4193     {
   4194         return error(GL_OUT_OF_MEMORY);
   4195     }
   4196 }
   4197 
   4198 void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
   4199 {
   4200     TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
   4201           shader, count, string, length);
   4202 
   4203     try
   4204     {
   4205         if (count < 0)
   4206         {
   4207             return error(GL_INVALID_VALUE);
   4208         }
   4209 
   4210         gl::Context *context = gl::getContext();
   4211 
   4212         if (context)
   4213         {
   4214             gl::Shader *shaderObject = context->getShader(shader);
   4215 
   4216             if (!shaderObject)
   4217             {
   4218                 if (context->getProgram(shader))
   4219                 {
   4220                     return error(GL_INVALID_OPERATION);
   4221                 }
   4222                 else
   4223                 {
   4224                     return error(GL_INVALID_VALUE);
   4225                 }
   4226             }
   4227 
   4228             shaderObject->setSource(count, string, length);
   4229         }
   4230     }
   4231     catch(std::bad_alloc&)
   4232     {
   4233         return error(GL_OUT_OF_MEMORY);
   4234     }
   4235 }
   4236 
   4237 void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
   4238 {
   4239     glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
   4240 }
   4241 
   4242 void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
   4243 {
   4244     TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
   4245 
   4246     try
   4247     {
   4248         switch (face)
   4249         {
   4250           case GL_FRONT:
   4251           case GL_BACK:
   4252           case GL_FRONT_AND_BACK:
   4253             break;
   4254           default:
   4255             return error(GL_INVALID_ENUM);
   4256         }
   4257 
   4258         switch (func)
   4259         {
   4260           case GL_NEVER:
   4261           case GL_ALWAYS:
   4262           case GL_LESS:
   4263           case GL_LEQUAL:
   4264           case GL_EQUAL:
   4265           case GL_GEQUAL:
   4266           case GL_GREATER:
   4267           case GL_NOTEQUAL:
   4268             break;
   4269           default:
   4270             return error(GL_INVALID_ENUM);
   4271         }
   4272 
   4273         gl::Context *context = gl::getContext();
   4274 
   4275         if (context)
   4276         {
   4277             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   4278             {
   4279                 context->setStencilParams(func, ref, mask);
   4280             }
   4281 
   4282             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   4283             {
   4284                 context->setStencilBackParams(func, ref, mask);
   4285             }
   4286         }
   4287     }
   4288     catch(std::bad_alloc&)
   4289     {
   4290         return error(GL_OUT_OF_MEMORY);
   4291     }
   4292 }
   4293 
   4294 void __stdcall glStencilMask(GLuint mask)
   4295 {
   4296     glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
   4297 }
   4298 
   4299 void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
   4300 {
   4301     TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
   4302 
   4303     try
   4304     {
   4305         switch (face)
   4306         {
   4307           case GL_FRONT:
   4308           case GL_BACK:
   4309           case GL_FRONT_AND_BACK:
   4310             break;
   4311           default:
   4312             return error(GL_INVALID_ENUM);
   4313         }
   4314 
   4315         gl::Context *context = gl::getContext();
   4316 
   4317         if (context)
   4318         {
   4319             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   4320             {
   4321                 context->setStencilWritemask(mask);
   4322             }
   4323 
   4324             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   4325             {
   4326                 context->setStencilBackWritemask(mask);
   4327             }
   4328         }
   4329     }
   4330     catch(std::bad_alloc&)
   4331     {
   4332         return error(GL_OUT_OF_MEMORY);
   4333     }
   4334 }
   4335 
   4336 void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
   4337 {
   4338     glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
   4339 }
   4340 
   4341 void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
   4342 {
   4343     TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
   4344           face, fail, zfail, zpass);
   4345 
   4346     try
   4347     {
   4348         switch (face)
   4349         {
   4350           case GL_FRONT:
   4351           case GL_BACK:
   4352           case GL_FRONT_AND_BACK:
   4353             break;
   4354           default:
   4355             return error(GL_INVALID_ENUM);
   4356         }
   4357 
   4358         switch (fail)
   4359         {
   4360           case GL_ZERO:
   4361           case GL_KEEP:
   4362           case GL_REPLACE:
   4363           case GL_INCR:
   4364           case GL_DECR:
   4365           case GL_INVERT:
   4366           case GL_INCR_WRAP:
   4367           case GL_DECR_WRAP:
   4368             break;
   4369           default:
   4370             return error(GL_INVALID_ENUM);
   4371         }
   4372 
   4373         switch (zfail)
   4374         {
   4375           case GL_ZERO:
   4376           case GL_KEEP:
   4377           case GL_REPLACE:
   4378           case GL_INCR:
   4379           case GL_DECR:
   4380           case GL_INVERT:
   4381           case GL_INCR_WRAP:
   4382           case GL_DECR_WRAP:
   4383             break;
   4384           default:
   4385             return error(GL_INVALID_ENUM);
   4386         }
   4387 
   4388         switch (zpass)
   4389         {
   4390           case GL_ZERO:
   4391           case GL_KEEP:
   4392           case GL_REPLACE:
   4393           case GL_INCR:
   4394           case GL_DECR:
   4395           case GL_INVERT:
   4396           case GL_INCR_WRAP:
   4397           case GL_DECR_WRAP:
   4398             break;
   4399           default:
   4400             return error(GL_INVALID_ENUM);
   4401         }
   4402 
   4403         gl::Context *context = gl::getContext();
   4404 
   4405         if (context)
   4406         {
   4407             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   4408             {
   4409                 context->setStencilOperations(fail, zfail, zpass);
   4410             }
   4411 
   4412             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   4413             {
   4414                 context->setStencilBackOperations(fail, zfail, zpass);
   4415             }
   4416         }
   4417     }
   4418     catch(std::bad_alloc&)
   4419     {
   4420         return error(GL_OUT_OF_MEMORY);
   4421     }
   4422 }
   4423 
   4424 GLboolean __stdcall glTestFenceNV(GLuint fence)
   4425 {
   4426     TRACE("(GLuint fence = %d)", fence);
   4427 
   4428     try
   4429     {
   4430         gl::Context *context = gl::getContext();
   4431 
   4432         if (context)
   4433         {
   4434             gl::Fence *fenceObject = context->getFence(fence);
   4435 
   4436             if (fenceObject == NULL)
   4437             {
   4438                 return error(GL_INVALID_OPERATION, GL_TRUE);
   4439             }
   4440 
   4441             return fenceObject->testFence();
   4442         }
   4443     }
   4444     catch(std::bad_alloc&)
   4445     {
   4446         error(GL_OUT_OF_MEMORY);
   4447     }
   4448 
   4449     return GL_TRUE;
   4450 }
   4451 
   4452 void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
   4453                             GLint border, GLenum format, GLenum type, const GLvoid* pixels)
   4454 {
   4455     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
   4456           "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  0x%0.8p)",
   4457           target, level, internalformat, width, height, border, format, type, pixels);
   4458 
   4459     try
   4460     {
   4461         if (level < 0 || width < 0 || height < 0)
   4462         {
   4463             return error(GL_INVALID_VALUE);
   4464         }
   4465 
   4466         if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
   4467         {
   4468             return error(GL_INVALID_VALUE);
   4469         }
   4470 
   4471         if (internalformat != format)
   4472         {
   4473             return error(GL_INVALID_OPERATION);
   4474         }
   4475 
   4476         switch (internalformat)
   4477         {
   4478           case GL_ALPHA:
   4479           case GL_LUMINANCE:
   4480           case GL_LUMINANCE_ALPHA:
   4481             switch (type)
   4482             {
   4483               case GL_UNSIGNED_BYTE:
   4484               case GL_FLOAT:
   4485               case GL_HALF_FLOAT_OES:
   4486                 break;
   4487               default:
   4488                 return error(GL_INVALID_ENUM);
   4489             }
   4490             break;
   4491           case GL_RGB:
   4492             switch (type)
   4493             {
   4494               case GL_UNSIGNED_BYTE:
   4495               case GL_UNSIGNED_SHORT_5_6_5:
   4496               case GL_FLOAT:
   4497               case GL_HALF_FLOAT_OES:
   4498                 break;
   4499               default:
   4500                 return error(GL_INVALID_ENUM);
   4501             }
   4502             break;
   4503           case GL_RGBA:
   4504             switch (type)
   4505             {
   4506               case GL_UNSIGNED_BYTE:
   4507               case GL_UNSIGNED_SHORT_4_4_4_4:
   4508               case GL_UNSIGNED_SHORT_5_5_5_1:
   4509               case GL_FLOAT:
   4510               case GL_HALF_FLOAT_OES:
   4511                 break;
   4512               default:
   4513                 return error(GL_INVALID_ENUM);
   4514             }
   4515             break;
   4516           case GL_BGRA_EXT:
   4517             switch (type)
   4518             {
   4519               case GL_UNSIGNED_BYTE:
   4520                 break;
   4521               default:
   4522                 return error(GL_INVALID_ENUM);
   4523             }
   4524             break;
   4525           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
   4526           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
   4527             break;
   4528           default:
   4529             return error(GL_INVALID_VALUE);
   4530         }
   4531 
   4532         if (border != 0)
   4533         {
   4534             return error(GL_INVALID_VALUE);
   4535         }
   4536 
   4537         gl::Context *context = gl::getContext();
   4538 
   4539         if (context)
   4540         {
   4541             switch (target)
   4542             {
   4543               case GL_TEXTURE_2D:
   4544                 if (width > (context->getMaximumTextureDimension() >> level) ||
   4545                     height > (context->getMaximumTextureDimension() >> level))
   4546                 {
   4547                     return error(GL_INVALID_VALUE);
   4548                 }
   4549                 break;
   4550               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   4551               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   4552               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   4553               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   4554               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   4555               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   4556                 if (width != height)
   4557                 {
   4558                     return error(GL_INVALID_VALUE);
   4559                 }
   4560 
   4561                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
   4562                     height > (context->getMaximumCubeTextureDimension() >> level))
   4563                 {
   4564                     return error(GL_INVALID_VALUE);
   4565                 }
   4566                 break;
   4567               default:
   4568                 return error(GL_INVALID_ENUM);
   4569             }
   4570 
   4571             if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
   4572                 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
   4573             {
   4574                 if (context->supportsCompressedTextures())
   4575                 {
   4576                     return error(GL_INVALID_OPERATION);
   4577                 }
   4578                 else
   4579                 {
   4580                     return error(GL_INVALID_ENUM);
   4581                 }
   4582             }
   4583 
   4584             if (type == GL_FLOAT)
   4585             {
   4586                 if (!context->supportsFloatTextures())
   4587                 {
   4588                     return error(GL_INVALID_ENUM);
   4589                 }
   4590             }
   4591             else if (type == GL_HALF_FLOAT_OES)
   4592             {
   4593                 if (!context->supportsHalfFloatTextures())
   4594                 {
   4595                     return error(GL_INVALID_ENUM);
   4596                 }
   4597             }
   4598 
   4599             if (target == GL_TEXTURE_2D)
   4600             {
   4601                 gl::Texture2D *texture = context->getTexture2D();
   4602 
   4603                 if (!texture)
   4604                 {
   4605                     return error(GL_INVALID_OPERATION);
   4606                 }
   4607 
   4608                 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4609             }
   4610             else
   4611             {
   4612                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4613 
   4614                 if (!texture)
   4615                 {
   4616                     return error(GL_INVALID_OPERATION);
   4617                 }
   4618 
   4619                 switch (target)
   4620                 {
   4621                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
   4622                     texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4623                     break;
   4624                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
   4625                     texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4626                     break;
   4627                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
   4628                     texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4629                     break;
   4630                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
   4631                     texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4632                     break;
   4633                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
   4634                     texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4635                     break;
   4636                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
   4637                     texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
   4638                     break;
   4639                   default: UNREACHABLE();
   4640                 }
   4641             }
   4642         }
   4643     }
   4644     catch(std::bad_alloc&)
   4645     {
   4646         return error(GL_OUT_OF_MEMORY);
   4647     }
   4648 }
   4649 
   4650 void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
   4651 {
   4652     glTexParameteri(target, pname, (GLint)param);
   4653 }
   4654 
   4655 void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
   4656 {
   4657     glTexParameteri(target, pname, (GLint)*params);
   4658 }
   4659 
   4660 void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
   4661 {
   4662     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
   4663 
   4664     try
   4665     {
   4666         gl::Context *context = gl::getContext();
   4667 
   4668         if (context)
   4669         {
   4670             gl::Texture *texture;
   4671 
   4672             switch (target)
   4673             {
   4674               case GL_TEXTURE_2D:
   4675                 texture = context->getTexture2D();
   4676                 break;
   4677               case GL_TEXTURE_CUBE_MAP:
   4678                 texture = context->getTextureCubeMap();
   4679                 break;
   4680               default:
   4681                 return error(GL_INVALID_ENUM);
   4682             }
   4683 
   4684             switch (pname)
   4685             {
   4686               case GL_TEXTURE_WRAP_S:
   4687                 if (!texture->setWrapS((GLenum)param))
   4688                 {
   4689                     return error(GL_INVALID_ENUM);
   4690                 }
   4691                 break;
   4692               case GL_TEXTURE_WRAP_T:
   4693                 if (!texture->setWrapT((GLenum)param))
   4694                 {
   4695                     return error(GL_INVALID_ENUM);
   4696                 }
   4697                 break;
   4698               case GL_TEXTURE_MIN_FILTER:
   4699                 if (!texture->setMinFilter((GLenum)param))
   4700                 {
   4701                     return error(GL_INVALID_ENUM);
   4702                 }
   4703                 break;
   4704               case GL_TEXTURE_MAG_FILTER:
   4705                 if (!texture->setMagFilter((GLenum)param))
   4706                 {
   4707                     return error(GL_INVALID_ENUM);
   4708                 }
   4709                 break;
   4710               default:
   4711                 return error(GL_INVALID_ENUM);
   4712             }
   4713         }
   4714     }
   4715     catch(std::bad_alloc&)
   4716     {
   4717         return error(GL_OUT_OF_MEMORY);
   4718     }
   4719 }
   4720 
   4721 void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
   4722 {
   4723     glTexParameteri(target, pname, *params);
   4724 }
   4725 
   4726 void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
   4727                                GLenum format, GLenum type, const GLvoid* pixels)
   4728 {
   4729     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
   4730           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
   4731           "const GLvoid* pixels = 0x%0.8p)",
   4732            target, level, xoffset, yoffset, width, height, format, type, pixels);
   4733 
   4734     try
   4735     {
   4736         if (!gl::IsTextureTarget(target))
   4737         {
   4738             return error(GL_INVALID_ENUM);
   4739         }
   4740 
   4741         if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
   4742         {
   4743             return error(GL_INVALID_VALUE);
   4744         }
   4745 
   4746         if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
   4747         {
   4748             return error(GL_INVALID_VALUE);
   4749         }
   4750 
   4751         if (!gl::CheckTextureFormatType(format, type))
   4752         {
   4753             return error(GL_INVALID_ENUM);
   4754         }
   4755 
   4756         if (width == 0 || height == 0 || pixels == NULL)
   4757         {
   4758             return;
   4759         }
   4760 
   4761         gl::Context *context = gl::getContext();
   4762 
   4763         if (context)
   4764         {
   4765             if (level > context->getMaximumTextureLevel())
   4766             {
   4767                 return error(GL_INVALID_VALUE);
   4768             }
   4769 
   4770             if (format == GL_FLOAT)
   4771             {
   4772                 if (!context->supportsFloatTextures())
   4773                 {
   4774                     return error(GL_INVALID_ENUM);
   4775                 }
   4776             }
   4777             else if (format == GL_HALF_FLOAT_OES)
   4778             {
   4779                 if (!context->supportsHalfFloatTextures())
   4780                 {
   4781                     return error(GL_INVALID_ENUM);
   4782                 }
   4783             }
   4784 
   4785             if (target == GL_TEXTURE_2D)
   4786             {
   4787                 gl::Texture2D *texture = context->getTexture2D();
   4788 
   4789                 if (!texture)
   4790                 {
   4791                     return error(GL_INVALID_OPERATION);
   4792                 }
   4793 
   4794                 if (texture->isCompressed())
   4795                 {
   4796                     return error(GL_INVALID_OPERATION);
   4797                 }
   4798 
   4799                 if (format != texture->getFormat())
   4800                 {
   4801                     return error(GL_INVALID_OPERATION);
   4802                 }
   4803 
   4804                 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
   4805             }
   4806             else if (gl::IsCubemapTextureTarget(target))
   4807             {
   4808                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
   4809 
   4810                 if (!texture)
   4811                 {
   4812                     return error(GL_INVALID_OPERATION);
   4813                 }
   4814 
   4815                 if (texture->isCompressed())
   4816                 {
   4817                     return error(GL_INVALID_OPERATION);
   4818                 }
   4819 
   4820                 if (format != texture->getFormat())
   4821                 {
   4822                     return error(GL_INVALID_OPERATION);
   4823                 }
   4824 
   4825                 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
   4826             }
   4827             else
   4828             {
   4829                 UNREACHABLE();
   4830             }
   4831         }
   4832     }
   4833     catch(std::bad_alloc&)
   4834     {
   4835         return error(GL_OUT_OF_MEMORY);
   4836     }
   4837 }
   4838 
   4839 void __stdcall glUniform1f(GLint location, GLfloat x)
   4840 {
   4841     glUniform1fv(location, 1, &x);
   4842 }
   4843 
   4844 void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
   4845 {
   4846     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   4847 
   4848     try
   4849     {
   4850         if (count < 0)
   4851         {
   4852             return error(GL_INVALID_VALUE);
   4853         }
   4854 
   4855         if (location == -1)
   4856         {
   4857             return;
   4858         }
   4859 
   4860         gl::Context *context = gl::getContext();
   4861 
   4862         if (context)
   4863         {
   4864             gl::Program *program = context->getCurrentProgram();
   4865 
   4866             if (!program)
   4867             {
   4868                 return error(GL_INVALID_OPERATION);
   4869             }
   4870 
   4871             if (!program->setUniform1fv(location, count, v))
   4872             {
   4873                 return error(GL_INVALID_OPERATION);
   4874             }
   4875         }
   4876     }
   4877     catch(std::bad_alloc&)
   4878     {
   4879         return error(GL_OUT_OF_MEMORY);
   4880     }
   4881 }
   4882 
   4883 void __stdcall glUniform1i(GLint location, GLint x)
   4884 {
   4885     glUniform1iv(location, 1, &x);
   4886 }
   4887 
   4888 void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
   4889 {
   4890     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   4891 
   4892     try
   4893     {
   4894         if (count < 0)
   4895         {
   4896             return error(GL_INVALID_VALUE);
   4897         }
   4898 
   4899         if (location == -1)
   4900         {
   4901             return;
   4902         }
   4903 
   4904         gl::Context *context = gl::getContext();
   4905 
   4906         if (context)
   4907         {
   4908             gl::Program *program = context->getCurrentProgram();
   4909 
   4910             if (!program)
   4911             {
   4912                 return error(GL_INVALID_OPERATION);
   4913             }
   4914 
   4915             if (!program->setUniform1iv(location, count, v))
   4916             {
   4917                 return error(GL_INVALID_OPERATION);
   4918             }
   4919         }
   4920     }
   4921     catch(std::bad_alloc&)
   4922     {
   4923         return error(GL_OUT_OF_MEMORY);
   4924     }
   4925 }
   4926 
   4927 void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
   4928 {
   4929     GLfloat xy[2] = {x, y};
   4930 
   4931     glUniform2fv(location, 1, (GLfloat*)&xy);
   4932 }
   4933 
   4934 void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
   4935 {
   4936     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   4937 
   4938     try
   4939     {
   4940         if (count < 0)
   4941         {
   4942             return error(GL_INVALID_VALUE);
   4943         }
   4944 
   4945         if (location == -1)
   4946         {
   4947             return;
   4948         }
   4949 
   4950         gl::Context *context = gl::getContext();
   4951 
   4952         if (context)
   4953         {
   4954             gl::Program *program = context->getCurrentProgram();
   4955 
   4956             if (!program)
   4957             {
   4958                 return error(GL_INVALID_OPERATION);
   4959             }
   4960 
   4961             if (!program->setUniform2fv(location, count, v))
   4962             {
   4963                 return error(GL_INVALID_OPERATION);
   4964             }
   4965         }
   4966     }
   4967     catch(std::bad_alloc&)
   4968     {
   4969         return error(GL_OUT_OF_MEMORY);
   4970     }
   4971 }
   4972 
   4973 void __stdcall glUniform2i(GLint location, GLint x, GLint y)
   4974 {
   4975     GLint xy[4] = {x, y};
   4976 
   4977     glUniform2iv(location, 1, (GLint*)&xy);
   4978 }
   4979 
   4980 void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
   4981 {
   4982     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   4983 
   4984     try
   4985     {
   4986         if (count < 0)
   4987         {
   4988             return error(GL_INVALID_VALUE);
   4989         }
   4990 
   4991         if (location == -1)
   4992         {
   4993             return;
   4994         }
   4995 
   4996         gl::Context *context = gl::getContext();
   4997 
   4998         if (context)
   4999         {
   5000             gl::Program *program = context->getCurrentProgram();
   5001 
   5002             if (!program)
   5003             {
   5004                 return error(GL_INVALID_OPERATION);
   5005             }
   5006 
   5007             if (!program->setUniform2iv(location, count, v))
   5008             {
   5009                 return error(GL_INVALID_OPERATION);
   5010             }
   5011         }
   5012     }
   5013     catch(std::bad_alloc&)
   5014     {
   5015         return error(GL_OUT_OF_MEMORY);
   5016     }
   5017 }
   5018 
   5019 void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
   5020 {
   5021     GLfloat xyz[3] = {x, y, z};
   5022 
   5023     glUniform3fv(location, 1, (GLfloat*)&xyz);
   5024 }
   5025 
   5026 void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
   5027 {
   5028     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   5029 
   5030     try
   5031     {
   5032         if (count < 0)
   5033         {
   5034             return error(GL_INVALID_VALUE);
   5035         }
   5036 
   5037         if (location == -1)
   5038         {
   5039             return;
   5040         }
   5041 
   5042         gl::Context *context = gl::getContext();
   5043 
   5044         if (context)
   5045         {
   5046             gl::Program *program = context->getCurrentProgram();
   5047 
   5048             if (!program)
   5049             {
   5050                 return error(GL_INVALID_OPERATION);
   5051             }
   5052 
   5053             if (!program->setUniform3fv(location, count, v))
   5054             {
   5055                 return error(GL_INVALID_OPERATION);
   5056             }
   5057         }
   5058     }
   5059     catch(std::bad_alloc&)
   5060     {
   5061         return error(GL_OUT_OF_MEMORY);
   5062     }
   5063 }
   5064 
   5065 void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
   5066 {
   5067     GLint xyz[3] = {x, y, z};
   5068 
   5069     glUniform3iv(location, 1, (GLint*)&xyz);
   5070 }
   5071 
   5072 void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
   5073 {
   5074     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   5075 
   5076     try
   5077     {
   5078         if (count < 0)
   5079         {
   5080             return error(GL_INVALID_VALUE);
   5081         }
   5082 
   5083         if (location == -1)
   5084         {
   5085             return;
   5086         }
   5087 
   5088         gl::Context *context = gl::getContext();
   5089 
   5090         if (context)
   5091         {
   5092             gl::Program *program = context->getCurrentProgram();
   5093 
   5094             if (!program)
   5095             {
   5096                 return error(GL_INVALID_OPERATION);
   5097             }
   5098 
   5099             if (!program->setUniform3iv(location, count, v))
   5100             {
   5101                 return error(GL_INVALID_OPERATION);
   5102             }
   5103         }
   5104     }
   5105     catch(std::bad_alloc&)
   5106     {
   5107         return error(GL_OUT_OF_MEMORY);
   5108     }
   5109 }
   5110 
   5111 void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   5112 {
   5113     GLfloat xyzw[4] = {x, y, z, w};
   5114 
   5115     glUniform4fv(location, 1, (GLfloat*)&xyzw);
   5116 }
   5117 
   5118 void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
   5119 {
   5120     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
   5121 
   5122     try
   5123     {
   5124         if (count < 0)
   5125         {
   5126             return error(GL_INVALID_VALUE);
   5127         }
   5128 
   5129         if (location == -1)
   5130         {
   5131             return;
   5132         }
   5133 
   5134         gl::Context *context = gl::getContext();
   5135 
   5136         if (context)
   5137         {
   5138             gl::Program *program = context->getCurrentProgram();
   5139 
   5140             if (!program)
   5141             {
   5142                 return error(GL_INVALID_OPERATION);
   5143             }
   5144 
   5145             if (!program->setUniform4fv(location, count, v))
   5146             {
   5147                 return error(GL_INVALID_OPERATION);
   5148             }
   5149         }
   5150     }
   5151     catch(std::bad_alloc&)
   5152     {
   5153         return error(GL_OUT_OF_MEMORY);
   5154     }
   5155 }
   5156 
   5157 void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
   5158 {
   5159     GLint xyzw[4] = {x, y, z, w};
   5160 
   5161     glUniform4iv(location, 1, (GLint*)&xyzw);
   5162 }
   5163 
   5164 void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
   5165 {
   5166     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
   5167 
   5168     try
   5169     {
   5170         if (count < 0)
   5171         {
   5172             return error(GL_INVALID_VALUE);
   5173         }
   5174 
   5175         if (location == -1)
   5176         {
   5177             return;
   5178         }
   5179 
   5180         gl::Context *context = gl::getContext();
   5181 
   5182         if (context)
   5183         {
   5184             gl::Program *program = context->getCurrentProgram();
   5185 
   5186             if (!program)
   5187             {
   5188                 return error(GL_INVALID_OPERATION);
   5189             }
   5190 
   5191             if (!program->setUniform4iv(location, count, v))
   5192             {
   5193                 return error(GL_INVALID_OPERATION);
   5194             }
   5195         }
   5196     }
   5197     catch(std::bad_alloc&)
   5198     {
   5199         return error(GL_OUT_OF_MEMORY);
   5200     }
   5201 }
   5202 
   5203 void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   5204 {
   5205     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
   5206           location, count, transpose, value);
   5207 
   5208     try
   5209     {
   5210         if (count < 0 || transpose != GL_FALSE)
   5211         {
   5212             return error(GL_INVALID_VALUE);
   5213         }
   5214 
   5215         if (location == -1)
   5216         {
   5217             return;
   5218         }
   5219 
   5220         gl::Context *context = gl::getContext();
   5221 
   5222         if (context)
   5223         {
   5224             gl::Program *program = context->getCurrentProgram();
   5225 
   5226             if (!program)
   5227             {
   5228                 return error(GL_INVALID_OPERATION);
   5229             }
   5230 
   5231             if (!program->setUniformMatrix2fv(location, count, value))
   5232             {
   5233                 return error(GL_INVALID_OPERATION);
   5234             }
   5235         }
   5236     }
   5237     catch(std::bad_alloc&)
   5238     {
   5239         return error(GL_OUT_OF_MEMORY);
   5240     }
   5241 }
   5242 
   5243 void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   5244 {
   5245     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
   5246           location, count, transpose, value);
   5247 
   5248     try
   5249     {
   5250         if (count < 0 || transpose != GL_FALSE)
   5251         {
   5252             return error(GL_INVALID_VALUE);
   5253         }
   5254 
   5255         if (location == -1)
   5256         {
   5257             return;
   5258         }
   5259 
   5260         gl::Context *context = gl::getContext();
   5261 
   5262         if (context)
   5263         {
   5264             gl::Program *program = context->getCurrentProgram();
   5265 
   5266             if (!program)
   5267             {
   5268                 return error(GL_INVALID_OPERATION);
   5269             }
   5270 
   5271             if (!program->setUniformMatrix3fv(location, count, value))
   5272             {
   5273                 return error(GL_INVALID_OPERATION);
   5274             }
   5275         }
   5276     }
   5277     catch(std::bad_alloc&)
   5278     {
   5279         return error(GL_OUT_OF_MEMORY);
   5280     }
   5281 }
   5282 
   5283 void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
   5284 {
   5285     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
   5286           location, count, transpose, value);
   5287 
   5288     try
   5289     {
   5290         if (count < 0 || transpose != GL_FALSE)
   5291         {
   5292             return error(GL_INVALID_VALUE);
   5293         }
   5294 
   5295         if (location == -1)
   5296         {
   5297             return;
   5298         }
   5299 
   5300         gl::Context *context = gl::getContext();
   5301 
   5302         if (context)
   5303         {
   5304             gl::Program *program = context->getCurrentProgram();
   5305 
   5306             if (!program)
   5307             {
   5308                 return error(GL_INVALID_OPERATION);
   5309             }
   5310 
   5311             if (!program->setUniformMatrix4fv(location, count, value))
   5312             {
   5313                 return error(GL_INVALID_OPERATION);
   5314             }
   5315         }
   5316     }
   5317     catch(std::bad_alloc&)
   5318     {
   5319         return error(GL_OUT_OF_MEMORY);
   5320     }
   5321 }
   5322 
   5323 void __stdcall glUseProgram(GLuint program)
   5324 {
   5325     TRACE("(GLuint program = %d)", program);
   5326 
   5327     try
   5328     {
   5329         gl::Context *context = gl::getContext();
   5330 
   5331         if (context)
   5332         {
   5333             gl::Program *programObject = context->getProgram(program);
   5334 
   5335             if (!programObject && program != 0)
   5336             {
   5337                 if (context->getShader(program))
   5338                 {
   5339                     return error(GL_INVALID_OPERATION);
   5340                 }
   5341                 else
   5342                 {
   5343                     return error(GL_INVALID_VALUE);
   5344                 }
   5345             }
   5346 
   5347             if (program != 0 && !programObject->isLinked())
   5348             {
   5349                 return error(GL_INVALID_OPERATION);
   5350             }
   5351 
   5352             context->useProgram(program);
   5353         }
   5354     }
   5355     catch(std::bad_alloc&)
   5356     {
   5357         return error(GL_OUT_OF_MEMORY);
   5358     }
   5359 }
   5360 
   5361 void __stdcall glValidateProgram(GLuint program)
   5362 {
   5363     TRACE("(GLuint program = %d)", program);
   5364 
   5365     try
   5366     {
   5367         gl::Context *context = gl::getContext();
   5368 
   5369         if (context)
   5370         {
   5371             gl::Program *programObject = context->getProgram(program);
   5372 
   5373             if (!programObject)
   5374             {
   5375                 if (context->getShader(program))
   5376                 {
   5377                     return error(GL_INVALID_OPERATION);
   5378                 }
   5379                 else
   5380                 {
   5381                     return error(GL_INVALID_VALUE);
   5382                 }
   5383             }
   5384 
   5385             programObject->validate();
   5386         }
   5387     }
   5388     catch(std::bad_alloc&)
   5389     {
   5390         return error(GL_OUT_OF_MEMORY);
   5391     }
   5392 }
   5393 
   5394 void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
   5395 {
   5396     TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
   5397 
   5398     try
   5399     {
   5400         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5401         {
   5402             return error(GL_INVALID_VALUE);
   5403         }
   5404 
   5405         gl::Context *context = gl::getContext();
   5406 
   5407         if (context)
   5408         {
   5409             GLfloat vals[4] = { x, 0, 0, 1 };
   5410             context->setVertexAttrib(index, vals);
   5411         }
   5412     }
   5413     catch(std::bad_alloc&)
   5414     {
   5415         return error(GL_OUT_OF_MEMORY);
   5416     }
   5417 }
   5418 
   5419 void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
   5420 {
   5421     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5422 
   5423     try
   5424     {
   5425         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5426         {
   5427             return error(GL_INVALID_VALUE);
   5428         }
   5429 
   5430         gl::Context *context = gl::getContext();
   5431 
   5432         if (context)
   5433         {
   5434             GLfloat vals[4] = { values[0], 0, 0, 1 };
   5435             context->setVertexAttrib(index, vals);
   5436         }
   5437     }
   5438     catch(std::bad_alloc&)
   5439     {
   5440         return error(GL_OUT_OF_MEMORY);
   5441     }
   5442 }
   5443 
   5444 void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
   5445 {
   5446     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
   5447 
   5448     try
   5449     {
   5450         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5451         {
   5452             return error(GL_INVALID_VALUE);
   5453         }
   5454 
   5455         gl::Context *context = gl::getContext();
   5456 
   5457         if (context)
   5458         {
   5459             GLfloat vals[4] = { x, y, 0, 1 };
   5460             context->setVertexAttrib(index, vals);
   5461         }
   5462     }
   5463     catch(std::bad_alloc&)
   5464     {
   5465         return error(GL_OUT_OF_MEMORY);
   5466     }
   5467 }
   5468 
   5469 void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
   5470 {
   5471     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5472 
   5473     try
   5474     {
   5475         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5476         {
   5477             return error(GL_INVALID_VALUE);
   5478         }
   5479 
   5480         gl::Context *context = gl::getContext();
   5481 
   5482         if (context)
   5483         {
   5484             GLfloat vals[4] = { values[0], values[1], 0, 1 };
   5485             context->setVertexAttrib(index, vals);
   5486         }
   5487     }
   5488     catch(std::bad_alloc&)
   5489     {
   5490         return error(GL_OUT_OF_MEMORY);
   5491     }
   5492 }
   5493 
   5494 void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
   5495 {
   5496     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
   5497 
   5498     try
   5499     {
   5500         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5501         {
   5502             return error(GL_INVALID_VALUE);
   5503         }
   5504 
   5505         gl::Context *context = gl::getContext();
   5506 
   5507         if (context)
   5508         {
   5509             GLfloat vals[4] = { x, y, z, 1 };
   5510             context->setVertexAttrib(index, vals);
   5511         }
   5512     }
   5513     catch(std::bad_alloc&)
   5514     {
   5515         return error(GL_OUT_OF_MEMORY);
   5516     }
   5517 }
   5518 
   5519 void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
   5520 {
   5521     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5522 
   5523     try
   5524     {
   5525         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5526         {
   5527             return error(GL_INVALID_VALUE);
   5528         }
   5529 
   5530         gl::Context *context = gl::getContext();
   5531 
   5532         if (context)
   5533         {
   5534             GLfloat vals[4] = { values[0], values[1], values[2], 1 };
   5535             context->setVertexAttrib(index, vals);
   5536         }
   5537     }
   5538     catch(std::bad_alloc&)
   5539     {
   5540         return error(GL_OUT_OF_MEMORY);
   5541     }
   5542 }
   5543 
   5544 void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   5545 {
   5546     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
   5547 
   5548     try
   5549     {
   5550         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5551         {
   5552             return error(GL_INVALID_VALUE);
   5553         }
   5554 
   5555         gl::Context *context = gl::getContext();
   5556 
   5557         if (context)
   5558         {
   5559             GLfloat vals[4] = { x, y, z, w };
   5560             context->setVertexAttrib(index, vals);
   5561         }
   5562     }
   5563     catch(std::bad_alloc&)
   5564     {
   5565         return error(GL_OUT_OF_MEMORY);
   5566     }
   5567 }
   5568 
   5569 void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
   5570 {
   5571     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
   5572 
   5573     try
   5574     {
   5575         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5576         {
   5577             return error(GL_INVALID_VALUE);
   5578         }
   5579 
   5580         gl::Context *context = gl::getContext();
   5581 
   5582         if (context)
   5583         {
   5584             context->setVertexAttrib(index, values);
   5585         }
   5586     }
   5587     catch(std::bad_alloc&)
   5588     {
   5589         return error(GL_OUT_OF_MEMORY);
   5590     }
   5591 }
   5592 
   5593 void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
   5594 {
   5595     TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
   5596           "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
   5597           index, size, type, normalized, stride, ptr);
   5598 
   5599     try
   5600     {
   5601         if (index >= gl::MAX_VERTEX_ATTRIBS)
   5602         {
   5603             return error(GL_INVALID_VALUE);
   5604         }
   5605 
   5606         if (size < 1 || size > 4)
   5607         {
   5608             return error(GL_INVALID_VALUE);
   5609         }
   5610 
   5611         switch (type)
   5612         {
   5613           case GL_BYTE:
   5614           case GL_UNSIGNED_BYTE:
   5615           case GL_SHORT:
   5616           case GL_UNSIGNED_SHORT:
   5617           case GL_FIXED:
   5618           case GL_FLOAT:
   5619             break;
   5620           default:
   5621             return error(GL_INVALID_ENUM);
   5622         }
   5623 
   5624         if (stride < 0)
   5625         {
   5626             return error(GL_INVALID_VALUE);
   5627         }
   5628 
   5629         gl::Context *context = gl::getContext();
   5630 
   5631         if (context)
   5632         {
   5633             context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
   5634         }
   5635     }
   5636     catch(std::bad_alloc&)
   5637     {
   5638         return error(GL_OUT_OF_MEMORY);
   5639     }
   5640 }
   5641 
   5642 void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
   5643 {
   5644     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
   5645 
   5646     try
   5647     {
   5648         if (width < 0 || height < 0)
   5649         {
   5650             return error(GL_INVALID_VALUE);
   5651         }
   5652 
   5653         gl::Context *context = gl::getContext();
   5654 
   5655         if (context)
   5656         {
   5657             context->setViewportParams(x, y, width, height);
   5658         }
   5659     }
   5660     catch(std::bad_alloc&)
   5661     {
   5662         return error(GL_OUT_OF_MEMORY);
   5663     }
   5664 }
   5665 
   5666 void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   5667                                       GLbitfield mask, GLenum filter)
   5668 {
   5669     TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
   5670           "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
   5671           "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
   5672           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   5673 
   5674     try
   5675     {
   5676         switch (filter)
   5677         {
   5678           case GL_NEAREST:
   5679             break;
   5680           default:
   5681             return error(GL_INVALID_ENUM);
   5682         }
   5683 
   5684         if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
   5685         {
   5686             return error(GL_INVALID_VALUE);
   5687         }
   5688 
   5689         if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
   5690         {
   5691             ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
   5692             return error(GL_INVALID_OPERATION);
   5693         }
   5694 
   5695         gl::Context *context = gl::getContext();
   5696 
   5697         if (context)
   5698         {
   5699             if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
   5700             {
   5701                 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
   5702                 return error(GL_INVALID_OPERATION);
   5703             }
   5704 
   5705             context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
   5706         }
   5707     }
   5708     catch(std::bad_alloc&)
   5709     {
   5710         return error(GL_OUT_OF_MEMORY);
   5711     }
   5712 }
   5713 
   5714 void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
   5715                                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
   5716 {
   5717     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
   5718           "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
   5719           "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
   5720           target, level, internalformat, width, height, depth, border, format, type, pixels);
   5721 
   5722     try
   5723     {
   5724         UNIMPLEMENTED();   // FIXME
   5725     }
   5726     catch(std::bad_alloc&)
   5727     {
   5728         return error(GL_OUT_OF_MEMORY);
   5729     }
   5730 }
   5731 
   5732 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
   5733 {
   5734     struct Extension
   5735     {
   5736         const char *name;
   5737         __eglMustCastToProperFunctionPointerType address;
   5738     };
   5739 
   5740     static const Extension glExtensions[] =
   5741     {
   5742         {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
   5743         {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
   5744         {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
   5745         {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
   5746         {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
   5747         {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
   5748         {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
   5749         {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
   5750         {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
   5751         {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
   5752     };
   5753 
   5754     for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
   5755     {
   5756         if (strcmp(procname, glExtensions[ext].name) == 0)
   5757         {
   5758             return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
   5759         }
   5760     }
   5761 
   5762     return NULL;
   5763 }
   5764 
   5765 }
   5766