// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.

#include "main.h"
#include "mathutil.h"
#include "utilities.h"
#include "Buffer.h"
#include "Context.h"
#include "Fence.h"
#include "Framebuffer.h"
#include "Program.h"
#include "Renderbuffer.h"
#include "Shader.h"
#include "Texture.h"
#include "Query.h"
#include "TransformFeedback.h"
#include "VertexArray.h"
#include "common/debug.h"
#include "Common/Version.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>

#include <algorithm>
#include <limits>

#ifdef __ANDROID__
#include <cutils/log.h>
#endif

namespace es2
{

static bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
	{
		return false;
	}

	return true;
}

static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
{
	if(IsCompressed(textureFormat, egl::getClientVersion()))
	{
		return error(GL_INVALID_OPERATION, false);
	}

	// [OpenGL ES 2.0.24] table 3.9
	switch(textureFormat)
	{
	case GL_ALPHA:
		if(colorbufferFormat != GL_ALPHA &&
		   colorbufferFormat != GL_RGBA &&
		   colorbufferFormat != GL_RGBA4 &&
		   colorbufferFormat != GL_RGB5_A1 &&
		   colorbufferFormat != GL_RGBA8_OES &&
		   colorbufferFormat != GL_BGRA8_EXT &&
		   colorbufferFormat != GL_RGBA16F_EXT &&
		   colorbufferFormat != GL_RGBA32F_EXT)
		{
			return error(GL_INVALID_OPERATION, false);
		}
		break;
	case GL_LUMINANCE:
	case GL_RGB:
		if(colorbufferFormat != GL_RGB &&
		   colorbufferFormat != GL_RGB565 &&
		   colorbufferFormat != GL_RGB8_OES &&
		   colorbufferFormat != GL_RGBA &&
		   colorbufferFormat != GL_RGBA4 &&
		   colorbufferFormat != GL_RGB5_A1 &&
		   colorbufferFormat != GL_RGBA8_OES &&
		   colorbufferFormat != GL_RGB16F_EXT &&
		   colorbufferFormat != GL_RGB32F_EXT &&
		   colorbufferFormat != GL_BGRA8_EXT &&
		   colorbufferFormat != GL_RGBA16F_EXT &&
		   colorbufferFormat != GL_RGBA32F_EXT)
		{
			return error(GL_INVALID_OPERATION, false);
		}
		break;
	case GL_LUMINANCE_ALPHA:
	case GL_RGBA:
		if(colorbufferFormat != GL_RGBA &&
		   colorbufferFormat != GL_RGBA4 &&
		   colorbufferFormat != GL_RGB5_A1 &&
		   colorbufferFormat != GL_RGBA8_OES &&
		   colorbufferFormat != GL_BGRA8_EXT &&
		   colorbufferFormat != GL_RGBA16F_EXT &&
		   colorbufferFormat != GL_RGBA32F_EXT)
		{
			return error(GL_INVALID_OPERATION, false);
		}
		break;
	case GL_DEPTH_COMPONENT:
	case GL_DEPTH_STENCIL_OES:
		return error(GL_INVALID_OPERATION, false);
	default:
		return error(GL_INVALID_ENUM, false);
	}
	return true;
}

void ActiveTexture(GLenum texture)
{
	TRACE("(GLenum texture = 0x%X)", texture);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
		{
			return error(GL_INVALID_ENUM);
		}

		context->setActiveSampler(texture - GL_TEXTURE0);
	}
}

void AttachShader(GLuint program, GLuint shader)
{
	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);
		es2::Shader *shaderObject = context->getShader(shader);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!programObject->attachShader(shaderObject))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void BeginQueryEXT(GLenum target, GLuint name)
{
	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);

	switch(target)
	{
	case GL_ANY_SAMPLES_PASSED_EXT:
	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(name == 0)
	{
		return error(GL_INVALID_OPERATION);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->beginQuery(target, name);
	}
}

void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(strncmp(name, "gl_", 3) == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		programObject->bindAttributeLocation(index, name);
	}
}

void BindBuffer(GLenum target, GLuint buffer)
{
	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLint clientVersion = egl::getClientVersion();

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			context->bindArrayBuffer(buffer);
			return;
		case GL_ELEMENT_ARRAY_BUFFER:
			context->bindElementArrayBuffer(buffer);
			return;
		case GL_COPY_READ_BUFFER:
			if(clientVersion >= 3)
			{
				context->bindCopyReadBuffer(buffer);
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_COPY_WRITE_BUFFER:
			if(clientVersion >= 3)
			{
				context->bindCopyWriteBuffer(buffer);
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_PIXEL_PACK_BUFFER:
			if(clientVersion >= 3)
			{
				context->bindPixelPackBuffer(buffer);
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_PIXEL_UNPACK_BUFFER:
			if(clientVersion >= 3)
			{
				context->bindPixelUnpackBuffer(buffer);
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TRANSFORM_FEEDBACK_BUFFER:
			if(clientVersion >= 3)
			{
				context->bindTransformFeedbackBuffer(buffer);
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_UNIFORM_BUFFER:
			if(clientVersion >= 3)
			{
				context->bindGenericUniformBuffer(buffer);
				return;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void BindFramebuffer(GLenum target, GLuint framebuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
	{
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
		{
			context->bindReadFramebuffer(framebuffer);
		}

		if(target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
		{
			context->bindDrawFramebuffer(framebuffer);
		}
	}
}

void BindRenderbuffer(GLenum target, GLuint renderbuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);

	if(target != GL_RENDERBUFFER)
	{
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		// [OpenGL ES 2.0.25] Section 4.4.3 page 110
		// [OpenGL ES 3.0.4] Section 4.4.2 page 204
		// If renderbuffer is not zero, then the resulting renderbuffer object
		// is a new state vector, initialized with a zero-sized memory buffer.
		context->bindRenderbuffer(renderbuffer);
	}
}

void BindTexture(GLenum target, GLuint texture)
{
	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture *textureObject = context->getTexture(texture);

		if(textureObject && textureObject->getTarget() != target && texture != 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLint clientVersion = context->getClientVersion();

		switch(target)
		{
		case GL_TEXTURE_2D:
			context->bindTexture2D(texture);
			break;
		case GL_TEXTURE_CUBE_MAP:
			context->bindTextureCubeMap(texture);
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			context->bindTextureExternal(texture);
			break;
		case GL_TEXTURE_2D_ARRAY:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			context->bindTexture2DArray(texture);
			break;
		case GL_TEXTURE_3D:
			context->bindTexture3D(texture);
			break;
		case GL_TEXTURE_RECTANGLE_ARB:
			context->bindTexture2DRect(texture);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
		red, green, blue, alpha);

	es2::Context* context = es2::getContext();

	if(context)
	{
		context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
	}
}

void BlendEquation(GLenum mode)
{
	glBlendEquationSeparate(mode, mode);
}

void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

	switch(modeRGB)
	{
	case GL_FUNC_ADD:
	case GL_FUNC_SUBTRACT:
	case GL_FUNC_REVERSE_SUBTRACT:
	case GL_MIN_EXT:
	case GL_MAX_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(modeAlpha)
	{
	case GL_FUNC_ADD:
	case GL_FUNC_SUBTRACT:
	case GL_FUNC_REVERSE_SUBTRACT:
	case GL_MIN_EXT:
	case GL_MAX_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setBlendEquation(modeRGB, modeAlpha);
	}
}

void BlendFunc(GLenum sfactor, GLenum dfactor)
{
	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
}

void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
	      srcRGB, dstRGB, srcAlpha, dstAlpha);

	GLint clientVersion = egl::getClientVersion();

	switch(srcRGB)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
	case GL_SRC_ALPHA_SATURATE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(dstRGB)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
		break;
	case GL_SRC_ALPHA_SATURATE:
		if(clientVersion < 3)
		{
			return error(GL_INVALID_ENUM);
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(srcAlpha)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
	case GL_SRC_ALPHA_SATURATE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(dstAlpha)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
		break;
	case GL_SRC_ALPHA_SATURATE:
		if(clientVersion < 3)
		{
			return error(GL_INVALID_ENUM);
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
	}
}

void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications

	TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
	      target, size, data, usage);

	if(size < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	GLint clientVersion = egl::getClientVersion();

	switch(usage)
	{
	case GL_STREAM_DRAW:
	case GL_STATIC_DRAW:
	case GL_DYNAMIC_DRAW:
		break;
	case GL_STREAM_READ:
	case GL_STREAM_COPY:
	case GL_STATIC_READ:
	case GL_STATIC_COPY:
	case GL_DYNAMIC_READ:
	case GL_DYNAMIC_COPY:
		if(clientVersion < 3)
		{
			return error(GL_INVALID_ENUM);
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Buffer *buffer = nullptr;
		if(!context->getBuffer(target, &buffer))
		{
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			// A null buffer means that "0" is bound to the requested buffer target
			return error(GL_INVALID_OPERATION);
		}

		buffer->bufferData(data, size, usage);
	}
}

void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
	offset = static_cast<GLint>(offset);

	TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
	      target, offset, size, data);

	if(size < 0 || offset < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Buffer *buffer = nullptr;
		if(!context->getBuffer(target, &buffer))
		{
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			// A null buffer means that "0" is bound to the requested buffer target
			return error(GL_INVALID_OPERATION);
		}

		if(buffer->isMapped())
		{
			// It is an invalid operation to update an already mapped buffer
			return error(GL_INVALID_OPERATION);
		}

		if((size_t)size + offset > buffer->size())
		{
			return error(GL_INVALID_VALUE);
		}

		buffer->bufferSubData(data, size, offset);
	}
}

GLenum CheckFramebufferStatus(GLenum target)
{
	TRACE("(GLenum target = 0x%X)", target);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
	{
		return error(GL_INVALID_ENUM, 0);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Framebuffer *framebuffer = nullptr;
		if(target == GL_READ_FRAMEBUFFER)
		{
			framebuffer = context->getReadFramebuffer();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
		}

		return framebuffer->completeness();
	}

	return 0;
}

void Clear(GLbitfield mask)
{
	TRACE("(GLbitfield mask = %X)", mask);

	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->clear(mask);
	}
}

void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
	      red, green, blue, alpha);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setClearColor(red, green, blue, alpha);
	}
}

void ClearDepthf(GLclampf depth)
{
	TRACE("(GLclampf depth = %f)", depth);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setClearDepth(depth);
	}
}

void ClearStencil(GLint s)
{
	TRACE("(GLint s = %d)", s);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setClearStencil(s);
	}
}

void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
	      red, green, blue, alpha);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
	}
}

void CompileShader(GLuint shader)
{
	TRACE("(GLuint shader = %d)", shader);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		shaderObject->compile();
	}
}

void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
                          GLint border, GLsizei imageSize, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, internalformat, width, height, border, imageSize, data);

	if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!IsCompressed(internalformat, egl::getClientVersion()))
	{
		return error(GL_INVALID_ENUM);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
		{
			return error(GL_INVALID_VALUE);
		}

		switch(target)
		{
		case GL_TEXTURE_2D:
		case GL_TEXTURE_RECTANGLE_ARB:
			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
			if(width != height)
			{
				return error(GL_INVALID_VALUE);
			}

			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
		{
			return error(GL_INVALID_VALUE);
		}

		if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
		{
			es2::Texture2D *texture = context->getTexture2D(target);

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
		}
		else
		{
			es2::TextureCubeMap *texture = context->getTextureCubeMap();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			switch(target)
			{
			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
				{
					GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
					if(validationError != GL_NONE)
					{
						return error(validationError);
					}

					texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
				}
				break;
			default: UNREACHABLE(target);
			}
		}
	}
}

