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