gfx/angle/src/libGLESv2/libGLESv2.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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 //
     8 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
    10 #include "common/version.h"
    12 #include <algorithm>
    14 #include "libGLESv2/main.h"
    15 #include "libGLESv2/utilities.h"
    16 #include "libGLESv2/Buffer.h"
    17 #include "libGLESv2/Fence.h"
    18 #include "libGLESv2/Framebuffer.h"
    19 #include "libGLESv2/Renderbuffer.h"
    20 #include "libGLESv2/Program.h"
    21 #include "libGLESv2/ProgramBinary.h"
    22 #include "libGLESv2/Texture.h"
    23 #include "libGLESv2/Query.h"
    24 #include "libGLESv2/Context.h"
    26 bool validImageSize(GLint level, GLsizei width, GLsizei height)
    27 {
    28     if (level < 0 || width < 0 || height < 0)
    29     {
    30         return false;
    31     }
    33     if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
    34     {
    35         return true;
    36     }
    38     if (level == 0)
    39     {
    40         return true;
    41     }
    43     if (gl::isPow2(width) && gl::isPow2(height))
    44     {
    45         return true;
    46     }
    48     return false;
    49 }
    51 // Verify that format/type are one of the combinations from table 3.4.
    52 bool checkTextureFormatType(GLenum format, GLenum type)
    53 {
    54     // validate <format> by itself (used as secondary key below)
    55     switch (format)
    56     {
    57       case GL_RGBA:
    58       case GL_BGRA_EXT:
    59       case GL_RGB:
    60       case GL_ALPHA:
    61       case GL_LUMINANCE:
    62       case GL_LUMINANCE_ALPHA:
    63       case GL_DEPTH_COMPONENT:
    64       case GL_DEPTH_STENCIL_OES:
    65         break;
    66       default:
    67         return gl::error(GL_INVALID_ENUM, false);
    68     }
    70     // invalid <type> -> sets INVALID_ENUM
    71     // invalid <format>+<type> combination -> sets INVALID_OPERATION
    72     switch (type)
    73     {
    74       case GL_UNSIGNED_BYTE:
    75         switch (format)
    76         {
    77           case GL_RGBA:
    78           case GL_BGRA_EXT:
    79           case GL_RGB:
    80           case GL_ALPHA:
    81           case GL_LUMINANCE:
    82           case GL_LUMINANCE_ALPHA:
    83             return true;
    84           default:
    85             return gl::error(GL_INVALID_OPERATION, false);
    86         }
    88       case GL_FLOAT:
    89       case GL_HALF_FLOAT_OES:
    90         switch (format)
    91         {
    92           case GL_RGBA:
    93           case GL_RGB:
    94           case GL_ALPHA:
    95           case GL_LUMINANCE:
    96           case GL_LUMINANCE_ALPHA:
    97             return true;
    98           default:
    99             return gl::error(GL_INVALID_OPERATION, false);
   100         }
   102       case GL_UNSIGNED_SHORT_4_4_4_4:
   103       case GL_UNSIGNED_SHORT_5_5_5_1:
   104         switch (format)
   105         {
   106           case GL_RGBA:
   107             return true;
   108           default:
   109             return gl::error(GL_INVALID_OPERATION, false);
   110         }
   112       case GL_UNSIGNED_SHORT_5_6_5:
   113         switch (format)
   114         {
   115           case GL_RGB:
   116             return true;
   117           default:
   118             return gl::error(GL_INVALID_OPERATION, false);
   119         }
   121       case GL_UNSIGNED_SHORT:
   122       case GL_UNSIGNED_INT:
   123         switch (format)
   124         {
   125           case GL_DEPTH_COMPONENT:
   126             return true;
   127           default:
   128             return gl::error(GL_INVALID_OPERATION, false);
   129         }
   131       case GL_UNSIGNED_INT_24_8_OES:
   132         switch (format)
   133         {
   134           case GL_DEPTH_STENCIL_OES:
   135             return true;
   136           default:
   137             return gl::error(GL_INVALID_OPERATION, false);
   138         }
   140       default:
   141         return gl::error(GL_INVALID_ENUM, false);
   142     }
   143 }
   145 bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
   146                               GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
   147                               gl::Texture2D *texture)
   148 {
   149     if (!texture)
   150     {
   151         return gl::error(GL_INVALID_OPERATION, false);
   152     }
   154     if (compressed != texture->isCompressed(level))
   155     {
   156         return gl::error(GL_INVALID_OPERATION, false);
   157     }
   159     if (format != GL_NONE)
   160     {
   161         GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
   162         if (internalformat != texture->getInternalFormat(level))
   163         {
   164             return gl::error(GL_INVALID_OPERATION, false);
   165         }
   166     }
   168     if (compressed)
   169     {
   170         if ((width % 4 != 0 && width != texture->getWidth(0)) ||
   171             (height % 4 != 0 && height != texture->getHeight(0)))
   172         {
   173             return gl::error(GL_INVALID_OPERATION, false);
   174         }
   175     }
   177     if (xoffset + width > texture->getWidth(level) ||
   178         yoffset + height > texture->getHeight(level))
   179     {
   180         return gl::error(GL_INVALID_VALUE, false);
   181     }
   183     return true;
   184 }
   186 bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
   187                                 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
   188                                 gl::TextureCubeMap *texture)
   189 {
   190     if (!texture)
   191     {
   192         return gl::error(GL_INVALID_OPERATION, false);
   193     }
   195     if (compressed != texture->isCompressed(target, level))
   196     {
   197         return gl::error(GL_INVALID_OPERATION, false);
   198     }
   200     if (format != GL_NONE)
   201     {
   202         GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
   203         if (internalformat != texture->getInternalFormat(target, level))
   204         {
   205             return gl::error(GL_INVALID_OPERATION, false);
   206         }
   207     }
   209     if (compressed)
   210     {
   211         if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
   212             (height % 4 != 0 && height != texture->getHeight(target, 0)))
   213         {
   214             return gl::error(GL_INVALID_OPERATION, false);
   215         }
   216     }
   218     if (xoffset + width > texture->getWidth(target, level) ||
   219         yoffset + height > texture->getHeight(target, level))
   220     {
   221         return gl::error(GL_INVALID_VALUE, false);
   222     }
   224     return true;
   225 }
   227 // check for combinations of format and type that are valid for ReadPixels
   228 bool validReadFormatType(GLenum format, GLenum type)
   229 {
   230     switch (format)
   231     {
   232       case GL_RGBA:
   233         switch (type)
   234         {
   235           case GL_UNSIGNED_BYTE:
   236             break;
   237           default:
   238             return false;
   239         }
   240         break;
   241       case GL_BGRA_EXT:
   242         switch (type)
   243         {
   244           case GL_UNSIGNED_BYTE:
   245           case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
   246           case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
   247             break;
   248           default:
   249             return false;
   250         }
   251         break;
   252       default:
   253         return false;
   254     }
   255     return true;
   256 }
   258 extern "C"
   259 {
   261 void __stdcall glActiveTexture(GLenum texture)
   262 {
   263     EVENT("(GLenum texture = 0x%X)", texture);
   265     try
   266     {
   267         gl::Context *context = gl::getNonLostContext();
   269         if (context)
   270         {
   271             if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
   272             {
   273                 return gl::error(GL_INVALID_ENUM);
   274             }
   276             context->setActiveSampler(texture - GL_TEXTURE0);
   277         }
   278     }
   279     catch(std::bad_alloc&)
   280     {
   281         return gl::error(GL_OUT_OF_MEMORY);
   282     }
   283 }
   285 void __stdcall glAttachShader(GLuint program, GLuint shader)
   286 {
   287     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
   289     try
   290     {
   291         gl::Context *context = gl::getNonLostContext();
   293         if (context)
   294         {
   295             gl::Program *programObject = context->getProgram(program);
   296             gl::Shader *shaderObject = context->getShader(shader);
   298             if (!programObject)
   299             {
   300                 if (context->getShader(program))
   301                 {
   302                     return gl::error(GL_INVALID_OPERATION);
   303                 }
   304                 else
   305                 {
   306                     return gl::error(GL_INVALID_VALUE);
   307                 }
   308             }
   310             if (!shaderObject)
   311             {
   312                 if (context->getProgram(shader))
   313                 {
   314                     return gl::error(GL_INVALID_OPERATION);
   315                 }
   316                 else
   317                 {
   318                     return gl::error(GL_INVALID_VALUE);
   319                 }
   320             }
   322             if (!programObject->attachShader(shaderObject))
   323             {
   324                 return gl::error(GL_INVALID_OPERATION);
   325             }
   326         }
   327     }
   328     catch(std::bad_alloc&)
   329     {
   330         return gl::error(GL_OUT_OF_MEMORY);
   331     }
   332 }
   334 void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
   335 {
   336     EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
   338     try
   339     {
   340         switch (target)
   341         {
   342           case GL_ANY_SAMPLES_PASSED_EXT: 
   343           case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
   344               break;
   345           default: 
   346               return gl::error(GL_INVALID_ENUM);
   347         }
   349         if (id == 0)
   350         {
   351             return gl::error(GL_INVALID_OPERATION);
   352         }
   354         gl::Context *context = gl::getNonLostContext();
   356         if (context)
   357         {
   358             context->beginQuery(target, id);
   359         }
   360     }
   361     catch(std::bad_alloc&)
   362     {
   363         return gl::error(GL_OUT_OF_MEMORY);
   364     }
   365 }
   367 void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
   368 {
   369     EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
   371     try
   372     {
   373         if (index >= gl::MAX_VERTEX_ATTRIBS)
   374         {
   375             return gl::error(GL_INVALID_VALUE);
   376         }
   378         gl::Context *context = gl::getNonLostContext();
   380         if (context)
   381         {
   382             gl::Program *programObject = context->getProgram(program);
   384             if (!programObject)
   385             {
   386                 if (context->getShader(program))
   387                 {
   388                     return gl::error(GL_INVALID_OPERATION);
   389                 }
   390                 else
   391                 {
   392                     return gl::error(GL_INVALID_VALUE);
   393                 }
   394             }
   396             if (strncmp(name, "gl_", 3) == 0)
   397             {
   398                 return gl::error(GL_INVALID_OPERATION);
   399             }
   401             programObject->bindAttributeLocation(index, name);
   402         }
   403     }
   404     catch(std::bad_alloc&)
   405     {
   406         return gl::error(GL_OUT_OF_MEMORY);
   407     }
   408 }
   410 void __stdcall glBindBuffer(GLenum target, GLuint buffer)
   411 {
   412     EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
   414     try
   415     {
   416         gl::Context *context = gl::getNonLostContext();
   418         if (context)
   419         {
   420             switch (target)
   421             {
   422               case GL_ARRAY_BUFFER:
   423                 context->bindArrayBuffer(buffer);
   424                 return;
   425               case GL_ELEMENT_ARRAY_BUFFER:
   426                 context->bindElementArrayBuffer(buffer);
   427                 return;
   428               default:
   429                 return gl::error(GL_INVALID_ENUM);
   430             }
   431         }
   432     }
   433     catch(std::bad_alloc&)
   434     {
   435         return gl::error(GL_OUT_OF_MEMORY);
   436     }
   437 }
   439 void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
   440 {
   441     EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
   443     try
   444     {
   445         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
   446         {
   447             return gl::error(GL_INVALID_ENUM);
   448         }
   450         gl::Context *context = gl::getNonLostContext();
   452         if (context)
   453         {
   454             if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
   455             {
   456                 context->bindReadFramebuffer(framebuffer);
   457             }
   459             if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
   460             {
   461                 context->bindDrawFramebuffer(framebuffer);
   462             }
   463         }
   464     }
   465     catch(std::bad_alloc&)
   466     {
   467         return gl::error(GL_OUT_OF_MEMORY);
   468     }
   469 }
   471 void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
   472 {
   473     EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
   475     try
   476     {
   477         if (target != GL_RENDERBUFFER)
   478         {
   479             return gl::error(GL_INVALID_ENUM);
   480         }
   482         gl::Context *context = gl::getNonLostContext();
   484         if (context)
   485         {
   486             context->bindRenderbuffer(renderbuffer);
   487         }
   488     }
   489     catch(std::bad_alloc&)
   490     {
   491         return gl::error(GL_OUT_OF_MEMORY);
   492     }
   493 }
   495 void __stdcall glBindTexture(GLenum target, GLuint texture)
   496 {
   497     EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
   499     try
   500     {
   501         gl::Context *context = gl::getNonLostContext();
   503         if (context)
   504         {
   505             gl::Texture *textureObject = context->getTexture(texture);
   507             if (textureObject && textureObject->getTarget() != target && texture != 0)
   508             {
   509                 return gl::error(GL_INVALID_OPERATION);
   510             }
   512             switch (target)
   513             {
   514               case GL_TEXTURE_2D:
   515                 context->bindTexture2D(texture);
   516                 return;
   517               case GL_TEXTURE_CUBE_MAP:
   518                 context->bindTextureCubeMap(texture);
   519                 return;
   520               default:
   521                 return gl::error(GL_INVALID_ENUM);
   522             }
   523         }
   524     }
   525     catch(std::bad_alloc&)
   526     {
   527         return gl::error(GL_OUT_OF_MEMORY);
   528     }
   529 }
   531 void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
   532 {
   533     EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
   534           red, green, blue, alpha);
   536     try
   537     {
   538         gl::Context* context = gl::getNonLostContext();
   540         if (context)
   541         {
   542             context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
   543         }
   544     }
   545     catch(std::bad_alloc&)
   546     {
   547         return gl::error(GL_OUT_OF_MEMORY);
   548     }
   549 }
   551 void __stdcall glBlendEquation(GLenum mode)
   552 {
   553     glBlendEquationSeparate(mode, mode);
   554 }
   556 void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
   557 {
   558     EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
   560     try
   561     {
   562         switch (modeRGB)
   563         {
   564           case GL_FUNC_ADD:
   565           case GL_FUNC_SUBTRACT:
   566           case GL_FUNC_REVERSE_SUBTRACT:
   567             break;
   568           default:
   569             return gl::error(GL_INVALID_ENUM);
   570         }
   572         switch (modeAlpha)
   573         {
   574           case GL_FUNC_ADD:
   575           case GL_FUNC_SUBTRACT:
   576           case GL_FUNC_REVERSE_SUBTRACT:
   577             break;
   578           default:
   579             return gl::error(GL_INVALID_ENUM);
   580         }
   582         gl::Context *context = gl::getNonLostContext();
   584         if (context)
   585         {
   586             context->setBlendEquation(modeRGB, modeAlpha);
   587         }
   588     }
   589     catch(std::bad_alloc&)
   590     {
   591         return gl::error(GL_OUT_OF_MEMORY);
   592     }
   593 }
   595 void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
   596 {
   597     glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
   598 }
   600 void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
   601 {
   602     EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
   603           srcRGB, dstRGB, srcAlpha, dstAlpha);
   605     try
   606     {
   607         switch (srcRGB)
   608         {
   609           case GL_ZERO:
   610           case GL_ONE:
   611           case GL_SRC_COLOR:
   612           case GL_ONE_MINUS_SRC_COLOR:
   613           case GL_DST_COLOR:
   614           case GL_ONE_MINUS_DST_COLOR:
   615           case GL_SRC_ALPHA:
   616           case GL_ONE_MINUS_SRC_ALPHA:
   617           case GL_DST_ALPHA:
   618           case GL_ONE_MINUS_DST_ALPHA:
   619           case GL_CONSTANT_COLOR:
   620           case GL_ONE_MINUS_CONSTANT_COLOR:
   621           case GL_CONSTANT_ALPHA:
   622           case GL_ONE_MINUS_CONSTANT_ALPHA:
   623           case GL_SRC_ALPHA_SATURATE:
   624             break;
   625           default:
   626             return gl::error(GL_INVALID_ENUM);
   627         }
   629         switch (dstRGB)
   630         {
   631           case GL_ZERO:
   632           case GL_ONE:
   633           case GL_SRC_COLOR:
   634           case GL_ONE_MINUS_SRC_COLOR:
   635           case GL_DST_COLOR:
   636           case GL_ONE_MINUS_DST_COLOR:
   637           case GL_SRC_ALPHA:
   638           case GL_ONE_MINUS_SRC_ALPHA:
   639           case GL_DST_ALPHA:
   640           case GL_ONE_MINUS_DST_ALPHA:
   641           case GL_CONSTANT_COLOR:
   642           case GL_ONE_MINUS_CONSTANT_COLOR:
   643           case GL_CONSTANT_ALPHA:
   644           case GL_ONE_MINUS_CONSTANT_ALPHA:
   645             break;
   646           default:
   647             return gl::error(GL_INVALID_ENUM);
   648         }
   650         switch (srcAlpha)
   651         {
   652           case GL_ZERO:
   653           case GL_ONE:
   654           case GL_SRC_COLOR:
   655           case GL_ONE_MINUS_SRC_COLOR:
   656           case GL_DST_COLOR:
   657           case GL_ONE_MINUS_DST_COLOR:
   658           case GL_SRC_ALPHA:
   659           case GL_ONE_MINUS_SRC_ALPHA:
   660           case GL_DST_ALPHA:
   661           case GL_ONE_MINUS_DST_ALPHA:
   662           case GL_CONSTANT_COLOR:
   663           case GL_ONE_MINUS_CONSTANT_COLOR:
   664           case GL_CONSTANT_ALPHA:
   665           case GL_ONE_MINUS_CONSTANT_ALPHA:
   666           case GL_SRC_ALPHA_SATURATE:
   667             break;
   668           default:
   669             return gl::error(GL_INVALID_ENUM);
   670         }
   672         switch (dstAlpha)
   673         {
   674           case GL_ZERO:
   675           case GL_ONE:
   676           case GL_SRC_COLOR:
   677           case GL_ONE_MINUS_SRC_COLOR:
   678           case GL_DST_COLOR:
   679           case GL_ONE_MINUS_DST_COLOR:
   680           case GL_SRC_ALPHA:
   681           case GL_ONE_MINUS_SRC_ALPHA:
   682           case GL_DST_ALPHA:
   683           case GL_ONE_MINUS_DST_ALPHA:
   684           case GL_CONSTANT_COLOR:
   685           case GL_ONE_MINUS_CONSTANT_COLOR:
   686           case GL_CONSTANT_ALPHA:
   687           case GL_ONE_MINUS_CONSTANT_ALPHA:
   688             break;
   689           default:
   690             return gl::error(GL_INVALID_ENUM);
   691         }
   693         bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
   694                                   dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
   696         bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
   697                                   dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
   699         if (constantColorUsed && constantAlphaUsed)
   700         {
   701             ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
   702             return gl::error(GL_INVALID_OPERATION);
   703         }
   705         gl::Context *context = gl::getNonLostContext();
   707         if (context)
   708         {
   709             context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
   710         }
   711     }
   712     catch(std::bad_alloc&)
   713     {
   714         return gl::error(GL_OUT_OF_MEMORY);
   715     }
   716 }
   718 void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
   719 {
   720     EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
   721           target, size, data, usage);
   723     try
   724     {
   725         if (size < 0)
   726         {
   727             return gl::error(GL_INVALID_VALUE);
   728         }
   730         switch (usage)
   731         {
   732           case GL_STREAM_DRAW:
   733           case GL_STATIC_DRAW:
   734           case GL_DYNAMIC_DRAW:
   735             break;
   736           default:
   737             return gl::error(GL_INVALID_ENUM);
   738         }
   740         gl::Context *context = gl::getNonLostContext();
   742         if (context)
   743         {
   744             gl::Buffer *buffer;
   746             switch (target)
   747             {
   748               case GL_ARRAY_BUFFER:
   749                 buffer = context->getArrayBuffer();
   750                 break;
   751               case GL_ELEMENT_ARRAY_BUFFER:
   752                 buffer = context->getElementArrayBuffer();
   753                 break;
   754               default:
   755                 return gl::error(GL_INVALID_ENUM);
   756             }
   758             if (!buffer)
   759             {
   760                 return gl::error(GL_INVALID_OPERATION);
   761             }
   763             buffer->bufferData(data, size, usage);
   764         }
   765     }
   766     catch(std::bad_alloc&)
   767     {
   768         return gl::error(GL_OUT_OF_MEMORY);
   769     }
   770 }
   772 void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
   773 {
   774     EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
   775           target, offset, size, data);
   777     try
   778     {
   779         if (size < 0 || offset < 0)
   780         {
   781             return gl::error(GL_INVALID_VALUE);
   782         }
   784         if (data == NULL)
   785         {
   786             return;
   787         }
   789         gl::Context *context = gl::getNonLostContext();
   791         if (context)
   792         {
   793             gl::Buffer *buffer;
   795             switch (target)
   796             {
   797               case GL_ARRAY_BUFFER:
   798                 buffer = context->getArrayBuffer();
   799                 break;
   800               case GL_ELEMENT_ARRAY_BUFFER:
   801                 buffer = context->getElementArrayBuffer();
   802                 break;
   803               default:
   804                 return gl::error(GL_INVALID_ENUM);
   805             }
   807             if (!buffer)
   808             {
   809                 return gl::error(GL_INVALID_OPERATION);
   810             }
   812             if ((size_t)size + offset > buffer->size())
   813             {
   814                 return gl::error(GL_INVALID_VALUE);
   815             }
   817             buffer->bufferSubData(data, size, offset);
   818         }
   819     }
   820     catch(std::bad_alloc&)
   821     {
   822         return gl::error(GL_OUT_OF_MEMORY);
   823     }
   824 }
   826 GLenum __stdcall glCheckFramebufferStatus(GLenum target)
   827 {
   828     EVENT("(GLenum target = 0x%X)", target);
   830     try
   831     {
   832         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
   833         {
   834             return gl::error(GL_INVALID_ENUM, 0);
   835         }
   837         gl::Context *context = gl::getNonLostContext();
   839         if (context)
   840         {
   841             gl::Framebuffer *framebuffer = NULL;
   842             if (target == GL_READ_FRAMEBUFFER_ANGLE)
   843             {
   844                 framebuffer = context->getReadFramebuffer();
   845             }
   846             else
   847             {
   848                 framebuffer = context->getDrawFramebuffer();
   849             }
   851             return framebuffer->completeness();
   852         }
   853     }
   854     catch(std::bad_alloc&)
   855     {
   856         return gl::error(GL_OUT_OF_MEMORY, 0);
   857     }
   859     return 0;
   860 }
   862 void __stdcall glClear(GLbitfield mask)
   863 {
   864     EVENT("(GLbitfield mask = %X)", mask);
   866     try
   867     {
   868         gl::Context *context = gl::getNonLostContext();
   870         if (context)
   871         {
   872             context->clear(mask);
   873         }
   874     }
   875     catch(std::bad_alloc&)
   876     {
   877         return gl::error(GL_OUT_OF_MEMORY);
   878     }
   879 }
   881 void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
   882 {
   883     EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
   884           red, green, blue, alpha);
   886     try
   887     {
   888         gl::Context *context = gl::getNonLostContext();
   890         if (context)
   891         {
   892             context->setClearColor(red, green, blue, alpha);
   893         }
   894     }
   895     catch(std::bad_alloc&)
   896     {
   897         return gl::error(GL_OUT_OF_MEMORY);
   898     }
   899 }
   901 void __stdcall glClearDepthf(GLclampf depth)
   902 {
   903     EVENT("(GLclampf depth = %f)", depth);
   905     try
   906     {
   907         gl::Context *context = gl::getNonLostContext();
   909         if (context)
   910         {
   911             context->setClearDepth(depth);
   912         }
   913     }
   914     catch(std::bad_alloc&)
   915     {
   916         return gl::error(GL_OUT_OF_MEMORY);
   917     }
   918 }
   920 void __stdcall glClearStencil(GLint s)
   921 {
   922     EVENT("(GLint s = %d)", s);
   924     try
   925     {
   926         gl::Context *context = gl::getNonLostContext();
   928         if (context)
   929         {
   930             context->setClearStencil(s);
   931         }
   932     }
   933     catch(std::bad_alloc&)
   934     {
   935         return gl::error(GL_OUT_OF_MEMORY);
   936     }
   937 }
   939 void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
   940 {
   941     EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
   942           red, green, blue, alpha);
   944     try
   945     {
   946         gl::Context *context = gl::getNonLostContext();
   948         if (context)
   949         {
   950             context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
   951         }
   952     }
   953     catch(std::bad_alloc&)
   954     {
   955         return gl::error(GL_OUT_OF_MEMORY);
   956     }
   957 }
   959 void __stdcall glCompileShader(GLuint shader)
   960 {
   961     EVENT("(GLuint shader = %d)", shader);
   963     try
   964     {
   965         gl::Context *context = gl::getNonLostContext();
   967         if (context)
   968         {
   969             gl::Shader *shaderObject = context->getShader(shader);
   971             if (!shaderObject)
   972             {
   973                 if (context->getProgram(shader))
   974                 {
   975                     return gl::error(GL_INVALID_OPERATION);
   976                 }
   977                 else
   978                 {
   979                     return gl::error(GL_INVALID_VALUE);
   980                 }
   981             }
   983             shaderObject->compile();
   984         }
   985     }
   986     catch(std::bad_alloc&)
   987     {
   988         return gl::error(GL_OUT_OF_MEMORY);
   989     }
   990 }
   992 void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 
   993                                       GLint border, GLsizei imageSize, const GLvoid* data)
   994 {
   995     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 
   996           "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
   997           target, level, internalformat, width, height, border, imageSize, data);
   999     try
  1001         if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
  1003             return gl::error(GL_INVALID_VALUE);
  1006         switch (internalformat)
  1008           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1009           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1010           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  1011           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  1012             break;
  1013           default:
  1014             return gl::error(GL_INVALID_ENUM);
  1017         if (border != 0)
  1019             return gl::error(GL_INVALID_OPERATION);
  1022         if (width != 1 && width != 2 && width % 4 != 0)
  1024             return gl::error(GL_INVALID_OPERATION);
  1027         if (height != 1 && height != 2 && height % 4 != 0)
  1029             return gl::error(GL_INVALID_OPERATION);
  1032         gl::Context *context = gl::getNonLostContext();
  1034         if (context)
  1036             if (level > context->getMaximumTextureLevel())
  1038                 return gl::error(GL_INVALID_VALUE);
  1041             switch (target)
  1043               case GL_TEXTURE_2D:
  1044                 if (width > (context->getMaximumTextureDimension() >> level) ||
  1045                     height > (context->getMaximumTextureDimension() >> level))
  1047                     return gl::error(GL_INVALID_VALUE);
  1049                 break;
  1050               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  1051               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  1052               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  1053               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  1054               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  1055               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  1056                 if (width != height)
  1058                     return gl::error(GL_INVALID_VALUE);
  1061                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
  1062                     height > (context->getMaximumCubeTextureDimension() >> level))
  1064                     return gl::error(GL_INVALID_VALUE);
  1066                 break;
  1067               default:
  1068                 return gl::error(GL_INVALID_ENUM);
  1071             switch (internalformat) {
  1072               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1073               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1074                 if (!context->supportsDXT1Textures())
  1076                     return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
  1078                 break;
  1079               case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  1080                 if (!context->supportsDXT3Textures())
  1082                     return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
  1084                 break;
  1085               case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  1086                 if (!context->supportsDXT5Textures())
  1088                     return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
  1090                 break;
  1091               default: UNREACHABLE();
  1094             if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
  1096                 return gl::error(GL_INVALID_VALUE);
  1099             if (target == GL_TEXTURE_2D)
  1101                 gl::Texture2D *texture = context->getTexture2D();
  1103                 if (!texture)
  1105                     return gl::error(GL_INVALID_OPERATION);
  1108                 if (texture->isImmutable())
  1110                     return gl::error(GL_INVALID_OPERATION);
  1113                 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
  1115             else
  1117                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
  1119                 if (!texture)
  1121                     return gl::error(GL_INVALID_OPERATION);
  1124                 if (texture->isImmutable())
  1126                     return gl::error(GL_INVALID_OPERATION);
  1129                 switch (target)
  1131                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  1132                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  1133                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  1134                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  1135                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  1136                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  1137                     texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
  1138                     break;
  1139                   default: UNREACHABLE();
  1145     catch(std::bad_alloc&)
  1147         return gl::error(GL_OUT_OF_MEMORY);
  1151 void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
  1152                                          GLenum format, GLsizei imageSize, const GLvoid* data)
  1154     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
  1155           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
  1156           "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
  1157           target, level, xoffset, yoffset, width, height, format, imageSize, data);
  1159     try
  1161         if (!gl::IsInternalTextureTarget(target))
  1163             return gl::error(GL_INVALID_ENUM);
  1166         if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
  1168             return gl::error(GL_INVALID_VALUE);
  1171         switch (format)
  1173           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1174           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1175           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  1176           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  1177             break;
  1178           default:
  1179             return gl::error(GL_INVALID_ENUM);
  1182         if (width == 0 || height == 0 || data == NULL)
  1184             return;
  1187         gl::Context *context = gl::getNonLostContext();
  1189         if (context)
  1191             if (level > context->getMaximumTextureLevel())
  1193                 return gl::error(GL_INVALID_VALUE);
  1196             switch (format) {
  1197               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1198               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1199                 if (!context->supportsDXT1Textures())
  1201                     return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
  1203                 break;
  1204               case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  1205                 if (!context->supportsDXT3Textures())
  1207                     return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
  1209                 break;
  1210               case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  1211                 if (!context->supportsDXT5Textures())
  1213                     return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
  1215                 break;
  1216               default: UNREACHABLE();
  1219             if (imageSize != gl::ComputeCompressedSize(width, height, format))
  1221                 return gl::error(GL_INVALID_VALUE);
  1224             if (xoffset % 4 != 0 || yoffset % 4 != 0)
  1226                 return gl::error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
  1227                                                     // does not exist unless DXT textures are supported.
  1230             if (target == GL_TEXTURE_2D)
  1232                 gl::Texture2D *texture = context->getTexture2D();
  1233                 if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture))
  1235                     texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
  1238             else if (gl::IsCubemapTextureTarget(target))
  1240                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
  1241                 if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture))
  1243                     texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
  1246             else
  1248                 UNREACHABLE();
  1252     catch(std::bad_alloc&)
  1254         return gl::error(GL_OUT_OF_MEMORY);
  1258 void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
  1260     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
  1261           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
  1262           target, level, internalformat, x, y, width, height, border);
  1264     try
  1266         if (!validImageSize(level, width, height))
  1268             return gl::error(GL_INVALID_VALUE);
  1271         if (border != 0)
  1273             return gl::error(GL_INVALID_VALUE);
  1276         gl::Context *context = gl::getNonLostContext();
  1278         if (context)
  1280             if (level > context->getMaximumTextureLevel())
  1282                 return gl::error(GL_INVALID_VALUE);
  1285             switch (target)
  1287               case GL_TEXTURE_2D:
  1288                 if (width > (context->getMaximumTextureDimension() >> level) ||
  1289                     height > (context->getMaximumTextureDimension() >> level))
  1291                     return gl::error(GL_INVALID_VALUE);
  1293                 break;
  1294               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  1295               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  1296               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  1297               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  1298               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  1299               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  1300                 if (width != height)
  1302                     return gl::error(GL_INVALID_VALUE);
  1305                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
  1306                     height > (context->getMaximumCubeTextureDimension() >> level))
  1308                     return gl::error(GL_INVALID_VALUE);
  1310                 break;
  1311               default:
  1312                 return gl::error(GL_INVALID_ENUM);
  1315             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
  1317             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
  1319                 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
  1322             if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
  1324                 return gl::error(GL_INVALID_OPERATION);
  1327             gl::Renderbuffer *source = framebuffer->getReadColorbuffer();
  1328             GLenum colorbufferFormat = source->getInternalFormat();
  1330             // [OpenGL ES 2.0.24] table 3.9
  1331             switch (internalformat)
  1333               case GL_ALPHA:
  1334                 if (colorbufferFormat != GL_ALPHA8_EXT &&
  1335                     colorbufferFormat != GL_RGBA4 &&
  1336                     colorbufferFormat != GL_RGB5_A1 &&
  1337                     colorbufferFormat != GL_BGRA8_EXT &&
  1338                     colorbufferFormat != GL_RGBA8_OES)
  1340                     return gl::error(GL_INVALID_OPERATION);
  1342                 break;
  1343               case GL_LUMINANCE:
  1344               case GL_RGB:
  1345                 if (colorbufferFormat != GL_RGB565 &&
  1346                     colorbufferFormat != GL_RGB8_OES &&
  1347                     colorbufferFormat != GL_RGBA4 &&
  1348                     colorbufferFormat != GL_RGB5_A1 &&
  1349                     colorbufferFormat != GL_BGRA8_EXT &&
  1350                     colorbufferFormat != GL_RGBA8_OES)
  1352                     return gl::error(GL_INVALID_OPERATION);
  1354                 break;
  1355               case GL_LUMINANCE_ALPHA:
  1356               case GL_RGBA:
  1357                 if (colorbufferFormat != GL_RGBA4 &&
  1358                     colorbufferFormat != GL_RGB5_A1 &&
  1359                     colorbufferFormat != GL_BGRA8_EXT &&
  1360                     colorbufferFormat != GL_RGBA8_OES)
  1362                      return gl::error(GL_INVALID_OPERATION);
  1364                  break;
  1365               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1366               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1367                 if (context->supportsDXT1Textures())
  1369                     return gl::error(GL_INVALID_OPERATION);
  1371                 else
  1373                     return gl::error(GL_INVALID_ENUM);
  1375                 break;
  1376               case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  1377                 if (context->supportsDXT3Textures())
  1379                     return gl::error(GL_INVALID_OPERATION);
  1381                 else
  1383                     return gl::error(GL_INVALID_ENUM);
  1385                 break;
  1386               case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  1387                 if (context->supportsDXT5Textures())
  1389                     return gl::error(GL_INVALID_OPERATION);
  1391                 else
  1393                     return gl::error(GL_INVALID_ENUM);
  1395                 break;
  1396               case GL_DEPTH_COMPONENT:
  1397               case GL_DEPTH_COMPONENT16:
  1398               case GL_DEPTH_COMPONENT32_OES:
  1399               case GL_DEPTH_STENCIL_OES:
  1400               case GL_DEPTH24_STENCIL8_OES:
  1401                   if (context->supportsDepthTextures())
  1403                       return gl::error(GL_INVALID_OPERATION);
  1405                   else
  1407                       return gl::error(GL_INVALID_ENUM);
  1409               default:
  1410                 return gl::error(GL_INVALID_ENUM);
  1413             if (target == GL_TEXTURE_2D)
  1415                 gl::Texture2D *texture = context->getTexture2D();
  1417                 if (!texture)
  1419                     return gl::error(GL_INVALID_OPERATION);
  1422                 if (texture->isImmutable())
  1424                     return gl::error(GL_INVALID_OPERATION);
  1427                 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
  1429             else if (gl::IsCubemapTextureTarget(target))
  1431                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
  1433                 if (!texture)
  1435                     return gl::error(GL_INVALID_OPERATION);
  1438                 if (texture->isImmutable())
  1440                     return gl::error(GL_INVALID_OPERATION);
  1443                 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
  1445             else UNREACHABLE();
  1448     catch(std::bad_alloc&)
  1450         return gl::error(GL_OUT_OF_MEMORY);
  1454 void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
  1456     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
  1457           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
  1458           target, level, xoffset, yoffset, x, y, width, height);
  1460     try
  1462         if (!gl::IsInternalTextureTarget(target))
  1464             return gl::error(GL_INVALID_ENUM);
  1467         if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
  1469             return gl::error(GL_INVALID_VALUE);
  1472         if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
  1474             return gl::error(GL_INVALID_VALUE);
  1477         if (width == 0 || height == 0)
  1479             return;
  1482         gl::Context *context = gl::getNonLostContext();
  1484         if (context)
  1486             if (level > context->getMaximumTextureLevel())
  1488                 return gl::error(GL_INVALID_VALUE);
  1491             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
  1493             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
  1495                 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
  1498             if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
  1500                 return gl::error(GL_INVALID_OPERATION);
  1503             gl::Renderbuffer *source = framebuffer->getReadColorbuffer();
  1504             GLenum colorbufferFormat = source->getInternalFormat();
  1505             gl::Texture *texture = NULL;
  1506             GLenum textureFormat = GL_RGBA;
  1508             if (target == GL_TEXTURE_2D)
  1510                 gl::Texture2D *tex2d = context->getTexture2D();
  1512                 if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d))
  1514                     return; // error already registered by validateSubImageParams
  1516                 textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level));
  1517                 texture = tex2d;
  1519             else if (gl::IsCubemapTextureTarget(target))
  1521                 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
  1523                 if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube))
  1525                     return; // error already registered by validateSubImageParams
  1527                 textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level));
  1528                 texture = texcube;
  1530             else UNREACHABLE();
  1532             // [OpenGL ES 2.0.24] table 3.9
  1533             switch (textureFormat)
  1535               case GL_ALPHA:
  1536                 if (colorbufferFormat != GL_ALPHA8_EXT &&
  1537                     colorbufferFormat != GL_RGBA4 &&
  1538                     colorbufferFormat != GL_RGB5_A1 &&
  1539                     colorbufferFormat != GL_RGBA8_OES)
  1541                     return gl::error(GL_INVALID_OPERATION);
  1543                 break;
  1544               case GL_LUMINANCE:
  1545               case GL_RGB:
  1546                 if (colorbufferFormat != GL_RGB565 &&
  1547                     colorbufferFormat != GL_RGB8_OES &&
  1548                     colorbufferFormat != GL_RGBA4 &&
  1549                     colorbufferFormat != GL_RGB5_A1 &&
  1550                     colorbufferFormat != GL_RGBA8_OES)
  1552                     return gl::error(GL_INVALID_OPERATION);
  1554                 break;
  1555               case GL_LUMINANCE_ALPHA:
  1556               case GL_RGBA:
  1557                 if (colorbufferFormat != GL_RGBA4 &&
  1558                     colorbufferFormat != GL_RGB5_A1 &&
  1559                     colorbufferFormat != GL_RGBA8_OES)
  1561                     return gl::error(GL_INVALID_OPERATION);
  1563                 break;
  1564               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1565               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1566               case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  1567               case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  1568                 return gl::error(GL_INVALID_OPERATION);
  1569               case GL_DEPTH_COMPONENT:
  1570               case GL_DEPTH_STENCIL_OES:
  1571                 return gl::error(GL_INVALID_OPERATION);
  1572               default:
  1573                 return gl::error(GL_INVALID_OPERATION);
  1576             texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
  1580     catch(std::bad_alloc&)
  1582         return gl::error(GL_OUT_OF_MEMORY);
  1586 GLuint __stdcall glCreateProgram(void)
  1588     EVENT("()");
  1590     try
  1592         gl::Context *context = gl::getNonLostContext();
  1594         if (context)
  1596             return context->createProgram();
  1599     catch(std::bad_alloc&)
  1601         return gl::error(GL_OUT_OF_MEMORY, 0);
  1604     return 0;
  1607 GLuint __stdcall glCreateShader(GLenum type)
  1609     EVENT("(GLenum type = 0x%X)", type);
  1611     try
  1613         gl::Context *context = gl::getNonLostContext();
  1615         if (context)
  1617             switch (type)
  1619               case GL_FRAGMENT_SHADER:
  1620               case GL_VERTEX_SHADER:
  1621                 return context->createShader(type);
  1622               default:
  1623                 return gl::error(GL_INVALID_ENUM, 0);
  1627     catch(std::bad_alloc&)
  1629         return gl::error(GL_OUT_OF_MEMORY, 0);
  1632     return 0;
  1635 void __stdcall glCullFace(GLenum mode)
  1637     EVENT("(GLenum mode = 0x%X)", mode);
  1639     try
  1641         switch (mode)
  1643           case GL_FRONT:
  1644           case GL_BACK:
  1645           case GL_FRONT_AND_BACK:
  1647                 gl::Context *context = gl::getNonLostContext();
  1649                 if (context)
  1651                     context->setCullMode(mode);
  1654             break;
  1655           default:
  1656             return gl::error(GL_INVALID_ENUM);
  1659     catch(std::bad_alloc&)
  1661         return gl::error(GL_OUT_OF_MEMORY);
  1665 void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
  1667     EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
  1669     try
  1671         if (n < 0)
  1673             return gl::error(GL_INVALID_VALUE);
  1676         gl::Context *context = gl::getNonLostContext();
  1678         if (context)
  1680             for (int i = 0; i < n; i++)
  1682                 context->deleteBuffer(buffers[i]);
  1686     catch(std::bad_alloc&)
  1688         return gl::error(GL_OUT_OF_MEMORY);
  1692 void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
  1694     EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
  1696     try
  1698         if (n < 0)
  1700             return gl::error(GL_INVALID_VALUE);
  1703         gl::Context *context = gl::getNonLostContext();
  1705         if (context)
  1707             for (int i = 0; i < n; i++)
  1709                 context->deleteFence(fences[i]);
  1713     catch(std::bad_alloc&)
  1715         return gl::error(GL_OUT_OF_MEMORY);
  1719 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
  1721     EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
  1723     try
  1725         if (n < 0)
  1727             return gl::error(GL_INVALID_VALUE);
  1730         gl::Context *context = gl::getNonLostContext();
  1732         if (context)
  1734             for (int i = 0; i < n; i++)
  1736                 if (framebuffers[i] != 0)
  1738                     context->deleteFramebuffer(framebuffers[i]);
  1743     catch(std::bad_alloc&)
  1745         return gl::error(GL_OUT_OF_MEMORY);
  1749 void __stdcall glDeleteProgram(GLuint program)
  1751     EVENT("(GLuint program = %d)", program);
  1753     try
  1755         if (program == 0)
  1757             return;
  1760         gl::Context *context = gl::getNonLostContext();
  1762         if (context)
  1764             if (!context->getProgram(program))
  1766                 if(context->getShader(program))
  1768                     return gl::error(GL_INVALID_OPERATION);
  1770                 else
  1772                     return gl::error(GL_INVALID_VALUE);
  1776             context->deleteProgram(program);
  1779     catch(std::bad_alloc&)
  1781         return gl::error(GL_OUT_OF_MEMORY);
  1785 void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
  1787     EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
  1789     try
  1791         if (n < 0)
  1793             return gl::error(GL_INVALID_VALUE);
  1796         gl::Context *context = gl::getNonLostContext();
  1798         if (context)
  1800             for (int i = 0; i < n; i++)
  1802                 context->deleteQuery(ids[i]);
  1806     catch(std::bad_alloc&)
  1808         return gl::error(GL_OUT_OF_MEMORY);
  1812 void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
  1814     EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
  1816     try
  1818         if (n < 0)
  1820             return gl::error(GL_INVALID_VALUE);
  1823         gl::Context *context = gl::getNonLostContext();
  1825         if (context)
  1827             for (int i = 0; i < n; i++)
  1829                 context->deleteRenderbuffer(renderbuffers[i]);
  1833     catch(std::bad_alloc&)
  1835         return gl::error(GL_OUT_OF_MEMORY);
  1839 void __stdcall glDeleteShader(GLuint shader)
  1841     EVENT("(GLuint shader = %d)", shader);
  1843     try
  1845         if (shader == 0)
  1847             return;
  1850         gl::Context *context = gl::getNonLostContext();
  1852         if (context)
  1854             if (!context->getShader(shader))
  1856                 if(context->getProgram(shader))
  1858                     return gl::error(GL_INVALID_OPERATION);
  1860                 else
  1862                     return gl::error(GL_INVALID_VALUE);
  1866             context->deleteShader(shader);
  1869     catch(std::bad_alloc&)
  1871         return gl::error(GL_OUT_OF_MEMORY);
  1875 void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
  1877     EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
  1879     try
  1881         if (n < 0)
  1883             return gl::error(GL_INVALID_VALUE);
  1886         gl::Context *context = gl::getNonLostContext();
  1888         if (context)
  1890             for (int i = 0; i < n; i++)
  1892                 if (textures[i] != 0)
  1894                     context->deleteTexture(textures[i]);
  1899     catch(std::bad_alloc&)
  1901         return gl::error(GL_OUT_OF_MEMORY);
  1905 void __stdcall glDepthFunc(GLenum func)
  1907     EVENT("(GLenum func = 0x%X)", func);
  1909     try
  1911         switch (func)
  1913           case GL_NEVER:
  1914           case GL_ALWAYS:
  1915           case GL_LESS:
  1916           case GL_LEQUAL:
  1917           case GL_EQUAL:
  1918           case GL_GREATER:
  1919           case GL_GEQUAL:
  1920           case GL_NOTEQUAL:
  1921             break;
  1922           default:
  1923             return gl::error(GL_INVALID_ENUM);
  1926         gl::Context *context = gl::getNonLostContext();
  1928         if (context)
  1930             context->setDepthFunc(func);
  1933     catch(std::bad_alloc&)
  1935         return gl::error(GL_OUT_OF_MEMORY);
  1939 void __stdcall glDepthMask(GLboolean flag)
  1941     EVENT("(GLboolean flag = %d)", flag);
  1943     try
  1945         gl::Context *context = gl::getNonLostContext();
  1947         if (context)
  1949             context->setDepthMask(flag != GL_FALSE);
  1952     catch(std::bad_alloc&)
  1954         return gl::error(GL_OUT_OF_MEMORY);
  1958 void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
  1960     EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
  1962     try
  1964         gl::Context *context = gl::getNonLostContext();
  1966         if (context)
  1968             context->setDepthRange(zNear, zFar);
  1971     catch(std::bad_alloc&)
  1973         return gl::error(GL_OUT_OF_MEMORY);
  1977 void __stdcall glDetachShader(GLuint program, GLuint shader)
  1979     EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
  1981     try
  1983         gl::Context *context = gl::getNonLostContext();
  1985         if (context)
  1988             gl::Program *programObject = context->getProgram(program);
  1989             gl::Shader *shaderObject = context->getShader(shader);
  1991             if (!programObject)
  1993                 gl::Shader *shaderByProgramHandle;
  1994                 shaderByProgramHandle = context->getShader(program);
  1995                 if (!shaderByProgramHandle)
  1997                     return gl::error(GL_INVALID_VALUE);
  1999                 else
  2001                     return gl::error(GL_INVALID_OPERATION);
  2005             if (!shaderObject)
  2007                 gl::Program *programByShaderHandle = context->getProgram(shader);
  2008                 if (!programByShaderHandle)
  2010                     return gl::error(GL_INVALID_VALUE);
  2012                 else
  2014                     return gl::error(GL_INVALID_OPERATION);
  2018             if (!programObject->detachShader(shaderObject))
  2020                 return gl::error(GL_INVALID_OPERATION);
  2024     catch(std::bad_alloc&)
  2026         return gl::error(GL_OUT_OF_MEMORY);
  2030 void __stdcall glDisable(GLenum cap)
  2032     EVENT("(GLenum cap = 0x%X)", cap);
  2034     try
  2036         gl::Context *context = gl::getNonLostContext();
  2038         if (context)
  2040             switch (cap)
  2042               case GL_CULL_FACE:                context->setCullFace(false);              break;
  2043               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(false);     break;
  2044               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
  2045               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(false);        break;
  2046               case GL_SCISSOR_TEST:             context->setScissorTest(false);           break;
  2047               case GL_STENCIL_TEST:             context->setStencilTest(false);           break;
  2048               case GL_DEPTH_TEST:               context->setDepthTest(false);             break;
  2049               case GL_BLEND:                    context->setBlend(false);                 break;
  2050               case GL_DITHER:                   context->setDither(false);                break;
  2051               default:
  2052                 return gl::error(GL_INVALID_ENUM);
  2056     catch(std::bad_alloc&)
  2058         return gl::error(GL_OUT_OF_MEMORY);
  2062 void __stdcall glDisableVertexAttribArray(GLuint index)
  2064     EVENT("(GLuint index = %d)", index);
  2066     try
  2068         if (index >= gl::MAX_VERTEX_ATTRIBS)
  2070             return gl::error(GL_INVALID_VALUE);
  2073         gl::Context *context = gl::getNonLostContext();
  2075         if (context)
  2077             context->setEnableVertexAttribArray(index, false);
  2080     catch(std::bad_alloc&)
  2082         return gl::error(GL_OUT_OF_MEMORY);
  2086 void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
  2088     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
  2090     try
  2092         if (count < 0 || first < 0)
  2094             return gl::error(GL_INVALID_VALUE);
  2097         gl::Context *context = gl::getNonLostContext();
  2099         if (context)
  2101             context->drawArrays(mode, first, count, 0);
  2104     catch(std::bad_alloc&)
  2106         return gl::error(GL_OUT_OF_MEMORY);
  2110 void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
  2112     EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
  2114     try
  2116         if (count < 0 || first < 0 || primcount < 0)
  2118             return gl::error(GL_INVALID_VALUE);
  2121         if (primcount > 0)
  2123             gl::Context *context = gl::getNonLostContext();
  2125             if (context)
  2127                 context->drawArrays(mode, first, count, primcount);
  2131     catch(std::bad_alloc&)
  2133         return gl::error(GL_OUT_OF_MEMORY);
  2137 void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
  2139     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
  2140           mode, count, type, indices);
  2142     try
  2144         if (count < 0)
  2146             return gl::error(GL_INVALID_VALUE);
  2149         gl::Context *context = gl::getNonLostContext();
  2151         if (context)
  2153             switch (type)
  2155               case GL_UNSIGNED_BYTE:
  2156               case GL_UNSIGNED_SHORT:
  2157                 break;
  2158               case GL_UNSIGNED_INT:
  2159                 if (!context->supports32bitIndices())
  2161                     return gl::error(GL_INVALID_ENUM);    
  2163                 break;
  2164               default:
  2165                 return gl::error(GL_INVALID_ENUM);
  2168             context->drawElements(mode, count, type, indices, 0);
  2171     catch(std::bad_alloc&)
  2173         return gl::error(GL_OUT_OF_MEMORY);
  2177 void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
  2179     EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
  2180           mode, count, type, indices, primcount);
  2182     try
  2184         if (count < 0 || primcount < 0)
  2186             return gl::error(GL_INVALID_VALUE);
  2189         if (primcount > 0)
  2191             gl::Context *context = gl::getNonLostContext();
  2193             if (context)
  2195                 switch (type)
  2197                   case GL_UNSIGNED_BYTE:
  2198                   case GL_UNSIGNED_SHORT:
  2199                     break;
  2200                   case GL_UNSIGNED_INT:
  2201                     if (!context->supports32bitIndices())
  2203                         return gl::error(GL_INVALID_ENUM);    
  2205                     break;
  2206                   default:
  2207                     return gl::error(GL_INVALID_ENUM);
  2210                 context->drawElements(mode, count, type, indices, primcount);
  2214     catch(std::bad_alloc&)
  2216         return gl::error(GL_OUT_OF_MEMORY);
  2220 void __stdcall glEnable(GLenum cap)
  2222     EVENT("(GLenum cap = 0x%X)", cap);
  2224     try
  2226         gl::Context *context = gl::getNonLostContext();
  2228         if (context)
  2230             switch (cap)
  2232               case GL_CULL_FACE:                context->setCullFace(true);              break;
  2233               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(true);     break;
  2234               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
  2235               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(true);        break;
  2236               case GL_SCISSOR_TEST:             context->setScissorTest(true);           break;
  2237               case GL_STENCIL_TEST:             context->setStencilTest(true);           break;
  2238               case GL_DEPTH_TEST:               context->setDepthTest(true);             break;
  2239               case GL_BLEND:                    context->setBlend(true);                 break;
  2240               case GL_DITHER:                   context->setDither(true);                break;
  2241               default:
  2242                 return gl::error(GL_INVALID_ENUM);
  2246     catch(std::bad_alloc&)
  2248         return gl::error(GL_OUT_OF_MEMORY);
  2252 void __stdcall glEnableVertexAttribArray(GLuint index)
  2254     EVENT("(GLuint index = %d)", index);
  2256     try
  2258         if (index >= gl::MAX_VERTEX_ATTRIBS)
  2260             return gl::error(GL_INVALID_VALUE);
  2263         gl::Context *context = gl::getNonLostContext();
  2265         if (context)
  2267             context->setEnableVertexAttribArray(index, true);
  2270     catch(std::bad_alloc&)
  2272         return gl::error(GL_OUT_OF_MEMORY);
  2276 void __stdcall glEndQueryEXT(GLenum target)
  2278     EVENT("GLenum target = 0x%X)", target);
  2280     try
  2282         switch (target)
  2284           case GL_ANY_SAMPLES_PASSED_EXT: 
  2285           case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
  2286               break;
  2287           default: 
  2288               return gl::error(GL_INVALID_ENUM);
  2291         gl::Context *context = gl::getNonLostContext();
  2293         if (context)
  2295             context->endQuery(target);
  2298     catch(std::bad_alloc&)
  2300         return gl::error(GL_OUT_OF_MEMORY);
  2304 void __stdcall glFinishFenceNV(GLuint fence)
  2306     EVENT("(GLuint fence = %d)", fence);
  2308     try
  2310         gl::Context *context = gl::getNonLostContext();
  2312         if (context)
  2314             gl::Fence* fenceObject = context->getFence(fence);
  2316             if (fenceObject == NULL)
  2318                 return gl::error(GL_INVALID_OPERATION);
  2321             fenceObject->finishFence();
  2324     catch(std::bad_alloc&)
  2326         return gl::error(GL_OUT_OF_MEMORY);
  2330 void __stdcall glFinish(void)
  2332     EVENT("()");
  2334     try
  2336         gl::Context *context = gl::getNonLostContext();
  2338         if (context)
  2340             context->sync(true);
  2343     catch(std::bad_alloc&)
  2345         return gl::error(GL_OUT_OF_MEMORY);
  2349 void __stdcall glFlush(void)
  2351     EVENT("()");
  2353     try
  2355         gl::Context *context = gl::getNonLostContext();
  2357         if (context)
  2359             context->sync(false);
  2362     catch(std::bad_alloc&)
  2364         return gl::error(GL_OUT_OF_MEMORY);
  2368 void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
  2370     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
  2371           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
  2373     try
  2375         if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
  2376             || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
  2378             return gl::error(GL_INVALID_ENUM);
  2381         gl::Context *context = gl::getNonLostContext();
  2383         if (context)
  2385             gl::Framebuffer *framebuffer = NULL;
  2386             GLuint framebufferHandle = 0;
  2387             if (target == GL_READ_FRAMEBUFFER_ANGLE)
  2389                 framebuffer = context->getReadFramebuffer();
  2390                 framebufferHandle = context->getReadFramebufferHandle();
  2392             else
  2394                 framebuffer = context->getDrawFramebuffer();
  2395                 framebufferHandle = context->getDrawFramebufferHandle();
  2398             if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
  2400                 return gl::error(GL_INVALID_OPERATION);
  2403             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
  2405                 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
  2407                 if (colorAttachment >= context->getMaximumRenderTargets())
  2409                     return gl::error(GL_INVALID_VALUE);
  2412                 framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer);
  2414             else
  2416                 switch (attachment)
  2418                   case GL_DEPTH_ATTACHMENT:
  2419                     framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
  2420                     break;
  2421                   case GL_STENCIL_ATTACHMENT:
  2422                     framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
  2423                     break;
  2424                   default:
  2425                     return gl::error(GL_INVALID_ENUM);
  2430     catch(std::bad_alloc&)
  2432         return gl::error(GL_OUT_OF_MEMORY);
  2436 void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
  2438     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
  2439           "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
  2441     try
  2443         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
  2445             return gl::error(GL_INVALID_ENUM);
  2448         gl::Context *context = gl::getNonLostContext();
  2450         if (context)
  2452             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
  2454                 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
  2456                 if (colorAttachment >= context->getMaximumRenderTargets())
  2458                     return gl::error(GL_INVALID_VALUE);
  2461             else
  2463                 switch (attachment)
  2465                   case GL_DEPTH_ATTACHMENT:
  2466                   case GL_STENCIL_ATTACHMENT:
  2467                     break;
  2468                   default:
  2469                     return gl::error(GL_INVALID_ENUM);
  2473             if (texture == 0)
  2475                 textarget = GL_NONE;
  2477             else
  2479                 gl::Texture *tex = context->getTexture(texture);
  2481                 if (tex == NULL)
  2483                     return gl::error(GL_INVALID_OPERATION);
  2486                 switch (textarget)
  2488                   case GL_TEXTURE_2D:
  2490                         if (tex->getTarget() != GL_TEXTURE_2D)
  2492                             return gl::error(GL_INVALID_OPERATION);
  2494                         gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
  2495                         if (tex2d->isCompressed(0))
  2497                             return gl::error(GL_INVALID_OPERATION);
  2499                         break;
  2502                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  2503                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  2504                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  2505                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  2506                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  2507                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  2509                         if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
  2511                             return gl::error(GL_INVALID_OPERATION);
  2513                         gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
  2514                         if (texcube->isCompressed(textarget, level))
  2516                             return gl::error(GL_INVALID_OPERATION);
  2518                         break;
  2521                   default:
  2522                     return gl::error(GL_INVALID_ENUM);
  2525                 if (level != 0)
  2527                     return gl::error(GL_INVALID_VALUE);
  2531             gl::Framebuffer *framebuffer = NULL;
  2532             GLuint framebufferHandle = 0;
  2533             if (target == GL_READ_FRAMEBUFFER_ANGLE)
  2535                 framebuffer = context->getReadFramebuffer();
  2536                 framebufferHandle = context->getReadFramebufferHandle();
  2538             else
  2540                 framebuffer = context->getDrawFramebuffer();
  2541                 framebufferHandle = context->getDrawFramebufferHandle();
  2544             if (framebufferHandle == 0 || !framebuffer)
  2546                 return gl::error(GL_INVALID_OPERATION);
  2549             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
  2551                 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
  2553                 if (colorAttachment >= context->getMaximumRenderTargets())
  2555                     return gl::error(GL_INVALID_VALUE);
  2558                 framebuffer->setColorbuffer(colorAttachment, textarget, texture);
  2560             else
  2562                 switch (attachment)
  2564                   case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
  2565                   case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
  2570     catch(std::bad_alloc&)
  2572         return gl::error(GL_OUT_OF_MEMORY);
  2576 void __stdcall glFrontFace(GLenum mode)
  2578     EVENT("(GLenum mode = 0x%X)", mode);
  2580     try
  2582         switch (mode)
  2584           case GL_CW:
  2585           case GL_CCW:
  2587                 gl::Context *context = gl::getNonLostContext();
  2589                 if (context)
  2591                     context->setFrontFace(mode);
  2594             break;
  2595           default:
  2596             return gl::error(GL_INVALID_ENUM);
  2599     catch(std::bad_alloc&)
  2601         return gl::error(GL_OUT_OF_MEMORY);
  2605 void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
  2607     EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
  2609     try
  2611         if (n < 0)
  2613             return gl::error(GL_INVALID_VALUE);
  2616         gl::Context *context = gl::getNonLostContext();
  2618         if (context)
  2620             for (int i = 0; i < n; i++)
  2622                 buffers[i] = context->createBuffer();
  2626     catch(std::bad_alloc&)
  2628         return gl::error(GL_OUT_OF_MEMORY);
  2632 void __stdcall glGenerateMipmap(GLenum target)
  2634     EVENT("(GLenum target = 0x%X)", target);
  2636     try
  2638         gl::Context *context = gl::getNonLostContext();
  2640         if (context)
  2642             switch (target)
  2644               case GL_TEXTURE_2D:
  2646                     gl::Texture2D *tex2d = context->getTexture2D();
  2648                     if (tex2d->isCompressed(0))
  2650                         return gl::error(GL_INVALID_OPERATION);
  2652                     if (tex2d->isDepth(0))
  2654                         return gl::error(GL_INVALID_OPERATION);
  2657                     tex2d->generateMipmaps();
  2658                     break;
  2661               case GL_TEXTURE_CUBE_MAP:
  2663                     gl::TextureCubeMap *texcube = context->getTextureCubeMap();
  2665                     if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0))
  2667                         return gl::error(GL_INVALID_OPERATION);
  2670                     texcube->generateMipmaps();
  2671                     break;
  2674               default:
  2675                 return gl::error(GL_INVALID_ENUM);
  2679     catch(std::bad_alloc&)
  2681         return gl::error(GL_OUT_OF_MEMORY);
  2685 void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
  2687     EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
  2689     try
  2691         if (n < 0)
  2693             return gl::error(GL_INVALID_VALUE);
  2696         gl::Context *context = gl::getNonLostContext();
  2698         if (context)
  2700             for (int i = 0; i < n; i++)
  2702                 fences[i] = context->createFence();
  2706     catch(std::bad_alloc&)
  2708         return gl::error(GL_OUT_OF_MEMORY);
  2712 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
  2714     EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
  2716     try
  2718         if (n < 0)
  2720             return gl::error(GL_INVALID_VALUE);
  2723         gl::Context *context = gl::getNonLostContext();
  2725         if (context)
  2727             for (int i = 0; i < n; i++)
  2729                 framebuffers[i] = context->createFramebuffer();
  2733     catch(std::bad_alloc&)
  2735         return gl::error(GL_OUT_OF_MEMORY);
  2739 void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
  2741     EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
  2743     try
  2745         if (n < 0)
  2747             return gl::error(GL_INVALID_VALUE);
  2750         gl::Context *context = gl::getNonLostContext();
  2752         if (context)
  2754             for (int i = 0; i < n; i++)
  2756                 ids[i] = context->createQuery();
  2760     catch(std::bad_alloc&)
  2762         return gl::error(GL_OUT_OF_MEMORY);
  2766 void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
  2768     EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
  2770     try
  2772         if (n < 0)
  2774             return gl::error(GL_INVALID_VALUE);
  2777         gl::Context *context = gl::getNonLostContext();
  2779         if (context)
  2781             for (int i = 0; i < n; i++)
  2783                 renderbuffers[i] = context->createRenderbuffer();
  2787     catch(std::bad_alloc&)
  2789         return gl::error(GL_OUT_OF_MEMORY);
  2793 void __stdcall glGenTextures(GLsizei n, GLuint* textures)
  2795     EVENT("(GLsizei n = %d, GLuint* textures =  0x%0.8p)", n, textures);
  2797     try
  2799         if (n < 0)
  2801             return gl::error(GL_INVALID_VALUE);
  2804         gl::Context *context = gl::getNonLostContext();
  2806         if (context)
  2808             for (int i = 0; i < n; i++)
  2810                 textures[i] = context->createTexture();
  2814     catch(std::bad_alloc&)
  2816         return gl::error(GL_OUT_OF_MEMORY);
  2820 void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
  2822     EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
  2823           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
  2824           program, index, bufsize, length, size, type, name);
  2826     try
  2828         if (bufsize < 0)
  2830             return gl::error(GL_INVALID_VALUE);
  2833         gl::Context *context = gl::getNonLostContext();
  2835         if (context)
  2837             gl::Program *programObject = context->getProgram(program);
  2839             if (!programObject)
  2841                 if (context->getShader(program))
  2843                     return gl::error(GL_INVALID_OPERATION);
  2845                 else
  2847                     return gl::error(GL_INVALID_VALUE);
  2851             if (index >= (GLuint)programObject->getActiveAttributeCount())
  2853                 return gl::error(GL_INVALID_VALUE);
  2856             programObject->getActiveAttribute(index, bufsize, length, size, type, name);
  2859     catch(std::bad_alloc&)
  2861         return gl::error(GL_OUT_OF_MEMORY);
  2865 void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
  2867     EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
  2868           "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
  2869           program, index, bufsize, length, size, type, name);
  2871     try
  2873         if (bufsize < 0)
  2875             return gl::error(GL_INVALID_VALUE);
  2878         gl::Context *context = gl::getNonLostContext();
  2880         if (context)
  2882             gl::Program *programObject = context->getProgram(program);
  2884             if (!programObject)
  2886                 if (context->getShader(program))
  2888                     return gl::error(GL_INVALID_OPERATION);
  2890                 else
  2892                     return gl::error(GL_INVALID_VALUE);
  2896             if (index >= (GLuint)programObject->getActiveUniformCount())
  2898                 return gl::error(GL_INVALID_VALUE);
  2901             programObject->getActiveUniform(index, bufsize, length, size, type, name);
  2904     catch(std::bad_alloc&)
  2906         return gl::error(GL_OUT_OF_MEMORY);
  2910 void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
  2912     EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
  2913           program, maxcount, count, shaders);
  2915     try
  2917         if (maxcount < 0)
  2919             return gl::error(GL_INVALID_VALUE);
  2922         gl::Context *context = gl::getNonLostContext();
  2924         if (context)
  2926             gl::Program *programObject = context->getProgram(program);
  2928             if (!programObject)
  2930                 if (context->getShader(program))
  2932                     return gl::error(GL_INVALID_OPERATION);
  2934                 else
  2936                     return gl::error(GL_INVALID_VALUE);
  2940             return programObject->getAttachedShaders(maxcount, count, shaders);
  2943     catch(std::bad_alloc&)
  2945         return gl::error(GL_OUT_OF_MEMORY);
  2949 int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
  2951     EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
  2953     try
  2955         gl::Context *context = gl::getNonLostContext();
  2957         if (context)
  2960             gl::Program *programObject = context->getProgram(program);
  2962             if (!programObject)
  2964                 if (context->getShader(program))
  2966                     return gl::error(GL_INVALID_OPERATION, -1);
  2968                 else
  2970                     return gl::error(GL_INVALID_VALUE, -1);
  2974             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  2975             if (!programObject->isLinked() || !programBinary)
  2977                 return gl::error(GL_INVALID_OPERATION, -1);
  2980             return programBinary->getAttributeLocation(name);
  2983     catch(std::bad_alloc&)
  2985         return gl::error(GL_OUT_OF_MEMORY, -1);
  2988     return -1;
  2991 void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
  2993     EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);
  2995     try
  2997         gl::Context *context = gl::getNonLostContext();
  2999         if (context)
  3001             if (!(context->getBooleanv(pname, params)))
  3003                 GLenum nativeType;
  3004                 unsigned int numParams = 0;
  3005                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
  3006                     return gl::error(GL_INVALID_ENUM);
  3008                 if (numParams == 0)
  3009                     return; // it is known that the pname is valid, but there are no parameters to return
  3011                 if (nativeType == GL_FLOAT)
  3013                     GLfloat *floatParams = NULL;
  3014                     floatParams = new GLfloat[numParams];
  3016                     context->getFloatv(pname, floatParams);
  3018                     for (unsigned int i = 0; i < numParams; ++i)
  3020                         if (floatParams[i] == 0.0f)
  3021                             params[i] = GL_FALSE;
  3022                         else
  3023                             params[i] = GL_TRUE;
  3026                     delete [] floatParams;
  3028                 else if (nativeType == GL_INT)
  3030                     GLint *intParams = NULL;
  3031                     intParams = new GLint[numParams];
  3033                     context->getIntegerv(pname, intParams);
  3035                     for (unsigned int i = 0; i < numParams; ++i)
  3037                         if (intParams[i] == 0)
  3038                             params[i] = GL_FALSE;
  3039                         else
  3040                             params[i] = GL_TRUE;
  3043                     delete [] intParams;
  3048     catch(std::bad_alloc&)
  3050         return gl::error(GL_OUT_OF_MEMORY);
  3054 void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
  3056     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
  3058     try
  3060         gl::Context *context = gl::getNonLostContext();
  3062         if (context)
  3064             gl::Buffer *buffer;
  3066             switch (target)
  3068               case GL_ARRAY_BUFFER:
  3069                 buffer = context->getArrayBuffer();
  3070                 break;
  3071               case GL_ELEMENT_ARRAY_BUFFER:
  3072                 buffer = context->getElementArrayBuffer();
  3073                 break;
  3074               default: return gl::error(GL_INVALID_ENUM);
  3077             if (!buffer)
  3079                 // A null buffer means that "0" is bound to the requested buffer target
  3080                 return gl::error(GL_INVALID_OPERATION);
  3083             switch (pname)
  3085               case GL_BUFFER_USAGE:
  3086                 *params = buffer->usage();
  3087                 break;
  3088               case GL_BUFFER_SIZE:
  3089                 *params = buffer->size();
  3090                 break;
  3091               default: return gl::error(GL_INVALID_ENUM);
  3095     catch(std::bad_alloc&)
  3097         return gl::error(GL_OUT_OF_MEMORY);
  3101 GLenum __stdcall glGetError(void)
  3103     EVENT("()");
  3105     gl::Context *context = gl::getContext();
  3107     if (context)
  3109         return context->getError();
  3112     return GL_NO_ERROR;
  3115 void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
  3117     EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
  3119     try
  3122         gl::Context *context = gl::getNonLostContext();
  3124         if (context)
  3126             gl::Fence *fenceObject = context->getFence(fence);
  3128             if (fenceObject == NULL)
  3130                 return gl::error(GL_INVALID_OPERATION);
  3133             fenceObject->getFenceiv(pname, params);
  3136     catch(std::bad_alloc&)
  3138         return gl::error(GL_OUT_OF_MEMORY);
  3142 void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
  3144     EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
  3146     try
  3148         gl::Context *context = gl::getNonLostContext();
  3150         if (context)
  3152             if (!(context->getFloatv(pname, params)))
  3154                 GLenum nativeType;
  3155                 unsigned int numParams = 0;
  3156                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
  3157                     return gl::error(GL_INVALID_ENUM);
  3159                 if (numParams == 0)
  3160                     return; // it is known that the pname is valid, but that there are no parameters to return.
  3162                 if (nativeType == GL_BOOL)
  3164                     GLboolean *boolParams = NULL;
  3165                     boolParams = new GLboolean[numParams];
  3167                     context->getBooleanv(pname, boolParams);
  3169                     for (unsigned int i = 0; i < numParams; ++i)
  3171                         if (boolParams[i] == GL_FALSE)
  3172                             params[i] = 0.0f;
  3173                         else
  3174                             params[i] = 1.0f;
  3177                     delete [] boolParams;
  3179                 else if (nativeType == GL_INT)
  3181                     GLint *intParams = NULL;
  3182                     intParams = new GLint[numParams];
  3184                     context->getIntegerv(pname, intParams);
  3186                     for (unsigned int i = 0; i < numParams; ++i)
  3188                         params[i] = (GLfloat)intParams[i];
  3191                     delete [] intParams;
  3196     catch(std::bad_alloc&)
  3198         return gl::error(GL_OUT_OF_MEMORY);
  3202 void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
  3204     EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
  3205           target, attachment, pname, params);
  3207     try
  3209         gl::Context *context = gl::getNonLostContext();
  3211         if (context)
  3213             if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
  3215                 return gl::error(GL_INVALID_ENUM);
  3218             gl::Framebuffer *framebuffer = NULL;
  3219             if (target == GL_READ_FRAMEBUFFER_ANGLE)
  3221                 if(context->getReadFramebufferHandle() == 0)
  3223                     return gl::error(GL_INVALID_OPERATION);
  3226                 framebuffer = context->getReadFramebuffer();
  3228             else 
  3230                 if (context->getDrawFramebufferHandle() == 0)
  3232                     return gl::error(GL_INVALID_OPERATION);
  3235                 framebuffer = context->getDrawFramebuffer();
  3238             GLenum attachmentType;
  3239             GLuint attachmentHandle;
  3241             if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
  3243                 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
  3245                 if (colorAttachment >= context->getMaximumRenderTargets())
  3247                     return gl::error(GL_INVALID_ENUM);
  3250                 attachmentType = framebuffer->getColorbufferType(colorAttachment);
  3251                 attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment);
  3253             else
  3255                 switch (attachment)
  3257                   case GL_DEPTH_ATTACHMENT:
  3258                     attachmentType = framebuffer->getDepthbufferType();
  3259                     attachmentHandle = framebuffer->getDepthbufferHandle();
  3260                     break;
  3261                   case GL_STENCIL_ATTACHMENT:
  3262                     attachmentType = framebuffer->getStencilbufferType();
  3263                     attachmentHandle = framebuffer->getStencilbufferHandle();
  3264                     break;
  3265                   default: return gl::error(GL_INVALID_ENUM);
  3269             GLenum attachmentObjectType;   // Type category
  3270             if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
  3272                 attachmentObjectType = attachmentType;
  3274             else if (gl::IsInternalTextureTarget(attachmentType))
  3276                 attachmentObjectType = GL_TEXTURE;
  3278             else
  3280                 UNREACHABLE();
  3281                 return;
  3284             switch (pname)
  3286               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
  3287                 *params = attachmentObjectType;
  3288                 break;
  3289               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
  3290                 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
  3292                     *params = attachmentHandle;
  3294                 else
  3296                     return gl::error(GL_INVALID_ENUM);
  3298                 break;
  3299               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
  3300                 if (attachmentObjectType == GL_TEXTURE)
  3302                     *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
  3304                 else
  3306                     return gl::error(GL_INVALID_ENUM);
  3308                 break;
  3309               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
  3310                 if (attachmentObjectType == GL_TEXTURE)
  3312                     if (gl::IsCubemapTextureTarget(attachmentType))
  3314                         *params = attachmentType;
  3316                     else
  3318                         *params = 0;
  3321                 else
  3323                     return gl::error(GL_INVALID_ENUM);
  3325                 break;
  3326               default:
  3327                 return gl::error(GL_INVALID_ENUM);
  3331     catch(std::bad_alloc&)
  3333         return gl::error(GL_OUT_OF_MEMORY);
  3337 GLenum __stdcall glGetGraphicsResetStatusEXT(void)
  3339     EVENT("()");
  3341     try
  3343         gl::Context *context = gl::getContext();
  3345         if (context)
  3347             return context->getResetStatus();
  3350         return GL_NO_ERROR;
  3352     catch(std::bad_alloc&)
  3354         return GL_OUT_OF_MEMORY;
  3358 void __stdcall glGetIntegerv(GLenum pname, GLint* params)
  3360     EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
  3362     try
  3364         gl::Context *context = gl::getNonLostContext();
  3366         if (context)
  3368             if (!(context->getIntegerv(pname, params)))
  3370                 GLenum nativeType;
  3371                 unsigned int numParams = 0;
  3372                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
  3373                     return gl::error(GL_INVALID_ENUM);
  3375                 if (numParams == 0)
  3376                     return; // it is known that pname is valid, but there are no parameters to return
  3378                 if (nativeType == GL_BOOL)
  3380                     GLboolean *boolParams = NULL;
  3381                     boolParams = new GLboolean[numParams];
  3383                     context->getBooleanv(pname, boolParams);
  3385                     for (unsigned int i = 0; i < numParams; ++i)
  3387                         if (boolParams[i] == GL_FALSE)
  3388                             params[i] = 0;
  3389                         else
  3390                             params[i] = 1;
  3393                     delete [] boolParams;
  3395                 else if (nativeType == GL_FLOAT)
  3397                     GLfloat *floatParams = NULL;
  3398                     floatParams = new GLfloat[numParams];
  3400                     context->getFloatv(pname, floatParams);
  3402                     for (unsigned int i = 0; i < numParams; ++i)
  3404                         if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
  3406                             params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
  3408                         else
  3409                             params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
  3412                     delete [] floatParams;
  3417     catch(std::bad_alloc&)
  3419         return gl::error(GL_OUT_OF_MEMORY);
  3423 void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
  3425     EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
  3427     try
  3429         gl::Context *context = gl::getNonLostContext();
  3431         if (context)
  3433             gl::Program *programObject = context->getProgram(program);
  3435             if (!programObject)
  3437                 return gl::error(GL_INVALID_VALUE);
  3440             switch (pname)
  3442               case GL_DELETE_STATUS:
  3443                 *params = programObject->isFlaggedForDeletion();
  3444                 return;
  3445               case GL_LINK_STATUS:
  3446                 *params = programObject->isLinked();
  3447                 return;
  3448               case GL_VALIDATE_STATUS:
  3449                 *params = programObject->isValidated();
  3450                 return;
  3451               case GL_INFO_LOG_LENGTH:
  3452                 *params = programObject->getInfoLogLength();
  3453                 return;
  3454               case GL_ATTACHED_SHADERS:
  3455                 *params = programObject->getAttachedShadersCount();
  3456                 return;
  3457               case GL_ACTIVE_ATTRIBUTES:
  3458                 *params = programObject->getActiveAttributeCount();
  3459                 return;
  3460               case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
  3461                 *params = programObject->getActiveAttributeMaxLength();
  3462                 return;
  3463               case GL_ACTIVE_UNIFORMS:
  3464                 *params = programObject->getActiveUniformCount();
  3465                 return;
  3466               case GL_ACTIVE_UNIFORM_MAX_LENGTH:
  3467                 *params = programObject->getActiveUniformMaxLength();
  3468                 return;
  3469               case GL_PROGRAM_BINARY_LENGTH_OES:
  3470                 *params = programObject->getProgramBinaryLength();
  3471                 return;
  3472               default:
  3473                 return gl::error(GL_INVALID_ENUM);
  3477     catch(std::bad_alloc&)
  3479         return gl::error(GL_OUT_OF_MEMORY);
  3483 void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
  3485     EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
  3486           program, bufsize, length, infolog);
  3488     try
  3490         if (bufsize < 0)
  3492             return gl::error(GL_INVALID_VALUE);
  3495         gl::Context *context = gl::getNonLostContext();
  3497         if (context)
  3499             gl::Program *programObject = context->getProgram(program);
  3501             if (!programObject)
  3503                 return gl::error(GL_INVALID_VALUE);
  3506             programObject->getInfoLog(bufsize, length, infolog);
  3509     catch(std::bad_alloc&)
  3511         return gl::error(GL_OUT_OF_MEMORY);
  3515 void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
  3517     EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
  3519     try
  3521         switch (pname)
  3523           case GL_CURRENT_QUERY_EXT:
  3524             break;
  3525           default:
  3526             return gl::error(GL_INVALID_ENUM);
  3529         gl::Context *context = gl::getNonLostContext();
  3531         if (context)
  3533             params[0] = context->getActiveQuery(target);
  3536     catch(std::bad_alloc&)
  3538         return gl::error(GL_OUT_OF_MEMORY);
  3542 void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
  3544     EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
  3546     try
  3548         switch (pname)
  3550           case GL_QUERY_RESULT_EXT:
  3551           case GL_QUERY_RESULT_AVAILABLE_EXT:
  3552             break;
  3553           default:
  3554             return gl::error(GL_INVALID_ENUM);
  3556         gl::Context *context = gl::getNonLostContext();
  3558         if (context)
  3560             gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
  3562             if (!queryObject)
  3564                 return gl::error(GL_INVALID_OPERATION);
  3567             if (context->getActiveQuery(queryObject->getType()) == id)
  3569                 return gl::error(GL_INVALID_OPERATION);
  3572             switch(pname)
  3574               case GL_QUERY_RESULT_EXT:
  3575                 params[0] = queryObject->getResult();
  3576                 break;
  3577               case GL_QUERY_RESULT_AVAILABLE_EXT:
  3578                 params[0] = queryObject->isResultAvailable();
  3579                 break;
  3580               default:
  3581                 ASSERT(false);
  3585     catch(std::bad_alloc&)
  3587         return gl::error(GL_OUT_OF_MEMORY);
  3591 void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
  3593     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
  3595     try
  3597         gl::Context *context = gl::getNonLostContext();
  3599         if (context)
  3601             if (target != GL_RENDERBUFFER)
  3603                 return gl::error(GL_INVALID_ENUM);
  3606             if (context->getRenderbufferHandle() == 0)
  3608                 return gl::error(GL_INVALID_OPERATION);
  3611             gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
  3613             switch (pname)
  3615               case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();          break;
  3616               case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();         break;
  3617               case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
  3618               case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();        break;
  3619               case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();      break;
  3620               case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();       break;
  3621               case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();      break;
  3622               case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();      break;
  3623               case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize();    break;
  3624               case GL_RENDERBUFFER_SAMPLES_ANGLE:
  3625                 if (context->getMaxSupportedSamples() != 0)
  3627                     *params = renderbuffer->getSamples();
  3629                 else
  3631                     return gl::error(GL_INVALID_ENUM);
  3633                 break;
  3634               default:
  3635                 return gl::error(GL_INVALID_ENUM);
  3639     catch(std::bad_alloc&)
  3641         return gl::error(GL_OUT_OF_MEMORY);
  3645 void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
  3647     EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
  3649     try
  3651         gl::Context *context = gl::getNonLostContext();
  3653         if (context)
  3655             gl::Shader *shaderObject = context->getShader(shader);
  3657             if (!shaderObject)
  3659                 return gl::error(GL_INVALID_VALUE);
  3662             switch (pname)
  3664               case GL_SHADER_TYPE:
  3665                 *params = shaderObject->getType();
  3666                 return;
  3667               case GL_DELETE_STATUS:
  3668                 *params = shaderObject->isFlaggedForDeletion();
  3669                 return;
  3670               case GL_COMPILE_STATUS:
  3671                 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
  3672                 return;
  3673               case GL_INFO_LOG_LENGTH:
  3674                 *params = shaderObject->getInfoLogLength();
  3675                 return;
  3676               case GL_SHADER_SOURCE_LENGTH:
  3677                 *params = shaderObject->getSourceLength();
  3678                 return;
  3679               case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
  3680                 *params = shaderObject->getTranslatedSourceLength();
  3681                 return;
  3682               default:
  3683                 return gl::error(GL_INVALID_ENUM);
  3687     catch(std::bad_alloc&)
  3689         return gl::error(GL_OUT_OF_MEMORY);
  3693 void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
  3695     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
  3696           shader, bufsize, length, infolog);
  3698     try
  3700         if (bufsize < 0)
  3702             return gl::error(GL_INVALID_VALUE);
  3705         gl::Context *context = gl::getNonLostContext();
  3707         if (context)
  3709             gl::Shader *shaderObject = context->getShader(shader);
  3711             if (!shaderObject)
  3713                 return gl::error(GL_INVALID_VALUE);
  3716             shaderObject->getInfoLog(bufsize, length, infolog);
  3719     catch(std::bad_alloc&)
  3721         return gl::error(GL_OUT_OF_MEMORY);
  3725 void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
  3727     EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
  3728           shadertype, precisiontype, range, precision);
  3730     try
  3732         switch (shadertype)
  3734           case GL_VERTEX_SHADER:
  3735           case GL_FRAGMENT_SHADER:
  3736             break;
  3737           default:
  3738             return gl::error(GL_INVALID_ENUM);
  3741         switch (precisiontype)
  3743           case GL_LOW_FLOAT:
  3744           case GL_MEDIUM_FLOAT:
  3745           case GL_HIGH_FLOAT:
  3746             // Assume IEEE 754 precision
  3747             range[0] = 127;
  3748             range[1] = 127;
  3749             *precision = 23;
  3750             break;
  3751           case GL_LOW_INT:
  3752           case GL_MEDIUM_INT:
  3753           case GL_HIGH_INT:
  3754             // Some (most) hardware only supports single-precision floating-point numbers,
  3755             // which can accurately represent integers up to +/-16777216
  3756             range[0] = 24;
  3757             range[1] = 24;
  3758             *precision = 0;
  3759             break;
  3760           default:
  3761             return gl::error(GL_INVALID_ENUM);
  3764     catch(std::bad_alloc&)
  3766         return gl::error(GL_OUT_OF_MEMORY);
  3770 void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
  3772     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
  3773           shader, bufsize, length, source);
  3775     try
  3777         if (bufsize < 0)
  3779             return gl::error(GL_INVALID_VALUE);
  3782         gl::Context *context = gl::getNonLostContext();
  3784         if (context)
  3786             gl::Shader *shaderObject = context->getShader(shader);
  3788             if (!shaderObject)
  3790                 return gl::error(GL_INVALID_OPERATION);
  3793             shaderObject->getSource(bufsize, length, source);
  3796     catch(std::bad_alloc&)
  3798         return gl::error(GL_OUT_OF_MEMORY);
  3802 void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
  3804     EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
  3805           shader, bufsize, length, source);
  3807     try
  3809         if (bufsize < 0)
  3811             return gl::error(GL_INVALID_VALUE);
  3814         gl::Context *context = gl::getNonLostContext();
  3816         if (context)
  3818             gl::Shader *shaderObject = context->getShader(shader);
  3820             if (!shaderObject)
  3822                 return gl::error(GL_INVALID_OPERATION);
  3825             shaderObject->getTranslatedSource(bufsize, length, source);
  3828     catch(std::bad_alloc&)
  3830         return gl::error(GL_OUT_OF_MEMORY);
  3834 const GLubyte* __stdcall glGetString(GLenum name)
  3836     EVENT("(GLenum name = 0x%X)", name);
  3838     try
  3840         gl::Context *context = gl::getNonLostContext();
  3842         switch (name)
  3844           case GL_VENDOR:
  3845             return (GLubyte*)"Google Inc.";
  3846           case GL_RENDERER:
  3847             return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
  3848           case GL_VERSION:
  3849             return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")";
  3850           case GL_SHADING_LANGUAGE_VERSION:
  3851             return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")";
  3852           case GL_EXTENSIONS:
  3853             return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
  3854           default:
  3855             return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
  3858     catch(std::bad_alloc&)
  3860         return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
  3864 void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
  3866     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
  3868     try
  3870         gl::Context *context = gl::getNonLostContext();
  3872         if (context)
  3874             gl::Texture *texture;
  3876             switch (target)
  3878               case GL_TEXTURE_2D:
  3879                 texture = context->getTexture2D();
  3880                 break;
  3881               case GL_TEXTURE_CUBE_MAP:
  3882                 texture = context->getTextureCubeMap();
  3883                 break;
  3884               default:
  3885                 return gl::error(GL_INVALID_ENUM);
  3888             switch (pname)
  3890               case GL_TEXTURE_MAG_FILTER:
  3891                 *params = (GLfloat)texture->getMagFilter();
  3892                 break;
  3893               case GL_TEXTURE_MIN_FILTER:
  3894                 *params = (GLfloat)texture->getMinFilter();
  3895                 break;
  3896               case GL_TEXTURE_WRAP_S:
  3897                 *params = (GLfloat)texture->getWrapS();
  3898                 break;
  3899               case GL_TEXTURE_WRAP_T:
  3900                 *params = (GLfloat)texture->getWrapT();
  3901                 break;
  3902               case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
  3903                 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
  3904                 break;
  3905               case GL_TEXTURE_USAGE_ANGLE:
  3906                 *params = (GLfloat)texture->getUsage();
  3907                 break;
  3908               case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  3909                 if (!context->supportsTextureFilterAnisotropy())
  3911                     return gl::error(GL_INVALID_ENUM);
  3913                 *params = (GLfloat)texture->getMaxAnisotropy();
  3914                 break;
  3915               default:
  3916                 return gl::error(GL_INVALID_ENUM);
  3920     catch(std::bad_alloc&)
  3922         return gl::error(GL_OUT_OF_MEMORY);
  3926 void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
  3928     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
  3930     try
  3932         gl::Context *context = gl::getNonLostContext();
  3934         if (context)
  3936             gl::Texture *texture;
  3938             switch (target)
  3940               case GL_TEXTURE_2D:
  3941                 texture = context->getTexture2D();
  3942                 break;
  3943               case GL_TEXTURE_CUBE_MAP:
  3944                 texture = context->getTextureCubeMap();
  3945                 break;
  3946               default:
  3947                 return gl::error(GL_INVALID_ENUM);
  3950             switch (pname)
  3952               case GL_TEXTURE_MAG_FILTER:
  3953                 *params = texture->getMagFilter();
  3954                 break;
  3955               case GL_TEXTURE_MIN_FILTER:
  3956                 *params = texture->getMinFilter();
  3957                 break;
  3958               case GL_TEXTURE_WRAP_S:
  3959                 *params = texture->getWrapS();
  3960                 break;
  3961               case GL_TEXTURE_WRAP_T:
  3962                 *params = texture->getWrapT();
  3963                 break;
  3964               case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
  3965                 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
  3966                 break;
  3967               case GL_TEXTURE_USAGE_ANGLE:
  3968                 *params = texture->getUsage();
  3969                 break;
  3970               case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  3971                 if (!context->supportsTextureFilterAnisotropy())
  3973                     return gl::error(GL_INVALID_ENUM);
  3975                 *params = (GLint)texture->getMaxAnisotropy();
  3976                 break;
  3977               default:
  3978                 return gl::error(GL_INVALID_ENUM);
  3982     catch(std::bad_alloc&)
  3984         return gl::error(GL_OUT_OF_MEMORY);
  3988 void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
  3990     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
  3991           program, location, bufSize, params);
  3993     try
  3995         if (bufSize < 0)
  3997             return gl::error(GL_INVALID_VALUE);
  4000         gl::Context *context = gl::getNonLostContext();
  4002         if (context)
  4004             if (program == 0)
  4006                 return gl::error(GL_INVALID_VALUE);
  4009             gl::Program *programObject = context->getProgram(program);
  4011             if (!programObject || !programObject->isLinked())
  4013                 return gl::error(GL_INVALID_OPERATION);
  4016             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  4017             if (!programBinary)
  4019                 return gl::error(GL_INVALID_OPERATION);
  4022             if (!programBinary->getUniformfv(location, &bufSize, params))
  4024                 return gl::error(GL_INVALID_OPERATION);
  4028     catch(std::bad_alloc&)
  4030         return gl::error(GL_OUT_OF_MEMORY);
  4034 void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
  4036     EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
  4038     try
  4040         gl::Context *context = gl::getNonLostContext();
  4042         if (context)
  4044             if (program == 0)
  4046                 return gl::error(GL_INVALID_VALUE);
  4049             gl::Program *programObject = context->getProgram(program);
  4051             if (!programObject || !programObject->isLinked())
  4053                 return gl::error(GL_INVALID_OPERATION);
  4056             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  4057             if (!programBinary)
  4059                 return gl::error(GL_INVALID_OPERATION);
  4062             if (!programBinary->getUniformfv(location, NULL, params))
  4064                 return gl::error(GL_INVALID_OPERATION);
  4068     catch(std::bad_alloc&)
  4070         return gl::error(GL_OUT_OF_MEMORY);
  4074 void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
  4076     EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", 
  4077           program, location, bufSize, params);
  4079     try
  4081         if (bufSize < 0)
  4083             return gl::error(GL_INVALID_VALUE);
  4086         gl::Context *context = gl::getNonLostContext();
  4088         if (context)
  4090             if (program == 0)
  4092                 return gl::error(GL_INVALID_VALUE);
  4095             gl::Program *programObject = context->getProgram(program);
  4097             if (!programObject || !programObject->isLinked())
  4099                 return gl::error(GL_INVALID_OPERATION);
  4102             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  4103             if (!programBinary)
  4105                 return gl::error(GL_INVALID_OPERATION);
  4108             if (!programBinary->getUniformiv(location, &bufSize, params))
  4110                 return gl::error(GL_INVALID_OPERATION);
  4114     catch(std::bad_alloc&)
  4116         return gl::error(GL_OUT_OF_MEMORY);
  4120 void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
  4122     EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
  4124     try
  4126         gl::Context *context = gl::getNonLostContext();
  4128         if (context)
  4130             if (program == 0)
  4132                 return gl::error(GL_INVALID_VALUE);
  4135             gl::Program *programObject = context->getProgram(program);
  4137             if (!programObject || !programObject->isLinked())
  4139                 return gl::error(GL_INVALID_OPERATION);
  4142             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  4143             if (!programBinary)
  4145                 return gl::error(GL_INVALID_OPERATION);
  4148             if (!programBinary->getUniformiv(location, NULL, params))
  4150                 return gl::error(GL_INVALID_OPERATION);
  4154     catch(std::bad_alloc&)
  4156         return gl::error(GL_OUT_OF_MEMORY);
  4160 int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
  4162     EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
  4164     try
  4166         gl::Context *context = gl::getNonLostContext();
  4168         if (strstr(name, "gl_") == name)
  4170             return -1;
  4173         if (context)
  4175             gl::Program *programObject = context->getProgram(program);
  4177             if (!programObject)
  4179                 if (context->getShader(program))
  4181                     return gl::error(GL_INVALID_OPERATION, -1);
  4183                 else
  4185                     return gl::error(GL_INVALID_VALUE, -1);
  4189             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  4190             if (!programObject->isLinked() || !programBinary)
  4192                 return gl::error(GL_INVALID_OPERATION, -1);
  4195             return programBinary->getUniformLocation(name);
  4198     catch(std::bad_alloc&)
  4200         return gl::error(GL_OUT_OF_MEMORY, -1);
  4203     return -1;
  4206 void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
  4208     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
  4210     try
  4212         gl::Context *context = gl::getNonLostContext();
  4214         if (context)
  4216             if (index >= gl::MAX_VERTEX_ATTRIBS)
  4218                 return gl::error(GL_INVALID_VALUE);
  4221             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
  4223             switch (pname)
  4225               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
  4226                 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
  4227                 break;
  4228               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
  4229                 *params = (GLfloat)attribState.mSize;
  4230                 break;
  4231               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
  4232                 *params = (GLfloat)attribState.mStride;
  4233                 break;
  4234               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
  4235                 *params = (GLfloat)attribState.mType;
  4236                 break;
  4237               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
  4238                 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
  4239                 break;
  4240               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
  4241                 *params = (GLfloat)attribState.mBoundBuffer.id();
  4242                 break;
  4243               case GL_CURRENT_VERTEX_ATTRIB:
  4244                 for (int i = 0; i < 4; ++i)
  4246                     params[i] = attribState.mCurrentValue[i];
  4248                 break;
  4249               case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
  4250                 *params = (GLfloat)attribState.mDivisor;
  4251                 break;
  4252               default: return gl::error(GL_INVALID_ENUM);
  4256     catch(std::bad_alloc&)
  4258         return gl::error(GL_OUT_OF_MEMORY);
  4262 void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
  4264     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
  4266     try
  4268         gl::Context *context = gl::getNonLostContext();
  4270         if (context)
  4272             if (index >= gl::MAX_VERTEX_ATTRIBS)
  4274                 return gl::error(GL_INVALID_VALUE);
  4277             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
  4279             switch (pname)
  4281               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
  4282                 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
  4283                 break;
  4284               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
  4285                 *params = attribState.mSize;
  4286                 break;
  4287               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
  4288                 *params = attribState.mStride;
  4289                 break;
  4290               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
  4291                 *params = attribState.mType;
  4292                 break;
  4293               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
  4294                 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
  4295                 break;
  4296               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
  4297                 *params = attribState.mBoundBuffer.id();
  4298                 break;
  4299               case GL_CURRENT_VERTEX_ATTRIB:
  4300                 for (int i = 0; i < 4; ++i)
  4302                     float currentValue = attribState.mCurrentValue[i];
  4303                     params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
  4305                 break;
  4306               case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
  4307                 *params = (GLint)attribState.mDivisor;
  4308                 break;
  4309               default: return gl::error(GL_INVALID_ENUM);
  4313     catch(std::bad_alloc&)
  4315         return gl::error(GL_OUT_OF_MEMORY);
  4319 void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
  4321     EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
  4323     try
  4325         gl::Context *context = gl::getNonLostContext();
  4327         if (context)
  4329             if (index >= gl::MAX_VERTEX_ATTRIBS)
  4331                 return gl::error(GL_INVALID_VALUE);
  4334             if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
  4336                 return gl::error(GL_INVALID_ENUM);
  4339             *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
  4342     catch(std::bad_alloc&)
  4344         return gl::error(GL_OUT_OF_MEMORY);
  4348 void __stdcall glHint(GLenum target, GLenum mode)
  4350     EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
  4352     try
  4354         switch (mode)
  4356           case GL_FASTEST:
  4357           case GL_NICEST:
  4358           case GL_DONT_CARE:
  4359             break;
  4360           default:
  4361             return gl::error(GL_INVALID_ENUM); 
  4364         gl::Context *context = gl::getNonLostContext();
  4365         switch (target)
  4367           case GL_GENERATE_MIPMAP_HINT:
  4368             if (context) context->setGenerateMipmapHint(mode);
  4369             break;
  4370           case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
  4371             if (context) context->setFragmentShaderDerivativeHint(mode);
  4372             break;
  4373           default:
  4374             return gl::error(GL_INVALID_ENUM);
  4377     catch(std::bad_alloc&)
  4379         return gl::error(GL_OUT_OF_MEMORY);
  4383 GLboolean __stdcall glIsBuffer(GLuint buffer)
  4385     EVENT("(GLuint buffer = %d)", buffer);
  4387     try
  4389         gl::Context *context = gl::getNonLostContext();
  4391         if (context && buffer)
  4393             gl::Buffer *bufferObject = context->getBuffer(buffer);
  4395             if (bufferObject)
  4397                 return GL_TRUE;
  4401     catch(std::bad_alloc&)
  4403         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4406     return GL_FALSE;
  4409 GLboolean __stdcall glIsEnabled(GLenum cap)
  4411     EVENT("(GLenum cap = 0x%X)", cap);
  4413     try
  4415         gl::Context *context = gl::getNonLostContext();
  4417         if (context)
  4419             switch (cap)
  4421               case GL_CULL_FACE:                return context->isCullFaceEnabled();
  4422               case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
  4423               case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
  4424               case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
  4425               case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
  4426               case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
  4427               case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
  4428               case GL_BLEND:                    return context->isBlendEnabled();
  4429               case GL_DITHER:                   return context->isDitherEnabled();
  4430               default:
  4431                 return gl::error(GL_INVALID_ENUM, false);
  4435     catch(std::bad_alloc&)
  4437         return gl::error(GL_OUT_OF_MEMORY, false);
  4440     return false;
  4443 GLboolean __stdcall glIsFenceNV(GLuint fence)
  4445     EVENT("(GLuint fence = %d)", fence);
  4447     try
  4449         gl::Context *context = gl::getNonLostContext();
  4451         if (context)
  4453             gl::Fence *fenceObject = context->getFence(fence);
  4455             if (fenceObject == NULL)
  4457                 return GL_FALSE;
  4460             return fenceObject->isFence();
  4463     catch(std::bad_alloc&)
  4465         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4468     return GL_FALSE;
  4471 GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
  4473     EVENT("(GLuint framebuffer = %d)", framebuffer);
  4475     try
  4477         gl::Context *context = gl::getNonLostContext();
  4479         if (context && framebuffer)
  4481             gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
  4483             if (framebufferObject)
  4485                 return GL_TRUE;
  4489     catch(std::bad_alloc&)
  4491         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4494     return GL_FALSE;
  4497 GLboolean __stdcall glIsProgram(GLuint program)
  4499     EVENT("(GLuint program = %d)", program);
  4501     try
  4503         gl::Context *context = gl::getNonLostContext();
  4505         if (context && program)
  4507             gl::Program *programObject = context->getProgram(program);
  4509             if (programObject)
  4511                 return GL_TRUE;
  4515     catch(std::bad_alloc&)
  4517         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4520     return GL_FALSE;
  4523 GLboolean __stdcall glIsQueryEXT(GLuint id)
  4525     EVENT("(GLuint id = %d)", id);
  4527     try
  4529         if (id == 0)
  4531             return GL_FALSE;
  4534         gl::Context *context = gl::getNonLostContext();
  4536         if (context)
  4538             gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
  4540             if (queryObject)
  4542                 return GL_TRUE;
  4546     catch(std::bad_alloc&)
  4548         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4551     return GL_FALSE;
  4554 GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
  4556     EVENT("(GLuint renderbuffer = %d)", renderbuffer);
  4558     try
  4560         gl::Context *context = gl::getNonLostContext();
  4562         if (context && renderbuffer)
  4564             gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
  4566             if (renderbufferObject)
  4568                 return GL_TRUE;
  4572     catch(std::bad_alloc&)
  4574         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4577     return GL_FALSE;
  4580 GLboolean __stdcall glIsShader(GLuint shader)
  4582     EVENT("(GLuint shader = %d)", shader);
  4584     try
  4586         gl::Context *context = gl::getNonLostContext();
  4588         if (context && shader)
  4590             gl::Shader *shaderObject = context->getShader(shader);
  4592             if (shaderObject)
  4594                 return GL_TRUE;
  4598     catch(std::bad_alloc&)
  4600         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4603     return GL_FALSE;
  4606 GLboolean __stdcall glIsTexture(GLuint texture)
  4608     EVENT("(GLuint texture = %d)", texture);
  4610     try
  4612         gl::Context *context = gl::getNonLostContext();
  4614         if (context && texture)
  4616             gl::Texture *textureObject = context->getTexture(texture);
  4618             if (textureObject)
  4620                 return GL_TRUE;
  4624     catch(std::bad_alloc&)
  4626         return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
  4629     return GL_FALSE;
  4632 void __stdcall glLineWidth(GLfloat width)
  4634     EVENT("(GLfloat width = %f)", width);
  4636     try
  4638         if (width <= 0.0f)
  4640             return gl::error(GL_INVALID_VALUE);
  4643         gl::Context *context = gl::getNonLostContext();
  4645         if (context)
  4647             context->setLineWidth(width);
  4650     catch(std::bad_alloc&)
  4652         return gl::error(GL_OUT_OF_MEMORY);
  4656 void __stdcall glLinkProgram(GLuint program)
  4658     EVENT("(GLuint program = %d)", program);
  4660     try
  4662         gl::Context *context = gl::getNonLostContext();
  4664         if (context)
  4666             gl::Program *programObject = context->getProgram(program);
  4668             if (!programObject)
  4670                 if (context->getShader(program))
  4672                     return gl::error(GL_INVALID_OPERATION);
  4674                 else
  4676                     return gl::error(GL_INVALID_VALUE);
  4680             context->linkProgram(program);
  4683     catch(std::bad_alloc&)
  4685         return gl::error(GL_OUT_OF_MEMORY);
  4689 void __stdcall glPixelStorei(GLenum pname, GLint param)
  4691     EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
  4693     try
  4695         gl::Context *context = gl::getNonLostContext();
  4697         if (context)
  4699             switch (pname)
  4701               case GL_UNPACK_ALIGNMENT:
  4702                 if (param != 1 && param != 2 && param != 4 && param != 8)
  4704                     return gl::error(GL_INVALID_VALUE);
  4707                 context->setUnpackAlignment(param);
  4708                 break;
  4710               case GL_PACK_ALIGNMENT:
  4711                 if (param != 1 && param != 2 && param != 4 && param != 8)
  4713                     return gl::error(GL_INVALID_VALUE);
  4716                 context->setPackAlignment(param);
  4717                 break;
  4719               case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
  4720                 context->setPackReverseRowOrder(param != 0);
  4721                 break;
  4723               default:
  4724                 return gl::error(GL_INVALID_ENUM);
  4728     catch(std::bad_alloc&)
  4730         return gl::error(GL_OUT_OF_MEMORY);
  4734 void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
  4736     EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
  4738     try
  4740         gl::Context *context = gl::getNonLostContext();
  4742         if (context)
  4744             context->setPolygonOffsetParams(factor, units);
  4747     catch(std::bad_alloc&)
  4749         return gl::error(GL_OUT_OF_MEMORY);
  4753 void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
  4754                                 GLenum format, GLenum type, GLsizei bufSize,
  4755                                 GLvoid *data)
  4757     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
  4758           "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
  4759           x, y, width, height, format, type, bufSize, data);
  4761     try
  4763         if (width < 0 || height < 0 || bufSize < 0)
  4765             return gl::error(GL_INVALID_VALUE);
  4768         gl::Context *context = gl::getNonLostContext();
  4770         if (context)
  4772             GLenum currentFormat, currentType;
  4774             // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
  4775             // and attempting to read back if that's the case is an error. The error will be registered
  4776             // by getCurrentReadFormat.
  4777             if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
  4778                 return;
  4780             if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
  4782                 return gl::error(GL_INVALID_OPERATION);
  4785             context->readPixels(x, y, width, height, format, type, &bufSize, data);
  4788     catch(std::bad_alloc&)
  4790         return gl::error(GL_OUT_OF_MEMORY);
  4794 void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
  4795                             GLenum format, GLenum type, GLvoid* pixels)
  4797     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
  4798           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
  4799           x, y, width, height, format, type,  pixels);
  4801     try
  4803         if (width < 0 || height < 0)
  4805             return gl::error(GL_INVALID_VALUE);
  4808         gl::Context *context = gl::getNonLostContext();
  4810         if (context)
  4812             GLenum currentFormat, currentType;
  4814             // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
  4815             // and attempting to read back if that's the case is an error. The error will be registered
  4816             // by getCurrentReadFormat.
  4817             if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
  4818                 return;
  4820             if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
  4822                 return gl::error(GL_INVALID_OPERATION);
  4825             context->readPixels(x, y, width, height, format, type, NULL, pixels);
  4828     catch(std::bad_alloc&)
  4830         return gl::error(GL_OUT_OF_MEMORY);
  4834 void __stdcall glReleaseShaderCompiler(void)
  4836     EVENT("()");
  4838     try
  4840         gl::Shader::releaseCompiler();
  4842     catch(std::bad_alloc&)
  4844         return gl::error(GL_OUT_OF_MEMORY);
  4848 void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
  4850     EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
  4851           target, samples, internalformat, width, height);
  4853     try
  4855         switch (target)
  4857           case GL_RENDERBUFFER:
  4858             break;
  4859           default:
  4860             return gl::error(GL_INVALID_ENUM);
  4863         if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
  4865             return gl::error(GL_INVALID_ENUM);
  4868         if (width < 0 || height < 0 || samples < 0)
  4870             return gl::error(GL_INVALID_VALUE);
  4873         gl::Context *context = gl::getNonLostContext();
  4875         if (context)
  4877             if (width > context->getMaximumRenderbufferDimension() || 
  4878                 height > context->getMaximumRenderbufferDimension() ||
  4879                 samples > context->getMaxSupportedSamples())
  4881                 return gl::error(GL_INVALID_VALUE);
  4884             GLuint handle = context->getRenderbufferHandle();
  4885             if (handle == 0)
  4887                 return gl::error(GL_INVALID_OPERATION);
  4890             switch (internalformat)
  4892               case GL_DEPTH_COMPONENT16:
  4893               case GL_RGBA4:
  4894               case GL_RGB5_A1:
  4895               case GL_RGB565:
  4896               case GL_RGB8_OES:
  4897               case GL_RGBA8_OES:
  4898               case GL_STENCIL_INDEX8:
  4899               case GL_DEPTH24_STENCIL8_OES:
  4900                 context->setRenderbufferStorage(width, height, internalformat, samples);
  4901                 break;
  4902               default:
  4903                 return gl::error(GL_INVALID_ENUM);
  4907     catch(std::bad_alloc&)
  4909         return gl::error(GL_OUT_OF_MEMORY);
  4913 void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
  4915     glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
  4918 void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
  4920     EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
  4922     try
  4924         gl::Context* context = gl::getNonLostContext();
  4926         if (context)
  4928             context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
  4931     catch(std::bad_alloc&)
  4933         return gl::error(GL_OUT_OF_MEMORY);
  4937 void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
  4939     EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
  4941     try
  4943         if (condition != GL_ALL_COMPLETED_NV)
  4945             return gl::error(GL_INVALID_ENUM);
  4948         gl::Context *context = gl::getNonLostContext();
  4950         if (context)
  4952             gl::Fence *fenceObject = context->getFence(fence);
  4954             if (fenceObject == NULL)
  4956                 return gl::error(GL_INVALID_OPERATION);
  4959             fenceObject->setFence(condition);    
  4962     catch(std::bad_alloc&)
  4964         return gl::error(GL_OUT_OF_MEMORY);
  4968 void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
  4970     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
  4972     try
  4974         if (width < 0 || height < 0)
  4976             return gl::error(GL_INVALID_VALUE);
  4979         gl::Context* context = gl::getNonLostContext();
  4981         if (context)
  4983             context->setScissorParams(x, y, width, height);
  4986     catch(std::bad_alloc&)
  4988         return gl::error(GL_OUT_OF_MEMORY);
  4992 void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
  4994     EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
  4995           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
  4996           n, shaders, binaryformat, binary, length);
  4998     try
  5000         // No binary shader formats are supported.
  5001         return gl::error(GL_INVALID_ENUM);
  5003     catch(std::bad_alloc&)
  5005         return gl::error(GL_OUT_OF_MEMORY);
  5009 void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
  5011     EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
  5012           shader, count, string, length);
  5014     try
  5016         if (count < 0)
  5018             return gl::error(GL_INVALID_VALUE);
  5021         gl::Context *context = gl::getNonLostContext();
  5023         if (context)
  5025             gl::Shader *shaderObject = context->getShader(shader);
  5027             if (!shaderObject)
  5029                 if (context->getProgram(shader))
  5031                     return gl::error(GL_INVALID_OPERATION);
  5033                 else
  5035                     return gl::error(GL_INVALID_VALUE);
  5039             shaderObject->setSource(count, string, length);
  5042     catch(std::bad_alloc&)
  5044         return gl::error(GL_OUT_OF_MEMORY);
  5048 void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
  5050     glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
  5053 void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
  5055     EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
  5057     try
  5059         switch (face)
  5061           case GL_FRONT:
  5062           case GL_BACK:
  5063           case GL_FRONT_AND_BACK:
  5064             break;
  5065           default:
  5066             return gl::error(GL_INVALID_ENUM);
  5069         switch (func)
  5071           case GL_NEVER:
  5072           case GL_ALWAYS:
  5073           case GL_LESS:
  5074           case GL_LEQUAL:
  5075           case GL_EQUAL:
  5076           case GL_GEQUAL:
  5077           case GL_GREATER:
  5078           case GL_NOTEQUAL:
  5079             break;
  5080           default:
  5081             return gl::error(GL_INVALID_ENUM);
  5084         gl::Context *context = gl::getNonLostContext();
  5086         if (context)
  5088             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
  5090                 context->setStencilParams(func, ref, mask);
  5093             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
  5095                 context->setStencilBackParams(func, ref, mask);
  5099     catch(std::bad_alloc&)
  5101         return gl::error(GL_OUT_OF_MEMORY);
  5105 void __stdcall glStencilMask(GLuint mask)
  5107     glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
  5110 void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
  5112     EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
  5114     try
  5116         switch (face)
  5118           case GL_FRONT:
  5119           case GL_BACK:
  5120           case GL_FRONT_AND_BACK:
  5121             break;
  5122           default:
  5123             return gl::error(GL_INVALID_ENUM);
  5126         gl::Context *context = gl::getNonLostContext();
  5128         if (context)
  5130             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
  5132                 context->setStencilWritemask(mask);
  5135             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
  5137                 context->setStencilBackWritemask(mask);
  5141     catch(std::bad_alloc&)
  5143         return gl::error(GL_OUT_OF_MEMORY);
  5147 void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
  5149     glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
  5152 void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
  5154     EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
  5155           face, fail, zfail, zpass);
  5157     try
  5159         switch (face)
  5161           case GL_FRONT:
  5162           case GL_BACK:
  5163           case GL_FRONT_AND_BACK:
  5164             break;
  5165           default:
  5166             return gl::error(GL_INVALID_ENUM);
  5169         switch (fail)
  5171           case GL_ZERO:
  5172           case GL_KEEP:
  5173           case GL_REPLACE:
  5174           case GL_INCR:
  5175           case GL_DECR:
  5176           case GL_INVERT:
  5177           case GL_INCR_WRAP:
  5178           case GL_DECR_WRAP:
  5179             break;
  5180           default:
  5181             return gl::error(GL_INVALID_ENUM);
  5184         switch (zfail)
  5186           case GL_ZERO:
  5187           case GL_KEEP:
  5188           case GL_REPLACE:
  5189           case GL_INCR:
  5190           case GL_DECR:
  5191           case GL_INVERT:
  5192           case GL_INCR_WRAP:
  5193           case GL_DECR_WRAP:
  5194             break;
  5195           default:
  5196             return gl::error(GL_INVALID_ENUM);
  5199         switch (zpass)
  5201           case GL_ZERO:
  5202           case GL_KEEP:
  5203           case GL_REPLACE:
  5204           case GL_INCR:
  5205           case GL_DECR:
  5206           case GL_INVERT:
  5207           case GL_INCR_WRAP:
  5208           case GL_DECR_WRAP:
  5209             break;
  5210           default:
  5211             return gl::error(GL_INVALID_ENUM);
  5214         gl::Context *context = gl::getNonLostContext();
  5216         if (context)
  5218             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
  5220                 context->setStencilOperations(fail, zfail, zpass);
  5223             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
  5225                 context->setStencilBackOperations(fail, zfail, zpass);
  5229     catch(std::bad_alloc&)
  5231         return gl::error(GL_OUT_OF_MEMORY);
  5235 GLboolean __stdcall glTestFenceNV(GLuint fence)
  5237     EVENT("(GLuint fence = %d)", fence);
  5239     try
  5241         gl::Context *context = gl::getNonLostContext();
  5243         if (context)
  5245             gl::Fence *fenceObject = context->getFence(fence);
  5247             if (fenceObject == NULL)
  5249                 return gl::error(GL_INVALID_OPERATION, GL_TRUE);
  5252             return fenceObject->testFence();
  5255     catch(std::bad_alloc&)
  5257         gl::error(GL_OUT_OF_MEMORY);
  5260     return GL_TRUE;
  5263 void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
  5264                             GLint border, GLenum format, GLenum type, const GLvoid* pixels)
  5266     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
  5267           "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  0x%0.8p)",
  5268           target, level, internalformat, width, height, border, format, type, pixels);
  5270     try
  5272         if (!validImageSize(level, width, height))
  5274             return gl::error(GL_INVALID_VALUE);
  5277         if (internalformat != GLint(format))
  5279             return gl::error(GL_INVALID_OPERATION);
  5282         // validate <type> by itself (used as secondary key below)
  5283         switch (type)
  5285           case GL_UNSIGNED_BYTE:
  5286           case GL_UNSIGNED_SHORT_5_6_5:
  5287           case GL_UNSIGNED_SHORT_4_4_4_4:
  5288           case GL_UNSIGNED_SHORT_5_5_5_1:
  5289           case GL_UNSIGNED_SHORT:
  5290           case GL_UNSIGNED_INT:
  5291           case GL_UNSIGNED_INT_24_8_OES:
  5292           case GL_HALF_FLOAT_OES:
  5293           case GL_FLOAT:
  5294             break;
  5295           default:
  5296             return gl::error(GL_INVALID_ENUM);
  5299         // validate <format> + <type> combinations
  5300         // - invalid <format> -> sets INVALID_ENUM
  5301         // - invalid <format>+<type> combination -> sets INVALID_OPERATION
  5302         switch (format)
  5304           case GL_ALPHA:
  5305           case GL_LUMINANCE:
  5306           case GL_LUMINANCE_ALPHA:
  5307             switch (type)
  5309               case GL_UNSIGNED_BYTE:
  5310               case GL_FLOAT:
  5311               case GL_HALF_FLOAT_OES:
  5312                 break;
  5313               default:
  5314                 return gl::error(GL_INVALID_OPERATION);
  5316             break;
  5317           case GL_RGB:
  5318             switch (type)
  5320               case GL_UNSIGNED_BYTE:
  5321               case GL_UNSIGNED_SHORT_5_6_5:
  5322               case GL_FLOAT:
  5323               case GL_HALF_FLOAT_OES:
  5324                 break;
  5325               default:
  5326                 return gl::error(GL_INVALID_OPERATION);
  5328             break;
  5329           case GL_RGBA:
  5330             switch (type)
  5332               case GL_UNSIGNED_BYTE:
  5333               case GL_UNSIGNED_SHORT_4_4_4_4:
  5334               case GL_UNSIGNED_SHORT_5_5_5_1:
  5335               case GL_FLOAT:
  5336               case GL_HALF_FLOAT_OES:
  5337                 break;
  5338               default:
  5339                 return gl::error(GL_INVALID_OPERATION);
  5341             break;
  5342           case GL_BGRA_EXT:
  5343             switch (type)
  5345               case GL_UNSIGNED_BYTE:
  5346                 break;
  5347               default:
  5348                 return gl::error(GL_INVALID_OPERATION);
  5350             break;
  5351           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
  5352           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  5353           case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  5354           case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  5355             break; 
  5356           case GL_DEPTH_COMPONENT:
  5357             switch (type)
  5359               case GL_UNSIGNED_SHORT:
  5360               case GL_UNSIGNED_INT:
  5361                 break;
  5362               default:
  5363                 return gl::error(GL_INVALID_OPERATION);
  5365             break;
  5366           case GL_DEPTH_STENCIL_OES:
  5367             switch (type)
  5369               case GL_UNSIGNED_INT_24_8_OES:
  5370                 break;
  5371               default:
  5372                 return gl::error(GL_INVALID_OPERATION);
  5374             break;
  5375           default:
  5376             return gl::error(GL_INVALID_ENUM);
  5379         if (border != 0)
  5381             return gl::error(GL_INVALID_VALUE);
  5384         gl::Context *context = gl::getNonLostContext();
  5386         if (context)
  5388             if (level > context->getMaximumTextureLevel())
  5390                 return gl::error(GL_INVALID_VALUE);
  5393             switch (target)
  5395               case GL_TEXTURE_2D:
  5396                 if (width > (context->getMaximumTextureDimension() >> level) ||
  5397                     height > (context->getMaximumTextureDimension() >> level))
  5399                     return gl::error(GL_INVALID_VALUE);
  5401                 break;
  5402               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  5403               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  5404               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  5405               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  5406               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  5407               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  5408                 if (width != height)
  5410                     return gl::error(GL_INVALID_VALUE);
  5413                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
  5414                     height > (context->getMaximumCubeTextureDimension() >> level))
  5416                     return gl::error(GL_INVALID_VALUE);
  5418                 break;
  5419               default:
  5420                 return gl::error(GL_INVALID_ENUM);
  5423             switch (format) {
  5424               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  5425               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  5426                 if (context->supportsDXT1Textures())
  5428                     return gl::error(GL_INVALID_OPERATION);
  5430                 else
  5432                     return gl::error(GL_INVALID_ENUM);
  5434                 break;
  5435               case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  5436                 if (context->supportsDXT3Textures())
  5438                     return gl::error(GL_INVALID_OPERATION);
  5440                 else
  5442                     return gl::error(GL_INVALID_ENUM);
  5444                 break;
  5445               case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  5446                 if (context->supportsDXT5Textures())
  5448                     return gl::error(GL_INVALID_OPERATION);
  5450                 else
  5452                     return gl::error(GL_INVALID_ENUM);
  5454                 break;
  5455               case GL_DEPTH_COMPONENT:
  5456               case GL_DEPTH_STENCIL_OES:
  5457                 if (!context->supportsDepthTextures())
  5459                     return gl::error(GL_INVALID_VALUE);
  5461                 if (target != GL_TEXTURE_2D)
  5463                     return gl::error(GL_INVALID_OPERATION);
  5465                 // OES_depth_texture supports loading depth data and multiple levels,
  5466                 // but ANGLE_depth_texture does not
  5467                 if (pixels != NULL || level != 0)
  5469                     return gl::error(GL_INVALID_OPERATION);
  5471                 break;
  5472               default:
  5473                 break;
  5476             if (type == GL_FLOAT)
  5478                 if (!context->supportsFloat32Textures())
  5480                     return gl::error(GL_INVALID_ENUM);
  5483             else if (type == GL_HALF_FLOAT_OES)
  5485                 if (!context->supportsFloat16Textures())
  5487                     return gl::error(GL_INVALID_ENUM);
  5491             if (target == GL_TEXTURE_2D)
  5493                 gl::Texture2D *texture = context->getTexture2D();
  5495                 if (!texture)
  5497                     return gl::error(GL_INVALID_OPERATION);
  5500                 if (texture->isImmutable())
  5502                     return gl::error(GL_INVALID_OPERATION);
  5505                 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5507             else
  5509                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
  5511                 if (!texture)
  5513                     return gl::error(GL_INVALID_OPERATION);
  5516                 if (texture->isImmutable())
  5518                     return gl::error(GL_INVALID_OPERATION);
  5521                 switch (target)
  5523                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  5524                     texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5525                     break;
  5526                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  5527                     texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5528                     break;
  5529                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  5530                     texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5531                     break;
  5532                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  5533                     texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5534                     break;
  5535                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  5536                     texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5537                     break;
  5538                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  5539                     texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
  5540                     break;
  5541                   default: UNREACHABLE();
  5546     catch(std::bad_alloc&)
  5548         return gl::error(GL_OUT_OF_MEMORY);
  5552 void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
  5554     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
  5556     try
  5558         gl::Context *context = gl::getNonLostContext();
  5560         if (context)
  5562             gl::Texture *texture;
  5564             switch (target)
  5566               case GL_TEXTURE_2D:
  5567                 texture = context->getTexture2D();
  5568                 break;
  5569               case GL_TEXTURE_CUBE_MAP:
  5570                 texture = context->getTextureCubeMap();
  5571                 break;
  5572               default:
  5573                 return gl::error(GL_INVALID_ENUM);
  5576             switch (pname)
  5578               case GL_TEXTURE_WRAP_S:
  5579                 if (!texture->setWrapS((GLenum)param))
  5581                     return gl::error(GL_INVALID_ENUM);
  5583                 break;
  5584               case GL_TEXTURE_WRAP_T:
  5585                 if (!texture->setWrapT((GLenum)param))
  5587                     return gl::error(GL_INVALID_ENUM);
  5589                 break;
  5590               case GL_TEXTURE_MIN_FILTER:
  5591                 if (!texture->setMinFilter((GLenum)param))
  5593                     return gl::error(GL_INVALID_ENUM);
  5595                 break;
  5596               case GL_TEXTURE_MAG_FILTER:
  5597                 if (!texture->setMagFilter((GLenum)param))
  5599                     return gl::error(GL_INVALID_ENUM);
  5601                 break;
  5602               case GL_TEXTURE_USAGE_ANGLE:
  5603                 if (!texture->setUsage((GLenum)param))
  5605                     return gl::error(GL_INVALID_ENUM);
  5607                 break;
  5608               case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  5609                 if (!context->supportsTextureFilterAnisotropy())
  5611                     return gl::error(GL_INVALID_ENUM);
  5613                 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
  5615                     return gl::error(GL_INVALID_VALUE);
  5617                 break;
  5618               default:
  5619                 return gl::error(GL_INVALID_ENUM);
  5623     catch(std::bad_alloc&)
  5625         return gl::error(GL_OUT_OF_MEMORY);
  5629 void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
  5631     glTexParameterf(target, pname, (GLfloat)*params);
  5634 void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
  5636     EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
  5638     try
  5640         gl::Context *context = gl::getNonLostContext();
  5642         if (context)
  5644             gl::Texture *texture;
  5646             switch (target)
  5648               case GL_TEXTURE_2D:
  5649                 texture = context->getTexture2D();
  5650                 break;
  5651               case GL_TEXTURE_CUBE_MAP:
  5652                 texture = context->getTextureCubeMap();
  5653                 break;
  5654               default:
  5655                 return gl::error(GL_INVALID_ENUM);
  5658             switch (pname)
  5660               case GL_TEXTURE_WRAP_S:
  5661                 if (!texture->setWrapS((GLenum)param))
  5663                     return gl::error(GL_INVALID_ENUM);
  5665                 break;
  5666               case GL_TEXTURE_WRAP_T:
  5667                 if (!texture->setWrapT((GLenum)param))
  5669                     return gl::error(GL_INVALID_ENUM);
  5671                 break;
  5672               case GL_TEXTURE_MIN_FILTER:
  5673                 if (!texture->setMinFilter((GLenum)param))
  5675                     return gl::error(GL_INVALID_ENUM);
  5677                 break;
  5678               case GL_TEXTURE_MAG_FILTER:
  5679                 if (!texture->setMagFilter((GLenum)param))
  5681                     return gl::error(GL_INVALID_ENUM);
  5683                 break;
  5684               case GL_TEXTURE_USAGE_ANGLE:
  5685                 if (!texture->setUsage((GLenum)param))
  5687                     return gl::error(GL_INVALID_ENUM);
  5689                 break;
  5690               case GL_TEXTURE_MAX_ANISOTROPY_EXT:
  5691                 if (!context->supportsTextureFilterAnisotropy())
  5693                     return gl::error(GL_INVALID_ENUM);
  5695                 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
  5697                     return gl::error(GL_INVALID_VALUE);
  5699                 break;
  5700               default:
  5701                 return gl::error(GL_INVALID_ENUM);
  5705     catch(std::bad_alloc&)
  5707         return gl::error(GL_OUT_OF_MEMORY);
  5711 void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
  5713     glTexParameteri(target, pname, *params);
  5716 void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
  5718     EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
  5719            target, levels, internalformat, width, height);
  5721     try
  5723         if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
  5725             return gl::error(GL_INVALID_ENUM);
  5728         if (width < 1 || height < 1 || levels < 1)
  5730             return gl::error(GL_INVALID_VALUE);
  5733         if (target == GL_TEXTURE_CUBE_MAP && width != height)
  5735             return gl::error(GL_INVALID_VALUE);
  5738         if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
  5740             return gl::error(GL_INVALID_OPERATION);
  5743         GLenum format = gl::ExtractFormat(internalformat);
  5744         GLenum type = gl::ExtractType(internalformat);
  5746         if (format == GL_NONE || type == GL_NONE)
  5748             return gl::error(GL_INVALID_ENUM);
  5751         gl::Context *context = gl::getNonLostContext();
  5753         if (context)
  5755             switch (target)
  5757               case GL_TEXTURE_2D:
  5758                 if (width > context->getMaximumTextureDimension() ||
  5759                     height > context->getMaximumTextureDimension())
  5761                     return gl::error(GL_INVALID_VALUE);
  5763                 break;
  5764               case GL_TEXTURE_CUBE_MAP:
  5765                 if (width > context->getMaximumCubeTextureDimension() ||
  5766                     height > context->getMaximumCubeTextureDimension())
  5768                     return gl::error(GL_INVALID_VALUE);
  5770                 break;
  5771               default:
  5772                 return gl::error(GL_INVALID_ENUM);
  5775             if (levels != 1 && !context->supportsNonPower2Texture())
  5777                 if (!gl::isPow2(width) || !gl::isPow2(height))
  5779                     return gl::error(GL_INVALID_OPERATION);
  5783             switch (internalformat)
  5785               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  5786               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  5787                 if (!context->supportsDXT1Textures())
  5789                     return gl::error(GL_INVALID_ENUM);
  5791                 break;
  5792               case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
  5793                 if (!context->supportsDXT3Textures())
  5795                     return gl::error(GL_INVALID_ENUM);
  5797                 break;
  5798               case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
  5799                 if (!context->supportsDXT5Textures())
  5801                     return gl::error(GL_INVALID_ENUM);
  5803                 break;
  5804               case GL_RGBA32F_EXT:
  5805               case GL_RGB32F_EXT:
  5806               case GL_ALPHA32F_EXT:
  5807               case GL_LUMINANCE32F_EXT:
  5808               case GL_LUMINANCE_ALPHA32F_EXT:
  5809                 if (!context->supportsFloat32Textures())
  5811                     return gl::error(GL_INVALID_ENUM);
  5813                 break;
  5814               case GL_RGBA16F_EXT:
  5815               case GL_RGB16F_EXT:
  5816               case GL_ALPHA16F_EXT:
  5817               case GL_LUMINANCE16F_EXT:
  5818               case GL_LUMINANCE_ALPHA16F_EXT:
  5819                 if (!context->supportsFloat16Textures())
  5821                     return gl::error(GL_INVALID_ENUM);
  5823                 break;
  5824               case GL_DEPTH_COMPONENT16:
  5825               case GL_DEPTH_COMPONENT32_OES:
  5826               case GL_DEPTH24_STENCIL8_OES:
  5827                 if (!context->supportsDepthTextures())
  5829                     return gl::error(GL_INVALID_ENUM);
  5831                 if (target != GL_TEXTURE_2D)
  5833                     return gl::error(GL_INVALID_OPERATION);
  5835                 // ANGLE_depth_texture only supports 1-level textures
  5836                 if (levels != 1)
  5838                     return gl::error(GL_INVALID_OPERATION);
  5840                 break;
  5841               default:
  5842                 break;
  5845             if (target == GL_TEXTURE_2D)
  5847                 gl::Texture2D *texture = context->getTexture2D();
  5849                 if (!texture || texture->id() == 0)
  5851                     return gl::error(GL_INVALID_OPERATION);
  5854                 if (texture->isImmutable())
  5856                     return gl::error(GL_INVALID_OPERATION);
  5859                 texture->storage(levels, internalformat, width, height);
  5861             else if (target == GL_TEXTURE_CUBE_MAP)
  5863                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
  5865                 if (!texture || texture->id() == 0)
  5867                     return gl::error(GL_INVALID_OPERATION);
  5870                 if (texture->isImmutable())
  5872                     return gl::error(GL_INVALID_OPERATION);
  5875                 texture->storage(levels, internalformat, width);
  5877             else UNREACHABLE();
  5880     catch(std::bad_alloc&)
  5882         return gl::error(GL_OUT_OF_MEMORY);
  5886 void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
  5887                                GLenum format, GLenum type, const GLvoid* pixels)
  5889     EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
  5890           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
  5891           "const GLvoid* pixels = 0x%0.8p)",
  5892            target, level, xoffset, yoffset, width, height, format, type, pixels);
  5894     try
  5896         if (!gl::IsInternalTextureTarget(target))
  5898             return gl::error(GL_INVALID_ENUM);
  5901         if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
  5903             return gl::error(GL_INVALID_VALUE);
  5906         if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
  5908             return gl::error(GL_INVALID_VALUE);
  5911         if (!checkTextureFormatType(format, type))
  5913             return; // error is set by helper function
  5916         gl::Context *context = gl::getNonLostContext();
  5918         if (context)
  5920             if (level > context->getMaximumTextureLevel())
  5922                 return gl::error(GL_INVALID_VALUE);
  5925             if (format == GL_FLOAT)
  5927                 if (!context->supportsFloat32Textures())
  5929                     return gl::error(GL_INVALID_ENUM);
  5932             else if (format == GL_HALF_FLOAT_OES)
  5934                 if (!context->supportsFloat16Textures())
  5936                     return gl::error(GL_INVALID_ENUM);
  5939             else if (gl::IsDepthTexture(format))
  5941                 if (!context->supportsDepthTextures())
  5943                     return gl::error(GL_INVALID_ENUM);
  5945                 if (target != GL_TEXTURE_2D)
  5947                     return gl::error(GL_INVALID_OPERATION);
  5949                 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
  5950                 return gl::error(GL_INVALID_OPERATION);
  5953             if (width == 0 || height == 0 || pixels == NULL)
  5955                 return;
  5958             if (target == GL_TEXTURE_2D)
  5960                 gl::Texture2D *texture = context->getTexture2D();
  5961                 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture))
  5963                     texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
  5966             else if (gl::IsCubemapTextureTarget(target))
  5968                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
  5969                 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture))
  5971                     texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
  5974             else
  5976                 UNREACHABLE();
  5980     catch(std::bad_alloc&)
  5982         return gl::error(GL_OUT_OF_MEMORY);
  5986 void __stdcall glUniform1f(GLint location, GLfloat x)
  5988     glUniform1fv(location, 1, &x);
  5991 void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
  5993     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
  5995     try
  5997         if (count < 0)
  5999             return gl::error(GL_INVALID_VALUE);
  6002         if (location == -1)
  6004             return;
  6007         gl::Context *context = gl::getNonLostContext();
  6009         if (context)
  6011             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6012             if (!programBinary)
  6014                 return gl::error(GL_INVALID_OPERATION);
  6017             if (!programBinary->setUniform1fv(location, count, v))
  6019                 return gl::error(GL_INVALID_OPERATION);
  6023     catch(std::bad_alloc&)
  6025         return gl::error(GL_OUT_OF_MEMORY);
  6029 void __stdcall glUniform1i(GLint location, GLint x)
  6031     glUniform1iv(location, 1, &x);
  6034 void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
  6036     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
  6038     try
  6040         if (count < 0)
  6042             return gl::error(GL_INVALID_VALUE);
  6045         if (location == -1)
  6047             return;
  6050         gl::Context *context = gl::getNonLostContext();
  6052         if (context)
  6054             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6055             if (!programBinary)
  6057                 return gl::error(GL_INVALID_OPERATION);
  6060             if (!programBinary->setUniform1iv(location, count, v))
  6062                 return gl::error(GL_INVALID_OPERATION);
  6066     catch(std::bad_alloc&)
  6068         return gl::error(GL_OUT_OF_MEMORY);
  6072 void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
  6074     GLfloat xy[2] = {x, y};
  6076     glUniform2fv(location, 1, (GLfloat*)&xy);
  6079 void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
  6081     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
  6083     try
  6085         if (count < 0)
  6087             return gl::error(GL_INVALID_VALUE);
  6090         if (location == -1)
  6092             return;
  6095         gl::Context *context = gl::getNonLostContext();
  6097         if (context)
  6099             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6100             if (!programBinary)
  6102                 return gl::error(GL_INVALID_OPERATION);
  6105             if (!programBinary->setUniform2fv(location, count, v))
  6107                 return gl::error(GL_INVALID_OPERATION);
  6111     catch(std::bad_alloc&)
  6113         return gl::error(GL_OUT_OF_MEMORY);
  6117 void __stdcall glUniform2i(GLint location, GLint x, GLint y)
  6119     GLint xy[4] = {x, y};
  6121     glUniform2iv(location, 1, (GLint*)&xy);
  6124 void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
  6126     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
  6128     try
  6130         if (count < 0)
  6132             return gl::error(GL_INVALID_VALUE);
  6135         if (location == -1)
  6137             return;
  6140         gl::Context *context = gl::getNonLostContext();
  6142         if (context)
  6144             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6145             if (!programBinary)
  6147                 return gl::error(GL_INVALID_OPERATION);
  6150             if (!programBinary->setUniform2iv(location, count, v))
  6152                 return gl::error(GL_INVALID_OPERATION);
  6156     catch(std::bad_alloc&)
  6158         return gl::error(GL_OUT_OF_MEMORY);
  6162 void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
  6164     GLfloat xyz[3] = {x, y, z};
  6166     glUniform3fv(location, 1, (GLfloat*)&xyz);
  6169 void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
  6171     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
  6173     try
  6175         if (count < 0)
  6177             return gl::error(GL_INVALID_VALUE);
  6180         if (location == -1)
  6182             return;
  6185         gl::Context *context = gl::getNonLostContext();
  6187         if (context)
  6189             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6190             if (!programBinary)
  6192                 return gl::error(GL_INVALID_OPERATION);
  6195             if (!programBinary->setUniform3fv(location, count, v))
  6197                 return gl::error(GL_INVALID_OPERATION);
  6201     catch(std::bad_alloc&)
  6203         return gl::error(GL_OUT_OF_MEMORY);
  6207 void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
  6209     GLint xyz[3] = {x, y, z};
  6211     glUniform3iv(location, 1, (GLint*)&xyz);
  6214 void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
  6216     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
  6218     try
  6220         if (count < 0)
  6222             return gl::error(GL_INVALID_VALUE);
  6225         if (location == -1)
  6227             return;
  6230         gl::Context *context = gl::getNonLostContext();
  6232         if (context)
  6234             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6235             if (!programBinary)
  6237                 return gl::error(GL_INVALID_OPERATION);
  6240             if (!programBinary->setUniform3iv(location, count, v))
  6242                 return gl::error(GL_INVALID_OPERATION);
  6246     catch(std::bad_alloc&)
  6248         return gl::error(GL_OUT_OF_MEMORY);
  6252 void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  6254     GLfloat xyzw[4] = {x, y, z, w};
  6256     glUniform4fv(location, 1, (GLfloat*)&xyzw);
  6259 void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
  6261     EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
  6263     try
  6265         if (count < 0)
  6267             return gl::error(GL_INVALID_VALUE);
  6270         if (location == -1)
  6272             return;
  6275         gl::Context *context = gl::getNonLostContext();
  6277         if (context)
  6279             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6280             if (!programBinary)
  6282                 return gl::error(GL_INVALID_OPERATION);
  6285             if (!programBinary->setUniform4fv(location, count, v))
  6287                 return gl::error(GL_INVALID_OPERATION);
  6291     catch(std::bad_alloc&)
  6293         return gl::error(GL_OUT_OF_MEMORY);
  6297 void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
  6299     GLint xyzw[4] = {x, y, z, w};
  6301     glUniform4iv(location, 1, (GLint*)&xyzw);
  6304 void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
  6306     EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
  6308     try
  6310         if (count < 0)
  6312             return gl::error(GL_INVALID_VALUE);
  6315         if (location == -1)
  6317             return;
  6320         gl::Context *context = gl::getNonLostContext();
  6322         if (context)
  6324             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6325             if (!programBinary)
  6327                 return gl::error(GL_INVALID_OPERATION);
  6330             if (!programBinary->setUniform4iv(location, count, v))
  6332                 return gl::error(GL_INVALID_OPERATION);
  6336     catch(std::bad_alloc&)
  6338         return gl::error(GL_OUT_OF_MEMORY);
  6342 void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  6344     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
  6345           location, count, transpose, value);
  6347     try
  6349         if (count < 0 || transpose != GL_FALSE)
  6351             return gl::error(GL_INVALID_VALUE);
  6354         if (location == -1)
  6356             return;
  6359         gl::Context *context = gl::getNonLostContext();
  6361         if (context)
  6363             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6364             if (!programBinary)
  6366                 return gl::error(GL_INVALID_OPERATION);
  6369             if (!programBinary->setUniformMatrix2fv(location, count, value))
  6371                 return gl::error(GL_INVALID_OPERATION);
  6375     catch(std::bad_alloc&)
  6377         return gl::error(GL_OUT_OF_MEMORY);
  6381 void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  6383     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
  6384           location, count, transpose, value);
  6386     try
  6388         if (count < 0 || transpose != GL_FALSE)
  6390             return gl::error(GL_INVALID_VALUE);
  6393         if (location == -1)
  6395             return;
  6398         gl::Context *context = gl::getNonLostContext();
  6400         if (context)
  6402             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6403             if (!programBinary)
  6405                 return gl::error(GL_INVALID_OPERATION);
  6408             if (!programBinary->setUniformMatrix3fv(location, count, value))
  6410                 return gl::error(GL_INVALID_OPERATION);
  6414     catch(std::bad_alloc&)
  6416         return gl::error(GL_OUT_OF_MEMORY);
  6420 void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  6422     EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
  6423           location, count, transpose, value);
  6425     try
  6427         if (count < 0 || transpose != GL_FALSE)
  6429             return gl::error(GL_INVALID_VALUE);
  6432         if (location == -1)
  6434             return;
  6437         gl::Context *context = gl::getNonLostContext();
  6439         if (context)
  6441             gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
  6442             if (!programBinary)
  6444                 return gl::error(GL_INVALID_OPERATION);
  6447             if (!programBinary->setUniformMatrix4fv(location, count, value))
  6449                 return gl::error(GL_INVALID_OPERATION);
  6453     catch(std::bad_alloc&)
  6455         return gl::error(GL_OUT_OF_MEMORY);
  6459 void __stdcall glUseProgram(GLuint program)
  6461     EVENT("(GLuint program = %d)", program);
  6463     try
  6465         gl::Context *context = gl::getNonLostContext();
  6467         if (context)
  6469             gl::Program *programObject = context->getProgram(program);
  6471             if (!programObject && program != 0)
  6473                 if (context->getShader(program))
  6475                     return gl::error(GL_INVALID_OPERATION);
  6477                 else
  6479                     return gl::error(GL_INVALID_VALUE);
  6483             if (program != 0 && !programObject->isLinked())
  6485                 return gl::error(GL_INVALID_OPERATION);
  6488             context->useProgram(program);
  6491     catch(std::bad_alloc&)
  6493         return gl::error(GL_OUT_OF_MEMORY);
  6497 void __stdcall glValidateProgram(GLuint program)
  6499     EVENT("(GLuint program = %d)", program);
  6501     try
  6503         gl::Context *context = gl::getNonLostContext();
  6505         if (context)
  6507             gl::Program *programObject = context->getProgram(program);
  6509             if (!programObject)
  6511                 if (context->getShader(program))
  6513                     return gl::error(GL_INVALID_OPERATION);
  6515                 else
  6517                     return gl::error(GL_INVALID_VALUE);
  6521             programObject->validate();
  6524     catch(std::bad_alloc&)
  6526         return gl::error(GL_OUT_OF_MEMORY);
  6530 void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
  6532     EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
  6534     try
  6536         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6538             return gl::error(GL_INVALID_VALUE);
  6541         gl::Context *context = gl::getNonLostContext();
  6543         if (context)
  6545             GLfloat vals[4] = { x, 0, 0, 1 };
  6546             context->setVertexAttrib(index, vals);
  6549     catch(std::bad_alloc&)
  6551         return gl::error(GL_OUT_OF_MEMORY);
  6555 void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
  6557     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
  6559     try
  6561         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6563             return gl::error(GL_INVALID_VALUE);
  6566         gl::Context *context = gl::getNonLostContext();
  6568         if (context)
  6570             GLfloat vals[4] = { values[0], 0, 0, 1 };
  6571             context->setVertexAttrib(index, vals);
  6574     catch(std::bad_alloc&)
  6576         return gl::error(GL_OUT_OF_MEMORY);
  6580 void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
  6582     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
  6584     try
  6586         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6588             return gl::error(GL_INVALID_VALUE);
  6591         gl::Context *context = gl::getNonLostContext();
  6593         if (context)
  6595             GLfloat vals[4] = { x, y, 0, 1 };
  6596             context->setVertexAttrib(index, vals);
  6599     catch(std::bad_alloc&)
  6601         return gl::error(GL_OUT_OF_MEMORY);
  6605 void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
  6607     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
  6609     try
  6611         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6613             return gl::error(GL_INVALID_VALUE);
  6616         gl::Context *context = gl::getNonLostContext();
  6618         if (context)
  6620             GLfloat vals[4] = { values[0], values[1], 0, 1 };
  6621             context->setVertexAttrib(index, vals);
  6624     catch(std::bad_alloc&)
  6626         return gl::error(GL_OUT_OF_MEMORY);
  6630 void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
  6632     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
  6634     try
  6636         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6638             return gl::error(GL_INVALID_VALUE);
  6641         gl::Context *context = gl::getNonLostContext();
  6643         if (context)
  6645             GLfloat vals[4] = { x, y, z, 1 };
  6646             context->setVertexAttrib(index, vals);
  6649     catch(std::bad_alloc&)
  6651         return gl::error(GL_OUT_OF_MEMORY);
  6655 void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
  6657     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
  6659     try
  6661         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6663             return gl::error(GL_INVALID_VALUE);
  6666         gl::Context *context = gl::getNonLostContext();
  6668         if (context)
  6670             GLfloat vals[4] = { values[0], values[1], values[2], 1 };
  6671             context->setVertexAttrib(index, vals);
  6674     catch(std::bad_alloc&)
  6676         return gl::error(GL_OUT_OF_MEMORY);
  6680 void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  6682     EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
  6684     try
  6686         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6688             return gl::error(GL_INVALID_VALUE);
  6691         gl::Context *context = gl::getNonLostContext();
  6693         if (context)
  6695             GLfloat vals[4] = { x, y, z, w };
  6696             context->setVertexAttrib(index, vals);
  6699     catch(std::bad_alloc&)
  6701         return gl::error(GL_OUT_OF_MEMORY);
  6705 void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
  6707     EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
  6709     try
  6711         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6713             return gl::error(GL_INVALID_VALUE);
  6716         gl::Context *context = gl::getNonLostContext();
  6718         if (context)
  6720             context->setVertexAttrib(index, values);
  6723     catch(std::bad_alloc&)
  6725         return gl::error(GL_OUT_OF_MEMORY);
  6729 void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
  6731     EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
  6733     try
  6735         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6737             return gl::error(GL_INVALID_VALUE);
  6740         gl::Context *context = gl::getNonLostContext();
  6742         if (context)
  6744             context->setVertexAttribDivisor(index, divisor);
  6747     catch(std::bad_alloc&)
  6749         return gl::error(GL_OUT_OF_MEMORY);
  6753 void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
  6755     EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
  6756           "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
  6757           index, size, type, normalized, stride, ptr);
  6759     try
  6761         if (index >= gl::MAX_VERTEX_ATTRIBS)
  6763             return gl::error(GL_INVALID_VALUE);
  6766         if (size < 1 || size > 4)
  6768             return gl::error(GL_INVALID_VALUE);
  6771         switch (type)
  6773           case GL_BYTE:
  6774           case GL_UNSIGNED_BYTE:
  6775           case GL_SHORT:
  6776           case GL_UNSIGNED_SHORT:
  6777           case GL_FIXED:
  6778           case GL_FLOAT:
  6779             break;
  6780           default:
  6781             return gl::error(GL_INVALID_ENUM);
  6784         if (stride < 0)
  6786             return gl::error(GL_INVALID_VALUE);
  6789         gl::Context *context = gl::getNonLostContext();
  6791         if (context)
  6793             context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
  6796     catch(std::bad_alloc&)
  6798         return gl::error(GL_OUT_OF_MEMORY);
  6802 void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
  6804     EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
  6806     try
  6808         if (width < 0 || height < 0)
  6810             return gl::error(GL_INVALID_VALUE);
  6813         gl::Context *context = gl::getNonLostContext();
  6815         if (context)
  6817             context->setViewportParams(x, y, width, height);
  6820     catch(std::bad_alloc&)
  6822         return gl::error(GL_OUT_OF_MEMORY);
  6826 void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  6827                                       GLbitfield mask, GLenum filter)
  6829     EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
  6830           "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
  6831           "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
  6832           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
  6834     try
  6836         switch (filter)
  6838           case GL_NEAREST:
  6839             break;
  6840           default:
  6841             return gl::error(GL_INVALID_ENUM);
  6844         if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
  6846             return gl::error(GL_INVALID_VALUE);
  6849         if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
  6851             ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
  6852             return gl::error(GL_INVALID_OPERATION);
  6855         gl::Context *context = gl::getNonLostContext();
  6857         if (context)
  6859             if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
  6861                 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
  6862                 return gl::error(GL_INVALID_OPERATION);
  6865             context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
  6868     catch(std::bad_alloc&)
  6870         return gl::error(GL_OUT_OF_MEMORY);
  6874 void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
  6875                                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
  6877     EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
  6878           "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
  6879           "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
  6880           target, level, internalformat, width, height, depth, border, format, type, pixels);
  6882     try
  6884         UNIMPLEMENTED();   // FIXME
  6886     catch(std::bad_alloc&)
  6888         return gl::error(GL_OUT_OF_MEMORY);
  6892 void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, 
  6893                                      GLenum *binaryFormat, void *binary)
  6895     EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
  6896           program, bufSize, length, binaryFormat, binary);
  6898     try
  6900         gl::Context *context = gl::getNonLostContext();
  6902         if (context)
  6904             gl::Program *programObject = context->getProgram(program);
  6906             if (!programObject || !programObject->isLinked())
  6908                 return gl::error(GL_INVALID_OPERATION);
  6911             gl::ProgramBinary *programBinary = programObject->getProgramBinary();
  6913             if (!programBinary)
  6915                 return gl::error(GL_INVALID_OPERATION);
  6918             if (!programBinary->save(binary, bufSize, length))
  6920                 return gl::error(GL_INVALID_OPERATION);
  6923             *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
  6926     catch(std::bad_alloc&)
  6928         return gl::error(GL_OUT_OF_MEMORY);
  6932 void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
  6933                                   const void *binary, GLint length)
  6935     EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
  6936           program, binaryFormat, binary, length);
  6938     try
  6940         gl::Context *context = gl::getNonLostContext();
  6942         if (context)
  6944             if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
  6946                 return gl::error(GL_INVALID_ENUM);
  6949             gl::Program *programObject = context->getProgram(program);
  6951             if (!programObject)
  6953                 return gl::error(GL_INVALID_OPERATION);
  6956             context->setProgramBinary(program, binary, length);
  6959     catch(std::bad_alloc&)
  6961         return gl::error(GL_OUT_OF_MEMORY);
  6965 void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
  6967     EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
  6969     try
  6971         gl::Context *context = gl::getNonLostContext();
  6973         if (context)
  6975             if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets())
  6977                 return gl::error(GL_INVALID_VALUE);
  6980             if (context->getDrawFramebufferHandle() == 0)
  6982                 if (n != 1)
  6984                     return gl::error(GL_INVALID_OPERATION);
  6987                 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
  6989                     return gl::error(GL_INVALID_OPERATION);
  6992             else
  6994                 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
  6996                     const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
  6997                     if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
  6999                         return gl::error(GL_INVALID_OPERATION);
  7004             gl::Framebuffer *framebuffer = context->getDrawFramebuffer();
  7006             for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
  7008                 framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
  7011             for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++)
  7013                 framebuffer->setDrawBufferState(colorAttachment, GL_NONE);
  7017     catch (std::bad_alloc&)
  7019         return gl::error(GL_OUT_OF_MEMORY);
  7023 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
  7025     struct Extension
  7027         const char *name;
  7028         __eglMustCastToProperFunctionPointerType address;
  7029     };
  7031     static const Extension glExtensions[] =
  7033         {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
  7034         {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
  7035         {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
  7036         {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
  7037         {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
  7038         {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
  7039         {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
  7040         {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
  7041         {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
  7042         {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
  7043         {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
  7044         {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
  7045         {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
  7046         {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
  7047         {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
  7048         {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
  7049         {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
  7050         {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
  7051         {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
  7052         {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
  7053         {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
  7054         {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
  7055         {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
  7056         {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT},
  7057         {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
  7058         {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
  7059         {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
  7060         {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
  7061         {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES},    };
  7063     for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++)
  7065         if (strcmp(procname, glExtensions[ext].name) == 0)
  7067             return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
  7071     return NULL;
  7074 // Non-public functions used by EGL
  7076 bool __stdcall glBindTexImage(egl::Surface *surface)
  7078     EVENT("(egl::Surface* surface = 0x%0.8p)",
  7079           surface);
  7081     try
  7083         gl::Context *context = gl::getNonLostContext();
  7085         if (context)
  7087             gl::Texture2D *textureObject = context->getTexture2D();
  7089             if (textureObject->isImmutable())
  7091                 return false;
  7094             if (textureObject)
  7096                 textureObject->bindTexImage(surface);
  7100     catch(std::bad_alloc&)
  7102         return gl::error(GL_OUT_OF_MEMORY, false);
  7105     return true;

mercurial