void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                             GLenum format, GLsizei imageSize, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
	      "GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, xoffset, yoffset, width, height, format, imageSize, data);

	if(!es2::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(imageSize != egl::ComputeCompressedSize(width, height, format))
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(xoffset % 4 != 0 || yoffset % 4 != 0)
		{
			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
			return error(GL_INVALID_OPERATION);
		}

		GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);

		if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
		{
			es2::Texture2D *texture = context->getTexture2D(target);

			GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
		}
		else if(es2::IsCubemapTextureTarget(target))
		{
			es2::TextureCubeMap *texture = context->getTextureCubeMap();

			GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
		}
		else UNREACHABLE(target);
	}
}

void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
	      target, level, internalformat, x, y, width, height, border);

	if(!validImageSize(level, width, height))
	{
		return error(GL_INVALID_VALUE);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_TEXTURE_2D:
		case GL_TEXTURE_RECTANGLE_ARB:
			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
			if(width != height)
			{
				return error(GL_INVALID_VALUE);
			}

			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
		}

		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
		{
			return error(GL_INVALID_OPERATION);
		}

		GLenum colorbufferFormat = source->getFormat();

		if(!validateColorBufferFormat(internalformat, colorbufferFormat))
		{
			return;
		}

		if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
		{
			es2::Texture2D *texture = context->getTexture2D(target);

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
		}
		else if(es2::IsCubemapTextureTarget(target))
		{
			es2::TextureCubeMap *texture = context->getTextureCubeMap();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
		}
		else UNREACHABLE(target);
	}
}

void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
	      target, level, xoffset, yoffset, x, y, width, height);

	if(!es2::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
		}

		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
		{
			return error(GL_INVALID_OPERATION);
		}

		es2::Texture *texture = nullptr;

		if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
		{
			texture = context->getTexture2D(target);
		}
		else if(es2::IsCubemapTextureTarget(target))
		{
			texture = context->getTextureCubeMap();
		}
		else UNREACHABLE(target);

		GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE, GL_NONE, texture, context->getClientVersion());
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
	}
}

GLuint CreateProgram(void)
{
	TRACE("()");

	es2::Context *context = es2::getContext();

	if(context)
	{
		return context->createProgram();
	}

	return 0;
}

GLuint CreateShader(GLenum type)
{
	TRACE("(GLenum type = 0x%X)", type);

	es2::Context *context = es2::getContext();

	if(context)
	{
		switch(type)
		{
		case GL_FRAGMENT_SHADER:
		case GL_VERTEX_SHADER:
			return context->createShader(type);
		default:
			return error(GL_INVALID_ENUM, 0);
		}
	}

	return 0;
}

void CullFace(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	switch(mode)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		{
			es2::Context *context = es2::getContext();

			if(context)
			{
				context->setCullMode(mode);
			}
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void DeleteBuffers(GLsizei n, const GLuint* buffers)
{
	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteBuffer(buffers[i]);
		}
	}
}

void DeleteFencesNV(GLsizei n, const GLuint* fences)
{
	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteFence(fences[i]);
		}
	}
}

void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			if(framebuffers[i] != 0)
			{
				context->deleteFramebuffer(framebuffers[i]);
			}
		}
	}
}

void DeleteProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	if(program == 0)
	{
		return;
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(!context->getProgram(program))
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		context->deleteProgram(program);
	}
}

void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
{
	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteQuery(ids[i]);
		}
	}
}

void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteRenderbuffer(renderbuffers[i]);
		}
	}
}

void DeleteShader(GLuint shader)
{
	TRACE("(GLuint shader = %d)", shader);

	if(shader == 0)
	{
		return;
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(!context->getShader(shader))
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		context->deleteShader(shader);
	}
}

void DeleteTextures(GLsizei n, const GLuint* textures)
{
	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			if(textures[i] != 0)
			{
				context->deleteTexture(textures[i]);
			}
		}
	}
}

void DepthFunc(GLenum func)
{
	TRACE("(GLenum func = 0x%X)", func);

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GREATER:
	case GL_GEQUAL:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setDepthFunc(func);
	}
}

void DepthMask(GLboolean flag)
{
	TRACE("(GLboolean flag = %d)", flag);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setDepthMask(flag != GL_FALSE);
	}
}

void DepthRangef(GLclampf zNear, GLclampf zFar)
{
	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setDepthRange(zNear, zFar);
	}
}

void DetachShader(GLuint program, GLuint shader)
{
	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

	es2::Context *context = es2::getContext();

	if(context)
	{

		es2::Program *programObject = context->getProgram(program);
		es2::Shader *shaderObject = context->getShader(shader);

		if(!programObject)
		{
			es2::Shader *shaderByProgramHandle;
			shaderByProgramHandle = context->getShader(program);
			if(!shaderByProgramHandle)
			{
				return error(GL_INVALID_VALUE);
			}
			else
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		if(!shaderObject)
		{
			es2::Program *programByShaderHandle = context->getProgram(shader);
			if(!programByShaderHandle)
			{
				return error(GL_INVALID_VALUE);
			}
			else
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		if(!programObject->detachShader(shaderObject))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Disable(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	es2::Context *context = es2::getContext();

	if(context)
	{
		switch(cap)
		{
		case GL_CULL_FACE:                     context->setCullFaceEnabled(false);                   break;
		case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(false);          break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(false);      break;
		case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(false);             break;
		case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(false);                break;
		case GL_STENCIL_TEST:                  context->setStencilTestEnabled(false);                break;
		case GL_DEPTH_TEST:                    context->setDepthTestEnabled(false);                  break;
		case GL_BLEND:                         context->setBlendEnabled(false);                      break;
		case GL_DITHER:                        context->setDitherEnabled(false);                     break;
		case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;
		case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(false);          break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void DisableVertexAttribArray(GLuint index)
{
	TRACE("(GLuint index = %d)", index);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setVertexAttribArrayEnabled(index, false);
	}
}

void DrawArrays(GLenum mode, GLint first, GLsizei count)
{
	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);

	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(count < 0 || first < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
		{
			return error(GL_INVALID_OPERATION);
		}

		context->drawArrays(mode, first, count);
	}
}

void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
	      mode, count, type, indices);

	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT:
		case GL_UNSIGNED_INT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
	}
}

void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{
	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
		mode, first, count, instanceCount);

	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(count < 0 || instanceCount < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
		{
			return error(GL_INVALID_OPERATION);
		}

		context->drawArrays(mode, first, count, instanceCount);
	}
}

void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
{
	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
		mode, count, type, indices, instanceCount);

	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(type)
	{
	case GL_UNSIGNED_BYTE:
	case GL_UNSIGNED_SHORT:
	case GL_UNSIGNED_INT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(count < 0 || instanceCount < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
		{
			return error(GL_INVALID_OPERATION);
		}

		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
	}
}

void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
{
	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(index >= es2::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		context->setVertexAttribDivisor(index, divisor);
	}
}

void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{
	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
		mode, first, count, instanceCount);

	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(count < 0 || instanceCount < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(!context->hasZeroDivisor())
		{
			return error(GL_INVALID_OPERATION);
		}

		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
		{
			return error(GL_INVALID_OPERATION);
		}

		context->drawArrays(mode, first, count, instanceCount);
	}
}

void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
{
	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
		mode, count, type, indices, instanceCount);

	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(type)
	{
	case GL_UNSIGNED_BYTE:
	case GL_UNSIGNED_SHORT:
	case GL_UNSIGNED_INT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(count < 0 || instanceCount < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(!context->hasZeroDivisor())
		{
			return error(GL_INVALID_OPERATION);
		}

		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
		{
			return error(GL_INVALID_OPERATION);
		}

		context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
	}
}

void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
	TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(index >= MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		context->setVertexAttribDivisor(index, divisor);
	}
}

void Enable(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	es2::Context *context = es2::getContext();

	if(context)
	{
		switch(cap)
		{
		case GL_CULL_FACE:                     context->setCullFaceEnabled(true);                   break;
		case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(true);          break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(true);      break;
		case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(true);             break;
		case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(true);                break;
		case GL_STENCIL_TEST:                  context->setStencilTestEnabled(true);                break;
		case GL_DEPTH_TEST:                    context->setDepthTestEnabled(true);                  break;
		case GL_BLEND:                         context->setBlendEnabled(true);                      break;
		case GL_DITHER:                        context->setDitherEnabled(true);                     break;
		case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;
		case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(true);          break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void EnableVertexAttribArray(GLuint index)
{
	TRACE("(GLuint index = %d)", index);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setVertexAttribArrayEnabled(index, true);
	}
}

void EndQueryEXT(GLenum target)
{
	TRACE("GLenum target = 0x%X)", target);

	switch(target)
	{
	case GL_ANY_SAMPLES_PASSED_EXT:
	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->endQuery(target);
	}
}

void FinishFenceNV(GLuint fence)
{
	TRACE("(GLuint fence = %d)", fence);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Fence *fenceObject = context->getFence(fence);

		if(!fenceObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		fenceObject->finishFence();
	}
}

void Finish(void)
{
	TRACE("()");

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->finish();
	}
}

void Flush(void)
{
	TRACE("()");

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->flush();
	}
}

void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);

	if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) ||
	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
	{
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Framebuffer *framebuffer = nullptr;
		GLuint framebufferName = 0;
		if(target == GL_READ_FRAMEBUFFER)
		{
			framebuffer = context->getReadFramebuffer();
			framebufferName = context->getReadFramebufferName();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
			framebufferName = context->getDrawFramebufferName();
		}

		if(!framebuffer || framebufferName == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		// [OpenGL ES 2.0.25] Section 4.4.3 page 112
		// [OpenGL ES 3.0.2] Section 4.4.2 page 201
		// 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
		// type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
		if(renderbuffer != 0)
		{
			if(!context->getRenderbuffer(renderbuffer))
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		GLint clientVersion = context->getClientVersion();

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0:
		case GL_COLOR_ATTACHMENT1:
		case GL_COLOR_ATTACHMENT2:
		case GL_COLOR_ATTACHMENT3:
		case GL_COLOR_ATTACHMENT4:
		case GL_COLOR_ATTACHMENT5:
		case GL_COLOR_ATTACHMENT6:
		case GL_COLOR_ATTACHMENT7:
		case GL_COLOR_ATTACHMENT8:
		case GL_COLOR_ATTACHMENT9:
		case GL_COLOR_ATTACHMENT10:
		case GL_COLOR_ATTACHMENT11:
		case GL_COLOR_ATTACHMENT12:
		case GL_COLOR_ATTACHMENT13:
		case GL_COLOR_ATTACHMENT14:
		case GL_COLOR_ATTACHMENT15:
		case GL_COLOR_ATTACHMENT16:
		case GL_COLOR_ATTACHMENT17:
		case GL_COLOR_ATTACHMENT18:
		case GL_COLOR_ATTACHMENT19:
		case GL_COLOR_ATTACHMENT20:
		case GL_COLOR_ATTACHMENT21:
		case GL_COLOR_ATTACHMENT22:
		case GL_COLOR_ATTACHMENT23:
		case GL_COLOR_ATTACHMENT24:
		case GL_COLOR_ATTACHMENT25:
		case GL_COLOR_ATTACHMENT26:
		case GL_COLOR_ATTACHMENT27:
		case GL_COLOR_ATTACHMENT28:
		case GL_COLOR_ATTACHMENT29:
		case GL_COLOR_ATTACHMENT30:
		case GL_COLOR_ATTACHMENT31:
			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
			{
				return error(GL_INVALID_ENUM);
			}
			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
			break;
		case GL_DEPTH_ATTACHMENT:
			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
			break;
		case GL_STENCIL_ATTACHMENT:
			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
			break;
		case GL_DEPTH_STENCIL_ATTACHMENT:
			if(clientVersion >= 3)
			{
				framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
				framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
				break;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
	{
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLint clientVersion = context->getClientVersion();

		if(texture == 0)
		{
			textarget = GL_NONE;
		}
		else
		{
			es2::Texture *tex = context->getTexture(texture);

			if(!tex)
			{
				return error(GL_INVALID_OPERATION);
			}

			switch(textarget)
			{
			case GL_TEXTURE_2D:
				if(tex->getTarget() != GL_TEXTURE_2D)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			case GL_TEXTURE_RECTANGLE_ARB:
				if(tex->getTarget() != GL_TEXTURE_RECTANGLE_ARB)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			default:
				return error(GL_INVALID_ENUM);
			}

			if((level != 0) && (clientVersion < 3))
			{
				return error(GL_INVALID_VALUE);
			}

			if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
			{
				return error(GL_INVALID_VALUE);
			}

			if(tex->isCompressed(textarget, level))
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		es2::Framebuffer *framebuffer = nullptr;
		GLuint framebufferName = 0;
		if(target == GL_READ_FRAMEBUFFER)
		{
			framebuffer = context->getReadFramebuffer();
			framebufferName = context->getReadFramebufferName();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
			framebufferName = context->getDrawFramebufferName();
		}

		if(framebufferName == 0 || !framebuffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0:
		case GL_COLOR_ATTACHMENT1:
		case GL_COLOR_ATTACHMENT2:
		case GL_COLOR_ATTACHMENT3:
		case GL_COLOR_ATTACHMENT4:
		case GL_COLOR_ATTACHMENT5:
		case GL_COLOR_ATTACHMENT6:
		case GL_COLOR_ATTACHMENT7:
		case GL_COLOR_ATTACHMENT8:
		case GL_COLOR_ATTACHMENT9:
		case GL_COLOR_ATTACHMENT10:
		case GL_COLOR_ATTACHMENT11:
		case GL_COLOR_ATTACHMENT12:
		case GL_COLOR_ATTACHMENT13:
		case GL_COLOR_ATTACHMENT14:
		case GL_COLOR_ATTACHMENT15:
		case GL_COLOR_ATTACHMENT16:
		case GL_COLOR_ATTACHMENT17:
		case GL_COLOR_ATTACHMENT18:
		case GL_COLOR_ATTACHMENT19:
		case GL_COLOR_ATTACHMENT20:
		case GL_COLOR_ATTACHMENT21:
		case GL_COLOR_ATTACHMENT22:
		case GL_COLOR_ATTACHMENT23:
		case GL_COLOR_ATTACHMENT24:
		case GL_COLOR_ATTACHMENT25:
		case GL_COLOR_ATTACHMENT26:
		case GL_COLOR_ATTACHMENT27:
		case GL_COLOR_ATTACHMENT28:
		case GL_COLOR_ATTACHMENT29:
		case GL_COLOR_ATTACHMENT30:
		case GL_COLOR_ATTACHMENT31:
			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
			{
				return error(GL_INVALID_ENUM);
			}
			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
			break;
		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture, level);   break;
		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
		case GL_DEPTH_STENCIL_ATTACHMENT:
			if(clientVersion >= 3)
			{
				framebuffer->setDepthbuffer(textarget, texture, level);
				framebuffer->setStencilbuffer(textarget, texture, level);
				break;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void FrontFace(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	switch(mode)
	{
	case GL_CW:
	case GL_CCW:
		{
			es2::Context *context = es2::getContext();

			if(context)
			{
				context->setFrontFace(mode);
			}
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void GenBuffers(GLsizei n, GLuint* buffers)
{
	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			buffers[i] = context->createBuffer();
		}
	}
}

void GenerateMipmap(GLenum target)
{
	TRACE("(GLenum target = 0x%X)", target);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture *texture = nullptr;

		GLint clientVersion = context->getClientVersion();

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_CUBE_MAP:
			{
				TextureCubeMap *cube = context->getTextureCubeMap();
				texture = cube;

				if(!cube->isCubeComplete())
				{
					return error(GL_INVALID_OPERATION);
				}
			}
			break;
		case GL_TEXTURE_2D_ARRAY:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			else
			{
				texture = context->getTexture2DArray();
			}
			break;
		case GL_TEXTURE_3D:
			texture = context->getTexture3D();
			break;
		case GL_TEXTURE_RECTANGLE_ARB:
			texture = context->getTexture2DRect();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!IsMipmappable(texture->getFormat(target, texture->getBaseLevel()), clientVersion))
		{
			return error(GL_INVALID_OPERATION);
		}

		texture->generateMipmaps();
	}
}

void GenFencesNV(GLsizei n, GLuint* fences)
{
	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			fences[i] = context->createFence();
		}
	}
}

void GenFramebuffers(GLsizei n, GLuint* framebuffers)
{
	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			framebuffers[i] = context->createFramebuffer();
		}
	}
}

void GenQueriesEXT(GLsizei n, GLuint* ids)
{
	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			ids[i] = context->createQuery();
		}
	}
}

void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			renderbuffers[i] = context->createRenderbuffer();
		}
	}
}

void GenTextures(GLsizei n, GLuint* textures)
{
	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			textures[i] = context->createTexture();
		}
	}
}

void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
	      program, index, bufsize, length, size, type, name);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(index >= programObject->getActiveAttributeCount())
		{
			return error(GL_INVALID_VALUE);
		}

		programObject->getActiveAttribute(index, bufsize, length, size, type, name);
	}
}

void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
	      program, index, bufsize, length, size, type, name);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(index >= programObject->getActiveUniformCount())
		{
			return error(GL_INVALID_VALUE);
		}

		programObject->getActiveUniform(index, bufsize, length, size, type, name);
	}
}

void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
	      program, maxcount, count, shaders);

	if(maxcount < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		return programObject->getAttachedShaders(maxcount, count, shaders);
	}
}

int GetAttribLocation(GLuint program, const GLchar* name)
{
	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

	es2::Context *context = es2::getContext();

	if(context)
	{

		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION, -1);
			}
			else
			{
				return error(GL_INVALID_VALUE, -1);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION, -1);
		}

		return programObject->getAttributeLocation(name);
	}

	return -1;
}

void GetBooleanv(GLenum pname, GLboolean* params)
{
	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(!(context->getBooleanv(pname, params)))
		{
			GLenum nativeType;
			unsigned int numParams = 0;
			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
				return error(GL_INVALID_ENUM);

			if(numParams == 0)
				return; // it is known that the pname is valid, but there are no parameters to return

			if(nativeType == GL_FLOAT)
			{
				GLfloat *floatParams = nullptr;
				floatParams = new GLfloat[numParams];

				context->getFloatv(pname, floatParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(floatParams[i] == 0.0f)
						params[i] = GL_FALSE;
					else
						params[i] = GL_TRUE;
				}

				delete [] floatParams;
			}
			else if(nativeType == GL_INT)
			{
				GLint *intParams = nullptr;
				intParams = new GLint[numParams];

				context->getIntegerv(pname, intParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(intParams[i] == 0)
						params[i] = GL_FALSE;
					else
						params[i] = GL_TRUE;
				}

				delete [] intParams;
			}
		}
	}
}

void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Buffer *buffer;
		if(!context->getBuffer(target, &buffer))
		{
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			// A null buffer means that "0" is bound to the requested buffer target
			return error(GL_INVALID_OPERATION);
		}

		GLint clientVersion = context->getClientVersion();

		switch(pname)
		{
		case GL_BUFFER_USAGE:
			*params = buffer->usage();
			break;
		case GL_BUFFER_SIZE:
			*params = (GLint)buffer->size();
			break;
		case GL_BUFFER_ACCESS_FLAGS:
			if(clientVersion >= 3)
			{
				*params = buffer->access();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_BUFFER_MAPPED:
			if(clientVersion >= 3)
			{
				*params = buffer->isMapped();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_BUFFER_MAP_LENGTH:
			if(clientVersion >= 3)
			{
				*params = (GLint)buffer->length();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_BUFFER_MAP_OFFSET:
			if(clientVersion >= 3)
			{
				*params = (GLint)buffer->offset();
				break;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

GLenum GetError(void)
{
	TRACE("()");

	es2::Context *context = es2::getContext();

	if(context)
	{
		return context->getError();
	}

	return GL_NO_ERROR;
}

void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
{
	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Fence *fenceObject = context->getFence(fence);

		if(!fenceObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		fenceObject->getFenceiv(pname, params);
	}
}

void GetFloatv(GLenum pname, GLfloat* params)
{
	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(!(context->getFloatv(pname, params)))
		{
			GLenum nativeType;
			unsigned int numParams = 0;
			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
				return error(GL_INVALID_ENUM);

			if(numParams == 0)
				return; // it is known that the pname is valid, but that there are no parameters to return.

			if(nativeType == GL_BOOL)
			{
				GLboolean *boolParams = nullptr;
				boolParams = new GLboolean[numParams];

				context->getBooleanv(pname, boolParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(boolParams[i] == GL_FALSE)
						params[i] = 0.0f;
					else
						params[i] = 1.0f;
				}

				delete [] boolParams;
			}
			else if(nativeType == GL_INT)
			{
				GLint *intParams = nullptr;
				intParams = new GLint[numParams];

				context->getIntegerv(pname, intParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					params[i] = (GLfloat)intParams[i];
				}

				delete [] intParams;
			}
		}
	}
}

void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
	      target, attachment, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
		{
			return error(GL_INVALID_ENUM);
		}

		GLuint framebufferName = 0;

		if(target == GL_READ_FRAMEBUFFER)
		{
			framebufferName = context->getReadFramebufferName();
		}
		else
		{
			framebufferName = context->getDrawFramebufferName();
		}

		GLint clientVersion = context->getClientVersion();

		if(framebufferName == 0)   // Default framebuffer.
		{
			if(clientVersion < 3)
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		switch(attachment)
		{
		case GL_BACK:
		case GL_DEPTH:
		case GL_STENCIL:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}

			if(framebufferName != 0)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_DEPTH_ATTACHMENT:
		case GL_STENCIL_ATTACHMENT:
			if(framebufferName == 0)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_DEPTH_STENCIL_ATTACHMENT:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}

			if(framebufferName == 0)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		default:
			if((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS)
			{
				if(framebufferName == 0)
				{
					return error(GL_INVALID_OPERATION);
				}
			}
			else return error(GL_INVALID_ENUM);
		}

		es2::Framebuffer *framebuffer = context->getFramebuffer(framebufferName);

		GLenum attachmentType;
		GLuint attachmentHandle;
		GLint attachmentLayer;
		Renderbuffer *renderbuffer = nullptr;
		switch(attachment)
		{
		case GL_BACK:
			attachmentType = framebuffer->getColorbufferType(0);
			attachmentHandle = framebuffer->getColorbufferName(0);
			attachmentLayer = framebuffer->getColorbufferLayer(0);
			renderbuffer = framebuffer->getColorbuffer(0);
			break;
		case GL_DEPTH:
		case GL_DEPTH_ATTACHMENT:
			attachmentType = framebuffer->getDepthbufferType();
			attachmentHandle = framebuffer->getDepthbufferName();
			attachmentLayer = framebuffer->getDepthbufferLayer();
			renderbuffer = framebuffer->getDepthbuffer();
			break;
		case GL_STENCIL:
		case GL_STENCIL_ATTACHMENT:
			attachmentType = framebuffer->getStencilbufferType();
			attachmentHandle = framebuffer->getStencilbufferName();
			attachmentLayer = framebuffer->getStencilbufferLayer();
			renderbuffer = framebuffer->getStencilbuffer();
			break;
		case GL_DEPTH_STENCIL_ATTACHMENT:
			attachmentType = framebuffer->getDepthbufferType();
			attachmentHandle = framebuffer->getDepthbufferName();
			attachmentLayer = framebuffer->getDepthbufferLayer();
			renderbuffer = framebuffer->getDepthbuffer();

			if(attachmentHandle != framebuffer->getStencilbufferName())
			{
				// Different attachments to DEPTH and STENCIL, query fails
				return error(GL_INVALID_OPERATION);
			}
			break;
		default:
			ASSERT((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS);
			attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
			attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
			attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
			renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
			break;
		}

		GLenum attachmentObjectType = GL_NONE;   // Type category
		if(framebufferName == 0)
		{
			attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
		}
		else if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
		{
			attachmentObjectType = attachmentType;
		}
		else if(es2::IsTextureTarget(attachmentType))
		{
			attachmentObjectType = GL_TEXTURE;
		}
		else UNREACHABLE(attachmentType);

		if(attachmentObjectType != GL_NONE)
		{
			switch(pname)
			{
			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
				*params = attachmentObjectType;
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
				if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
				{
					*params = attachmentHandle;
				}
				else
				{
					return error(GL_INVALID_ENUM);
				}
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
				if(attachmentObjectType == GL_TEXTURE)
				{
					*params = clientVersion < 3 ? 0 : renderbuffer->getLevel();   // glFramebufferTexture2D does not allow level to be set to anything else in GL ES 2.0
				}
				else
				{
					return error(GL_INVALID_ENUM);
				}
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
				if(attachmentObjectType == GL_TEXTURE)
				{
					if(es2::IsCubemapTextureTarget(attachmentType))
					{
						*params = attachmentType;
					}
					else
					{
						*params = 0;
					}
				}
				else
				{
					return error(GL_INVALID_ENUM);
				}
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
				if(clientVersion >= 3)
				{
					*params = attachmentLayer;
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
				if(clientVersion >= 3)
				{
					*params = renderbuffer->getRedSize();
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
				if(clientVersion >= 3)
				{
					*params = renderbuffer->getGreenSize();
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
				if(clientVersion >= 3)
				{
					*params = renderbuffer->getBlueSize();
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
				if(clientVersion >= 3)
				{
					*params = renderbuffer->getAlphaSize();
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
				if(clientVersion >= 3)
				{
					*params = renderbuffer->getDepthSize();
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
				if(clientVersion >= 3)
				{
					*params = renderbuffer->getStencilSize();
				}
				else return error(GL_INVALID_ENUM);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
		//	case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT:   // GL_EXT_color_buffer_half_float
				if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
				{
					return error(GL_INVALID_OPERATION);
				}

				*params = GetComponentType(renderbuffer->getFormat(), attachment);
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
				if(clientVersion >= 3)
				{
					*params = GetColorEncoding(renderbuffer->getFormat());
				}
				else return error(GL_INVALID_ENUM);
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
		}
		else
		{
			// ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
			// is NONE, then querying any other pname will generate INVALID_ENUM.

			// ES 3.0.2 spec pg 235 states that if the attachment type is none,
			// GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
			// INVALID_OPERATION for all other pnames

			switch(pname)
			{
			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
				*params = GL_NONE;
				break;
			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
				if(clientVersion < 3)
				{
					return error(GL_INVALID_ENUM);
				}
				*params = 0;
				break;
			default:
				if(clientVersion < 3)
				{
					return error(GL_INVALID_ENUM);
				}
				else
				{
					return error(GL_INVALID_OPERATION);
				}
			}
		}
	}
}

GLenum GetGraphicsResetStatusEXT(void)
{
	TRACE("()");

	return GL_NO_ERROR;
}

void GetIntegerv(GLenum pname, GLint* params)
{
	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);

	es2::Context *context = es2::getContext();

	if(!context)
	{
		// Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
		#ifdef __ANDROID__
			ALOGI("expected_badness glGetIntegerv() called without current context.");
		#else
			ERR("glGetIntegerv() called without current context.");
		#endif

		// This is not spec compliant! When there is no current GL context, functions should
		// have no side effects. Google Maps queries these values before creating a context,
		// so we need this as a bug-compatible workaround.
		switch(pname)
		{
		case GL_MAX_TEXTURE_SIZE:                 *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE;  return;
		case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return;
		case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
		case GL_STENCIL_BITS:                     *params = 8;                                     return;
		case GL_ALIASED_LINE_WIDTH_RANGE:
			params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
			params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
			return;
		}
	}

	if(context)
	{
		if(!(context->getIntegerv(pname, params)))
		{
			GLenum nativeType;
			unsigned int numParams = 0;
			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
				return error(GL_INVALID_ENUM);

			if(numParams == 0)
				return; // it is known that pname is valid, but there are no parameters to return

			if(nativeType == GL_BOOL)
			{
				GLboolean *boolParams = nullptr;
				boolParams = new GLboolean[numParams];

				context->getBooleanv(pname, boolParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
				}

				delete [] boolParams;
			}
			else if(nativeType == GL_FLOAT)
			{
				GLfloat *floatParams = nullptr;
				floatParams = new GLfloat[numParams];

				context->getFloatv(pname, floatParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
					{
						params[i] = convert_float_fixed(floatParams[i]);
					}
					else
					{
						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
					}
				}

				delete [] floatParams;
			}
		}
	}
}

void GetProgramiv(GLuint program, GLenum pname, GLint* params)
{
	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		GLint clientVersion = egl::getClientVersion();

		switch(pname)
		{
		case GL_DELETE_STATUS:
			*params = programObject->isFlaggedForDeletion();
			return;
		case GL_LINK_STATUS:
			*params = programObject->isLinked();
			return;
		case GL_VALIDATE_STATUS:
			*params = programObject->isValidated();
			return;
		case GL_INFO_LOG_LENGTH:
			*params = (GLint)programObject->getInfoLogLength();
			return;
		case GL_ATTACHED_SHADERS:
			*params = programObject->getAttachedShadersCount();
			return;
		case GL_ACTIVE_ATTRIBUTES:
			*params = (GLint)programObject->getActiveAttributeCount();
			return;
		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
			*params = programObject->getActiveAttributeMaxLength();
			return;
		case GL_ACTIVE_UNIFORMS:
			*params = (GLint)programObject->getActiveUniformCount();
			return;
		case GL_ACTIVE_UNIFORM_MAX_LENGTH:
			*params = programObject->getActiveUniformMaxLength();
			return;
		case GL_ACTIVE_UNIFORM_BLOCKS:
			if(clientVersion >= 3)
			{
				*params = (GLint)programObject->getActiveUniformBlockCount();
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
			if(clientVersion >= 3)
			{
				*params = programObject->getActiveUniformBlockMaxLength();
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
			if(clientVersion >= 3)
			{
				*params = programObject->getTransformFeedbackBufferMode();
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TRANSFORM_FEEDBACK_VARYINGS:
			if(clientVersion >= 3)
			{
				*params = programObject->getTransformFeedbackVaryingCount();
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
			if(clientVersion >= 3)
			{
				*params = programObject->getTransformFeedbackVaryingMaxLength();
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
			if(clientVersion >= 3)
			{
				*params = programObject->getBinaryRetrievableHint();
				return;
			}
			else return error(GL_INVALID_ENUM);
		case GL_PROGRAM_BINARY_LENGTH:
			if(clientVersion >= 3)
			{
				*params = programObject->getBinaryLength();
				return;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
	      program, bufsize, length, infolog);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		programObject->getInfoLog(bufsize, length, infolog);
	}
}

void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
{
	TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);

	switch(pname)
	{
	case GL_CURRENT_QUERY_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		params[0] = context->getActiveQuery(target);
	}
}

void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
{
	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);

	switch(pname)
	{
	case GL_QUERY_RESULT_EXT:
	case GL_QUERY_RESULT_AVAILABLE_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Query *queryObject = context->getQuery(name);

		if(!queryObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(context->getActiveQuery(queryObject->getType()) == name)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(pname)
		{
		case GL_QUERY_RESULT_EXT:
			params[0] = queryObject->getResult();
			break;
		case GL_QUERY_RESULT_AVAILABLE_EXT:
			params[0] = queryObject->isResultAvailable();
			break;
		default:
			ASSERT(false);
		}
	}
}

void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(target != GL_RENDERBUFFER)
		{
			return error(GL_INVALID_ENUM);
		}

		if(context->getRenderbufferName() == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());

		switch(pname)
		{
		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
		case GL_RENDERBUFFER_INTERNAL_FORMAT:
			{
				GLint internalformat = renderbuffer->getFormat();
				*params = (internalformat == GL_NONE) ? GL_RGBA4 : internalformat;
			}
			break;
		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
		case GL_RENDERBUFFER_SAMPLES:         *params = renderbuffer->getSamples();     break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		switch(pname)
		{
		case GL_SHADER_TYPE:
			*params = shaderObject->getType();
			return;
		case GL_DELETE_STATUS:
			*params = shaderObject->isFlaggedForDeletion();
			return;
		case GL_COMPILE_STATUS:
			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
			return;
		case GL_INFO_LOG_LENGTH:
			*params = (GLint)shaderObject->getInfoLogLength();
			return;
		case GL_SHADER_SOURCE_LENGTH:
			*params = (GLint)shaderObject->getSourceLength();
			return;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
	      shader, bufsize, length, infolog);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		shaderObject->getInfoLog(bufsize, length, infolog);
	}
}

void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
	      shadertype, precisiontype, range, precision);

	switch(shadertype)
	{
	case GL_VERTEX_SHADER:
	case GL_FRAGMENT_SHADER:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(precisiontype)
	{
	case GL_LOW_FLOAT:
	case GL_MEDIUM_FLOAT:
	case GL_HIGH_FLOAT:
		// IEEE 754 single-precision
		range[0] = 127;
		range[1] = 127;
		*precision = 23;
		break;
	case GL_LOW_INT:
	case GL_MEDIUM_INT:
	case GL_HIGH_INT:
		// Full integer precision is supported
		range[0] = 31;
		range[1] = 30;
		*precision = 0;
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
	      shader, bufsize, length, source);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		shaderObject->getSource(bufsize, length, source);
	}
}

const GLubyte* GetString(GLenum name)
{
	TRACE("(GLenum name = 0x%X)", name);

	switch(name)
	{
	case GL_VENDOR:
		return (GLubyte*)"Google Inc.";
	case GL_RENDERER:
		return (GLubyte*)"Google SwiftShader";
	case GL_VERSION:
	{
		es2::Context *context = es2::getContext();
		return (context && (context->getClientVersion() >= 3)) ?
		       (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
		       (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
	}
	case GL_SHADING_LANGUAGE_VERSION:
	{
		es2::Context *context = es2::getContext();
		return (context && (context->getClientVersion() >= 3)) ?
		       (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
		       (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
	}
	case GL_EXTENSIONS:
	{
		es2::Context *context = es2::getContext();
		return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
	}
	default:
		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
	}
}

void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture *texture;

		GLint clientVersion = context->getClientVersion();

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		case GL_TEXTURE_2D_ARRAY:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			else
			{
				texture = context->getTexture2DArray();
			}
			break;
		case GL_TEXTURE_3D:
			texture = context->getTexture3D();
			break;
		case GL_TEXTURE_RECTANGLE_ARB:
			texture = context->getTexture2DRect();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = (GLfloat)texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = (GLfloat)texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = (GLfloat)texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = (GLfloat)texture->getWrapT();
			break;
		case GL_TEXTURE_WRAP_R_OES:
			*params = (GLfloat)texture->getWrapR();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = texture->getMaxAnisotropy();
			break;
		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
			*params = (GLfloat)1;
			break;
		case GL_TEXTURE_BASE_LEVEL:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getBaseLevel();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_COMPARE_FUNC:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getCompareFunc();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_COMPARE_MODE:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getCompareMode();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_IMMUTABLE_FORMAT:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getImmutableFormat();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_IMMUTABLE_LEVELS:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getImmutableLevels();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_MAX_LEVEL:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getMaxLevel();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_MAX_LOD:
			if(clientVersion >= 3)
			{
				*params = texture->getMaxLOD();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_MIN_LOD:
			if(clientVersion >= 3)
			{
				*params = texture->getMinLOD();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_R:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getSwizzleR();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_G:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getSwizzleG();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_B:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getSwizzleB();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_A:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)texture->getSwizzleA();
				break;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture *texture;

		GLint clientVersion = context->getClientVersion();

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		case GL_TEXTURE_2D_ARRAY:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			else
			{
				texture = context->getTexture2DArray();
			}
			break;
		case GL_TEXTURE_3D:
			texture = context->getTexture3D();
			break;
		case GL_TEXTURE_RECTANGLE_ARB:
			texture = context->getTexture2DRect();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = texture->getWrapT();
			break;
		case GL_TEXTURE_WRAP_R_OES:
			*params = texture->getWrapR();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = (GLint)texture->getMaxAnisotropy();
			break;
		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
			*params = 1;
			break;
		case GL_TEXTURE_BASE_LEVEL:
			if(clientVersion >= 3)
			{
				*params = texture->getBaseLevel();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_COMPARE_FUNC:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getCompareFunc();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_COMPARE_MODE:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getCompareMode();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_IMMUTABLE_FORMAT:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getImmutableFormat();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_IMMUTABLE_LEVELS:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getImmutableLevels();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_MAX_LEVEL:
			if(clientVersion >= 3)
			{
				*params = texture->getMaxLevel();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_MAX_LOD:
			if(clientVersion >= 3)
			{
				*params = (GLint)roundf(texture->getMaxLOD());
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_MIN_LOD:
			if(clientVersion >= 3)
			{
				*params = (GLint)roundf(texture->getMinLOD());
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_R:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getSwizzleR();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_G:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getSwizzleG();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_B:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getSwizzleB();
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_TEXTURE_SWIZZLE_A:
			if(clientVersion >= 3)
			{
				*params = (GLint)texture->getSwizzleA();
				break;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
	      program, location, bufSize, params);

	if(bufSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformfv(location, &bufSize, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void GetUniformfv(GLuint program, GLint location, GLfloat* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformfv(location, nullptr, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
	      program, location, bufSize, params);

	if(bufSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformiv(location, &bufSize, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void GetUniformiv(GLuint program, GLint location, GLint* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformiv(location, nullptr, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

int GetUniformLocation(GLuint program, const GLchar* name)
{
	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

	es2::Context *context = es2::getContext();

	if(strstr(name, "gl_") == name)
	{
		return -1;
	}

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION, -1);
			}
			else
			{
				return error(GL_INVALID_VALUE, -1);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION, -1);
		}

		return programObject->getUniformLocation(name);
	}

	return -1;
}

void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(index >= es2::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);

		GLint clientVersion = context->getClientVersion();

		switch(pname)
		{
		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
			*params = (GLfloat)attribState.mSize;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
			*params = (GLfloat)attribState.mStride;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
			*params = (GLfloat)attribState.mType;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
			*params = (GLfloat)attribState.mBoundBuffer.name();
			break;
		case GL_CURRENT_VERTEX_ATTRIB:
			{
				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
				for(int i = 0; i < 4; ++i)
				{
					params[i] = attrib.getCurrentValueF(i);
				}
			}
			break;
		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
			if(clientVersion >= 3)
			{
				*params = (GLfloat)(attribState.mPureInteger ? GL_TRUE : GL_FALSE);
				break;
			}
			else return error(GL_INVALID_ENUM);
		default: return error(GL_INVALID_ENUM);
		}
	}
}

void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(index >= es2::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);

		GLint clientVersion = context->getClientVersion();

		switch(pname)
		{
		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
			*params = attribState.mSize;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
			*params = attribState.mStride;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
			*params = attribState.mType;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
			*params = attribState.mBoundBuffer.name();
			break;
		case GL_CURRENT_VERTEX_ATTRIB:
			{
				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
				for(int i = 0; i < 4; ++i)
				{
					float currentValue = attrib.getCurrentValueF(i);
					params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
				}
			}
			break;
		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
			if(clientVersion >= 3)
			{
				*params = (attribState.mPureInteger ? GL_TRUE : GL_FALSE);
				break;
			}
			else return error(GL_INVALID_ENUM);
		default: return error(GL_INVALID_ENUM);
		}
	}
}

void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
{
	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(index >= es2::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
		{
			return error(GL_INVALID_ENUM);
		}

		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
	}
}

void Hint(GLenum target, GLenum mode)
{
	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);

	switch(mode)
	{
	case GL_FASTEST:
	case GL_NICEST:
	case GL_DONT_CARE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_GENERATE_MIPMAP_HINT:
			context->setGenerateMipmapHint(mode);
			break;
		case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
			context->setFragmentShaderDerivativeHint(mode);
			break;
		case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
			context->setTextureFilteringHint(mode);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

GLboolean IsBuffer(GLuint buffer)
{
	TRACE("(GLuint buffer = %d)", buffer);

	es2::Context *context = es2::getContext();

	if(context && buffer)
	{
		es2::Buffer *bufferObject = context->getBuffer(buffer);

		if(bufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsEnabled(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLint clientVersion = context->getClientVersion();

		switch(cap)
		{
		case GL_CULL_FACE:                return context->isCullFaceEnabled();
		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
		case GL_BLEND:                    return context->isBlendEnabled();
		case GL_DITHER:                   return context->isDitherEnabled();
		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
			if(clientVersion >= 3)
			{
				return context->isPrimitiveRestartFixedIndexEnabled();
			}
			else return error(GL_INVALID_ENUM, false);
		case GL_RASTERIZER_DISCARD:
			if(clientVersion >= 3)
			{
				return context->isRasterizerDiscardEnabled();
			}
			else return error(GL_INVALID_ENUM, false);
		default:
			return error(GL_INVALID_ENUM, false);
		}
	}

	return false;
}

GLboolean IsFenceNV(GLuint fence)
{
	TRACE("(GLuint fence = %d)", fence);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Fence *fenceObject = context->getFence(fence);

		if(!fenceObject)
		{
			return GL_FALSE;
		}

		return fenceObject->isFence();
	}

	return GL_FALSE;
}

GLboolean IsFramebuffer(GLuint framebuffer)
{
	TRACE("(GLuint framebuffer = %d)", framebuffer);

	es2::Context *context = es2::getContext();

	if(context && framebuffer)
	{
		es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);

		if(framebufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	es2::Context *context = es2::getContext();

	if(context && program)
	{
		es2::Program *programObject = context->getProgram(program);

		if(programObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsQueryEXT(GLuint name)
{
	TRACE("(GLuint name = %d)", name);

	if(name == 0)
	{
		return GL_FALSE;
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Query *queryObject = context->getQuery(name);

		if(queryObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsRenderbuffer(GLuint renderbuffer)
{
	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

	es2::Context *context = es2::getContext();

	if(context && renderbuffer)
	{
		es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);

		if(renderbufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsShader(GLuint shader)
{
	TRACE("(GLuint shader = %d)", shader);

	es2::Context *context = es2::getContext();

	if(context && shader)
	{
		es2::Shader *shaderObject = context->getShader(shader);

		if(shaderObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsTexture(GLuint texture)
{
	TRACE("(GLuint texture = %d)", texture);

	es2::Context *context = es2::getContext();

	if(context && texture)
	{
		es2::Texture *textureObject = context->getTexture(texture);

		if(textureObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

void LineWidth(GLfloat width)
{
	TRACE("(GLfloat width = %f)", width);

	if(width <= 0.0f)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setLineWidth(width);
	}
}

void LinkProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(programObject == context->getCurrentProgram())
		{
			es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
			if(transformFeedback && transformFeedback->isActive())
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		programObject->link();
	}
}

void PixelStorei(GLenum pname, GLint param)
{
	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLint clientVersion = context->getClientVersion();

		switch(pname)
		{
		case GL_UNPACK_ALIGNMENT:
			if(param != 1 && param != 2 && param != 4 && param != 8)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setUnpackAlignment(param);
			break;
		case GL_PACK_ALIGNMENT:
			if(param != 1 && param != 2 && param != 4 && param != 8)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPackAlignment(param);
			break;
		case GL_PACK_ROW_LENGTH:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setPackRowLength(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_PACK_SKIP_PIXELS:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setPackSkipPixels(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_PACK_SKIP_ROWS:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setPackSkipRows(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_UNPACK_ROW_LENGTH:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setUnpackRowLength(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_UNPACK_IMAGE_HEIGHT:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setUnpackImageHeight(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_UNPACK_SKIP_PIXELS:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setUnpackSkipPixels(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_UNPACK_SKIP_ROWS:
			if(clientVersion >= 3)
			{
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setUnpackSkipRows(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		case GL_UNPACK_SKIP_IMAGES:
			if(clientVersion >= 3) {
				if(param < 0)
				{
					return error(GL_INVALID_VALUE);
				}
				context->setUnpackSkipImages(param);
				break;
			}
			else return error(GL_INVALID_ENUM);
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void PolygonOffset(GLfloat factor, GLfloat units)
{
	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setPolygonOffsetParams(factor, units);
	}
}

void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
                    GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
	      x, y, width, height, format, type, bufSize, data);

	if(width < 0 || height < 0 || bufSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->readPixels(x, y, width, height, format, type, &bufSize, data);
	}
}

void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
	      x, y, width, height, format, type,  pixels);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
	}
}

void ReleaseShaderCompiler(void)
{
	TRACE("()");

	es2::Shader::releaseCompiler();
}

void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
	      target, samples, internalformat, width, height);

	switch(target)
	{
	case GL_RENDERBUFFER:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(width < 0 || height < 0 || samples < 0 ||
	   width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
	   height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
	{
		return error(GL_INVALID_VALUE);
	}

	if(samples > es2::IMPLEMENTATION_MAX_SAMPLES ||
	   (IsNonNormalizedInteger(internalformat) && samples > 0))
	{
		return error(GL_INVALID_OPERATION);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLuint handle = context->getRenderbufferName();
		if(handle == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLint clientVersion = context->getClientVersion();

		if(IsColorRenderable(internalformat, clientVersion))
		{
			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
		}
		else if(IsDepthRenderable(internalformat, clientVersion) && IsStencilRenderable(internalformat, clientVersion))
		{
			context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
		}
		else if(IsDepthRenderable(internalformat, clientVersion))
		{
			context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
		}
		else if(IsStencilRenderable(internalformat, clientVersion))
		{
			context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
		}
		else error(GL_INVALID_ENUM);
	}
}

void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
	RenderbufferStorageMultisample(target, samples, internalformat, width, height);
}

void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
	RenderbufferStorageMultisample(target, 0, internalformat, width, height);
}

void SampleCoverage(GLclampf value, GLboolean invert)
{
	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

	es2::Context* context = es2::getContext();

	if(context)
	{
		context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
	}
}

void SetFenceNV(GLuint fence, GLenum condition)
{
	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);

	if(condition != GL_ALL_COMPLETED_NV)
	{
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Fence *fenceObject = context->getFence(fence);

		if(!fenceObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		fenceObject->setFence(condition);
	}
}

void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context* context = es2::getContext();

	if(context)
	{
		context->setScissorParams(x, y, width, height);
	}
}

void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
	      "const GLvoid* binary = %p, GLsizei length = %d)",
	      n, shaders, binaryformat, binary, length);

	// No binary shader formats are supported.
	return error(GL_INVALID_ENUM);
}

void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
{
	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
	      shader, count, string, length);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		shaderObject->setSource(count, string, length);
	}
}

void StencilFunc(GLenum func, GLint ref, GLuint mask)
{
	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
}

void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
{
	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);

	switch(face)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GEQUAL:
	case GL_GREATER:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
		{
			context->setStencilParams(func, ref, mask);
		}

		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
		{
			context->setStencilBackParams(func, ref, mask);
		}
	}
}

void StencilMask(GLuint mask)
{
	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
}

void StencilMaskSeparate(GLenum face, GLuint mask)
{
	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);

	switch(face)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
		{
			context->setStencilWritemask(mask);
		}

		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
		{
			context->setStencilBackWritemask(mask);
		}
	}
}

void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
{
	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
}

void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
	      face, fail, zfail, zpass);

	switch(face)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(fail)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP:
	case GL_DECR_WRAP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(zfail)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP:
	case GL_DECR_WRAP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(zpass)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP:
	case GL_DECR_WRAP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
		{
			context->setStencilOperations(fail, zfail, zpass);
		}

		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
		{
			context->setStencilBackOperations(fail, zfail, zpass);
		}
	}
}

GLboolean TestFenceNV(GLuint fence)
{
	TRACE("(GLuint fence = %d)", fence);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Fence *fenceObject = context->getFence(fence);

		if(!fenceObject)
		{
			return error(GL_INVALID_OPERATION, GL_TRUE);
		}

		return fenceObject->testFence();
	}

	return GL_TRUE;
}

void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                GLint border, GLenum format, GLenum type, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* data =  %p)",
	      target, level, internalformat, width, height, border, format, type, data);

	if(!validImageSize(level, width, height))
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLint clientVersion = context->getClientVersion();
		if(clientVersion < 3)
		{
			if(internalformat != (GLint)format)
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		GLenum validationError = ValidateTextureFormatType(format, type, internalformat, context->getClientVersion());
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		if(border != 0)
		{
			return error(GL_INVALID_VALUE);
		}

		switch(target)
		{
		case GL_TEXTURE_2D:
		case GL_TEXTURE_RECTANGLE_ARB:
			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
			if(width != height)
			{
				return error(GL_INVALID_VALUE);
			}

			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);

		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
		{
			es2::Texture2D *texture = context->getTexture2D(target);

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setImage(context, level, width, height, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
		}
		else
		{
			es2::TextureCubeMap *texture = context->getTextureCubeMap();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setImage(context, target, level, width, height, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
		}
	}
}

void TexParameterf(GLenum target, GLenum pname, GLfloat param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture *texture;

		GLint clientVersion = context->getClientVersion();

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_2D_ARRAY:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			else
			{
				texture = context->getTexture2DArray();
			}
			break;
		case GL_TEXTURE_3D:
			texture = context->getTexture3D();
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		case GL_TEXTURE_RECTANGLE_ARB:
			texture = context->getTexture2DRect();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_WRAP_S:
			if(!texture->setWrapS((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_T:
			if(!texture->setWrapT((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_R_OES:
			if(!texture->setWrapR((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MIN_FILTER:
			if(!texture->setMinFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAG_FILTER:
			if(!texture->setMagFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			if(!texture->setMaxAnisotropy(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_BASE_LEVEL:
			if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_COMPARE_FUNC:
			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_COMPARE_MODE:
			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MAX_LEVEL:
			if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MAX_LOD:
			if(clientVersion < 3 || !texture->setMaxLOD(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MIN_LOD:
			if(clientVersion < 3 || !texture->setMinLOD(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_R:
			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_G:
			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_B:
			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_A:
			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
	glTexParameterf(target, pname, *params);
}

void TexParameteri(GLenum target, GLenum pname, GLint param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture *texture;

		GLint clientVersion = context->getClientVersion();

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_2D_ARRAY:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			else
			{
				texture = context->getTexture2DArray();
			}
			break;
		case GL_TEXTURE_3D:
			texture = context->getTexture3D();
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		case GL_TEXTURE_RECTANGLE_ARB:
			texture = context->getTexture2DRect();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_WRAP_S:
			if(!texture->setWrapS((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_T:
			if(!texture->setWrapT((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_R_OES:
			if(!texture->setWrapR((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MIN_FILTER:
			if(!texture->setMinFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAG_FILTER:
			if(!texture->setMagFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			if(!texture->setMaxAnisotropy((GLfloat)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_BASE_LEVEL:
			if(clientVersion < 3 || !texture->setBaseLevel(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_COMPARE_FUNC:
			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_COMPARE_MODE:
			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MAX_LEVEL:
			if(clientVersion < 3 || !texture->setMaxLevel(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MAX_LOD:
			if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MIN_LOD:
			if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_R:
			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_G:
			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_B:
			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_SWIZZLE_A:
			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
{
	glTexParameteri(target, pname, *params);
}

void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                   GLenum format, GLenum type, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
	      "const GLvoid* data = %p)",
	      target, level, xoffset, yoffset, width, height, format, type, data);

	if(!es2::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
		{
			es2::Texture2D *texture = context->getTexture2D(target);

			GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			texture->subImage(context, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), data);
		}
		else if(es2::IsCubemapTextureTarget(target))
		{
			es2::TextureCubeMap *texture = context->getTextureCubeMap();

			GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
			if(validationError != GL_NONE)
			{
				return error(validationError);
			}

			texture->subImage(context, target, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), data);
		}
		else UNREACHABLE(target);
	}
}

void Uniform1f(GLint location, GLfloat x)
{
	glUniform1fv(location, 1, &x);
}

void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform1fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform1i(GLint location, GLint x)
{
	glUniform1iv(location, 1, &x);
}

void Uniform1iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform1iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform2f(GLint location, GLfloat x, GLfloat y)
{
	GLfloat xy[2] = {x, y};

	glUniform2fv(location, 1, (GLfloat*)&xy);
}

void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform2fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform2i(GLint location, GLint x, GLint y)
{
	GLint xy[4] = {x, y};

	glUniform2iv(location, 1, (GLint*)&xy);
}

void Uniform2iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform2iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
	GLfloat xyz[3] = {x, y, z};

	glUniform3fv(location, 1, (GLfloat*)&xyz);
}

void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform3fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform3i(GLint location, GLint x, GLint y, GLint z)
{
	GLint xyz[3] = {x, y, z};

	glUniform3iv(location, 1, (GLint*)&xyz);
}

void Uniform3iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform3iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	GLfloat xyzw[4] = {x, y, z, w};

	glUniform4fv(location, 1, (GLfloat*)&xyzw);
}

void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform4fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
{
	GLint xyzw[4] = {x, y, z, w};

	glUniform4iv(location, 1, (GLint*)&xyzw);
}

void Uniform4iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniform4iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
	      location, count, transpose, value);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
		{
			return error(GL_INVALID_VALUE);
		}

		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniformMatrix2fv(location, count, transpose, value))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
	      location, count, transpose, value);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
		{
			return error(GL_INVALID_VALUE);
		}

		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniformMatrix3fv(location, count, transpose, value))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
	      location, count, transpose, value);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
		{
			return error(GL_INVALID_VALUE);
		}

		es2::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(location == -1)
		{
			return;
		}

		if(!program->setUniformMatrix4fv(location, count, transpose, value))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void UseProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
		{
			return error(GL_INVALID_OPERATION);
		}

		es2::Program *programObject = context->getProgram(program);

		if(!programObject && program != 0)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(program != 0 && !programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		context->useProgram(program);
	}
}

void ValidateProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		programObject->validate(context->getDevice());
	}
}

void VertexAttrib1f(GLuint index, GLfloat x)
{
	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { x, 0, 0, 1 };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib1fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { values[0], 0, 0, 1 };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
{
	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { x, y, 0, 1 };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib2fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { values[0], values[1], 0, 1 };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { x, y, z, 1 };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib3fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { values[0], values[1], values[2], 1 };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLfloat vals[4] = { x, y, z, w };
		context->setVertexAttrib(index, vals);
	}
}

void VertexAttrib4fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setVertexAttrib(index, values);
	}
}

void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
	      index, size, type, normalized, stride, ptr);

	if(index >= es2::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(size < 1 || size > 4)
	{
		return error(GL_INVALID_VALUE);
	}

	GLint clientVersion = egl::getClientVersion();

	switch(type)
	{
	case GL_BYTE:
	case GL_UNSIGNED_BYTE:
	case GL_SHORT:
	case GL_UNSIGNED_SHORT:
	case GL_FIXED:
	case GL_FLOAT:
	case GL_HALF_FLOAT_OES:   // GL_OES_vertex_half_float
		break;
	case GL_INT_2_10_10_10_REV:
	case GL_UNSIGNED_INT_2_10_10_10_REV:
		if(clientVersion >= 3)
		{
			if(size != 4)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		}
		else return error(GL_INVALID_ENUM);
	case GL_INT:
	case GL_UNSIGNED_INT:
	case GL_HALF_FLOAT:
		if(clientVersion >= 3)
		{
			break;
		}
		else return error(GL_INVALID_ENUM);
	default:
		return error(GL_INVALID_ENUM);
	}

	if(stride < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::VertexArray* vertexArray = context->getCurrentVertexArray();
		if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && ptr)
		{
			// GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
			// to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
			return error(GL_INVALID_OPERATION);
		}

		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), false, stride, ptr);
	}
}

void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		context->setViewportParams(x, y, width, height);
	}
}

static void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter, bool allowPartialDepthStencilBlit)
{
	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);

	switch(filter)
	{
	case GL_NEAREST:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
		{
			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
			return error(GL_INVALID_OPERATION);
		}

		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, false, allowPartialDepthStencilBlit);
	}
}

void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
	BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, true);
}

void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                          GLbitfield mask, GLenum filter)
{
	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
	{
		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
		return error(GL_INVALID_OPERATION);
	}

	BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, false);
}

void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
                   GLint border, GLenum format, GLenum type, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
	      target, level, internalformat, width, height, depth, border, format, type, data);

	switch(target)
	{
	case GL_TEXTURE_3D:
		switch(format)
		{
		case GL_DEPTH_COMPONENT:
		case GL_DEPTH_STENCIL_OES:
			return error(GL_INVALID_OPERATION);
		default:
			break;
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(internalformat != format)
	{
		return error(GL_INVALID_OPERATION);
	}

	GLenum validationError = ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion());
	if(validationError != GL_NONE)
	{
		return error(validationError);
	}

	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
	{
		return error(GL_INVALID_VALUE);
	}

	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
	{
		return error(GL_INVALID_VALUE);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture3D *texture = context->getTexture3D();

		if(!texture)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
		GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		texture->setImage(context, level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
	}
}

void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)",
	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);

	switch(target)
	{
	case GL_TEXTURE_3D:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
	{
		return;
	}

	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
	{
		return error(GL_INVALID_VALUE);
	}

	if((width < 0) || (height < 0) || (depth < 0))
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture3D *texture = context->getTexture3D();

		GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), data);
	}
}

void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
	      target, level, xoffset, yoffset, zoffset, x, y, width, height);

	switch(target)
	{
	case GL_TEXTURE_3D:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Framebuffer *framebuffer = context->getReadFramebuffer();

		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
		}

		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();

		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
		{
			return error(GL_INVALID_OPERATION);
		}

		es2::Texture3D *texture = context->getTexture3D();

		GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
	}
}

void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
	      "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, internalformat, width, height, depth, border, imageSize, data);

	switch(target)
	{
	case GL_TEXTURE_3D:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
	{
		return error(GL_INVALID_VALUE);
	}

	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
	{
		return error(GL_INVALID_VALUE);
	}

	if(!IsCompressed(internalformat, egl::getClientVersion()))
	{
		return error(GL_INVALID_ENUM);
	}

	if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture3D *texture = context->getTexture3D();

		if(!texture)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);

		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
	}
}

void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
	      "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);

	switch(target)
	{
	case GL_TEXTURE_3D:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!IsCompressed(format, egl::getClientVersion()))
	{
		return error(GL_INVALID_ENUM);
	}

	if(imageSize != egl::ComputeCompressedSize(width, height, format) * depth)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture3D *texture = context->getTexture3D();

		if(!texture)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
		if(validationError != GL_NONE)
		{
			return error(validationError);
		}

		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
	}
}

void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
	      "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
	{
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		if(texture == 0)
		{
			textarget = GL_NONE;
		}
		else
		{
			es2::Texture *tex = context->getTexture(texture);

			if(!tex)
			{
				return error(GL_INVALID_OPERATION);
			}

			if(tex->isCompressed(textarget, level))
			{
				return error(GL_INVALID_OPERATION);
			}

			switch(textarget)
			{
			case GL_TEXTURE_3D:
				if(tex->getTarget() != GL_TEXTURE_3D)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			default:
				return error(GL_INVALID_ENUM);
			}

			if(level != 0)
			{
				return error(GL_INVALID_VALUE);
			}
		}

		es2::Framebuffer *framebuffer = nullptr;
		GLuint framebufferName = 0;
		if(target == GL_READ_FRAMEBUFFER)
		{
			framebuffer = context->getReadFramebuffer();
			framebufferName = context->getReadFramebufferName();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
			framebufferName = context->getDrawFramebufferName();
		}

		if(framebufferName == 0 || !framebuffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLint clientVersion = context->getClientVersion();

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT1:
		case GL_COLOR_ATTACHMENT2:
		case GL_COLOR_ATTACHMENT3:
		case GL_COLOR_ATTACHMENT4:
		case GL_COLOR_ATTACHMENT5:
		case GL_COLOR_ATTACHMENT6:
		case GL_COLOR_ATTACHMENT7:
		case GL_COLOR_ATTACHMENT8:
		case GL_COLOR_ATTACHMENT9:
		case GL_COLOR_ATTACHMENT10:
		case GL_COLOR_ATTACHMENT11:
		case GL_COLOR_ATTACHMENT12:
		case GL_COLOR_ATTACHMENT13:
		case GL_COLOR_ATTACHMENT14:
		case GL_COLOR_ATTACHMENT15:
		case GL_COLOR_ATTACHMENT16:
		case GL_COLOR_ATTACHMENT17:
		case GL_COLOR_ATTACHMENT18:
		case GL_COLOR_ATTACHMENT19:
		case GL_COLOR_ATTACHMENT20:
		case GL_COLOR_ATTACHMENT21:
		case GL_COLOR_ATTACHMENT22:
		case GL_COLOR_ATTACHMENT23:
		case GL_COLOR_ATTACHMENT24:
		case GL_COLOR_ATTACHMENT25:
		case GL_COLOR_ATTACHMENT26:
		case GL_COLOR_ATTACHMENT27:
		case GL_COLOR_ATTACHMENT28:
		case GL_COLOR_ATTACHMENT29:
		case GL_COLOR_ATTACHMENT30:
		case GL_COLOR_ATTACHMENT31:
			if(clientVersion < 3)
			{
				return error(GL_INVALID_ENUM);
			}
			// fall through
		case GL_COLOR_ATTACHMENT0:
			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
			{
				return error(GL_INVALID_ENUM);
			}
			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
			break;
		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
	if(egl::getClientVersion() == 1)
	{
		return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
	}

	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);

	switch(target)
	{
	case GL_TEXTURE_2D:
	case GL_TEXTURE_RECTANGLE_ARB:
	case GL_TEXTURE_EXTERNAL_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		es2::Texture2D *texture = context->getTexture2D(target);

		if(!texture)
		{
			return error(GL_INVALID_OPERATION);
		}

		egl::Image *eglImage = context->getSharedImage(image);

		if(!eglImage)
		{
			return error(GL_INVALID_OPERATION);
		}

		texture->setSharedImage(eglImage);
	}
}

void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);

	UNIMPLEMENTED();
}

GLboolean IsRenderbufferOES(GLuint renderbuffer)
{
	return IsRenderbuffer(renderbuffer);
}

void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
{
	BindRenderbuffer(target, renderbuffer);
}

void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
{
	DeleteRenderbuffers(n, renderbuffers);
}

void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
{
	GenRenderbuffers(n, renderbuffers);
}

void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
	RenderbufferStorage(target, internalformat, width, height);
}

void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
{
	GetRenderbufferParameteriv(target, pname, params);
}

GLboolean IsFramebufferOES(GLuint framebuffer)
{
	return IsFramebuffer(framebuffer);
}

void BindFramebufferOES(GLenum target, GLuint framebuffer)
{
	BindFramebuffer(target, framebuffer);
}

void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
{
	DeleteFramebuffers(n, framebuffers);
}

void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
{
	GenFramebuffers(n, framebuffers);
}

GLenum CheckFramebufferStatusOES(GLenum target)
{
	return CheckFramebufferStatus(target);
}

void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
	FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
}

void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
	FramebufferTexture2D(target, attachment, textarget, texture, level);
}

void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
	GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
}

void GenerateMipmapOES(GLenum target)
{
	GenerateMipmap(target);
}

void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
{
	TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);

	if(n < 0 || n > MAX_DRAW_BUFFERS)
	{
		return error(GL_INVALID_VALUE);
	}

	es2::Context *context = es2::getContext();

	if(context)
	{
		GLuint drawFramebufferName = context->getDrawFramebufferName();

		if((drawFramebufferName == 0) && (n != 1))
		{
			return error(GL_INVALID_OPERATION);
		}

		for(unsigned int i = 0; i < (unsigned)n; i++)
		{
			switch(bufs[i])
			{
			case GL_BACK:
				if(drawFramebufferName != 0)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			case GL_NONE:
				break;
			case GL_COLOR_ATTACHMENT0_EXT:
			case GL_COLOR_ATTACHMENT1_EXT:
			case GL_COLOR_ATTACHMENT2_EXT:
			case GL_COLOR_ATTACHMENT3_EXT:
			case GL_COLOR_ATTACHMENT4_EXT:
			case GL_COLOR_ATTACHMENT5_EXT:
			case GL_COLOR_ATTACHMENT6_EXT:
			case GL_COLOR_ATTACHMENT7_EXT:
			case GL_COLOR_ATTACHMENT8_EXT:
			case GL_COLOR_ATTACHMENT9_EXT:
			case GL_COLOR_ATTACHMENT10_EXT:
			case GL_COLOR_ATTACHMENT11_EXT:
			case GL_COLOR_ATTACHMENT12_EXT:
			case GL_COLOR_ATTACHMENT13_EXT:
			case GL_COLOR_ATTACHMENT14_EXT:
			case GL_COLOR_ATTACHMENT15_EXT:
				{
					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);

					if(index >= MAX_COLOR_ATTACHMENTS)
					{
						return error(GL_INVALID_OPERATION);
					}

					if(index != i)
					{
						return error(GL_INVALID_OPERATION);
					}

					if(drawFramebufferName == 0)
					{
						return error(GL_INVALID_OPERATION);
					}
				}
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
		}

		context->setFramebufferDrawBuffers(n, bufs);
	}
}

}

extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
{
	struct Function
	{
		const char *name;
		__eglMustCastToProperFunctionPointerType address;
	};

	struct CompareFunctor
	{
		bool operator()(const Function &a, const Function &b) const
		{
			return strcmp(a.name, b.name) < 0;
		}
	};

	// This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
	// The Unix command "LC_COLLATE=C sort" will generate the correct order.
	static const Function glFunctions[] =
	{
		#define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}

		FUNCTION(glActiveTexture),
		FUNCTION(glAttachShader),
		FUNCTION(glBeginQuery),
		FUNCTION(glBeginQueryEXT),
		FUNCTION(glBeginTransformFeedback),
		FUNCTION(glBindAttribLocation),
		FUNCTION(glBindBuffer),
		FUNCTION(glBindBufferBase),
		FUNCTION(glBindBufferRange),
		FUNCTION(glBindFramebuffer),
		FUNCTION(glBindFramebufferOES),
		FUNCTION(glBindRenderbuffer),
		FUNCTION(glBindRenderbufferOES),
		FUNCTION(glBindSampler),
		FUNCTION(glBindTexture),
		FUNCTION(glBindTransformFeedback),
		FUNCTION(glBindVertexArray),
		FUNCTION(glBlendColor),
		FUNCTION(glBlendEquation),
		FUNCTION(glBlendEquationSeparate),
		FUNCTION(glBlendFunc),
		FUNCTION(glBlendFuncSeparate),
		FUNCTION(glBlitFramebuffer),
		FUNCTION(glBlitFramebufferANGLE),
		FUNCTION(glBufferData),
		FUNCTION(glBufferSubData),
		FUNCTION(glCheckFramebufferStatus),
		FUNCTION(glCheckFramebufferStatusOES),
		FUNCTION(glClear),
		FUNCTION(glClearBufferfi),
		FUNCTION(glClearBufferfv),
		FUNCTION(glClearBufferiv),
		FUNCTION(glClearBufferuiv),
		FUNCTION(glClearColor),
		FUNCTION(glClearDepthf),
		FUNCTION(glClearStencil),
		FUNCTION(glClientWaitSync),
		FUNCTION(glColorMask),
		FUNCTION(glCompileShader),
		FUNCTION(glCompressedTexImage2D),
		FUNCTION(glCompressedTexImage3D),
		FUNCTION(glCompressedTexSubImage2D),
		FUNCTION(glCompressedTexSubImage3D),
		FUNCTION(glCopyBufferSubData),
		FUNCTION(glCopyTexImage2D),
		FUNCTION(glCopyTexSubImage2D),
		FUNCTION(glCopyTexSubImage3D),
		FUNCTION(glCreateProgram),
		FUNCTION(glCreateShader),
		FUNCTION(glCullFace),
		FUNCTION(glDeleteBuffers),
		FUNCTION(glDeleteFencesNV),
		FUNCTION(glDeleteFramebuffers),
		FUNCTION(glDeleteFramebuffersOES),
		FUNCTION(glDeleteProgram),
		FUNCTION(glDeleteQueries),
		FUNCTION(glDeleteQueriesEXT),
		FUNCTION(glDeleteRenderbuffers),
		FUNCTION(glDeleteRenderbuffersOES),
		FUNCTION(glDeleteSamplers),
		FUNCTION(glDeleteShader),
		FUNCTION(glDeleteSync),
		FUNCTION(glDeleteTextures),
		FUNCTION(glDeleteTransformFeedbacks),
		FUNCTION(glDeleteVertexArrays),
		FUNCTION(glDepthFunc),
		FUNCTION(glDepthMask),
		FUNCTION(glDepthRangef),
		FUNCTION(glDetachShader),
		FUNCTION(glDisable),
		FUNCTION(glDisableVertexAttribArray),
		FUNCTION(glDrawArrays),
		FUNCTION(glDrawArraysInstanced),
		FUNCTION(glDrawBuffers),
		FUNCTION(glDrawBuffersEXT),
		FUNCTION(glDrawElements),
		FUNCTION(glDrawElementsInstanced),
		FUNCTION(glDrawRangeElements),
		FUNCTION(glEGLImageTargetRenderbufferStorageOES),
		FUNCTION(glEGLImageTargetTexture2DOES),
		FUNCTION(glEnable),
		FUNCTION(glEnableVertexAttribArray),
		FUNCTION(glEndQuery),
		FUNCTION(glEndQueryEXT),
		FUNCTION(glEndTransformFeedback),
		FUNCTION(glFenceSync),
		FUNCTION(glFinish),
		FUNCTION(glFinishFenceNV),
		FUNCTION(glFlush),
		FUNCTION(glFlushMappedBufferRange),
		FUNCTION(glFramebufferRenderbuffer),
		FUNCTION(glFramebufferRenderbufferOES),
		FUNCTION(glFramebufferTexture2D),
		FUNCTION(glFramebufferTexture2DOES),
		FUNCTION(glFramebufferTextureLayer),
		FUNCTION(glFrontFace),
		FUNCTION(glGenBuffers),
		FUNCTION(glGenFencesNV),
		FUNCTION(glGenFramebuffers),
		FUNCTION(glGenFramebuffersOES),
		FUNCTION(glGenQueries),
		FUNCTION(glGenQueriesEXT),
		FUNCTION(glGenRenderbuffers),
		FUNCTION(glGenRenderbuffersOES),
		FUNCTION(glGenSamplers),
		FUNCTION(glGenTextures),
		FUNCTION(glGenTransformFeedbacks),
		FUNCTION(glGenVertexArrays),
		FUNCTION(glGenerateMipmap),
		FUNCTION(glGenerateMipmapOES),
		FUNCTION(glGetActiveAttrib),
		FUNCTION(glGetActiveUniform),
		FUNCTION(glGetActiveUniformBlockName),
		FUNCTION(glGetActiveUniformBlockiv),
		FUNCTION(glGetActiveUniformsiv),
		FUNCTION(glGetAttachedShaders),
		FUNCTION(glGetAttribLocation),
		FUNCTION(glGetBooleanv),
		FUNCTION(glGetBufferParameteri64v),
		FUNCTION(glGetBufferParameteriv),
		FUNCTION(glGetBufferPointerv),
		FUNCTION(glGetError),
		FUNCTION(glGetFenceivNV),
		FUNCTION(glGetFloatv),
		FUNCTION(glGetFragDataLocation),
		FUNCTION(glGetFramebufferAttachmentParameteriv),
		FUNCTION(glGetFramebufferAttachmentParameterivOES),
		FUNCTION(glGetGraphicsResetStatusEXT),
		FUNCTION(glGetInteger64i_v),
		FUNCTION(glGetInteger64v),
		FUNCTION(glGetIntegeri_v),
		FUNCTION(glGetIntegerv),
		FUNCTION(glGetInternalformativ),
		FUNCTION(glGetProgramBinary),
		FUNCTION(glGetProgramInfoLog),
		FUNCTION(glGetProgramiv),
		FUNCTION(glGetQueryObjectuiv),
		FUNCTION(glGetQueryObjectuivEXT),
		FUNCTION(glGetQueryiv),
		FUNCTION(glGetQueryivEXT),
		FUNCTION(glGetRenderbufferParameteriv),
		FUNCTION(glGetRenderbufferParameterivOES),
		FUNCTION(glGetSamplerParameterfv),
		FUNCTION(glGetSamplerParameteriv),
		FUNCTION(glGetShaderInfoLog),
		FUNCTION(glGetShaderPrecisionFormat),
		FUNCTION(glGetShaderSource),
		FUNCTION(glGetShaderiv),
		FUNCTION(glGetString),
		FUNCTION(glGetStringi),
		FUNCTION(glGetSynciv),
		FUNCTION(glGetTexParameterfv),
		FUNCTION(glGetTexParameteriv),
		FUNCTION(glGetTransformFeedbackVarying),
		FUNCTION(glGetUniformBlockIndex),
		FUNCTION(glGetUniformIndices),
		FUNCTION(glGetUniformLocation),
		FUNCTION(glGetUniformfv),
		FUNCTION(glGetUniformiv),
		FUNCTION(glGetUniformuiv),
		FUNCTION(glGetVertexAttribIiv),
		FUNCTION(glGetVertexAttribIuiv),
		FUNCTION(glGetVertexAttribPointerv),
		FUNCTION(glGetVertexAttribfv),
		FUNCTION(glGetVertexAttribiv),
		FUNCTION(glGetnUniformfvEXT),
		FUNCTION(glGetnUniformivEXT),
		FUNCTION(glHint),
		FUNCTION(glInvalidateFramebuffer),
		FUNCTION(glInvalidateSubFramebuffer),
		FUNCTION(glIsBuffer),
		FUNCTION(glIsEnabled),
		FUNCTION(glIsFenceNV),
		FUNCTION(glIsFramebuffer),
		FUNCTION(glIsFramebufferOES),
		FUNCTION(glIsProgram),
		FUNCTION(glIsQuery),
		FUNCTION(glIsQueryEXT),
		FUNCTION(glIsRenderbuffer),
		FUNCTION(glIsRenderbufferOES),
		FUNCTION(glIsSampler),
		FUNCTION(glIsShader),
		FUNCTION(glIsSync),
		FUNCTION(glIsTexture),
		FUNCTION(glIsTransformFeedback),
		FUNCTION(glIsVertexArray),
		FUNCTION(glLineWidth),
		FUNCTION(glLinkProgram),
		FUNCTION(glMapBufferRange),
		FUNCTION(glPauseTransformFeedback),
		FUNCTION(glPixelStorei),
		FUNCTION(glPolygonOffset),
		FUNCTION(glProgramBinary),
		FUNCTION(glProgramParameteri),
		FUNCTION(glReadBuffer),
		FUNCTION(glReadPixels),
		FUNCTION(glReadnPixelsEXT),
		FUNCTION(glReleaseShaderCompiler),
		FUNCTION(glRenderbufferStorage),
		FUNCTION(glRenderbufferStorageMultisample),
		FUNCTION(glRenderbufferStorageMultisampleANGLE),
		FUNCTION(glRenderbufferStorageOES),
		FUNCTION(glResumeTransformFeedback),
		FUNCTION(glSampleCoverage),
		FUNCTION(glSamplerParameterf),
		FUNCTION(glSamplerParameterfv),
		FUNCTION(glSamplerParameteri),
		FUNCTION(glSamplerParameteriv),
		FUNCTION(glScissor),
		FUNCTION(glSetFenceNV),
		FUNCTION(glShaderBinary),
		FUNCTION(glShaderSource),
		FUNCTION(glStencilFunc),
		FUNCTION(glStencilFuncSeparate),
		FUNCTION(glStencilMask),
		FUNCTION(glStencilMaskSeparate),
		FUNCTION(glStencilOp),
		FUNCTION(glStencilOpSeparate),
		FUNCTION(glTestFenceNV),
		FUNCTION(glTexImage2D),
		FUNCTION(glTexImage3D),
		FUNCTION(glTexImage3DOES),
		FUNCTION(glTexParameterf),
		FUNCTION(glTexParameterfv),
		FUNCTION(glTexParameteri),
		FUNCTION(glTexParameteriv),
		FUNCTION(glTexStorage2D),
		FUNCTION(glTexStorage3D),
		FUNCTION(glTexSubImage2D),
		FUNCTION(glTexSubImage3D),
		FUNCTION(glTransformFeedbackVaryings),
		FUNCTION(glUniform1f),
		FUNCTION(glUniform1fv),
		FUNCTION(glUniform1i),
		FUNCTION(glUniform1iv),
		FUNCTION(glUniform1ui),
		FUNCTION(glUniform1uiv),
		FUNCTION(glUniform2f),
		FUNCTION(glUniform2fv),
		FUNCTION(glUniform2i),
		FUNCTION(glUniform2iv),
		FUNCTION(glUniform2ui),
		FUNCTION(glUniform2uiv),
		FUNCTION(glUniform3f),
		FUNCTION(glUniform3fv),
		FUNCTION(glUniform3i),
		FUNCTION(glUniform3iv),
		FUNCTION(glUniform3ui),
		FUNCTION(glUniform3uiv),
		FUNCTION(glUniform4f),
		FUNCTION(glUniform4fv),
		FUNCTION(glUniform4i),
		FUNCTION(glUniform4iv),
		FUNCTION(glUniform4ui),
		FUNCTION(glUniform4uiv),
		FUNCTION(glUniformBlockBinding),
		FUNCTION(glUniformMatrix2fv),
		FUNCTION(glUniformMatrix2x3fv),
		FUNCTION(glUniformMatrix2x4fv),
		FUNCTION(glUniformMatrix3fv),
		FUNCTION(glUniformMatrix3x2fv),
		FUNCTION(glUniformMatrix3x4fv),
		FUNCTION(glUniformMatrix4fv),
		FUNCTION(glUniformMatrix4x2fv),
		FUNCTION(glUniformMatrix4x3fv),
		FUNCTION(glUnmapBuffer),
		FUNCTION(glUseProgram),
		FUNCTION(glValidateProgram),
		FUNCTION(glVertexAttrib1f),
		FUNCTION(glVertexAttrib1fv),
		FUNCTION(glVertexAttrib2f),
		FUNCTION(glVertexAttrib2fv),
		FUNCTION(glVertexAttrib3f),
		FUNCTION(glVertexAttrib3fv),
		FUNCTION(glVertexAttrib4f),
		FUNCTION(glVertexAttrib4fv),
		FUNCTION(glVertexAttribDivisor),
		FUNCTION(glVertexAttribI4i),
		FUNCTION(glVertexAttribI4iv),
		FUNCTION(glVertexAttribI4ui),
		FUNCTION(glVertexAttribI4uiv),
		FUNCTION(glVertexAttribIPointer),
		FUNCTION(glVertexAttribPointer),
		FUNCTION(glViewport),
		FUNCTION(glWaitSync),

		#undef FUNCTION
	};

	static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
	static const Function *const glFunctionsEnd = glFunctions + numFunctions;

	Function needle;
	needle.name = procname;

	if(procname && strncmp("gl", procname, 2) == 0)
	{
		const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
		if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
		{
			return (__eglMustCastToProperFunctionPointerType)result->address;
		}
	}

	return nullptr;
}
