Apply the Apache 2.0 license.

Change-Id: I4a7aeefedcd2d891093520d5a10ebefadcddb5be
Reviewed-on: https://swiftshader-review.googlesource.com/5320
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLES_CM/Buffer.cpp b/src/OpenGL/libGLES_CM/Buffer.cpp
index 7377d03..2947284 100644
--- a/src/OpenGL/libGLES_CM/Buffer.cpp
+++ b/src/OpenGL/libGLES_CM/Buffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    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.
 
 // Buffer.cpp: Implements the Buffer class, representing storage of vertex and/or
 // index data. Implements GL buffer objects and related functionality.
diff --git a/src/OpenGL/libGLES_CM/Buffer.h b/src/OpenGL/libGLES_CM/Buffer.h
index 0310d1c..0ad1069 100644
--- a/src/OpenGL/libGLES_CM/Buffer.h
+++ b/src/OpenGL/libGLES_CM/Buffer.h
@@ -1,53 +1,56 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Buffer.h: Defines the Buffer class, representing storage of vertex and/or

-// index data. Implements GL buffer objects and related functionality.

-// [OpenGL ES 2.0.24] section 2.9 page 21.

-

-#ifndef LIBGLES_CM_BUFFER_H_

-#define LIBGLES_CM_BUFFER_H_

-

-#include "common/Object.hpp"

-#include "Common/Resource.hpp"

-

-#include <GLES/gl.h>

-

-#include <cstddef>

-#include <vector>

-

-namespace es1

-{

-class Buffer : public gl::NamedObject

-{

-  public:

-    explicit Buffer(GLuint name);

-

-    virtual ~Buffer();

-

-    void bufferData(const void *data, GLsizeiptr size, GLenum usage);

-    void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);

-

-	const void *data() { return mContents ? mContents->data() : 0; }

-    size_t size() const { return mSize; }

-    GLenum usage() const { return mUsage; }

-

-	sw::Resource *getResource();

-

-  private:

-    sw::Resource *mContents;

-    size_t mSize;

-    GLenum mUsage;

-};

-

-}

-

-#endif   // LIBGLES_CM_BUFFER_H_

+// 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.
+
+// Buffer.h: Defines the Buffer class, representing storage of vertex and/or
+// index data. Implements GL buffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 2.9 page 21.
+
+#ifndef LIBGLES_CM_BUFFER_H_
+#define LIBGLES_CM_BUFFER_H_
+
+#include "common/Object.hpp"
+#include "Common/Resource.hpp"
+
+#include <GLES/gl.h>
+
+#include <cstddef>
+#include <vector>
+
+namespace es1
+{
+class Buffer : public gl::NamedObject
+{
+public:
+	explicit Buffer(GLuint name);
+
+	virtual ~Buffer();
+
+	void bufferData(const void *data, GLsizeiptr size, GLenum usage);
+	void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+
+	const void *data() { return mContents ? mContents->data() : 0; }
+	size_t size() const { return mSize; }
+	GLenum usage() const { return mUsage; }
+
+	sw::Resource *getResource();
+
+private:
+	sw::Resource *mContents;
+	size_t mSize;
+	GLenum mUsage;
+};
+
+}
+
+#endif   // LIBGLES_CM_BUFFER_H_
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 0b1ce44..b659bd9 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -1,3456 +1,3458 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Context.cpp: Implements the es1::Context class, managing all GL state and performing

-// rendering operations. It is the GLES2 specific implementation of EGLContext.

-

-#include "Context.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "ResourceManager.h"

-#include "Buffer.h"

-#include "Framebuffer.h"

-#include "Renderbuffer.h"

-#include "Texture.h"

-#include "VertexDataManager.h"

-#include "IndexDataManager.h"

-#include "libEGL/Display.h"

-#include "libEGL/Surface.h"

-#include "Common/Half.hpp"

-

-#include <EGL/eglext.h>

-

-using std::abs;

-

-namespace es1

-{

-Context::Context(const egl::Config *config, const Context *shareContext)

-    : modelViewStack(MAX_MODELVIEW_STACK_DEPTH),

-      projectionStack(MAX_PROJECTION_STACK_DEPTH),

-	  textureStack0(MAX_TEXTURE_STACK_DEPTH),

-	  textureStack1(MAX_TEXTURE_STACK_DEPTH)

-{

-	sw::Context *context = new sw::Context();

-	device = new es1::Device(context);

-

-	mVertexDataManager = new VertexDataManager(this);

-    mIndexDataManager = new IndexDataManager();

-

-    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);

-

-    mState.depthClearValue = 1.0f;

-    mState.stencilClearValue = 0;

-

-    mState.cullFaceEnabled = false;

-    mState.cullMode = GL_BACK;

-    mState.frontFace = GL_CCW;

-    mState.depthTestEnabled = false;

-    mState.depthFunc = GL_LESS;

-    mState.blendEnabled = false;

-    mState.sourceBlendRGB = GL_ONE;

-    mState.sourceBlendAlpha = GL_ONE;

-    mState.destBlendRGB = GL_ZERO;

-    mState.destBlendAlpha = GL_ZERO;

-    mState.blendEquationRGB = GL_FUNC_ADD_OES;

-    mState.blendEquationAlpha = GL_FUNC_ADD_OES;

-    mState.stencilTestEnabled = false;

-    mState.stencilFunc = GL_ALWAYS;

-    mState.stencilRef = 0;

-    mState.stencilMask = -1;

-    mState.stencilWritemask = -1;

-    mState.stencilFail = GL_KEEP;

-    mState.stencilPassDepthFail = GL_KEEP;

-    mState.stencilPassDepthPass = GL_KEEP;

-    mState.polygonOffsetFillEnabled = false;

-    mState.polygonOffsetFactor = 0.0f;

-    mState.polygonOffsetUnits = 0.0f;

-    mState.sampleAlphaToCoverageEnabled = false;

-    mState.sampleCoverageEnabled = false;

-    mState.sampleCoverageValue = 1.0f;

-    mState.sampleCoverageInvert = false;

-    mState.scissorTestEnabled = false;

-    mState.ditherEnabled = true;

-	mState.shadeModel = GL_SMOOTH;

-    mState.generateMipmapHint = GL_DONT_CARE;

-	mState.perspectiveCorrectionHint = GL_DONT_CARE;

-	mState.fogHint = GL_DONT_CARE;

-

-    mState.lineWidth = 1.0f;

-

-    mState.viewportX = 0;

-    mState.viewportY = 0;

-    mState.viewportWidth = 0;

-    mState.viewportHeight = 0;

-    mState.zNear = 0.0f;

-    mState.zFar = 1.0f;

-

-    mState.scissorX = 0;

-    mState.scissorY = 0;

-    mState.scissorWidth = 0;

-    mState.scissorHeight = 0;

-

-    mState.colorMaskRed = true;

-    mState.colorMaskGreen = true;

-    mState.colorMaskBlue = true;

-    mState.colorMaskAlpha = true;

-    mState.depthMask = true;

-

-	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)

-	{

-		mState.textureUnit[i].color = {0, 0, 0, 0};

-		mState.textureUnit[i].environmentMode = GL_MODULATE;

-		mState.textureUnit[i].combineRGB = GL_MODULATE;

-		mState.textureUnit[i].combineAlpha = GL_MODULATE;

-		mState.textureUnit[i].src0RGB = GL_TEXTURE;

-		mState.textureUnit[i].src1RGB = GL_PREVIOUS;

-		mState.textureUnit[i].src2RGB = GL_CONSTANT;

-		mState.textureUnit[i].src0Alpha = GL_TEXTURE;

-		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;

-		mState.textureUnit[i].src2Alpha = GL_CONSTANT;

-		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;

-		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;

-		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;

-		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;

-		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;

-		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;

-	}

-

-    if(shareContext)

-    {

-        mResourceManager = shareContext->mResourceManager;

-        mResourceManager->addRef();

-    }

-    else

-    {

-        mResourceManager = new ResourceManager();

-    }

-

-    // [OpenGL ES 2.0.24] section 3.7 page 83:

-    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional

-    // and cube map texture state vectors respectively associated with them.

-    // In order that access to these initial textures not be lost, they are treated as texture

-    // objects all of whose names are 0.

-

-    mTexture2DZero = new Texture2D(0);

-    mTextureExternalZero = new TextureExternal(0);

-

-    mState.activeSampler = 0;

-    bindArrayBuffer(0);

-    bindElementArrayBuffer(0);

-    bindTexture2D(0);

-    bindFramebuffer(0);

-    bindRenderbuffer(0);

-

-    mState.packAlignment = 4;

-    mState.unpackAlignment = 4;

-

-    mInvalidEnum = false;

-    mInvalidValue = false;

-    mInvalidOperation = false;

-    mOutOfMemory = false;

-    mInvalidFramebufferOperation = false;

-	mMatrixStackOverflow = false;

-	mMatrixStackUnderflow = false;

-

-	lightingEnabled = false;

-

-	for(int i = 0; i < MAX_LIGHTS; i++)

-	{

-		light[i].enabled = false;

-		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};

-		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};

-		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};

-		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};

-		light[i].direction = {0.0f, 0.0f, -1.0f};

-		light[i].attenuation = {1.0f, 0.0f, 0.0f};

-		light[i].spotExponent = 0.0f;

-		light[i].spotCutoffAngle = 180.0f;

-	}

-

-	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};

-	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};

-

-	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};

-	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};

-	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};

-	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};

-	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};

-	materialShininess = 0.0f;

-	lightModelTwoSide = false;

-

-	matrixMode = GL_MODELVIEW;

-

-	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)

-	{

-		texture2Denabled[i] = false;

-		textureExternalEnabled[i] = false;

-	}

-

-	clientTexture = GL_TEXTURE0;

-

-	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);

-

-	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)

-	{

-		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);

-	}

-

-	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);

-	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);

-

-	clipFlags = 0;

-

-	alphaTestEnabled = false;

-	alphaTestFunc = GL_ALWAYS;

-	alphaTestRef = 0;

-

-	fogEnabled = false;

-	fogMode = GL_EXP;

-	fogDensity = 1.0f;

-	fogStart = 0.0f;

-	fogEnd = 1.0f;

-	fogColor = {0, 0, 0, 0};

-

-	lineSmoothEnabled = false;

-	colorMaterialEnabled = false;

-	normalizeEnabled = false;

-	rescaleNormalEnabled = false;

-	multisampleEnabled = true;

-	sampleAlphaToOneEnabled = false;

-

-	colorLogicOpEnabled = false;

-	logicalOperation = GL_COPY;

-

-	pointSpriteEnabled = false;

-	pointSmoothEnabled = false;

-	pointSizeMin = 0.0f;

-	pointSizeMax = 1.0f;

-	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};

-	pointFadeThresholdSize = 1.0f;

-

-    mHasBeenCurrent = false;

-

-    markAllStateDirty();

-}

-

-Context::~Context()

-{

-    while(!mFramebufferNameSpace.empty())

-    {

-        deleteFramebuffer(mFramebufferNameSpace.firstName());

-    }

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)

-        {

-            mState.samplerTexture[type][sampler] = nullptr;

-        }

-    }

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mState.vertexAttribute[i].mBoundBuffer = nullptr;

-    }

-

-    mState.arrayBuffer = nullptr;

-    mState.elementArrayBuffer = nullptr;

-    mState.renderbuffer = nullptr;

-

-    mTexture2DZero = nullptr;

-    mTextureExternalZero = nullptr;

-

-    delete mVertexDataManager;

-    delete mIndexDataManager;

-

-    mResourceManager->release();

-	delete device;

-}

-

-void Context::makeCurrent(egl::Surface *surface)

-{

-    if(!mHasBeenCurrent)

-    {

-        mState.viewportX = 0;

-        mState.viewportY = 0;

-        mState.viewportWidth = surface->getWidth();

-        mState.viewportHeight = surface->getHeight();

-

-        mState.scissorX = 0;

-        mState.scissorY = 0;

-        mState.scissorWidth = surface->getWidth();

-        mState.scissorHeight = surface->getHeight();

-

-        mHasBeenCurrent = true;

-    }

-

-    // Wrap the existing resources into GL objects and assign them to the '0' names

-    egl::Image *defaultRenderTarget = surface->getRenderTarget();

-    egl::Image *depthStencil = surface->getDepthStencil();

-

-    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);

-    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);

-    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);

-

-    setFramebufferZero(framebufferZero);

-

-    if(defaultRenderTarget)

-    {

-        defaultRenderTarget->release();

-    }

-

-    if(depthStencil)

-    {

-        depthStencil->release();

-    }

-

-    markAllStateDirty();

-}

-

-int Context::getClientVersion() const

-{

-	return 1;

-}

-

-// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.

-void Context::markAllStateDirty()

-{

-    mDepthStateDirty = true;

-    mMaskStateDirty = true;

-    mBlendStateDirty = true;

-    mStencilStateDirty = true;

-    mPolygonOffsetStateDirty = true;

-    mSampleStateDirty = true;

-    mDitherStateDirty = true;

-    mFrontFaceDirty = true;

-}

-

-void Context::setClearColor(float red, float green, float blue, float alpha)

-{

-    mState.colorClearValue.red = red;

-    mState.colorClearValue.green = green;

-    mState.colorClearValue.blue = blue;

-    mState.colorClearValue.alpha = alpha;

-}

-

-void Context::setClearDepth(float depth)

-{

-    mState.depthClearValue = depth;

-}

-

-void Context::setClearStencil(int stencil)

-{

-    mState.stencilClearValue = stencil;

-}

-

-void Context::setCullFaceEnabled(bool enabled)

-{

-    mState.cullFaceEnabled = enabled;

-}

-

-bool Context::isCullFaceEnabled() const

-{

-    return mState.cullFaceEnabled;

-}

-

-void Context::setCullMode(GLenum mode)

-{

-   mState.cullMode = mode;

-}

-

-void Context::setFrontFace(GLenum front)

-{

-    if(mState.frontFace != front)

-    {

-        mState.frontFace = front;

-        mFrontFaceDirty = true;

-    }

-}

-

-void Context::setDepthTestEnabled(bool enabled)

-{

-    if(mState.depthTestEnabled != enabled)

-    {

-        mState.depthTestEnabled = enabled;

-        mDepthStateDirty = true;

-    }

-}

-

-bool Context::isDepthTestEnabled() const

-{

-    return mState.depthTestEnabled;

-}

-

-void Context::setDepthFunc(GLenum depthFunc)

-{

-    if(mState.depthFunc != depthFunc)

-    {

-        mState.depthFunc = depthFunc;

-        mDepthStateDirty = true;

-    }

-}

-

-void Context::setDepthRange(float zNear, float zFar)

-{

-    mState.zNear = zNear;

-    mState.zFar = zFar;

-}

-

-void Context::setAlphaTestEnabled(bool enabled)

-{

-	alphaTestEnabled = enabled;

-}

-

-bool Context::isAlphaTestEnabled() const

-{

-	return alphaTestEnabled;

-}

-

-void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)

-{

-	alphaTestFunc = alphaFunc;

-	alphaTestRef = reference;

-}

-

-void Context::setBlendEnabled(bool enabled)

-{

-    if(mState.blendEnabled != enabled)

-    {

-        mState.blendEnabled = enabled;

-        mBlendStateDirty = true;

-    }

-}

-

-bool Context::isBlendEnabled() const

-{

-    return mState.blendEnabled;

-}

-

-void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)

-{

-    if(mState.sourceBlendRGB != sourceRGB ||

-       mState.sourceBlendAlpha != sourceAlpha ||

-       mState.destBlendRGB != destRGB ||

-       mState.destBlendAlpha != destAlpha)

-    {

-        mState.sourceBlendRGB = sourceRGB;

-        mState.destBlendRGB = destRGB;

-        mState.sourceBlendAlpha = sourceAlpha;

-        mState.destBlendAlpha = destAlpha;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)

-{

-    if(mState.blendEquationRGB != rgbEquation ||

-       mState.blendEquationAlpha != alphaEquation)

-    {

-        mState.blendEquationRGB = rgbEquation;

-        mState.blendEquationAlpha = alphaEquation;

-        mBlendStateDirty = true;

-    }

-}

-

-void Context::setStencilTestEnabled(bool enabled)

-{

-    if(mState.stencilTestEnabled != enabled)

-    {

-        mState.stencilTestEnabled = enabled;

-        mStencilStateDirty = true;

-    }

-}

-

-bool Context::isStencilTestEnabled() const

-{

-    return mState.stencilTestEnabled;

-}

-

-void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)

-{

-    if(mState.stencilFunc != stencilFunc ||

-       mState.stencilRef != stencilRef ||

-       mState.stencilMask != stencilMask)

-    {

-        mState.stencilFunc = stencilFunc;

-        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;

-        mState.stencilMask = stencilMask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilWritemask(GLuint stencilWritemask)

-{

-    if(mState.stencilWritemask != stencilWritemask)

-    {

-        mState.stencilWritemask = stencilWritemask;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)

-{

-    if(mState.stencilFail != stencilFail ||

-       mState.stencilPassDepthFail != stencilPassDepthFail ||

-       mState.stencilPassDepthPass != stencilPassDepthPass)

-    {

-        mState.stencilFail = stencilFail;

-        mState.stencilPassDepthFail = stencilPassDepthFail;

-        mState.stencilPassDepthPass = stencilPassDepthPass;

-        mStencilStateDirty = true;

-    }

-}

-

-void Context::setPolygonOffsetFillEnabled(bool enabled)

-{

-    if(mState.polygonOffsetFillEnabled != enabled)

-    {

-        mState.polygonOffsetFillEnabled = enabled;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-bool Context::isPolygonOffsetFillEnabled() const

-{

-    return mState.polygonOffsetFillEnabled;

-}

-

-void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)

-{

-    if(mState.polygonOffsetFactor != factor ||

-       mState.polygonOffsetUnits != units)

-    {

-        mState.polygonOffsetFactor = factor;

-        mState.polygonOffsetUnits = units;

-        mPolygonOffsetStateDirty = true;

-    }

-}

-

-void Context::setSampleAlphaToCoverageEnabled(bool enabled)

-{

-    if(mState.sampleAlphaToCoverageEnabled != enabled)

-    {

-        mState.sampleAlphaToCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleAlphaToCoverageEnabled() const

-{

-    return mState.sampleAlphaToCoverageEnabled;

-}

-

-void Context::setSampleCoverageEnabled(bool enabled)

-{

-    if(mState.sampleCoverageEnabled != enabled)

-    {

-        mState.sampleCoverageEnabled = enabled;

-        mSampleStateDirty = true;

-    }

-}

-

-bool Context::isSampleCoverageEnabled() const

-{

-    return mState.sampleCoverageEnabled;

-}

-

-void Context::setSampleCoverageParams(GLclampf value, bool invert)

-{

-    if(mState.sampleCoverageValue != value ||

-       mState.sampleCoverageInvert != invert)

-    {

-        mState.sampleCoverageValue = value;

-        mState.sampleCoverageInvert = invert;

-        mSampleStateDirty = true;

-    }

-}

-

-void Context::setScissorTestEnabled(bool enabled)

-{

-    mState.scissorTestEnabled = enabled;

-}

-

-bool Context::isScissorTestEnabled() const

-{

-    return mState.scissorTestEnabled;

-}

-

-void Context::setShadeModel(GLenum mode)

-{

-    mState.shadeModel = mode;

-}

-

-void Context::setDitherEnabled(bool enabled)

-{

-    if(mState.ditherEnabled != enabled)

-    {

-        mState.ditherEnabled = enabled;

-        mDitherStateDirty = true;

-    }

-}

-

-bool Context::isDitherEnabled() const

-{

-    return mState.ditherEnabled;

-}

-

-void Context::setLightingEnabled(bool enable)

-{

-    lightingEnabled = enable;

-}

-

-bool Context::isLightingEnabled() const

-{

-	return lightingEnabled;

-}

-

-void Context::setLightEnabled(int index, bool enable)

-{

-    light[index].enabled = enable;

-}

-

-bool Context::isLightEnabled(int index) const

-{

-	return light[index].enabled;

-}

-

-void Context::setLightAmbient(int index, float r, float g, float b, float a)

-{

-	light[index].ambient = {r, g, b, a};

-}

-

-void Context::setLightDiffuse(int index, float r, float g, float b, float a)

-{

-	light[index].diffuse = {r, g, b, a};

-}

-

-void Context::setLightSpecular(int index, float r, float g, float b, float a)

-{

-	light[index].specular = {r, g, b, a};

-}

-

-void Context::setLightPosition(int index, float x, float y, float z, float w)

-{

-	sw::float4 v = {x, y, z, w};

-

-	// Transform from object coordinates to eye coordinates

-	v = modelViewStack.current() * v;

-

-	light[index].position = {v.x, v.y, v.z, v.w};

-}

-

-void Context::setLightDirection(int index, float x, float y, float z)

-{

-	// FIXME: Transform by inverse of 3x3 model-view matrix

-	light[index].direction = {x, y, z};

-}

-

-void Context::setLightAttenuationConstant(int index, float constant)

-{

-	light[index].attenuation.constant = constant;

-}

-

-void Context::setLightAttenuationLinear(int index, float linear)

-{

-	light[index].attenuation.linear = linear;

-}

-

-void Context::setLightAttenuationQuadratic(int index, float quadratic)

-{

-	light[index].attenuation.quadratic = quadratic;

-}

-

-void Context::setSpotLightExponent(int index, float exponent)

-{

-	light[index].spotExponent = exponent;

-}

-

-void Context::setSpotLightCutoff(int index, float cutoff)

-{

-	light[index].spotCutoffAngle = cutoff;

-}

-

-void Context::setGlobalAmbient(float red, float green, float blue, float alpha)

-{

-	globalAmbient.red = red;

-	globalAmbient.green = green;

-	globalAmbient.blue = blue;

-	globalAmbient.alpha = alpha;

-}

-

-void Context::setMaterialAmbient(float red, float green, float blue, float alpha)

-{

-	materialAmbient.red = red;

-	materialAmbient.green = green;

-	materialAmbient.blue = blue;

-	materialAmbient.alpha = alpha;

-}

-

-void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)

-{

-	materialDiffuse.red = red;

-	materialDiffuse.green = green;

-	materialDiffuse.blue = blue;

-	materialDiffuse.alpha = alpha;

-}

-

-void Context::setMaterialSpecular(float red, float green, float blue, float alpha)

-{

-	materialSpecular.red = red;

-	materialSpecular.green = green;

-	materialSpecular.blue = blue;

-	materialSpecular.alpha = alpha;

-}

-

-void Context::setMaterialEmission(float red, float green, float blue, float alpha)

-{

-	materialEmission.red = red;

-	materialEmission.green = green;

-	materialEmission.blue = blue;

-	materialEmission.alpha = alpha;

-}

-

-void Context::setMaterialShininess(float shininess)

-{

-	materialShininess = shininess;

-}

-

-void Context::setLightModelTwoSide(bool enable)

-{

-	lightModelTwoSide = enable;

-}

-

-void Context::setFogEnabled(bool enable)

-{

-	fogEnabled = enable;

-}

-

-bool Context::isFogEnabled() const

-{

-	return fogEnabled;

-}

-

-void Context::setFogMode(GLenum mode)

-{

-	fogMode = mode;

-}

-

-void Context::setFogDensity(float fogDensity)

-{

-	this->fogDensity = fogDensity;

-}

-

-void Context::setFogStart(float fogStart)

-{

-	this->fogStart = fogStart;

-}

-

-void Context::setFogEnd(float fogEnd)

-{

-	this->fogEnd = fogEnd;

-}

-

-void Context::setFogColor(float r, float g, float b, float a)

-{

-	this->fogColor = {r, g, b, a};

-}

-

-void Context::setTexture2Denabled(bool enable)

-{

-    texture2Denabled[mState.activeSampler] = enable;

-}

-

-bool Context::isTexture2Denabled() const

-{

-	return texture2Denabled[mState.activeSampler];

-}

-

-void Context::setTextureExternalEnabled(bool enable)

-{

-    textureExternalEnabled[mState.activeSampler] = enable;

-}

-

-bool Context::isTextureExternalEnabled() const

-{

-    return textureExternalEnabled[mState.activeSampler];

-}

-

-void Context::setLineWidth(GLfloat width)

-{

-    mState.lineWidth = width;

-	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));

-}

-

-void Context::setGenerateMipmapHint(GLenum hint)

-{

-    mState.generateMipmapHint = hint;

-}

-

-void Context::setPerspectiveCorrectionHint(GLenum hint)

-{

-    mState.perspectiveCorrectionHint = hint;

-}

-

-void Context::setFogHint(GLenum hint)

-{

-    mState.fogHint = hint;

-}

-

-void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.viewportX = x;

-    mState.viewportY = y;

-    mState.viewportWidth = width;

-    mState.viewportHeight = height;

-}

-

-void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-    mState.scissorX = x;

-    mState.scissorY = y;

-    mState.scissorWidth = width;

-    mState.scissorHeight = height;

-}

-

-void Context::setColorMask(bool red, bool green, bool blue, bool alpha)

-{

-    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||

-       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)

-    {

-        mState.colorMaskRed = red;

-        mState.colorMaskGreen = green;

-        mState.colorMaskBlue = blue;

-        mState.colorMaskAlpha = alpha;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setDepthMask(bool mask)

-{

-    if(mState.depthMask != mask)

-    {

-        mState.depthMask = mask;

-        mMaskStateDirty = true;

-    }

-}

-

-void Context::setActiveSampler(unsigned int active)

-{

-    mState.activeSampler = active;

-}

-

-GLuint Context::getFramebufferName() const

-{

-    return mState.framebuffer;

-}

-

-GLuint Context::getRenderbufferName() const

-{

-    return mState.renderbuffer.name();

-}

-

-GLuint Context::getArrayBufferName() const

-{

-    return mState.arrayBuffer.name();

-}

-

-void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)

-{

-    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;

-}

-

-const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)

-{

-    return mState.vertexAttribute[attribNum];

-}

-

-void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,

-                                   GLsizei stride, const void *pointer)

-{

-    mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;

-    mState.vertexAttribute[attribNum].mSize = size;

-    mState.vertexAttribute[attribNum].mType = type;

-    mState.vertexAttribute[attribNum].mNormalized = normalized;

-    mState.vertexAttribute[attribNum].mStride = stride;

-    mState.vertexAttribute[attribNum].mPointer = pointer;

-}

-

-const void *Context::getVertexAttribPointer(unsigned int attribNum) const

-{

-    return mState.vertexAttribute[attribNum].mPointer;

-}

-

-const VertexAttributeArray &Context::getVertexAttributes()

-{

-    return mState.vertexAttribute;

-}

-

-void Context::setPackAlignment(GLint alignment)

-{

-    mState.packAlignment = alignment;

-}

-

-GLint Context::getPackAlignment() const

-{

-    return mState.packAlignment;

-}

-

-void Context::setUnpackAlignment(GLint alignment)

-{

-    mState.unpackAlignment = alignment;

-}

-

-GLint Context::getUnpackAlignment() const

-{

-    return mState.unpackAlignment;

-}

-

-GLuint Context::createBuffer()

-{

-    return mResourceManager->createBuffer();

-}

-

-GLuint Context::createTexture()

-{

-    return mResourceManager->createTexture();

-}

-

-GLuint Context::createRenderbuffer()

-{

-    return mResourceManager->createRenderbuffer();

-}

-

-// Returns an unused framebuffer name

-GLuint Context::createFramebuffer()

-{

-	return mFramebufferNameSpace.allocate();

-}

-

-void Context::deleteBuffer(GLuint buffer)

-{

-	detachBuffer(buffer);

-

-    mResourceManager->deleteBuffer(buffer);

-}

-

-void Context::deleteTexture(GLuint texture)

-{

-	detachTexture(texture);

-

-    mResourceManager->deleteTexture(texture);

-}

-

-void Context::deleteRenderbuffer(GLuint renderbuffer)

-{

-	detachRenderbuffer(renderbuffer);

-

-    mResourceManager->deleteRenderbuffer(renderbuffer);

-}

-

-void Context::deleteFramebuffer(GLuint framebuffer)

-{

-	detachFramebuffer(framebuffer);

-

-    Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);

-

-    if(framebufferObject)

-    {

-		delete framebufferObject;

-    }

-}

-

-Buffer *Context::getBuffer(GLuint handle)

-{

-    return mResourceManager->getBuffer(handle);

-}

-

-Texture *Context::getTexture(GLuint handle)

-{

-    return mResourceManager->getTexture(handle);

-}

-

-Renderbuffer *Context::getRenderbuffer(GLuint handle)

-{

-    return mResourceManager->getRenderbuffer(handle);

-}

-

-Framebuffer *Context::getFramebuffer()

-{

-    return getFramebuffer(mState.framebuffer);

-}

-

-void Context::bindArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.arrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindElementArrayBuffer(unsigned int buffer)

-{

-    mResourceManager->checkBufferAllocation(buffer);

-

-    mState.elementArrayBuffer = getBuffer(buffer);

-}

-

-void Context::bindTexture2D(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);

-

-    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindTextureExternal(GLuint texture)

-{

-    mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);

-

-    mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);

-}

-

-void Context::bindFramebuffer(GLuint framebuffer)

-{

-    if(!getFramebuffer(framebuffer))

-    {

-		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());

-    }

-

-    mState.framebuffer = framebuffer;

-}

-

-void Context::bindRenderbuffer(GLuint renderbuffer)

-{

-	mResourceManager->checkRenderbufferAllocation(renderbuffer);

-

-    mState.renderbuffer = getRenderbuffer(renderbuffer);

-}

-

-void Context::setFramebufferZero(Framebuffer *buffer)

-{

-	delete mFramebufferNameSpace.remove(0);

-    mFramebufferNameSpace.insert(0, buffer);

-}

-

-void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)

-{

-    Renderbuffer *renderbufferObject = mState.renderbuffer;

-    renderbufferObject->setStorage(renderbuffer);

-}

-

-Framebuffer *Context::getFramebuffer(unsigned int handle)

-{

-	return mFramebufferNameSpace.find(handle);

-}

-

-Buffer *Context::getArrayBuffer()

-{

-    return mState.arrayBuffer;

-}

-

-Buffer *Context::getElementArrayBuffer()

-{

-    return mState.elementArrayBuffer;

-}

-

-Texture2D *Context::getTexture2D()

-{

-    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));

-}

-

-TextureExternal *Context::getTextureExternal()

-{

-    return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));

-}

-

-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)

-{

-    GLuint texid = mState.samplerTexture[type][sampler].name();

-

-    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target

-    {

-        switch(type)

-        {

-        case TEXTURE_2D: return mTexture2DZero;

-        case TEXTURE_EXTERNAL: return mTextureExternalZero;

-        default: UNREACHABLE(type);

-        }

-    }

-

-    return mState.samplerTexture[type][sampler];

-}

-

-bool Context::getBooleanv(GLenum pname, GLboolean *params)

-{

-    switch(pname)

-    {

-    case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;

-    case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;

-    case GL_COLOR_WRITEMASK:

-        params[0] = mState.colorMaskRed;

-        params[1] = mState.colorMaskGreen;

-        params[2] = mState.colorMaskBlue;

-        params[3] = mState.colorMaskAlpha;

-        break;

-    case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;

-    case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;

-    case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;

-    case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;

-    case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;

-    case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;

-    case GL_BLEND:                    *params = mState.blendEnabled;                 break;

-    case GL_DITHER:                   *params = mState.ditherEnabled;                break;

-	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getFloatv(GLenum pname, GLfloat *params)

-{

-    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application.

-    switch(pname)

-    {

-    case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;

-    case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;

-    case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;

-    case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;

-    case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;

-        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;

-        break;

-    case GL_ALIASED_POINT_SIZE_RANGE:

-        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;

-        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;

-        break;

-	case GL_SMOOTH_LINE_WIDTH_RANGE:

-        params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;

-        params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;

-        break;

-    case GL_SMOOTH_POINT_SIZE_RANGE:

-        params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;

-        params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;

-        break;

-    case GL_DEPTH_RANGE:

-        params[0] = mState.zNear;

-        params[1] = mState.zFar;

-        break;

-    case GL_COLOR_CLEAR_VALUE:

-        params[0] = mState.colorClearValue.red;

-        params[1] = mState.colorClearValue.green;

-        params[2] = mState.colorClearValue.blue;

-        params[3] = mState.colorClearValue.alpha;

-        break;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-        *params = MAX_TEXTURE_MAX_ANISOTROPY;

-		break;

-	case GL_MODELVIEW_MATRIX:

-		for(int i = 0; i < 16; i++)

-		{

-			params[i] = modelViewStack.current()[i % 4][i / 4];

-		}

-		break;

-	case GL_PROJECTION_MATRIX:

-		for(int i = 0; i < 16; i++)

-		{

-			params[i] = projectionStack.current()[i % 4][i / 4];

-		}

-		break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getIntegerv(GLenum pname, GLint *params)

-{

-    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation

-    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names

-    // GetIntegerv as its native query function. As it would require conversion in any

-    // case, this should make no difference to the calling application. You may find it in

-    // Context::getFloatv.

-    switch(pname)

-    {

-    case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;

-	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;

-    case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;

-    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;

-    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;

-    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;

-	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;

-    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;

-    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;

-    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;

-    case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;

-    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;

-    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;

-    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;

-    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;

-    case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;

-    case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;

-    case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;

-    case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;

-    case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;

-    case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;

-    case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;

-    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;

-    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;

-	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;

-	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;

-	case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-			int width, height, samples;

-

-            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES)

-            {

-                switch(pname)

-                {

-                case GL_SAMPLE_BUFFERS:

-                    if(samples > 1)

-                    {

-                        *params = 1;

-                    }

-                    else

-                    {

-                        *params = 0;

-                    }

-                    break;

-                case GL_SAMPLES:

-                    *params = samples;

-                    break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:

-		{

-			Framebuffer *framebuffer = getFramebuffer();

-			*params = framebuffer->getImplementationColorReadType();

-		}

-		break;

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:

-		{

-			Framebuffer *framebuffer = getFramebuffer();

-			*params = framebuffer->getImplementationColorReadFormat();

-		}

-		break;

-    case GL_MAX_VIEWPORT_DIMS:

-        {

-			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;

-            params[0] = maxDimension;

-            params[1] = maxDimension;

-        }

-        break;

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-        {

-			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)

-			{

-				params[i] = compressedTextureFormats[i];

-			}

-        }

-        break;

-    case GL_VIEWPORT:

-        params[0] = mState.viewportX;

-        params[1] = mState.viewportY;

-        params[2] = mState.viewportWidth;

-        params[3] = mState.viewportHeight;

-        break;

-    case GL_SCISSOR_BOX:

-        params[0] = mState.scissorX;

-        params[1] = mState.scissorY;

-        params[2] = mState.scissorWidth;

-        params[3] = mState.scissorHeight;

-        break;

-    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;

-    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-            Renderbuffer *colorbuffer = framebuffer->getColorbuffer();

-

-            if(colorbuffer)

-            {

-                switch(pname)

-                {

-                case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;

-                case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;

-                case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;

-                case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;

-                }

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_DEPTH_BITS:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-

-            if(depthbuffer)

-            {

-                *params = depthbuffer->getDepthSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_STENCIL_BITS:

-        {

-            Framebuffer *framebuffer = getFramebuffer();

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-

-            if(stencilbuffer)

-            {

-                *params = stencilbuffer->getStencilSize();

-            }

-            else

-            {

-                *params = 0;

-            }

-        }

-        break;

-    case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();                 break;

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;

-	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;

-    case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;

-	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;

-	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;

-	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;

-	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;

-	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;

-	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;

-	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;

-	case GL_VERTEX_ARRAY_SIZE:                   *params = mState.vertexAttribute[sw::Position].mSize;                                       break;

-	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;

-	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;

-	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;

-	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;

-	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;

-	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;

-	case GL_COLOR_ARRAY_SIZE:                    *params = mState.vertexAttribute[sw::Color0].mSize;                                         break;

-	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;

-	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;

-	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;

-	case GL_TEXTURE_COORD_ARRAY_SIZE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize;               break;

-	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;

-	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;

-	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;

-    default:

-        return false;

-    }

-

-    return true;

-}

-

-bool Context::getPointerv(GLenum pname, const GLvoid **params)

-{

-	switch(pname)

-	{

-	case GL_VERTEX_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Position].mPointer;                         break;

-	case GL_NORMAL_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Normal].mPointer;                           break;

-	case GL_COLOR_ARRAY_POINTER:          *params = mState.vertexAttribute[sw::Color0].mPointer;                           break;

-	case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer;                        break;

-	case GL_TEXTURE_COORD_ARRAY_POINTER:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;

-	default:

-		return false;

-	}

-

-	return true;

-}

-

-int Context::getQueryParameterNum(GLenum pname)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-		return NUM_COMPRESSED_TEXTURE_FORMATS;

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:

-    case GL_ARRAY_BUFFER_BINDING:

-    case GL_FRAMEBUFFER_BINDING_OES:

-    case GL_RENDERBUFFER_BINDING_OES:

-    case GL_PACK_ALIGNMENT:

-    case GL_UNPACK_ALIGNMENT:

-    case GL_GENERATE_MIPMAP_HINT:

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-    case GL_DEPTH_BITS:

-    case GL_STENCIL_BITS:

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:

-    case GL_CULL_FACE_MODE:

-    case GL_FRONT_FACE:

-    case GL_ACTIVE_TEXTURE:

-    case GL_STENCIL_FUNC:

-    case GL_STENCIL_VALUE_MASK:

-    case GL_STENCIL_REF:

-    case GL_STENCIL_FAIL:

-    case GL_STENCIL_PASS_DEPTH_FAIL:

-    case GL_STENCIL_PASS_DEPTH_PASS:

-    case GL_DEPTH_FUNC:

-    case GL_BLEND_SRC_RGB_OES:

-    case GL_BLEND_SRC_ALPHA_OES:

-    case GL_BLEND_DST_RGB_OES:

-    case GL_BLEND_DST_ALPHA_OES:

-    case GL_BLEND_EQUATION_RGB_OES:

-    case GL_BLEND_EQUATION_ALPHA_OES:

-    case GL_STENCIL_WRITEMASK:

-    case GL_STENCIL_CLEAR_VALUE:

-    case GL_SUBPIXEL_BITS:

-    case GL_MAX_TEXTURE_SIZE:

-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:

-    case GL_TEXTURE_BINDING_2D:

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:

-        return 1;

-    case GL_MAX_VIEWPORT_DIMS:

-        return 2;

-    case GL_VIEWPORT:

-    case GL_SCISSOR_BOX:

-        return 4;

-    case GL_SAMPLE_COVERAGE_INVERT:

-    case GL_DEPTH_WRITEMASK:

-    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,

-    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural

-    case GL_SAMPLE_COVERAGE:

-    case GL_SCISSOR_TEST:

-    case GL_STENCIL_TEST:

-    case GL_DEPTH_TEST:

-    case GL_BLEND:

-    case GL_DITHER:

-        return 1;

-    case GL_COLOR_WRITEMASK:

-        return 4;

-    case GL_POLYGON_OFFSET_FACTOR:

-    case GL_POLYGON_OFFSET_UNITS:

-    case GL_SAMPLE_COVERAGE_VALUE:

-    case GL_DEPTH_CLEAR_VALUE:

-    case GL_LINE_WIDTH:

-        return 1;

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-    case GL_ALIASED_POINT_SIZE_RANGE:

-    case GL_DEPTH_RANGE:

-        return 2;

-    case GL_COLOR_CLEAR_VALUE:

-        return 4;

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-	case GL_MAX_LIGHTS:

-	case GL_MAX_MODELVIEW_STACK_DEPTH:

-	case GL_MAX_PROJECTION_STACK_DEPTH:

-	case GL_MAX_TEXTURE_STACK_DEPTH:

-	case GL_MAX_TEXTURE_UNITS:

-	case GL_MAX_CLIP_PLANES:

-	case GL_POINT_SIZE_ARRAY_TYPE_OES:

-	case GL_POINT_SIZE_ARRAY_STRIDE_OES:

-	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:

-        return 1;

-	case GL_CURRENT_COLOR:

-		return 4;

-	case GL_CURRENT_NORMAL:

-		return 3;

-	case GL_CURRENT_TEXTURE_COORDS:

-		return 4;

-	case GL_POINT_SIZE:

-	case GL_POINT_SIZE_MIN:

-	case GL_POINT_SIZE_MAX:

-	case GL_POINT_FADE_THRESHOLD_SIZE:

-		return 1;

-	case GL_POINT_DISTANCE_ATTENUATION:

-		return 3;

-	case GL_SMOOTH_POINT_SIZE_RANGE:

-	case GL_SMOOTH_LINE_WIDTH_RANGE:

-		return 2;

-	case GL_SHADE_MODEL:

-	case GL_MATRIX_MODE:

-	case GL_MODELVIEW_STACK_DEPTH:

-	case GL_PROJECTION_STACK_DEPTH:

-	case GL_TEXTURE_STACK_DEPTH:

-		return 1;

-	case GL_MODELVIEW_MATRIX:

-	case GL_PROJECTION_MATRIX:

-	case GL_TEXTURE_MATRIX:

-		return 16;

-	case GL_ALPHA_TEST_FUNC:

-	case GL_ALPHA_TEST_REF:

-	case GL_BLEND_DST:

-	case GL_BLEND_SRC:

-	case GL_LOGIC_OP_MODE:

-	case GL_VERTEX_ARRAY_SIZE:

-	case GL_VERTEX_ARRAY_TYPE:

-	case GL_VERTEX_ARRAY_STRIDE:

-	case GL_NORMAL_ARRAY_TYPE:

-	case GL_NORMAL_ARRAY_STRIDE:

-	case GL_COLOR_ARRAY_SIZE:

-	case GL_COLOR_ARRAY_TYPE:

-	case GL_COLOR_ARRAY_STRIDE:

-	case GL_TEXTURE_COORD_ARRAY_SIZE:

-	case GL_TEXTURE_COORD_ARRAY_TYPE:

-	case GL_TEXTURE_COORD_ARRAY_STRIDE:

-	case GL_VERTEX_ARRAY_POINTER:

-	case GL_NORMAL_ARRAY_POINTER:

-	case GL_COLOR_ARRAY_POINTER:

-	case GL_TEXTURE_COORD_ARRAY_POINTER:

-	case GL_LIGHT_MODEL_TWO_SIDE:

-		return 1;

-	default:

-		UNREACHABLE(pname);

-    }

-

-    return -1;

-}

-

-bool Context::isQueryParameterInt(GLenum pname)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_COMPRESSED_TEXTURE_FORMATS:

-    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:

-    case GL_ARRAY_BUFFER_BINDING:

-    case GL_FRAMEBUFFER_BINDING_OES:

-    case GL_RENDERBUFFER_BINDING_OES:

-    case GL_PACK_ALIGNMENT:

-    case GL_UNPACK_ALIGNMENT:

-    case GL_GENERATE_MIPMAP_HINT:

-    case GL_RED_BITS:

-    case GL_GREEN_BITS:

-    case GL_BLUE_BITS:

-    case GL_ALPHA_BITS:

-    case GL_DEPTH_BITS:

-    case GL_STENCIL_BITS:

-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:

-    case GL_CULL_FACE_MODE:

-    case GL_FRONT_FACE:

-    case GL_ACTIVE_TEXTURE:

-    case GL_STENCIL_FUNC:

-    case GL_STENCIL_VALUE_MASK:

-    case GL_STENCIL_REF:

-    case GL_STENCIL_FAIL:

-    case GL_STENCIL_PASS_DEPTH_FAIL:

-    case GL_STENCIL_PASS_DEPTH_PASS:

-    case GL_DEPTH_FUNC:

-    case GL_BLEND_SRC_RGB_OES:

-    case GL_BLEND_SRC_ALPHA_OES:

-    case GL_BLEND_DST_RGB_OES:

-    case GL_BLEND_DST_ALPHA_OES:

-    case GL_BLEND_EQUATION_RGB_OES:

-    case GL_BLEND_EQUATION_ALPHA_OES:

-    case GL_STENCIL_WRITEMASK:

-    case GL_STENCIL_CLEAR_VALUE:

-    case GL_SUBPIXEL_BITS:

-    case GL_MAX_TEXTURE_SIZE:

-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:

-    case GL_SAMPLE_BUFFERS:

-    case GL_SAMPLES:

-    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:

-    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:

-    case GL_TEXTURE_BINDING_2D:

-    case GL_TEXTURE_BINDING_CUBE_MAP_OES:

-    case GL_TEXTURE_BINDING_EXTERNAL_OES:

-    case GL_MAX_VIEWPORT_DIMS:

-    case GL_VIEWPORT:

-    case GL_SCISSOR_BOX:

-	case GL_MAX_LIGHTS:

-	case GL_MAX_MODELVIEW_STACK_DEPTH:

-	case GL_MAX_PROJECTION_STACK_DEPTH:

-	case GL_MAX_TEXTURE_STACK_DEPTH:

-	case GL_MAX_TEXTURE_UNITS:

-	case GL_MAX_CLIP_PLANES:

-	case GL_POINT_SIZE_ARRAY_TYPE_OES:

-	case GL_POINT_SIZE_ARRAY_STRIDE_OES:

-	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:

-        return true;

-    }

-

-    return false;

-}

-

-bool Context::isQueryParameterFloat(GLenum pname)

-{

-    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation

-    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due

-    // to the fact that it is stored internally as a float, and so would require conversion

-    // if returned from Context::getIntegerv. Since this conversion is already implemented

-    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we

-    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling

-    // application.

-    switch(pname)

-    {

-    case GL_POLYGON_OFFSET_FACTOR:

-    case GL_POLYGON_OFFSET_UNITS:

-    case GL_SAMPLE_COVERAGE_VALUE:

-    case GL_DEPTH_CLEAR_VALUE:

-    case GL_LINE_WIDTH:

-    case GL_ALIASED_LINE_WIDTH_RANGE:

-    case GL_ALIASED_POINT_SIZE_RANGE:

-    case GL_SMOOTH_LINE_WIDTH_RANGE:

-    case GL_SMOOTH_POINT_SIZE_RANGE:

-    case GL_DEPTH_RANGE:

-    case GL_COLOR_CLEAR_VALUE:

-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:

-	case GL_LIGHT_MODEL_AMBIENT:

-	case GL_POINT_SIZE_MIN:

-	case GL_POINT_SIZE_MAX:

-	case GL_POINT_DISTANCE_ATTENUATION:

-	case GL_POINT_FADE_THRESHOLD_SIZE:

-        return true;

-    }

-

-    return false;

-}

-

-bool Context::isQueryParameterBool(GLenum pname)

-{

-    switch(pname)

-    {

-    case GL_SAMPLE_COVERAGE_INVERT:

-    case GL_DEPTH_WRITEMASK:

-    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,

-    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.

-    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural

-    case GL_SAMPLE_COVERAGE:

-    case GL_SCISSOR_TEST:

-    case GL_STENCIL_TEST:

-    case GL_DEPTH_TEST:

-    case GL_BLEND:

-    case GL_DITHER:

-    case GL_COLOR_WRITEMASK:

-	case GL_LIGHT_MODEL_TWO_SIDE:

-        return true;

-    }

-

-    return false;

-}

-

-bool Context::isQueryParameterPointer(GLenum pname)

-{

-    switch(pname)

-    {

-	case GL_VERTEX_ARRAY_POINTER:

-	case GL_NORMAL_ARRAY_POINTER:

-	case GL_COLOR_ARRAY_POINTER:

-	case GL_TEXTURE_COORD_ARRAY_POINTER:

-	case GL_POINT_SIZE_ARRAY_POINTER_OES:

-        return true;

-    }

-

-    return false;

-}

-

-// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle

-bool Context::applyRenderTarget()

-{

-    Framebuffer *framebuffer = getFramebuffer();

-	int width, height, samples;

-

-    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);

-    }

-

-    egl::Image *renderTarget = framebuffer->getRenderTarget();

-	device->setRenderTarget(0, renderTarget);

-	if(renderTarget) renderTarget->release();

-

-    egl::Image *depthBuffer = framebuffer->getDepthBuffer();

-    device->setDepthBuffer(depthBuffer);

-	if(depthBuffer) depthBuffer->release();

-

-	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();

-	device->setStencilBuffer(stencilBuffer);

-	if(stencilBuffer) stencilBuffer->release();

-

-    Viewport viewport;

-    float zNear = clamp01(mState.zNear);

-    float zFar = clamp01(mState.zFar);

-

-    viewport.x0 = mState.viewportX;

-    viewport.y0 = mState.viewportY;

-    viewport.width = mState.viewportWidth;

-    viewport.height = mState.viewportHeight;

-    viewport.minZ = zNear;

-    viewport.maxZ = zFar;

-

-    device->setViewport(viewport);

-

-    if(mState.scissorTestEnabled)

-    {

-		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};

-		scissor.clip(0, 0, width, height);

-

-		device->setScissorRect(scissor);

-        device->setScissorEnable(true);

-    }

-    else

-    {

-        device->setScissorEnable(false);

-    }

-

-    return true;

-}

-

-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)

-void Context::applyState(GLenum drawMode)

-{

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(mState.cullFaceEnabled)

-    {

-        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));

-    }

-    else

-    {

-		device->setCullMode(sw::CULL_NONE);

-    }

-

-    if(mDepthStateDirty)

-    {

-        if(mState.depthTestEnabled)

-        {

-			device->setDepthBufferEnable(true);

-			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));

-        }

-        else

-        {

-            device->setDepthBufferEnable(false);

-        }

-

-        mDepthStateDirty = false;

-    }

-

-    if(mBlendStateDirty)

-    {

-        if(mState.blendEnabled)

-        {

-			device->setAlphaBlendEnable(true);

-			device->setSeparateAlphaBlendEnable(true);

-

-			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));

-			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));

-			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));

-

-            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));

-			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));

-			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));

-        }

-        else

-        {

-			device->setAlphaBlendEnable(false);

-        }

-

-        mBlendStateDirty = false;

-    }

-

-    if(mStencilStateDirty || mFrontFaceDirty)

-    {

-        if(mState.stencilTestEnabled && framebuffer->hasStencil())

-        {

-			device->setStencilEnable(true);

-			device->setTwoSidedStencil(true);

-

-            // get the maximum size of the stencil ref

-            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();

-            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;

-

-			device->setStencilWriteMask(mState.stencilWritemask);

-			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-			device->setStencilMask(mState.stencilMask);

-

-			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));

-			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-

-			device->setStencilWriteMaskCCW(mState.stencilWritemask);

-			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));

-

-			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);

-			device->setStencilMaskCCW(mState.stencilMask);

-

-			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));

-			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));

-			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));

-        }

-        else

-        {

-			device->setStencilEnable(false);

-        }

-

-        mStencilStateDirty = false;

-        mFrontFaceDirty = false;

-    }

-

-    if(mMaskStateDirty)

-    {

-		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));

-		device->setDepthWriteEnable(mState.depthMask);

-

-        mMaskStateDirty = false;

-    }

-

-    if(mPolygonOffsetStateDirty)

-    {

-        if(mState.polygonOffsetFillEnabled)

-        {

-            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();

-            if(depthbuffer)

-            {

-				device->setSlopeDepthBias(mState.polygonOffsetFactor);

-                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));

-				device->setDepthBias(depthBias);

-            }

-        }

-        else

-        {

-            device->setSlopeDepthBias(0);

-            device->setDepthBias(0);

-        }

-

-        mPolygonOffsetStateDirty = false;

-    }

-

-    if(mSampleStateDirty)

-    {

-        if(mState.sampleAlphaToCoverageEnabled)

-        {

-            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);

-        }

-		else

-		{

-			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);

-		}

-

-        if(mState.sampleCoverageEnabled)

-        {

-            unsigned int mask = 0;

-            if(mState.sampleCoverageValue != 0)

-            {

-				int width, height, samples;

-				framebuffer->completeness(width, height, samples);

-

-                float threshold = 0.5f;

-

-                for(int i = 0; i < samples; i++)

-                {

-                    mask <<= 1;

-

-                    if((i + 1) * mState.sampleCoverageValue >= threshold)

-                    {

-                        threshold += 1.0f;

-                        mask |= 1;

-                    }

-                }

-            }

-

-            if(mState.sampleCoverageInvert)

-            {

-                mask = ~mask;

-            }

-

-			device->setMultiSampleMask(mask);

-        }

-        else

-        {

-			device->setMultiSampleMask(0xFFFFFFFF);

-        }

-

-        mSampleStateDirty = false;

-    }

-

-    if(mDitherStateDirty)

-    {

-    //	UNIMPLEMENTED();   // FIXME

-

-        mDitherStateDirty = false;

-    }

-

-	switch(mState.shadeModel)

-	{

-	default: UNREACHABLE(mState.shadeModel);

-	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;

-	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;

-	}

-

-	device->setLightingEnable(lightingEnabled);

-	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));

-

-	for(int i = 0; i < MAX_LIGHTS; i++)

-	{

-		device->setLightEnable(i, light[i].enabled);

-		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));

-		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));

-		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));

-		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);

-

-		if(light[i].position.w != 0.0f)

-		{

-			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));

-		}

-		else   // Directional light

-		{

-			// Hack: set the position far way

-			float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));

-			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));

-		}

-	}

-

-	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));

-	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));

-	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));

-	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));

-	device->setMaterialShininess(materialShininess);

-

-    device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);

-	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);

-	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);

-	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);

-

-	const sw::Matrix Z(1, 0, 0, 0,

-	                   0, 1, 0, 0,

-	                   0, 0, 0.5, 0.5,

-	                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]

-

-    device->setProjectionMatrix(Z * projectionStack.current());

-    device->setModelMatrix(modelViewStack.current());

-    device->setTextureMatrix(0, textureStack0.current());

-	device->setTextureMatrix(1, textureStack1.current());

-	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);

-	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);

-	device->setTexGen(0, sw::TEXGEN_NONE);

-	device->setTexGen(1, sw::TEXGEN_NONE);

-

-	device->setAlphaTestEnable(alphaTestEnabled);

-	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));

-	device->setAlphaReference(alphaTestRef * 0xFF);

-

-	device->setFogEnable(fogEnabled);

-	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));

-	device->setFogDensity(fogDensity);

-	device->setFogStart(fogStart);

-	device->setFogEnd(fogEnd);

-

-	switch(fogMode)

-	{

-	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;

-	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;

-	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;

-	default: UNREACHABLE(fogMode);

-	}

-

-	device->setColorLogicOpEnabled(colorLogicOpEnabled);

-	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));

-

-	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);

-}

-

-GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)

-{

-    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];

-

-    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);

-    if(err != GL_NO_ERROR)

-    {

-        return err;

-    }

-

-	device->resetInputStreams(false);

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-	{

-		sw::Resource *resource = attributes[i].vertexBuffer;

-		const void *buffer = (char*)resource->data() + attributes[i].offset;

-

-		int stride = attributes[i].stride;

-

-		buffer = (char*)buffer + stride * base;

-

-		sw::Stream attribute(resource, buffer, stride);

-

-		attribute.type = attributes[i].type;

-		attribute.count = attributes[i].count;

-		attribute.normalized = attributes[i].normalized;

-

-		device->setInputStream(i, attribute);

-	}

-

-	return GL_NO_ERROR;

-}

-

-// Applies the indices and element array bindings

-GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)

-{

-    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);

-

-    if(err == GL_NO_ERROR)

-    {

-        device->setIndexBuffer(indexInfo->indexBuffer);

-    }

-

-    return err;

-}

-

-void Context::applyTextures()

-{

-	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)

-    {

-        Texture *texture = nullptr;

-

-		if(textureExternalEnabled[unit])

-		{

-			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);

-		}

-		else if(texture2Denabled[unit])

-		{

-			texture = getSamplerTexture(unit, TEXTURE_2D);

-		}

-

-		if(texture && texture->isSamplerComplete())

-        {

-			texture->autoGenerateMipmaps();

-

-            GLenum wrapS = texture->getWrapS();

-            GLenum wrapT = texture->getWrapT();

-            GLenum minFilter = texture->getMinFilter();

-            GLenum magFilter = texture->getMagFilter();

-			GLfloat maxAnisotropy = texture->getMaxAnisotropy();

-

-			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));

-            device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));

-

-			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));

-			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));

-			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);

-

-			applyTexture(unit, texture);

-

-			device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));

-

-			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)

-			{

-				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs

-				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp

-				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc

-				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-

-				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As

-				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap

-				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac

-				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-

-				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);

-

-				switch(mState.textureUnit[unit].environmentMode)

-				{

-				case GL_REPLACE:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = As

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cs, Av = As

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_MODULATE:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = CpCs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = CpCs, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_DECAL:

-					if(texFormat == GL_ALPHA ||

-					   texFormat == GL_LUMINANCE ||

-					   texFormat == GL_LUMINANCE_ALPHA)

-					{

-						// undefined   // FIXME: Log

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cp(1 - As) + CsAs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_BLEND:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cp(1 - Cs) + CcCs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				case GL_ADD:

-					if(IsAlpha(texFormat))   // GL_ALPHA

-					{

-						// Cv = Cp, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)

-					{

-						// Cv = Cp + Cs, Av = Ap

-						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);

-					}

-					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)

-					{

-						// Cv = Cp + Cs, Av = ApAs

-						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);

-						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);

-					}

-					else UNREACHABLE(texFormat);

-					break;

-				default:

-					UNREACHABLE(mState.textureUnit[unit].environmentMode);

-				}

-			}

-			else   // GL_COMBINE

-			{

-				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));

-				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));

-				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));

-				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));

-				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));

-				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));

-

-				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));

-

-				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));

-				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));

-				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));

-				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));

-				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));

-				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));

-

-				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));

-			}

-        }

-        else

-        {

-            applyTexture(unit, nullptr);

-

-			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);

-			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);

-			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);

-

-			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);

-			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);

-			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);

-        }

-    }

-}

-

-void Context::setTextureEnvMode(GLenum texEnvMode)

-{

-	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;

-}

-

-void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};

-}

-

-void Context::setCombineRGB(GLenum combineRGB)

-{

-	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;

-}

-

-void Context::setCombineAlpha(GLenum combineAlpha)

-{

-	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;

-}

-

-void Context::setOperand0RGB(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand0RGB = operand;

-}

-

-void Context::setOperand1RGB(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand1RGB = operand;

-}

-

-void Context::setOperand2RGB(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand2RGB = operand;

-}

-

-void Context::setOperand0Alpha(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand0Alpha = operand;

-}

-

-void Context::setOperand1Alpha(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand1Alpha = operand;

-}

-

-void Context::setOperand2Alpha(GLenum operand)

-{

-	mState.textureUnit[mState.activeSampler].operand2Alpha = operand;

-}

-

-void Context::setSrc0RGB(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src0RGB = src;

-}

-

-void Context::setSrc1RGB(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src1RGB = src;

-}

-

-void Context::setSrc2RGB(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src2RGB = src;

-}

-

-void Context::setSrc0Alpha(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src0Alpha = src;

-}

-

-void Context::setSrc1Alpha(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src1Alpha = src;

-}

-

-void Context::setSrc2Alpha(GLenum src)

-{

-	mState.textureUnit[mState.activeSampler].src2Alpha = src;

-}

-

-void Context::applyTexture(int index, Texture *baseTexture)

-{

-	sw::Resource *resource = 0;

-

-	if(baseTexture)

-	{

-		resource = baseTexture->getResource();

-	}

-

-	device->setTextureResource(index, resource);

-

-	if(baseTexture)

-	{

-		int levelCount = baseTexture->getLevelCount();

-

-		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)

-		{

-			Texture2D *texture = static_cast<Texture2D*>(baseTexture);

-

-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)

-			{

-				int surfaceLevel = mipmapLevel;

-

-				if(surfaceLevel < 0)

-				{

-					surfaceLevel = 0;

-				}

-				else if(surfaceLevel >= levelCount)

-				{

-					surfaceLevel = levelCount - 1;

-				}

-

-				egl::Image *surface = texture->getImage(surfaceLevel);

-				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);

-			}

-		}

-		else UNIMPLEMENTED();

-	}

-	else

-	{

-		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);

-	}

-}

-

-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,

-                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)

-{

-    Framebuffer *framebuffer = getFramebuffer();

-	int framebufferWidth, framebufferHeight, framebufferSamples;

-

-    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-    }

-

-    if(getFramebufferName() != 0 && framebufferSamples != 0)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)

-	{

-		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-	}

-

-	GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);

-

-	// Sized query sanity check

-    if(bufSize)

-    {

-        int requiredSize = outputPitch * height;

-        if(requiredSize > *bufSize)

-        {

-            return error(GL_INVALID_OPERATION);

-        }

-    }

-

-    egl::Image *renderTarget = framebuffer->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect rect = {x, y, x + width, y + height};

-	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

-

-    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);

-    unsigned char *dest = (unsigned char*)pixels;

-    int inputPitch = (int)renderTarget->getPitch();

-

-    for(int j = 0; j < rect.y1 - rect.y0; j++)

-    {

-		unsigned short *dest16 = (unsigned short*)dest;

-		unsigned int *dest32 = (unsigned int*)dest;

-

-		if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&

-           format == GL_RGBA && type == GL_UNSIGNED_BYTE)

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 4);

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&

-                format == GL_RGBA && type == GL_UNSIGNED_BYTE)

-        {

-            for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				unsigned int argb = *(unsigned int*)(source + 4 * i);

-

-				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);

-			}

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&

-                format == GL_RGBA && type == GL_UNSIGNED_BYTE)

-        {

-            for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				unsigned int xrgb = *(unsigned int*)(source + 4 * i);

-

-				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;

-			}

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&

-                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)

-        {

-            for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				unsigned int xrgb = *(unsigned int*)(source + 4 * i);

-

-				dest32[i] = xrgb | 0xFF000000;

-			}

-        }

-        else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&

-                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 4);

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&

-                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 2);

-        }

-		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&

-                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT

-        {

-            memcpy(dest, source, (rect.x1 - rect.x0) * 2);

-        }

-		else

-		{

-			for(int i = 0; i < rect.x1 - rect.x0; i++)

-			{

-				float r;

-				float g;

-				float b;

-				float a;

-

-				switch(renderTarget->getInternalFormat())

-				{

-				case sw::FORMAT_R5G6B5:

-					{

-						unsigned short rgb = *(unsigned short*)(source + 2 * i);

-

-						a = 1.0f;

-						b = (rgb & 0x001F) * (1.0f / 0x001F);

-						g = (rgb & 0x07E0) * (1.0f / 0x07E0);

-						r = (rgb & 0xF800) * (1.0f / 0xF800);

-					}

-					break;

-				case sw::FORMAT_A1R5G5B5:

-					{

-						unsigned short argb = *(unsigned short*)(source + 2 * i);

-

-						a = (argb & 0x8000) ? 1.0f : 0.0f;

-						b = (argb & 0x001F) * (1.0f / 0x001F);

-						g = (argb & 0x03E0) * (1.0f / 0x03E0);

-						r = (argb & 0x7C00) * (1.0f / 0x7C00);

-					}

-					break;

-				case sw::FORMAT_A8R8G8B8:

-					{

-						unsigned int argb = *(unsigned int*)(source + 4 * i);

-

-						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);

-						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);

-						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);

-					}

-					break;

-				case sw::FORMAT_A8B8G8R8:

-					{

-						unsigned int abgr = *(unsigned int*)(source + 4 * i);

-

-						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);

-						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);

-						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);

-					}

-					break;

-				case sw::FORMAT_X8R8G8B8:

-					{

-						unsigned int xrgb = *(unsigned int*)(source + 4 * i);

-

-						a = 1.0f;

-						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);

-						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);

-					}

-					break;

-				case sw::FORMAT_X8B8G8R8:

-					{

-						unsigned int xbgr = *(unsigned int*)(source + 4 * i);

-

-						a = 1.0f;

-						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);

-						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);

-						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);

-					}

-					break;

-				case sw::FORMAT_A2R10G10B10:

-					{

-						unsigned int argb = *(unsigned int*)(source + 4 * i);

-

-						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);

-						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);

-						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);

-						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);

-					}

-					break;

-				default:

-					UNIMPLEMENTED();   // FIXME

-					UNREACHABLE(renderTarget->getInternalFormat());

-				}

-

-				switch(format)

-				{

-				case GL_RGBA:

-					switch(type)

-					{

-					case GL_UNSIGNED_BYTE:

-						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);

-						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);

-						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);

-						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				case GL_BGRA_EXT:

-					switch(type)

-					{

-					case GL_UNSIGNED_BYTE:

-						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);

-						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);

-						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);

-						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);

-						break;

-					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:

-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section

-						// this type is packed as follows:

-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0

-						//  --------------------------------------------------------------------------------

-						// |       4th         |        3rd         |        2nd        |   1st component   |

-						//  --------------------------------------------------------------------------------

-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.

-						dest16[i] =

-							((unsigned short)(15 * a + 0.5f) << 12)|

-							((unsigned short)(15 * r + 0.5f) << 8) |

-							((unsigned short)(15 * g + 0.5f) << 4) |

-							((unsigned short)(15 * b + 0.5f) << 0);

-						break;

-					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:

-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section

-						// this type is packed as follows:

-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0

-						//  --------------------------------------------------------------------------------

-						// | 4th |          3rd           |           2nd          |      1st component     |

-						//  --------------------------------------------------------------------------------

-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.

-						dest16[i] =

-							((unsigned short)(     a + 0.5f) << 15) |

-							((unsigned short)(31 * r + 0.5f) << 10) |

-							((unsigned short)(31 * g + 0.5f) << 5) |

-							((unsigned short)(31 * b + 0.5f) << 0);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				case GL_RGB:

-					switch(type)

-					{

-					case GL_UNSIGNED_SHORT_5_6_5:

-						dest16[i] =

-							((unsigned short)(31 * b + 0.5f) << 0) |

-							((unsigned short)(63 * g + 0.5f) << 5) |

-							((unsigned short)(31 * r + 0.5f) << 11);

-						break;

-					default: UNREACHABLE(type);

-					}

-					break;

-				default: UNREACHABLE(format);

-				}

-			}

-        }

-

-		source += inputPitch;

-		dest += outputPitch;

-    }

-

-	renderTarget->unlock();

-	renderTarget->release();

-}

-

-void Context::clear(GLbitfield mask)

-{

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)

-    {

-        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    float depth = clamp01(mState.depthClearValue);

-    int stencil = mState.stencilClearValue & 0x000000FF;

-

-	if(mask & GL_COLOR_BUFFER_BIT)

-	{

-		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |

-		                        (mState.colorMaskGreen ? 0x2 : 0) |

-		                        (mState.colorMaskBlue ? 0x4 : 0) |

-		                        (mState.colorMaskAlpha ? 0x8 : 0);

-

-		if(rgbaMask != 0)

-		{

-			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);

-		}

-	}

-

-	if(mask & GL_DEPTH_BUFFER_BIT)

-	{

-		if(mState.depthMask != 0)

-		{

-			device->clearDepth(depth);

-		}

-	}

-

-	if(mask & GL_STENCIL_BUFFER_BIT)

-	{

-		if(mState.stencilWritemask != 0)

-		{

-			device->clearStencil(stencil, mState.stencilWritemask);

-		}

-	}

-}

-

-void Context::drawArrays(GLenum mode, GLint first, GLsizei count)

-{

-    sw::DrawType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-    GLenum err = applyVertexBuffer(0, first, count);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    applyTextures();

-

-    if(!cullSkipsDraw(mode))

-    {

-        device->drawPrimitive(primitiveType, primitiveCount);

-    }

-}

-

-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)

-{

-    if(!indices && !mState.elementArrayBuffer)

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    sw::DrawType primitiveType;

-    int primitiveCount;

-

-    if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))

-        return error(GL_INVALID_ENUM);

-

-    if(primitiveCount <= 0)

-    {

-        return;

-    }

-

-    if(!applyRenderTarget())

-    {

-        return;

-    }

-

-    applyState(mode);

-

-    TranslatedIndexData indexInfo;

-    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;

-    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);

-    if(err != GL_NO_ERROR)

-    {

-        return error(err);

-    }

-

-    applyTextures();

-

-    if(!cullSkipsDraw(mode))

-    {

-		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);

-    }

-}

-

-void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)

-{

-	es1::Framebuffer *framebuffer = getFramebuffer();

-	es1::Renderbuffer *renderbuffer = framebuffer->getColorbuffer();

-	float targetWidth = (float)renderbuffer->getWidth();

-	float targetHeight = (float)renderbuffer->getHeight();

-	float x0 = 2.0f * x / targetWidth - 1.0f;

-	float y0 = 2.0f * y / targetHeight - 1.0f;

-	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;

-	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;

-	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);

-

-	float vertices[][3] = {{x0, y0, Zw},

-						   {x0, y1, Zw},

-						   {x1, y0, Zw},

-						   {x1, y1, Zw}};

-

-	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented

-	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);

-	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);

-	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);

-	int Ucr = texture->getCropRectU();

-	int Vcr = texture->getCropRectV();

-	int Wcr = texture->getCropRectW();

-	int Hcr = texture->getCropRectH();

-

-	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},

-							{Ucr / textureWidth, (Vcr + Hcr) / textureHeight},

-							{(Ucr + Wcr) / textureWidth, Vcr / textureHeight},

-							{(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};

-

-	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];

-	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];

-	gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;

-	mState.arrayBuffer = nullptr;

-

-	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);

-	glEnableClientState(GL_VERTEX_ARRAY);

-	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);

-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

-

-	sw::Matrix P = projectionStack.current();

-	sw::Matrix M = modelViewStack.current();

-	sw::Matrix T = textureStack0.current();

-

-	projectionStack.identity();

-	modelViewStack.identity();

-	textureStack0.identity();

-

-	drawArrays(GL_TRIANGLE_STRIP, 0, 4);

-

-	// Restore state

-	mState.vertexAttribute[sw::Position] = oldPositionAttribute;

-	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;

-	mState.arrayBuffer = oldArrayBuffer;

-	oldArrayBuffer = nullptr;

-	oldPositionAttribute.mBoundBuffer = nullptr;

-	oldTexCoord0Attribute.mBoundBuffer = nullptr;

-	textureStack0.load(T);

-	modelViewStack.load(M);

-	projectionStack.load(P);

-}

-

-void Context::finish()

-{

-	device->finish();

-}

-

-void Context::flush()

-{

-    // We don't queue anything without processing it as fast as possible

-}

-

-void Context::recordInvalidEnum()

-{

-    mInvalidEnum = true;

-}

-

-void Context::recordInvalidValue()

-{

-    mInvalidValue = true;

-}

-

-void Context::recordInvalidOperation()

-{

-    mInvalidOperation = true;

-}

-

-void Context::recordOutOfMemory()

-{

-    mOutOfMemory = true;

-}

-

-void Context::recordInvalidFramebufferOperation()

-{

-    mInvalidFramebufferOperation = true;

-}

-

-void Context::recordMatrixStackOverflow()

-{

-    mMatrixStackOverflow = true;

-}

-

-void Context::recordMatrixStackUnderflow()

-{

-    mMatrixStackUnderflow = true;

-}

-

-// Get one of the recorded errors and clear its flag, if any.

-// [OpenGL ES 2.0.24] section 2.5 page 13.

-GLenum Context::getError()

-{

-    if(mInvalidEnum)

-    {

-        mInvalidEnum = false;

-

-        return GL_INVALID_ENUM;

-    }

-

-    if(mInvalidValue)

-    {

-        mInvalidValue = false;

-

-        return GL_INVALID_VALUE;

-    }

-

-    if(mInvalidOperation)

-    {

-        mInvalidOperation = false;

-

-        return GL_INVALID_OPERATION;

-    }

-

-    if(mOutOfMemory)

-    {

-        mOutOfMemory = false;

-

-        return GL_OUT_OF_MEMORY;

-    }

-

-    if(mInvalidFramebufferOperation)

-    {

-        mInvalidFramebufferOperation = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;

-    }

-

-	if(mMatrixStackOverflow)

-    {

-        mMatrixStackOverflow = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;

-    }

-

-	if(mMatrixStackUnderflow)

-    {

-        mMatrixStackUnderflow = false;

-

-        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;

-    }

-

-    return GL_NO_ERROR;

-}

-

-int Context::getSupportedMultisampleCount(int requested)

-{

-	int supported = 0;

-

-	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)

-	{

-		if(supported >= requested)

-		{

-			return supported;

-		}

-

-		supported = multisampleCount[i];

-	}

-

-	return supported;

-}

-

-void Context::detachBuffer(GLuint buffer)

-{

-    // [OpenGL ES 2.0.24] section 2.9 page 22:

-    // If a buffer object is deleted while it is bound, all bindings to that object in the current context

-    // (i.e. in the thread that called Delete-Buffers) are reset to zero.

-

-    if(mState.arrayBuffer.name() == buffer)

-    {

-        mState.arrayBuffer = nullptr;

-    }

-

-    if(mState.elementArrayBuffer.name() == buffer)

-    {

-        mState.elementArrayBuffer = nullptr;

-    }

-

-    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)

-    {

-        if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)

-        {

-            mState.vertexAttribute[attribute].mBoundBuffer = nullptr;

-        }

-    }

-}

-

-void Context::detachTexture(GLuint texture)

-{

-    // [OpenGL ES 2.0.24] section 3.8 page 84:

-    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are

-    // rebound to texture object zero

-

-    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)

-    {

-        for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)

-        {

-            if(mState.samplerTexture[type][sampler].name() == texture)

-            {

-                mState.samplerTexture[type][sampler] = nullptr;

-            }

-        }

-    }

-

-    // [OpenGL ES 2.0.24] section 4.4 page 112:

-    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is

-    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this

-    // image was attached in the currently bound framebuffer.

-

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(framebuffer)

-    {

-        framebuffer->detachTexture(texture);

-    }

-}

-

-void Context::detachFramebuffer(GLuint framebuffer)

-{

-    // [OpenGL ES 2.0.24] section 4.4 page 107:

-    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though

-    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.

-

-    if(mState.framebuffer == framebuffer)

-    {

-        bindFramebuffer(0);

-    }

-}

-

-void Context::detachRenderbuffer(GLuint renderbuffer)

-{

-    // [OpenGL ES 2.0.24] section 4.4 page 109:

-    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer

-    // had been executed with the target RENDERBUFFER and name of zero.

-

-    if(mState.renderbuffer.name() == renderbuffer)

-    {

-        bindRenderbuffer(0);

-    }

-

-    // [OpenGL ES 2.0.24] section 4.4 page 111:

-    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,

-    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment

-    // point to which this image was attached in the currently bound framebuffer.

-

-    Framebuffer *framebuffer = getFramebuffer();

-

-    if(framebuffer)

-    {

-        framebuffer->detachRenderbuffer(renderbuffer);

-    }

-}

-

-bool Context::cullSkipsDraw(GLenum drawMode)

-{

-    return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);

-}

-

-bool Context::isTriangleMode(GLenum drawMode)

-{

-    switch(drawMode)

-    {

-    case GL_TRIANGLES:

-    case GL_TRIANGLE_FAN:

-    case GL_TRIANGLE_STRIP:

-        return true;

-    case GL_POINTS:

-    case GL_LINES:

-    case GL_LINE_LOOP:

-    case GL_LINE_STRIP:

-        return false;

-    default: UNREACHABLE(drawMode);

-    }

-

-    return false;

-}

-

-void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

-{

-    ASSERT(index < MAX_VERTEX_ATTRIBS);

-

-    mState.vertexAttribute[index].mCurrentValue[0] = x;

-    mState.vertexAttribute[index].mCurrentValue[1] = y;

-    mState.vertexAttribute[index].mCurrentValue[2] = z;

-    mState.vertexAttribute[index].mCurrentValue[3] = w;

-

-    mVertexDataManager->dirtyCurrentValue(index);

-}

-

-void Context::bindTexImage(egl::Surface *surface)

-{

-	es1::Texture2D *textureObject = getTexture2D();

-

-    if(textureObject)

-    {

-		textureObject->bindTexImage(surface);

-	}

-}

-

-EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)

-{

-    switch(target)

-    {

-    case EGL_GL_TEXTURE_2D_KHR:

-        break;

-    case EGL_GL_RENDERBUFFER_KHR:

-        break;

-    default:

-        return EGL_BAD_PARAMETER;

-    }

-

-    if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-    {

-        return EGL_BAD_MATCH;

-    }

-

-	if(target == EGL_GL_TEXTURE_2D_KHR)

-    {

-        Texture *texture = getTexture(name);

-

-        if(!texture || texture->getTarget() != GL_TEXTURE_2D)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling

-        {

-            return EGL_BAD_ACCESS;

-        }

-

-        if(textureLevel != 0 && !texture->isSamplerComplete())

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))

-        {

-            return EGL_BAD_PARAMETER;

-        }

-    }

-    else if(target == EGL_GL_RENDERBUFFER_KHR)

-    {

-        Renderbuffer *renderbuffer = getRenderbuffer(name);

-

-        if(!renderbuffer)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(renderbuffer->isShared())   // Already an EGLImage sibling

-        {

-            return EGL_BAD_ACCESS;

-        }

-    }

-    else UNREACHABLE(target);

-

-	return EGL_SUCCESS;

-}

-

-egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)

-{

-    if(target == EGL_GL_TEXTURE_2D_KHR)

-    {

-        es1::Texture *texture = getTexture(name);

-

-        return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);

-    }

-    else if(target == EGL_GL_RENDERBUFFER_KHR)

-    {

-        es1::Renderbuffer *renderbuffer = getRenderbuffer(name);

-

-        return renderbuffer->createSharedImage();

-    }

-    else UNREACHABLE(target);

-

-	return 0;

-}

-

-Device *Context::getDevice()

-{

-	return device;

-}

-

-void Context::setMatrixMode(GLenum mode)

-{

-    matrixMode = mode;

-}

-

-sw::MatrixStack &Context::currentMatrixStack()

-{

-	switch(matrixMode)

-	{

-	case GL_MODELVIEW:

-		return modelViewStack;

-	case GL_PROJECTION:

-		return projectionStack;

-	case GL_TEXTURE:

-		switch(mState.activeSampler)

-		{

-		case 0: return textureStack0;

-		case 1: return textureStack1;

-		}

-		break;

-	}

-

-	UNREACHABLE(matrixMode);

-	return textureStack0;

-}

-

-void Context::loadIdentity()

-{

-	currentMatrixStack().identity();

-}

-

-void Context::load(const GLfloat *m)

-{

-    currentMatrixStack().load(m);

-}

-

-void Context::pushMatrix()

-{

-	if(!currentMatrixStack().push())

-	{

-		return error(GL_STACK_OVERFLOW);

-	}

-}

-

-void Context::popMatrix()

-{

-    if(!currentMatrixStack().pop())

-	{

-		return error(GL_STACK_OVERFLOW);

-	}

-}

-

-void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-    currentMatrixStack().rotate(angle, x, y, z);

-}

-

-void Context::translate(GLfloat x, GLfloat y, GLfloat z)

-{

-    currentMatrixStack().translate(x, y, z);

-}

-

-void Context::scale(GLfloat x, GLfloat y, GLfloat z)

-{

-    currentMatrixStack().scale(x, y, z);

-}

-

-void Context::multiply(const GLfloat *m)

-{

-    currentMatrixStack().multiply(m);

-}

-

-void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);

-}

-

-void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);

-}

-

-void Context::setClipPlane(int index, const float plane[4])

-{

-	sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);

-	device->setClipPlane(index, &clipPlane.A);

-}

-

-void Context::setClipPlaneEnabled(int index, bool enable)

-{

-	clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);

-	device->setClipFlags(clipFlags);

-}

-

-bool Context::isClipPlaneEnabled(int index) const

-{

-	return (clipFlags & (1 << index)) != 0;

-}

-

-void Context::setColorLogicOpEnabled(bool enable)

-{

-	colorLogicOpEnabled = enable;

-}

-

-bool Context::isColorLogicOpEnabled() const

-{

-	return colorLogicOpEnabled;

-}

-

-void Context::setLogicalOperation(GLenum logicOp)

-{

-	logicalOperation = logicOp;

-}

-

-void Context::setLineSmoothEnabled(bool enable)

-{

-	lineSmoothEnabled = enable;

-}

-

-bool Context::isLineSmoothEnabled() const

-{

-	return lineSmoothEnabled;

-}

-

-void Context::setColorMaterialEnabled(bool enable)

-{

-	colorMaterialEnabled = enable;

-}

-

-bool Context::isColorMaterialEnabled() const

-{

-	return colorMaterialEnabled;

-}

-

-void Context::setNormalizeEnabled(bool enable)

-{

-	normalizeEnabled = enable;

-}

-

-bool Context::isNormalizeEnabled() const

-{

-	return normalizeEnabled;

-}

-

-void Context::setRescaleNormalEnabled(bool enable)

-{

-	rescaleNormalEnabled = enable;

-}

-

-bool Context::isRescaleNormalEnabled() const

-{

-	return rescaleNormalEnabled;

-}

-

-void Context::setVertexArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;

-}

-

-bool Context::isVertexArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::Position].mArrayEnabled;

-}

-

-void Context::setNormalArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;

-}

-

-bool Context::isNormalArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::Normal].mArrayEnabled;

-}

-

-void Context::setColorArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;

-}

-

-bool Context::isColorArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::Color0].mArrayEnabled;

-}

-

-void Context::setPointSizeArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;

-}

-

-bool Context::isPointSizeArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;

-}

-

-void Context::setTextureCoordArrayEnabled(bool enable)

-{

-	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;

-}

-

-bool Context::isTextureCoordArrayEnabled() const

-{

-	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;

-}

-

-void Context::setMultisampleEnabled(bool enable)

-{

-	multisampleEnabled = enable;

-}

-

-bool Context::isMultisampleEnabled() const

-{

-	return multisampleEnabled;

-}

-

-void Context::setSampleAlphaToOneEnabled(bool enable)

-{

-	sampleAlphaToOneEnabled = enable;

-}

-

-bool Context::isSampleAlphaToOneEnabled() const

-{

-	return sampleAlphaToOneEnabled;

-}

-

-void Context::setPointSpriteEnabled(bool enable)

-{

-	pointSpriteEnabled = enable;

-}

-

-bool Context::isPointSpriteEnabled() const

-{

-	return pointSpriteEnabled;

-}

-

-void Context::setPointSmoothEnabled(bool enable)

-{

-	pointSmoothEnabled = enable;

-}

-

-bool Context::isPointSmoothEnabled() const

-{

-	return pointSmoothEnabled;

-}

-

-

-void Context::setPointSizeMin(float min)

-{

-	pointSizeMin = min;

-}

-

-void Context::setPointSizeMax(float max)

-{

-	pointSizeMax = max;

-}

-

-void Context::setPointDistanceAttenuation(float a, float b, float c)

-{

-	pointDistanceAttenuation = {a, b, c};

-}

-

-void Context::setPointFadeThresholdSize(float threshold)

-{

-	pointFadeThresholdSize = threshold;

-}

-

-void Context::clientActiveTexture(GLenum texture)

-{

-	clientTexture = texture;

-}

-

-GLenum Context::getClientActiveTexture() const

-{

-	return clientTexture;

-}

-

-unsigned int Context::getActiveTexture() const

-{

-	return mState.activeSampler;

-}

-

-}

-

-egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)

-{

-	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext

-	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));

-}

+// 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.
+
+// Context.cpp: Implements the es1::Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#include "Context.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "ResourceManager.h"
+#include "Buffer.h"
+#include "Framebuffer.h"
+#include "Renderbuffer.h"
+#include "Texture.h"
+#include "VertexDataManager.h"
+#include "IndexDataManager.h"
+#include "libEGL/Display.h"
+#include "libEGL/Surface.h"
+#include "Common/Half.hpp"
+
+#include <EGL/eglext.h>
+
+using std::abs;
+
+namespace es1
+{
+Context::Context(const egl::Config *config, const Context *shareContext)
+	: modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
+	  projectionStack(MAX_PROJECTION_STACK_DEPTH),
+	  textureStack0(MAX_TEXTURE_STACK_DEPTH),
+	  textureStack1(MAX_TEXTURE_STACK_DEPTH)
+{
+	sw::Context *context = new sw::Context();
+	device = new es1::Device(context);
+
+	mVertexDataManager = new VertexDataManager(this);
+	mIndexDataManager = new IndexDataManager();
+
+	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+	mState.depthClearValue = 1.0f;
+	mState.stencilClearValue = 0;
+
+	mState.cullFaceEnabled = false;
+	mState.cullMode = GL_BACK;
+	mState.frontFace = GL_CCW;
+	mState.depthTestEnabled = false;
+	mState.depthFunc = GL_LESS;
+	mState.blendEnabled = false;
+	mState.sourceBlendRGB = GL_ONE;
+	mState.sourceBlendAlpha = GL_ONE;
+	mState.destBlendRGB = GL_ZERO;
+	mState.destBlendAlpha = GL_ZERO;
+	mState.blendEquationRGB = GL_FUNC_ADD_OES;
+	mState.blendEquationAlpha = GL_FUNC_ADD_OES;
+	mState.stencilTestEnabled = false;
+	mState.stencilFunc = GL_ALWAYS;
+	mState.stencilRef = 0;
+	mState.stencilMask = -1;
+	mState.stencilWritemask = -1;
+	mState.stencilFail = GL_KEEP;
+	mState.stencilPassDepthFail = GL_KEEP;
+	mState.stencilPassDepthPass = GL_KEEP;
+	mState.polygonOffsetFillEnabled = false;
+	mState.polygonOffsetFactor = 0.0f;
+	mState.polygonOffsetUnits = 0.0f;
+	mState.sampleAlphaToCoverageEnabled = false;
+	mState.sampleCoverageEnabled = false;
+	mState.sampleCoverageValue = 1.0f;
+	mState.sampleCoverageInvert = false;
+	mState.scissorTestEnabled = false;
+	mState.ditherEnabled = true;
+	mState.shadeModel = GL_SMOOTH;
+	mState.generateMipmapHint = GL_DONT_CARE;
+	mState.perspectiveCorrectionHint = GL_DONT_CARE;
+	mState.fogHint = GL_DONT_CARE;
+
+	mState.lineWidth = 1.0f;
+
+	mState.viewportX = 0;
+	mState.viewportY = 0;
+	mState.viewportWidth = 0;
+	mState.viewportHeight = 0;
+	mState.zNear = 0.0f;
+	mState.zFar = 1.0f;
+
+	mState.scissorX = 0;
+	mState.scissorY = 0;
+	mState.scissorWidth = 0;
+	mState.scissorHeight = 0;
+
+	mState.colorMaskRed = true;
+	mState.colorMaskGreen = true;
+	mState.colorMaskBlue = true;
+	mState.colorMaskAlpha = true;
+	mState.depthMask = true;
+
+	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
+	{
+		mState.textureUnit[i].color = {0, 0, 0, 0};
+		mState.textureUnit[i].environmentMode = GL_MODULATE;
+		mState.textureUnit[i].combineRGB = GL_MODULATE;
+		mState.textureUnit[i].combineAlpha = GL_MODULATE;
+		mState.textureUnit[i].src0RGB = GL_TEXTURE;
+		mState.textureUnit[i].src1RGB = GL_PREVIOUS;
+		mState.textureUnit[i].src2RGB = GL_CONSTANT;
+		mState.textureUnit[i].src0Alpha = GL_TEXTURE;
+		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;
+		mState.textureUnit[i].src2Alpha = GL_CONSTANT;
+		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;
+		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;
+		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;
+		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;
+		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;
+		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;
+	}
+
+	if(shareContext)
+	{
+		mResourceManager = shareContext->mResourceManager;
+		mResourceManager->addRef();
+	}
+	else
+	{
+		mResourceManager = new ResourceManager();
+	}
+
+	// [OpenGL ES 2.0.24] section 3.7 page 83:
+	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
+	// and cube map texture state vectors respectively associated with them.
+	// In order that access to these initial textures not be lost, they are treated as texture
+	// objects all of whose names are 0.
+
+	mTexture2DZero = new Texture2D(0);
+	mTextureExternalZero = new TextureExternal(0);
+
+	mState.activeSampler = 0;
+	bindArrayBuffer(0);
+	bindElementArrayBuffer(0);
+	bindTexture2D(0);
+	bindFramebuffer(0);
+	bindRenderbuffer(0);
+
+	mState.packAlignment = 4;
+	mState.unpackAlignment = 4;
+
+	mInvalidEnum = false;
+	mInvalidValue = false;
+	mInvalidOperation = false;
+	mOutOfMemory = false;
+	mInvalidFramebufferOperation = false;
+	mMatrixStackOverflow = false;
+	mMatrixStackUnderflow = false;
+
+	lightingEnabled = false;
+
+	for(int i = 0; i < MAX_LIGHTS; i++)
+	{
+		light[i].enabled = false;
+		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
+		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
+		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
+		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
+		light[i].direction = {0.0f, 0.0f, -1.0f};
+		light[i].attenuation = {1.0f, 0.0f, 0.0f};
+		light[i].spotExponent = 0.0f;
+		light[i].spotCutoffAngle = 180.0f;
+	}
+
+	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
+	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
+
+	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
+	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
+	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
+	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
+	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
+	materialShininess = 0.0f;
+	lightModelTwoSide = false;
+
+	matrixMode = GL_MODELVIEW;
+
+	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
+	{
+		texture2Denabled[i] = false;
+		textureExternalEnabled[i] = false;
+	}
+
+	clientTexture = GL_TEXTURE0;
+
+	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);
+
+	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
+	{
+		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);
+	}
+
+	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);
+	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);
+
+	clipFlags = 0;
+
+	alphaTestEnabled = false;
+	alphaTestFunc = GL_ALWAYS;
+	alphaTestRef = 0;
+
+	fogEnabled = false;
+	fogMode = GL_EXP;
+	fogDensity = 1.0f;
+	fogStart = 0.0f;
+	fogEnd = 1.0f;
+	fogColor = {0, 0, 0, 0};
+
+	lineSmoothEnabled = false;
+	colorMaterialEnabled = false;
+	normalizeEnabled = false;
+	rescaleNormalEnabled = false;
+	multisampleEnabled = true;
+	sampleAlphaToOneEnabled = false;
+
+	colorLogicOpEnabled = false;
+	logicalOperation = GL_COPY;
+
+	pointSpriteEnabled = false;
+	pointSmoothEnabled = false;
+	pointSizeMin = 0.0f;
+	pointSizeMax = 1.0f;
+	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};
+	pointFadeThresholdSize = 1.0f;
+
+	mHasBeenCurrent = false;
+
+	markAllStateDirty();
+}
+
+Context::~Context()
+{
+	while(!mFramebufferNameSpace.empty())
+	{
+		deleteFramebuffer(mFramebufferNameSpace.firstName());
+	}
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
+		{
+			mState.samplerTexture[type][sampler] = nullptr;
+		}
+	}
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mState.vertexAttribute[i].mBoundBuffer = nullptr;
+	}
+
+	mState.arrayBuffer = nullptr;
+	mState.elementArrayBuffer = nullptr;
+	mState.renderbuffer = nullptr;
+
+	mTexture2DZero = nullptr;
+	mTextureExternalZero = nullptr;
+
+	delete mVertexDataManager;
+	delete mIndexDataManager;
+
+	mResourceManager->release();
+	delete device;
+}
+
+void Context::makeCurrent(egl::Surface *surface)
+{
+	if(!mHasBeenCurrent)
+	{
+		mState.viewportX = 0;
+		mState.viewportY = 0;
+		mState.viewportWidth = surface->getWidth();
+		mState.viewportHeight = surface->getHeight();
+
+		mState.scissorX = 0;
+		mState.scissorY = 0;
+		mState.scissorWidth = surface->getWidth();
+		mState.scissorHeight = surface->getHeight();
+
+		mHasBeenCurrent = true;
+	}
+
+	// Wrap the existing resources into GL objects and assign them to the '0' names
+	egl::Image *defaultRenderTarget = surface->getRenderTarget();
+	egl::Image *depthStencil = surface->getDepthStencil();
+
+	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
+	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+
+	setFramebufferZero(framebufferZero);
+
+	if(defaultRenderTarget)
+	{
+		defaultRenderTarget->release();
+	}
+
+	if(depthStencil)
+	{
+		depthStencil->release();
+	}
+
+	markAllStateDirty();
+}
+
+int Context::getClientVersion() const
+{
+	return 1;
+}
+
+// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
+void Context::markAllStateDirty()
+{
+	mDepthStateDirty = true;
+	mMaskStateDirty = true;
+	mBlendStateDirty = true;
+	mStencilStateDirty = true;
+	mPolygonOffsetStateDirty = true;
+	mSampleStateDirty = true;
+	mDitherStateDirty = true;
+	mFrontFaceDirty = true;
+}
+
+void Context::setClearColor(float red, float green, float blue, float alpha)
+{
+	mState.colorClearValue.red = red;
+	mState.colorClearValue.green = green;
+	mState.colorClearValue.blue = blue;
+	mState.colorClearValue.alpha = alpha;
+}
+
+void Context::setClearDepth(float depth)
+{
+	mState.depthClearValue = depth;
+}
+
+void Context::setClearStencil(int stencil)
+{
+	mState.stencilClearValue = stencil;
+}
+
+void Context::setCullFaceEnabled(bool enabled)
+{
+	mState.cullFaceEnabled = enabled;
+}
+
+bool Context::isCullFaceEnabled() const
+{
+	return mState.cullFaceEnabled;
+}
+
+void Context::setCullMode(GLenum mode)
+{
+   mState.cullMode = mode;
+}
+
+void Context::setFrontFace(GLenum front)
+{
+	if(mState.frontFace != front)
+	{
+		mState.frontFace = front;
+		mFrontFaceDirty = true;
+	}
+}
+
+void Context::setDepthTestEnabled(bool enabled)
+{
+	if(mState.depthTestEnabled != enabled)
+	{
+		mState.depthTestEnabled = enabled;
+		mDepthStateDirty = true;
+	}
+}
+
+bool Context::isDepthTestEnabled() const
+{
+	return mState.depthTestEnabled;
+}
+
+void Context::setDepthFunc(GLenum depthFunc)
+{
+	if(mState.depthFunc != depthFunc)
+	{
+		mState.depthFunc = depthFunc;
+		mDepthStateDirty = true;
+	}
+}
+
+void Context::setDepthRange(float zNear, float zFar)
+{
+	mState.zNear = zNear;
+	mState.zFar = zFar;
+}
+
+void Context::setAlphaTestEnabled(bool enabled)
+{
+	alphaTestEnabled = enabled;
+}
+
+bool Context::isAlphaTestEnabled() const
+{
+	return alphaTestEnabled;
+}
+
+void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)
+{
+	alphaTestFunc = alphaFunc;
+	alphaTestRef = reference;
+}
+
+void Context::setBlendEnabled(bool enabled)
+{
+	if(mState.blendEnabled != enabled)
+	{
+		mState.blendEnabled = enabled;
+		mBlendStateDirty = true;
+	}
+}
+
+bool Context::isBlendEnabled() const
+{
+	return mState.blendEnabled;
+}
+
+void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
+{
+	if(mState.sourceBlendRGB != sourceRGB ||
+	   mState.sourceBlendAlpha != sourceAlpha ||
+	   mState.destBlendRGB != destRGB ||
+	   mState.destBlendAlpha != destAlpha)
+	{
+		mState.sourceBlendRGB = sourceRGB;
+		mState.destBlendRGB = destRGB;
+		mState.sourceBlendAlpha = sourceAlpha;
+		mState.destBlendAlpha = destAlpha;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
+{
+	if(mState.blendEquationRGB != rgbEquation ||
+	   mState.blendEquationAlpha != alphaEquation)
+	{
+		mState.blendEquationRGB = rgbEquation;
+		mState.blendEquationAlpha = alphaEquation;
+		mBlendStateDirty = true;
+	}
+}
+
+void Context::setStencilTestEnabled(bool enabled)
+{
+	if(mState.stencilTestEnabled != enabled)
+	{
+		mState.stencilTestEnabled = enabled;
+		mStencilStateDirty = true;
+	}
+}
+
+bool Context::isStencilTestEnabled() const
+{
+	return mState.stencilTestEnabled;
+}
+
+void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
+{
+	if(mState.stencilFunc != stencilFunc ||
+	   mState.stencilRef != stencilRef ||
+	   mState.stencilMask != stencilMask)
+	{
+		mState.stencilFunc = stencilFunc;
+		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
+		mState.stencilMask = stencilMask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilWritemask(GLuint stencilWritemask)
+{
+	if(mState.stencilWritemask != stencilWritemask)
+	{
+		mState.stencilWritemask = stencilWritemask;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
+{
+	if(mState.stencilFail != stencilFail ||
+	   mState.stencilPassDepthFail != stencilPassDepthFail ||
+	   mState.stencilPassDepthPass != stencilPassDepthPass)
+	{
+		mState.stencilFail = stencilFail;
+		mState.stencilPassDepthFail = stencilPassDepthFail;
+		mState.stencilPassDepthPass = stencilPassDepthPass;
+		mStencilStateDirty = true;
+	}
+}
+
+void Context::setPolygonOffsetFillEnabled(bool enabled)
+{
+	if(mState.polygonOffsetFillEnabled != enabled)
+	{
+		mState.polygonOffsetFillEnabled = enabled;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+bool Context::isPolygonOffsetFillEnabled() const
+{
+	return mState.polygonOffsetFillEnabled;
+}
+
+void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
+{
+	if(mState.polygonOffsetFactor != factor ||
+	   mState.polygonOffsetUnits != units)
+	{
+		mState.polygonOffsetFactor = factor;
+		mState.polygonOffsetUnits = units;
+		mPolygonOffsetStateDirty = true;
+	}
+}
+
+void Context::setSampleAlphaToCoverageEnabled(bool enabled)
+{
+	if(mState.sampleAlphaToCoverageEnabled != enabled)
+	{
+		mState.sampleAlphaToCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleAlphaToCoverageEnabled() const
+{
+	return mState.sampleAlphaToCoverageEnabled;
+}
+
+void Context::setSampleCoverageEnabled(bool enabled)
+{
+	if(mState.sampleCoverageEnabled != enabled)
+	{
+		mState.sampleCoverageEnabled = enabled;
+		mSampleStateDirty = true;
+	}
+}
+
+bool Context::isSampleCoverageEnabled() const
+{
+	return mState.sampleCoverageEnabled;
+}
+
+void Context::setSampleCoverageParams(GLclampf value, bool invert)
+{
+	if(mState.sampleCoverageValue != value ||
+	   mState.sampleCoverageInvert != invert)
+	{
+		mState.sampleCoverageValue = value;
+		mState.sampleCoverageInvert = invert;
+		mSampleStateDirty = true;
+	}
+}
+
+void Context::setScissorTestEnabled(bool enabled)
+{
+	mState.scissorTestEnabled = enabled;
+}
+
+bool Context::isScissorTestEnabled() const
+{
+	return mState.scissorTestEnabled;
+}
+
+void Context::setShadeModel(GLenum mode)
+{
+	mState.shadeModel = mode;
+}
+
+void Context::setDitherEnabled(bool enabled)
+{
+	if(mState.ditherEnabled != enabled)
+	{
+		mState.ditherEnabled = enabled;
+		mDitherStateDirty = true;
+	}
+}
+
+bool Context::isDitherEnabled() const
+{
+	return mState.ditherEnabled;
+}
+
+void Context::setLightingEnabled(bool enable)
+{
+	lightingEnabled = enable;
+}
+
+bool Context::isLightingEnabled() const
+{
+	return lightingEnabled;
+}
+
+void Context::setLightEnabled(int index, bool enable)
+{
+	light[index].enabled = enable;
+}
+
+bool Context::isLightEnabled(int index) const
+{
+	return light[index].enabled;
+}
+
+void Context::setLightAmbient(int index, float r, float g, float b, float a)
+{
+	light[index].ambient = {r, g, b, a};
+}
+
+void Context::setLightDiffuse(int index, float r, float g, float b, float a)
+{
+	light[index].diffuse = {r, g, b, a};
+}
+
+void Context::setLightSpecular(int index, float r, float g, float b, float a)
+{
+	light[index].specular = {r, g, b, a};
+}
+
+void Context::setLightPosition(int index, float x, float y, float z, float w)
+{
+	sw::float4 v = {x, y, z, w};
+
+	// Transform from object coordinates to eye coordinates
+	v = modelViewStack.current() * v;
+
+	light[index].position = {v.x, v.y, v.z, v.w};
+}
+
+void Context::setLightDirection(int index, float x, float y, float z)
+{
+	// FIXME: Transform by inverse of 3x3 model-view matrix
+	light[index].direction = {x, y, z};
+}
+
+void Context::setLightAttenuationConstant(int index, float constant)
+{
+	light[index].attenuation.constant = constant;
+}
+
+void Context::setLightAttenuationLinear(int index, float linear)
+{
+	light[index].attenuation.linear = linear;
+}
+
+void Context::setLightAttenuationQuadratic(int index, float quadratic)
+{
+	light[index].attenuation.quadratic = quadratic;
+}
+
+void Context::setSpotLightExponent(int index, float exponent)
+{
+	light[index].spotExponent = exponent;
+}
+
+void Context::setSpotLightCutoff(int index, float cutoff)
+{
+	light[index].spotCutoffAngle = cutoff;
+}
+
+void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
+{
+	globalAmbient.red = red;
+	globalAmbient.green = green;
+	globalAmbient.blue = blue;
+	globalAmbient.alpha = alpha;
+}
+
+void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
+{
+	materialAmbient.red = red;
+	materialAmbient.green = green;
+	materialAmbient.blue = blue;
+	materialAmbient.alpha = alpha;
+}
+
+void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
+{
+	materialDiffuse.red = red;
+	materialDiffuse.green = green;
+	materialDiffuse.blue = blue;
+	materialDiffuse.alpha = alpha;
+}
+
+void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
+{
+	materialSpecular.red = red;
+	materialSpecular.green = green;
+	materialSpecular.blue = blue;
+	materialSpecular.alpha = alpha;
+}
+
+void Context::setMaterialEmission(float red, float green, float blue, float alpha)
+{
+	materialEmission.red = red;
+	materialEmission.green = green;
+	materialEmission.blue = blue;
+	materialEmission.alpha = alpha;
+}
+
+void Context::setMaterialShininess(float shininess)
+{
+	materialShininess = shininess;
+}
+
+void Context::setLightModelTwoSide(bool enable)
+{
+	lightModelTwoSide = enable;
+}
+
+void Context::setFogEnabled(bool enable)
+{
+	fogEnabled = enable;
+}
+
+bool Context::isFogEnabled() const
+{
+	return fogEnabled;
+}
+
+void Context::setFogMode(GLenum mode)
+{
+	fogMode = mode;
+}
+
+void Context::setFogDensity(float fogDensity)
+{
+	this->fogDensity = fogDensity;
+}
+
+void Context::setFogStart(float fogStart)
+{
+	this->fogStart = fogStart;
+}
+
+void Context::setFogEnd(float fogEnd)
+{
+	this->fogEnd = fogEnd;
+}
+
+void Context::setFogColor(float r, float g, float b, float a)
+{
+	this->fogColor = {r, g, b, a};
+}
+
+void Context::setTexture2Denabled(bool enable)
+{
+	texture2Denabled[mState.activeSampler] = enable;
+}
+
+bool Context::isTexture2Denabled() const
+{
+	return texture2Denabled[mState.activeSampler];
+}
+
+void Context::setTextureExternalEnabled(bool enable)
+{
+	textureExternalEnabled[mState.activeSampler] = enable;
+}
+
+bool Context::isTextureExternalEnabled() const
+{
+	return textureExternalEnabled[mState.activeSampler];
+}
+
+void Context::setLineWidth(GLfloat width)
+{
+	mState.lineWidth = width;
+	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
+}
+
+void Context::setGenerateMipmapHint(GLenum hint)
+{
+	mState.generateMipmapHint = hint;
+}
+
+void Context::setPerspectiveCorrectionHint(GLenum hint)
+{
+	mState.perspectiveCorrectionHint = hint;
+}
+
+void Context::setFogHint(GLenum hint)
+{
+	mState.fogHint = hint;
+}
+
+void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.viewportX = x;
+	mState.viewportY = y;
+	mState.viewportWidth = width;
+	mState.viewportHeight = height;
+}
+
+void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	mState.scissorX = x;
+	mState.scissorY = y;
+	mState.scissorWidth = width;
+	mState.scissorHeight = height;
+}
+
+void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
+	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
+	{
+		mState.colorMaskRed = red;
+		mState.colorMaskGreen = green;
+		mState.colorMaskBlue = blue;
+		mState.colorMaskAlpha = alpha;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setDepthMask(bool mask)
+{
+	if(mState.depthMask != mask)
+	{
+		mState.depthMask = mask;
+		mMaskStateDirty = true;
+	}
+}
+
+void Context::setActiveSampler(unsigned int active)
+{
+	mState.activeSampler = active;
+}
+
+GLuint Context::getFramebufferName() const
+{
+	return mState.framebuffer;
+}
+
+GLuint Context::getRenderbufferName() const
+{
+	return mState.renderbuffer.name();
+}
+
+GLuint Context::getArrayBufferName() const
+{
+	return mState.arrayBuffer.name();
+}
+
+void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
+{
+	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
+}
+
+const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
+{
+	return mState.vertexAttribute[attribNum];
+}
+
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
+                                   GLsizei stride, const void *pointer)
+{
+	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
+	mState.vertexAttribute[attribNum].mSize = size;
+	mState.vertexAttribute[attribNum].mType = type;
+	mState.vertexAttribute[attribNum].mNormalized = normalized;
+	mState.vertexAttribute[attribNum].mStride = stride;
+	mState.vertexAttribute[attribNum].mPointer = pointer;
+}
+
+const void *Context::getVertexAttribPointer(unsigned int attribNum) const
+{
+	return mState.vertexAttribute[attribNum].mPointer;
+}
+
+const VertexAttributeArray &Context::getVertexAttributes()
+{
+	return mState.vertexAttribute;
+}
+
+void Context::setPackAlignment(GLint alignment)
+{
+	mState.packAlignment = alignment;
+}
+
+GLint Context::getPackAlignment() const
+{
+	return mState.packAlignment;
+}
+
+void Context::setUnpackAlignment(GLint alignment)
+{
+	mState.unpackAlignment = alignment;
+}
+
+GLint Context::getUnpackAlignment() const
+{
+	return mState.unpackAlignment;
+}
+
+GLuint Context::createBuffer()
+{
+	return mResourceManager->createBuffer();
+}
+
+GLuint Context::createTexture()
+{
+	return mResourceManager->createTexture();
+}
+
+GLuint Context::createRenderbuffer()
+{
+	return mResourceManager->createRenderbuffer();
+}
+
+// Returns an unused framebuffer name
+GLuint Context::createFramebuffer()
+{
+	return mFramebufferNameSpace.allocate();
+}
+
+void Context::deleteBuffer(GLuint buffer)
+{
+	detachBuffer(buffer);
+
+	mResourceManager->deleteBuffer(buffer);
+}
+
+void Context::deleteTexture(GLuint texture)
+{
+	detachTexture(texture);
+
+	mResourceManager->deleteTexture(texture);
+}
+
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+	detachRenderbuffer(renderbuffer);
+
+	mResourceManager->deleteRenderbuffer(renderbuffer);
+}
+
+void Context::deleteFramebuffer(GLuint framebuffer)
+{
+	detachFramebuffer(framebuffer);
+
+	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
+
+	if(framebufferObject)
+	{
+		delete framebufferObject;
+	}
+}
+
+Buffer *Context::getBuffer(GLuint handle)
+{
+	return mResourceManager->getBuffer(handle);
+}
+
+Texture *Context::getTexture(GLuint handle)
+{
+	return mResourceManager->getTexture(handle);
+}
+
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
+{
+	return mResourceManager->getRenderbuffer(handle);
+}
+
+Framebuffer *Context::getFramebuffer()
+{
+	return getFramebuffer(mState.framebuffer);
+}
+
+void Context::bindArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.arrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindElementArrayBuffer(unsigned int buffer)
+{
+	mResourceManager->checkBufferAllocation(buffer);
+
+	mState.elementArrayBuffer = getBuffer(buffer);
+}
+
+void Context::bindTexture2D(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+
+	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindTextureExternal(GLuint texture)
+{
+	mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
+
+	mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
+}
+
+void Context::bindFramebuffer(GLuint framebuffer)
+{
+	if(!getFramebuffer(framebuffer))
+	{
+		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
+	}
+
+	mState.framebuffer = framebuffer;
+}
+
+void Context::bindRenderbuffer(GLuint renderbuffer)
+{
+	mResourceManager->checkRenderbufferAllocation(renderbuffer);
+
+	mState.renderbuffer = getRenderbuffer(renderbuffer);
+}
+
+void Context::setFramebufferZero(Framebuffer *buffer)
+{
+	delete mFramebufferNameSpace.remove(0);
+	mFramebufferNameSpace.insert(0, buffer);
+}
+
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+{
+	Renderbuffer *renderbufferObject = mState.renderbuffer;
+	renderbufferObject->setStorage(renderbuffer);
+}
+
+Framebuffer *Context::getFramebuffer(unsigned int handle)
+{
+	return mFramebufferNameSpace.find(handle);
+}
+
+Buffer *Context::getArrayBuffer()
+{
+	return mState.arrayBuffer;
+}
+
+Buffer *Context::getElementArrayBuffer()
+{
+	return mState.elementArrayBuffer;
+}
+
+Texture2D *Context::getTexture2D()
+{
+	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
+}
+
+TextureExternal *Context::getTextureExternal()
+{
+	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
+}
+
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
+{
+	GLuint texid = mState.samplerTexture[type][sampler].name();
+
+	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
+	{
+		switch(type)
+		{
+		case TEXTURE_2D: return mTexture2DZero;
+		case TEXTURE_EXTERNAL: return mTextureExternalZero;
+		default: UNREACHABLE(type);
+		}
+	}
+
+	return mState.samplerTexture[type][sampler];
+}
+
+bool Context::getBooleanv(GLenum pname, GLboolean *params)
+{
+	switch(pname)
+	{
+	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
+	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
+	case GL_COLOR_WRITEMASK:
+		params[0] = mState.colorMaskRed;
+		params[1] = mState.colorMaskGreen;
+		params[2] = mState.colorMaskBlue;
+		params[3] = mState.colorMaskAlpha;
+		break;
+	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
+	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
+	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
+	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
+	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
+	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
+	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
+	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
+	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getFloatv(GLenum pname, GLfloat *params)
+{
+	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application.
+	switch(pname)
+	{
+	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
+	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
+	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
+	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
+	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
+		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
+		break;
+	case GL_ALIASED_POINT_SIZE_RANGE:
+		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
+		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
+		break;
+	case GL_SMOOTH_LINE_WIDTH_RANGE:
+		params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;
+		params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;
+		break;
+	case GL_SMOOTH_POINT_SIZE_RANGE:
+		params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;
+		params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;
+		break;
+	case GL_DEPTH_RANGE:
+		params[0] = mState.zNear;
+		params[1] = mState.zFar;
+		break;
+	case GL_COLOR_CLEAR_VALUE:
+		params[0] = mState.colorClearValue.red;
+		params[1] = mState.colorClearValue.green;
+		params[2] = mState.colorClearValue.blue;
+		params[3] = mState.colorClearValue.alpha;
+		break;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+		*params = MAX_TEXTURE_MAX_ANISOTROPY;
+		break;
+	case GL_MODELVIEW_MATRIX:
+		for(int i = 0; i < 16; i++)
+		{
+			params[i] = modelViewStack.current()[i % 4][i / 4];
+		}
+		break;
+	case GL_PROJECTION_MATRIX:
+		for(int i = 0; i < 16; i++)
+		{
+			params[i] = projectionStack.current()[i % 4][i / 4];
+		}
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getIntegerv(GLenum pname, GLint *params)
+{
+	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
+	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+	// GetIntegerv as its native query function. As it would require conversion in any
+	// case, this should make no difference to the calling application. You may find it in
+	// Context::getFloatv.
+	switch(pname)
+	{
+	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
+	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;
+	case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;
+	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
+	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
+	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
+	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;
+	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
+	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
+	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
+	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
+	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
+	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
+	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
+	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
+	case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;
+	case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;
+	case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;
+	case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;
+	case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;
+	case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;
+	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
+	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
+	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
+	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			int width, height, samples;
+
+			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES)
+			{
+				switch(pname)
+				{
+				case GL_SAMPLE_BUFFERS:
+					if(samples > 1)
+					{
+						*params = 1;
+					}
+					else
+					{
+						*params = 0;
+					}
+					break;
+				case GL_SAMPLES:
+					*params = samples;
+					break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			*params = framebuffer->getImplementationColorReadType();
+		}
+		break;
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			*params = framebuffer->getImplementationColorReadFormat();
+		}
+		break;
+	case GL_MAX_VIEWPORT_DIMS:
+		{
+			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
+			params[0] = maxDimension;
+			params[1] = maxDimension;
+		}
+		break;
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		{
+			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
+			{
+				params[i] = compressedTextureFormats[i];
+			}
+		}
+		break;
+	case GL_VIEWPORT:
+		params[0] = mState.viewportX;
+		params[1] = mState.viewportY;
+		params[2] = mState.viewportWidth;
+		params[3] = mState.viewportHeight;
+		break;
+	case GL_SCISSOR_BOX:
+		params[0] = mState.scissorX;
+		params[1] = mState.scissorY;
+		params[2] = mState.scissorWidth;
+		params[3] = mState.scissorHeight;
+		break;
+	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
+	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
+
+			if(colorbuffer)
+			{
+				switch(pname)
+				{
+				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
+				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
+				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
+				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
+				}
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_DEPTH_BITS:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+
+			if(depthbuffer)
+			{
+				*params = depthbuffer->getDepthSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_STENCIL_BITS:
+		{
+			Framebuffer *framebuffer = getFramebuffer();
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+
+			if(stencilbuffer)
+			{
+				*params = stencilbuffer->getStencilSize();
+			}
+			else
+			{
+				*params = 0;
+			}
+		}
+		break;
+	case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;
+	case GL_TEXTURE_BINDING_CUBE_MAP_OES:        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();                 break;
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;
+	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;
+	case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;
+	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;
+	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;
+	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;
+	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;
+	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;
+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;
+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;
+	case GL_VERTEX_ARRAY_SIZE:                   *params = mState.vertexAttribute[sw::Position].mSize;                                       break;
+	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;
+	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;
+	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;
+	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;
+	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;
+	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;
+	case GL_COLOR_ARRAY_SIZE:                    *params = mState.vertexAttribute[sw::Color0].mSize;                                         break;
+	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;
+	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;
+	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;
+	case GL_TEXTURE_COORD_ARRAY_SIZE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize;               break;
+	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;
+	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;
+	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+bool Context::getPointerv(GLenum pname, const GLvoid **params)
+{
+	switch(pname)
+	{
+	case GL_VERTEX_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Position].mPointer;                         break;
+	case GL_NORMAL_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Normal].mPointer;                           break;
+	case GL_COLOR_ARRAY_POINTER:          *params = mState.vertexAttribute[sw::Color0].mPointer;                           break;
+	case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer;                        break;
+	case GL_TEXTURE_COORD_ARRAY_POINTER:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+int Context::getQueryParameterNum(GLenum pname)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+		return NUM_COMPRESSED_TEXTURE_FORMATS;
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+	case GL_ARRAY_BUFFER_BINDING:
+	case GL_FRAMEBUFFER_BINDING_OES:
+	case GL_RENDERBUFFER_BINDING_OES:
+	case GL_PACK_ALIGNMENT:
+	case GL_UNPACK_ALIGNMENT:
+	case GL_GENERATE_MIPMAP_HINT:
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+	case GL_DEPTH_BITS:
+	case GL_STENCIL_BITS:
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+	case GL_CULL_FACE_MODE:
+	case GL_FRONT_FACE:
+	case GL_ACTIVE_TEXTURE:
+	case GL_STENCIL_FUNC:
+	case GL_STENCIL_VALUE_MASK:
+	case GL_STENCIL_REF:
+	case GL_STENCIL_FAIL:
+	case GL_STENCIL_PASS_DEPTH_FAIL:
+	case GL_STENCIL_PASS_DEPTH_PASS:
+	case GL_DEPTH_FUNC:
+	case GL_BLEND_SRC_RGB_OES:
+	case GL_BLEND_SRC_ALPHA_OES:
+	case GL_BLEND_DST_RGB_OES:
+	case GL_BLEND_DST_ALPHA_OES:
+	case GL_BLEND_EQUATION_RGB_OES:
+	case GL_BLEND_EQUATION_ALPHA_OES:
+	case GL_STENCIL_WRITEMASK:
+	case GL_STENCIL_CLEAR_VALUE:
+	case GL_SUBPIXEL_BITS:
+	case GL_MAX_TEXTURE_SIZE:
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+	case GL_TEXTURE_BINDING_2D:
+	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:
+		return 1;
+	case GL_MAX_VIEWPORT_DIMS:
+		return 2;
+	case GL_VIEWPORT:
+	case GL_SCISSOR_BOX:
+		return 4;
+	case GL_SAMPLE_COVERAGE_INVERT:
+	case GL_DEPTH_WRITEMASK:
+	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
+	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
+	case GL_SAMPLE_COVERAGE:
+	case GL_SCISSOR_TEST:
+	case GL_STENCIL_TEST:
+	case GL_DEPTH_TEST:
+	case GL_BLEND:
+	case GL_DITHER:
+		return 1;
+	case GL_COLOR_WRITEMASK:
+		return 4;
+	case GL_POLYGON_OFFSET_FACTOR:
+	case GL_POLYGON_OFFSET_UNITS:
+	case GL_SAMPLE_COVERAGE_VALUE:
+	case GL_DEPTH_CLEAR_VALUE:
+	case GL_LINE_WIDTH:
+		return 1;
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+	case GL_ALIASED_POINT_SIZE_RANGE:
+	case GL_DEPTH_RANGE:
+		return 2;
+	case GL_COLOR_CLEAR_VALUE:
+		return 4;
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+	case GL_MAX_LIGHTS:
+	case GL_MAX_MODELVIEW_STACK_DEPTH:
+	case GL_MAX_PROJECTION_STACK_DEPTH:
+	case GL_MAX_TEXTURE_STACK_DEPTH:
+	case GL_MAX_TEXTURE_UNITS:
+	case GL_MAX_CLIP_PLANES:
+	case GL_POINT_SIZE_ARRAY_TYPE_OES:
+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+		return 1;
+	case GL_CURRENT_COLOR:
+		return 4;
+	case GL_CURRENT_NORMAL:
+		return 3;
+	case GL_CURRENT_TEXTURE_COORDS:
+		return 4;
+	case GL_POINT_SIZE:
+	case GL_POINT_SIZE_MIN:
+	case GL_POINT_SIZE_MAX:
+	case GL_POINT_FADE_THRESHOLD_SIZE:
+		return 1;
+	case GL_POINT_DISTANCE_ATTENUATION:
+		return 3;
+	case GL_SMOOTH_POINT_SIZE_RANGE:
+	case GL_SMOOTH_LINE_WIDTH_RANGE:
+		return 2;
+	case GL_SHADE_MODEL:
+	case GL_MATRIX_MODE:
+	case GL_MODELVIEW_STACK_DEPTH:
+	case GL_PROJECTION_STACK_DEPTH:
+	case GL_TEXTURE_STACK_DEPTH:
+		return 1;
+	case GL_MODELVIEW_MATRIX:
+	case GL_PROJECTION_MATRIX:
+	case GL_TEXTURE_MATRIX:
+		return 16;
+	case GL_ALPHA_TEST_FUNC:
+	case GL_ALPHA_TEST_REF:
+	case GL_BLEND_DST:
+	case GL_BLEND_SRC:
+	case GL_LOGIC_OP_MODE:
+	case GL_VERTEX_ARRAY_SIZE:
+	case GL_VERTEX_ARRAY_TYPE:
+	case GL_VERTEX_ARRAY_STRIDE:
+	case GL_NORMAL_ARRAY_TYPE:
+	case GL_NORMAL_ARRAY_STRIDE:
+	case GL_COLOR_ARRAY_SIZE:
+	case GL_COLOR_ARRAY_TYPE:
+	case GL_COLOR_ARRAY_STRIDE:
+	case GL_TEXTURE_COORD_ARRAY_SIZE:
+	case GL_TEXTURE_COORD_ARRAY_TYPE:
+	case GL_TEXTURE_COORD_ARRAY_STRIDE:
+	case GL_VERTEX_ARRAY_POINTER:
+	case GL_NORMAL_ARRAY_POINTER:
+	case GL_COLOR_ARRAY_POINTER:
+	case GL_TEXTURE_COORD_ARRAY_POINTER:
+	case GL_LIGHT_MODEL_TWO_SIDE:
+		return 1;
+	default:
+		UNREACHABLE(pname);
+	}
+
+	return -1;
+}
+
+bool Context::isQueryParameterInt(GLenum pname)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_COMPRESSED_TEXTURE_FORMATS:
+	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+	case GL_ARRAY_BUFFER_BINDING:
+	case GL_FRAMEBUFFER_BINDING_OES:
+	case GL_RENDERBUFFER_BINDING_OES:
+	case GL_PACK_ALIGNMENT:
+	case GL_UNPACK_ALIGNMENT:
+	case GL_GENERATE_MIPMAP_HINT:
+	case GL_RED_BITS:
+	case GL_GREEN_BITS:
+	case GL_BLUE_BITS:
+	case GL_ALPHA_BITS:
+	case GL_DEPTH_BITS:
+	case GL_STENCIL_BITS:
+	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+	case GL_CULL_FACE_MODE:
+	case GL_FRONT_FACE:
+	case GL_ACTIVE_TEXTURE:
+	case GL_STENCIL_FUNC:
+	case GL_STENCIL_VALUE_MASK:
+	case GL_STENCIL_REF:
+	case GL_STENCIL_FAIL:
+	case GL_STENCIL_PASS_DEPTH_FAIL:
+	case GL_STENCIL_PASS_DEPTH_PASS:
+	case GL_DEPTH_FUNC:
+	case GL_BLEND_SRC_RGB_OES:
+	case GL_BLEND_SRC_ALPHA_OES:
+	case GL_BLEND_DST_RGB_OES:
+	case GL_BLEND_DST_ALPHA_OES:
+	case GL_BLEND_EQUATION_RGB_OES:
+	case GL_BLEND_EQUATION_ALPHA_OES:
+	case GL_STENCIL_WRITEMASK:
+	case GL_STENCIL_CLEAR_VALUE:
+	case GL_SUBPIXEL_BITS:
+	case GL_MAX_TEXTURE_SIZE:
+	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
+	case GL_SAMPLE_BUFFERS:
+	case GL_SAMPLES:
+	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+	case GL_TEXTURE_BINDING_2D:
+	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
+	case GL_TEXTURE_BINDING_EXTERNAL_OES:
+	case GL_MAX_VIEWPORT_DIMS:
+	case GL_VIEWPORT:
+	case GL_SCISSOR_BOX:
+	case GL_MAX_LIGHTS:
+	case GL_MAX_MODELVIEW_STACK_DEPTH:
+	case GL_MAX_PROJECTION_STACK_DEPTH:
+	case GL_MAX_TEXTURE_STACK_DEPTH:
+	case GL_MAX_TEXTURE_UNITS:
+	case GL_MAX_CLIP_PLANES:
+	case GL_POINT_SIZE_ARRAY_TYPE_OES:
+	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+		return true;
+	}
+
+	return false;
+}
+
+bool Context::isQueryParameterFloat(GLenum pname)
+{
+	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+	// to the fact that it is stored internally as a float, and so would require conversion
+	// if returned from Context::getIntegerv. Since this conversion is already implemented
+	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+	// application.
+	switch(pname)
+	{
+	case GL_POLYGON_OFFSET_FACTOR:
+	case GL_POLYGON_OFFSET_UNITS:
+	case GL_SAMPLE_COVERAGE_VALUE:
+	case GL_DEPTH_CLEAR_VALUE:
+	case GL_LINE_WIDTH:
+	case GL_ALIASED_LINE_WIDTH_RANGE:
+	case GL_ALIASED_POINT_SIZE_RANGE:
+	case GL_SMOOTH_LINE_WIDTH_RANGE:
+	case GL_SMOOTH_POINT_SIZE_RANGE:
+	case GL_DEPTH_RANGE:
+	case GL_COLOR_CLEAR_VALUE:
+	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+	case GL_LIGHT_MODEL_AMBIENT:
+	case GL_POINT_SIZE_MIN:
+	case GL_POINT_SIZE_MAX:
+	case GL_POINT_DISTANCE_ATTENUATION:
+	case GL_POINT_FADE_THRESHOLD_SIZE:
+		return true;
+	}
+
+	return false;
+}
+
+bool Context::isQueryParameterBool(GLenum pname)
+{
+	switch(pname)
+	{
+	case GL_SAMPLE_COVERAGE_INVERT:
+	case GL_DEPTH_WRITEMASK:
+	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
+	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
+	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
+	case GL_SAMPLE_COVERAGE:
+	case GL_SCISSOR_TEST:
+	case GL_STENCIL_TEST:
+	case GL_DEPTH_TEST:
+	case GL_BLEND:
+	case GL_DITHER:
+	case GL_COLOR_WRITEMASK:
+	case GL_LIGHT_MODEL_TWO_SIDE:
+		return true;
+	}
+
+	return false;
+}
+
+bool Context::isQueryParameterPointer(GLenum pname)
+{
+	switch(pname)
+	{
+	case GL_VERTEX_ARRAY_POINTER:
+	case GL_NORMAL_ARRAY_POINTER:
+	case GL_COLOR_ARRAY_POINTER:
+	case GL_TEXTURE_COORD_ARRAY_POINTER:
+	case GL_POINT_SIZE_ARRAY_POINTER_OES:
+		return true;
+	}
+
+	return false;
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
+bool Context::applyRenderTarget()
+{
+	Framebuffer *framebuffer = getFramebuffer();
+	int width, height, samples;
+
+	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);
+	}
+
+	egl::Image *renderTarget = framebuffer->getRenderTarget();
+	device->setRenderTarget(0, renderTarget);
+	if(renderTarget) renderTarget->release();
+
+	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
+	device->setDepthBuffer(depthBuffer);
+	if(depthBuffer) depthBuffer->release();
+
+	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
+	device->setStencilBuffer(stencilBuffer);
+	if(stencilBuffer) stencilBuffer->release();
+
+	Viewport viewport;
+	float zNear = clamp01(mState.zNear);
+	float zFar = clamp01(mState.zFar);
+
+	viewport.x0 = mState.viewportX;
+	viewport.y0 = mState.viewportY;
+	viewport.width = mState.viewportWidth;
+	viewport.height = mState.viewportHeight;
+	viewport.minZ = zNear;
+	viewport.maxZ = zFar;
+
+	device->setViewport(viewport);
+
+	if(mState.scissorTestEnabled)
+	{
+		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
+		scissor.clip(0, 0, width, height);
+
+		device->setScissorRect(scissor);
+		device->setScissorEnable(true);
+	}
+	else
+	{
+		device->setScissorEnable(false);
+	}
+
+	return true;
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
+void Context::applyState(GLenum drawMode)
+{
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(mState.cullFaceEnabled)
+	{
+		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
+	}
+	else
+	{
+		device->setCullMode(sw::CULL_NONE);
+	}
+
+	if(mDepthStateDirty)
+	{
+		if(mState.depthTestEnabled)
+		{
+			device->setDepthBufferEnable(true);
+			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
+		}
+		else
+		{
+			device->setDepthBufferEnable(false);
+		}
+
+		mDepthStateDirty = false;
+	}
+
+	if(mBlendStateDirty)
+	{
+		if(mState.blendEnabled)
+		{
+			device->setAlphaBlendEnable(true);
+			device->setSeparateAlphaBlendEnable(true);
+
+			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
+			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
+			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
+
+			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
+			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
+			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
+		}
+		else
+		{
+			device->setAlphaBlendEnable(false);
+		}
+
+		mBlendStateDirty = false;
+	}
+
+	if(mStencilStateDirty || mFrontFaceDirty)
+	{
+		if(mState.stencilTestEnabled && framebuffer->hasStencil())
+		{
+			device->setStencilEnable(true);
+			device->setTwoSidedStencil(true);
+
+			// get the maximum size of the stencil ref
+			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
+
+			device->setStencilWriteMask(mState.stencilWritemask);
+			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+			device->setStencilMask(mState.stencilMask);
+
+			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
+			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+
+			device->setStencilWriteMaskCCW(mState.stencilWritemask);
+			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
+
+			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
+			device->setStencilMaskCCW(mState.stencilMask);
+
+			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
+			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
+			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
+		}
+		else
+		{
+			device->setStencilEnable(false);
+		}
+
+		mStencilStateDirty = false;
+		mFrontFaceDirty = false;
+	}
+
+	if(mMaskStateDirty)
+	{
+		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
+		device->setDepthWriteEnable(mState.depthMask);
+
+		mMaskStateDirty = false;
+	}
+
+	if(mPolygonOffsetStateDirty)
+	{
+		if(mState.polygonOffsetFillEnabled)
+		{
+			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
+			if(depthbuffer)
+			{
+				device->setSlopeDepthBias(mState.polygonOffsetFactor);
+				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
+				device->setDepthBias(depthBias);
+			}
+		}
+		else
+		{
+			device->setSlopeDepthBias(0);
+			device->setDepthBias(0);
+		}
+
+		mPolygonOffsetStateDirty = false;
+	}
+
+	if(mSampleStateDirty)
+	{
+		if(mState.sampleAlphaToCoverageEnabled)
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
+		}
+		else
+		{
+			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
+		}
+
+		if(mState.sampleCoverageEnabled)
+		{
+			unsigned int mask = 0;
+			if(mState.sampleCoverageValue != 0)
+			{
+				int width, height, samples;
+				framebuffer->completeness(width, height, samples);
+
+				float threshold = 0.5f;
+
+				for(int i = 0; i < samples; i++)
+				{
+					mask <<= 1;
+
+					if((i + 1) * mState.sampleCoverageValue >= threshold)
+					{
+						threshold += 1.0f;
+						mask |= 1;
+					}
+				}
+			}
+
+			if(mState.sampleCoverageInvert)
+			{
+				mask = ~mask;
+			}
+
+			device->setMultiSampleMask(mask);
+		}
+		else
+		{
+			device->setMultiSampleMask(0xFFFFFFFF);
+		}
+
+		mSampleStateDirty = false;
+	}
+
+	if(mDitherStateDirty)
+	{
+	//	UNIMPLEMENTED();   // FIXME
+
+		mDitherStateDirty = false;
+	}
+
+	switch(mState.shadeModel)
+	{
+	default: UNREACHABLE(mState.shadeModel);
+	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
+	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
+	}
+
+	device->setLightingEnable(lightingEnabled);
+	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
+
+	for(int i = 0; i < MAX_LIGHTS; i++)
+	{
+		device->setLightEnable(i, light[i].enabled);
+		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
+		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
+		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
+		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
+
+		if(light[i].position.w != 0.0f)
+		{
+			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
+		}
+		else   // Directional light
+		{
+			// Hack: set the position far way
+			float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));
+			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
+		}
+	}
+
+	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
+	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
+	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
+	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
+	device->setMaterialShininess(materialShininess);
+
+	device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
+	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
+	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
+	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
+
+	const sw::Matrix Z(1, 0, 0, 0,
+	                   0, 1, 0, 0,
+	                   0, 0, 0.5, 0.5,
+	                   0, 0, 0, 1);   // Map depth range from [-1, 1] to [0, 1]
+
+	device->setProjectionMatrix(Z * projectionStack.current());
+	device->setModelMatrix(modelViewStack.current());
+	device->setTextureMatrix(0, textureStack0.current());
+	device->setTextureMatrix(1, textureStack1.current());
+	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);
+	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);
+	device->setTexGen(0, sw::TEXGEN_NONE);
+	device->setTexGen(1, sw::TEXGEN_NONE);
+
+	device->setAlphaTestEnable(alphaTestEnabled);
+	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));
+	device->setAlphaReference(alphaTestRef * 0xFF);
+
+	device->setFogEnable(fogEnabled);
+	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));
+	device->setFogDensity(fogDensity);
+	device->setFogStart(fogStart);
+	device->setFogEnd(fogEnd);
+
+	switch(fogMode)
+	{
+	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
+	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;
+	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;
+	default: UNREACHABLE(fogMode);
+	}
+
+	device->setColorLogicOpEnabled(colorLogicOpEnabled);
+	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));
+
+	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);
+}
+
+GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
+{
+	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
+
+	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
+	if(err != GL_NO_ERROR)
+	{
+		return err;
+	}
+
+	device->resetInputStreams(false);
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		sw::Resource *resource = attributes[i].vertexBuffer;
+		const void *buffer = (char*)resource->data() + attributes[i].offset;
+
+		int stride = attributes[i].stride;
+
+		buffer = (char*)buffer + stride * base;
+
+		sw::Stream attribute(resource, buffer, stride);
+
+		attribute.type = attributes[i].type;
+		attribute.count = attributes[i].count;
+		attribute.normalized = attributes[i].normalized;
+
+		device->setInputStream(i, attribute);
+	}
+
+	return GL_NO_ERROR;
+}
+
+// Applies the indices and element array bindings
+GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
+
+	if(err == GL_NO_ERROR)
+	{
+		device->setIndexBuffer(indexInfo->indexBuffer);
+	}
+
+	return err;
+}
+
+void Context::applyTextures()
+{
+	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
+	{
+		Texture *texture = nullptr;
+
+		if(textureExternalEnabled[unit])
+		{
+			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);
+		}
+		else if(texture2Denabled[unit])
+		{
+			texture = getSamplerTexture(unit, TEXTURE_2D);
+		}
+
+		if(texture && texture->isSamplerComplete())
+		{
+			texture->autoGenerateMipmaps();
+
+			GLenum wrapS = texture->getWrapS();
+			GLenum wrapT = texture->getWrapT();
+			GLenum minFilter = texture->getMinFilter();
+			GLenum magFilter = texture->getMagFilter();
+			GLfloat maxAnisotropy = texture->getMaxAnisotropy();
+
+			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));
+			device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));
+
+			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
+			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));
+			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);
+
+			applyTexture(unit, texture);
+
+			device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));
+
+			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)
+			{
+				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs
+				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp
+				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc
+				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+
+				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As
+				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap
+				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac
+				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+
+				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);
+
+				switch(mState.textureUnit[unit].environmentMode)
+				{
+				case GL_REPLACE:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = As
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cs, Av = As
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_MODULATE:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = CpCs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = CpCs, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_DECAL:
+					if(texFormat == GL_ALPHA ||
+					   texFormat == GL_LUMINANCE ||
+					   texFormat == GL_LUMINANCE_ALPHA)
+					{
+						// undefined   // FIXME: Log
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cp(1 - As) + CsAs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_BLEND:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cp(1 - Cs) + CcCs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				case GL_ADD:
+					if(IsAlpha(texFormat))   // GL_ALPHA
+					{
+						// Cv = Cp, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
+					{
+						// Cv = Cp + Cs, Av = Ap
+						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
+					}
+					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
+					{
+						// Cv = Cp + Cs, Av = ApAs
+						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
+						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
+					}
+					else UNREACHABLE(texFormat);
+					break;
+				default:
+					UNREACHABLE(mState.textureUnit[unit].environmentMode);
+				}
+			}
+			else   // GL_COMBINE
+			{
+				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));
+				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));
+				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));
+				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));
+				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));
+				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));
+
+				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));
+
+				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));
+				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));
+				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));
+				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));
+				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));
+				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));
+
+				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));
+			}
+		}
+		else
+		{
+			applyTexture(unit, nullptr);
+
+			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);
+			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
+			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
+
+			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);
+			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
+			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
+		}
+	}
+}
+
+void Context::setTextureEnvMode(GLenum texEnvMode)
+{
+	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;
+}
+
+void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};
+}
+
+void Context::setCombineRGB(GLenum combineRGB)
+{
+	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;
+}
+
+void Context::setCombineAlpha(GLenum combineAlpha)
+{
+	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;
+}
+
+void Context::setOperand0RGB(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand0RGB = operand;
+}
+
+void Context::setOperand1RGB(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand1RGB = operand;
+}
+
+void Context::setOperand2RGB(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand2RGB = operand;
+}
+
+void Context::setOperand0Alpha(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand0Alpha = operand;
+}
+
+void Context::setOperand1Alpha(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand1Alpha = operand;
+}
+
+void Context::setOperand2Alpha(GLenum operand)
+{
+	mState.textureUnit[mState.activeSampler].operand2Alpha = operand;
+}
+
+void Context::setSrc0RGB(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src0RGB = src;
+}
+
+void Context::setSrc1RGB(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src1RGB = src;
+}
+
+void Context::setSrc2RGB(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src2RGB = src;
+}
+
+void Context::setSrc0Alpha(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src0Alpha = src;
+}
+
+void Context::setSrc1Alpha(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src1Alpha = src;
+}
+
+void Context::setSrc2Alpha(GLenum src)
+{
+	mState.textureUnit[mState.activeSampler].src2Alpha = src;
+}
+
+void Context::applyTexture(int index, Texture *baseTexture)
+{
+	sw::Resource *resource = 0;
+
+	if(baseTexture)
+	{
+		resource = baseTexture->getResource();
+	}
+
+	device->setTextureResource(index, resource);
+
+	if(baseTexture)
+	{
+		int levelCount = baseTexture->getLevelCount();
+
+		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
+
+			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
+			{
+				int surfaceLevel = mipmapLevel;
+
+				if(surfaceLevel < 0)
+				{
+					surfaceLevel = 0;
+				}
+				else if(surfaceLevel >= levelCount)
+				{
+					surfaceLevel = levelCount - 1;
+				}
+
+				egl::Image *surface = texture->getImage(surfaceLevel);
+				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);
+			}
+		}
+		else UNIMPLEMENTED();
+	}
+	else
+	{
+		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);
+	}
+}
+
+void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+{
+	Framebuffer *framebuffer = getFramebuffer();
+	int framebufferWidth, framebufferHeight, framebufferSamples;
+
+	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+	}
+
+	if(getFramebufferName() != 0 && framebufferSamples != 0)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
+	{
+		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);
+
+	// Sized query sanity check
+	if(bufSize)
+	{
+		int requiredSize = outputPitch * height;
+		if(requiredSize > *bufSize)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
+	egl::Image *renderTarget = framebuffer->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect rect = {x, y, x + width, y + height};
+	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
+	unsigned char *dest = (unsigned char*)pixels;
+	int inputPitch = (int)renderTarget->getPitch();
+
+	for(int j = 0; j < rect.y1 - rect.y0; j++)
+	{
+		unsigned short *dest16 = (unsigned short*)dest;
+		unsigned int *dest32 = (unsigned int*)dest;
+
+		if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
+		   format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				unsigned int argb = *(unsigned int*)(source + 4 * i);
+
+				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
+			}
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
+
+				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
+			}
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
+
+				dest32[i] = xrgb | 0xFF000000;
+			}
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
+				format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
+		}
+		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
+				format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
+		{
+			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
+		}
+		else
+		{
+			for(int i = 0; i < rect.x1 - rect.x0; i++)
+			{
+				float r;
+				float g;
+				float b;
+				float a;
+
+				switch(renderTarget->getInternalFormat())
+				{
+				case sw::FORMAT_R5G6B5:
+					{
+						unsigned short rgb = *(unsigned short*)(source + 2 * i);
+
+						a = 1.0f;
+						b = (rgb & 0x001F) * (1.0f / 0x001F);
+						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
+						r = (rgb & 0xF800) * (1.0f / 0xF800);
+					}
+					break;
+				case sw::FORMAT_A1R5G5B5:
+					{
+						unsigned short argb = *(unsigned short*)(source + 2 * i);
+
+						a = (argb & 0x8000) ? 1.0f : 0.0f;
+						b = (argb & 0x001F) * (1.0f / 0x001F);
+						g = (argb & 0x03E0) * (1.0f / 0x03E0);
+						r = (argb & 0x7C00) * (1.0f / 0x7C00);
+					}
+					break;
+				case sw::FORMAT_A8R8G8B8:
+					{
+						unsigned int argb = *(unsigned int*)(source + 4 * i);
+
+						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
+						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
+						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
+					}
+					break;
+				case sw::FORMAT_A8B8G8R8:
+					{
+						unsigned int abgr = *(unsigned int*)(source + 4 * i);
+
+						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
+						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
+						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
+					}
+					break;
+				case sw::FORMAT_X8R8G8B8:
+					{
+						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
+
+						a = 1.0f;
+						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
+						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
+					}
+					break;
+				case sw::FORMAT_X8B8G8R8:
+					{
+						unsigned int xbgr = *(unsigned int*)(source + 4 * i);
+
+						a = 1.0f;
+						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
+						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
+						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
+					}
+					break;
+				case sw::FORMAT_A2R10G10B10:
+					{
+						unsigned int argb = *(unsigned int*)(source + 4 * i);
+
+						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
+						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
+						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
+						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
+					}
+					break;
+				default:
+					UNIMPLEMENTED();   // FIXME
+					UNREACHABLE(renderTarget->getInternalFormat());
+				}
+
+				switch(format)
+				{
+				case GL_RGBA:
+					switch(type)
+					{
+					case GL_UNSIGNED_BYTE:
+						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
+						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
+						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
+						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				case GL_BGRA_EXT:
+					switch(type)
+					{
+					case GL_UNSIGNED_BYTE:
+						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
+						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
+						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
+						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
+						break;
+					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+						// this type is packed as follows:
+						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+						//  --------------------------------------------------------------------------------
+						// |       4th         |        3rd         |        2nd        |   1st component   |
+						//  --------------------------------------------------------------------------------
+						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+						dest16[i] =
+							((unsigned short)(15 * a + 0.5f) << 12)|
+							((unsigned short)(15 * r + 0.5f) << 8) |
+							((unsigned short)(15 * g + 0.5f) << 4) |
+							((unsigned short)(15 * b + 0.5f) << 0);
+						break;
+					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+						// this type is packed as follows:
+						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+						//  --------------------------------------------------------------------------------
+						// | 4th |          3rd           |           2nd          |      1st component     |
+						//  --------------------------------------------------------------------------------
+						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+						dest16[i] =
+							((unsigned short)(     a + 0.5f) << 15) |
+							((unsigned short)(31 * r + 0.5f) << 10) |
+							((unsigned short)(31 * g + 0.5f) << 5) |
+							((unsigned short)(31 * b + 0.5f) << 0);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				case GL_RGB:
+					switch(type)
+					{
+					case GL_UNSIGNED_SHORT_5_6_5:
+						dest16[i] =
+							((unsigned short)(31 * b + 0.5f) << 0) |
+							((unsigned short)(63 * g + 0.5f) << 5) |
+							((unsigned short)(31 * r + 0.5f) << 11);
+						break;
+					default: UNREACHABLE(type);
+					}
+					break;
+				default: UNREACHABLE(format);
+				}
+			}
+		}
+
+		source += inputPitch;
+		dest += outputPitch;
+	}
+
+	renderTarget->unlock();
+	renderTarget->release();
+}
+
+void Context::clear(GLbitfield mask)
+{
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
+	{
+		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	float depth = clamp01(mState.depthClearValue);
+	int stencil = mState.stencilClearValue & 0x000000FF;
+
+	if(mask & GL_COLOR_BUFFER_BIT)
+	{
+		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
+		                        (mState.colorMaskGreen ? 0x2 : 0) |
+		                        (mState.colorMaskBlue ? 0x4 : 0) |
+		                        (mState.colorMaskAlpha ? 0x8 : 0);
+
+		if(rgbaMask != 0)
+		{
+			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
+		}
+	}
+
+	if(mask & GL_DEPTH_BUFFER_BIT)
+	{
+		if(mState.depthMask != 0)
+		{
+			device->clearDepth(depth);
+		}
+	}
+
+	if(mask & GL_STENCIL_BUFFER_BIT)
+	{
+		if(mState.stencilWritemask != 0)
+		{
+			device->clearStencil(stencil, mState.stencilWritemask);
+		}
+	}
+}
+
+void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	sw::DrawType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	GLenum err = applyVertexBuffer(0, first, count);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyTextures();
+
+	if(!cullSkipsDraw(mode))
+	{
+		device->drawPrimitive(primitiveType, primitiveCount);
+	}
+}
+
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+	if(!indices && !mState.elementArrayBuffer)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	sw::DrawType primitiveType;
+	int primitiveCount;
+
+	if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
+		return error(GL_INVALID_ENUM);
+
+	if(primitiveCount <= 0)
+	{
+		return;
+	}
+
+	if(!applyRenderTarget())
+	{
+		return;
+	}
+
+	applyState(mode);
+
+	TranslatedIndexData indexInfo;
+	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
+	if(err != GL_NO_ERROR)
+	{
+		return error(err);
+	}
+
+	applyTextures();
+
+	if(!cullSkipsDraw(mode))
+	{
+		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
+	}
+}
+
+void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	es1::Framebuffer *framebuffer = getFramebuffer();
+	es1::Renderbuffer *renderbuffer = framebuffer->getColorbuffer();
+	float targetWidth = (float)renderbuffer->getWidth();
+	float targetHeight = (float)renderbuffer->getHeight();
+	float x0 = 2.0f * x / targetWidth - 1.0f;
+	float y0 = 2.0f * y / targetHeight - 1.0f;
+	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;
+	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;
+	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);
+
+	float vertices[][3] = {{x0, y0, Zw},
+	                       {x0, y1, Zw},
+	                       {x1, y0, Zw},
+	                       {x1, y1, Zw}};
+
+	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented
+	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);
+	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);
+	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);
+	int Ucr = texture->getCropRectU();
+	int Vcr = texture->getCropRectV();
+	int Wcr = texture->getCropRectW();
+	int Hcr = texture->getCropRectH();
+
+	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},
+	                        {Ucr / textureWidth, (Vcr + Hcr) / textureHeight},
+	                        {(Ucr + Wcr) / textureWidth, Vcr / textureHeight},
+	                        {(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};
+
+	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];
+	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];
+	gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;
+	mState.arrayBuffer = nullptr;
+
+	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+	sw::Matrix P = projectionStack.current();
+	sw::Matrix M = modelViewStack.current();
+	sw::Matrix T = textureStack0.current();
+
+	projectionStack.identity();
+	modelViewStack.identity();
+	textureStack0.identity();
+
+	drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+	// Restore state
+	mState.vertexAttribute[sw::Position] = oldPositionAttribute;
+	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;
+	mState.arrayBuffer = oldArrayBuffer;
+	oldArrayBuffer = nullptr;
+	oldPositionAttribute.mBoundBuffer = nullptr;
+	oldTexCoord0Attribute.mBoundBuffer = nullptr;
+	textureStack0.load(T);
+	modelViewStack.load(M);
+	projectionStack.load(P);
+}
+
+void Context::finish()
+{
+	device->finish();
+}
+
+void Context::flush()
+{
+	// We don't queue anything without processing it as fast as possible
+}
+
+void Context::recordInvalidEnum()
+{
+	mInvalidEnum = true;
+}
+
+void Context::recordInvalidValue()
+{
+	mInvalidValue = true;
+}
+
+void Context::recordInvalidOperation()
+{
+	mInvalidOperation = true;
+}
+
+void Context::recordOutOfMemory()
+{
+	mOutOfMemory = true;
+}
+
+void Context::recordInvalidFramebufferOperation()
+{
+	mInvalidFramebufferOperation = true;
+}
+
+void Context::recordMatrixStackOverflow()
+{
+	mMatrixStackOverflow = true;
+}
+
+void Context::recordMatrixStackUnderflow()
+{
+	mMatrixStackUnderflow = true;
+}
+
+// Get one of the recorded errors and clear its flag, if any.
+// [OpenGL ES 2.0.24] section 2.5 page 13.
+GLenum Context::getError()
+{
+	if(mInvalidEnum)
+	{
+		mInvalidEnum = false;
+
+		return GL_INVALID_ENUM;
+	}
+
+	if(mInvalidValue)
+	{
+		mInvalidValue = false;
+
+		return GL_INVALID_VALUE;
+	}
+
+	if(mInvalidOperation)
+	{
+		mInvalidOperation = false;
+
+		return GL_INVALID_OPERATION;
+	}
+
+	if(mOutOfMemory)
+	{
+		mOutOfMemory = false;
+
+		return GL_OUT_OF_MEMORY;
+	}
+
+	if(mInvalidFramebufferOperation)
+	{
+		mInvalidFramebufferOperation = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
+	}
+
+	if(mMatrixStackOverflow)
+	{
+		mMatrixStackOverflow = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
+	}
+
+	if(mMatrixStackUnderflow)
+	{
+		mMatrixStackUnderflow = false;
+
+		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
+	}
+
+	return GL_NO_ERROR;
+}
+
+int Context::getSupportedMultisampleCount(int requested)
+{
+	int supported = 0;
+
+	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
+	{
+		if(supported >= requested)
+		{
+			return supported;
+		}
+
+		supported = multisampleCount[i];
+	}
+
+	return supported;
+}
+
+void Context::detachBuffer(GLuint buffer)
+{
+	// [OpenGL ES 2.0.24] section 2.9 page 22:
+	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
+	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
+
+	if(mState.arrayBuffer.name() == buffer)
+	{
+		mState.arrayBuffer = nullptr;
+	}
+
+	if(mState.elementArrayBuffer.name() == buffer)
+	{
+		mState.elementArrayBuffer = nullptr;
+	}
+
+	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+	{
+		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
+		{
+			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
+		}
+	}
+}
+
+void Context::detachTexture(GLuint texture)
+{
+	// [OpenGL ES 2.0.24] section 3.8 page 84:
+	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
+	// rebound to texture object zero
+
+	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+	{
+		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
+		{
+			if(mState.samplerTexture[type][sampler].name() == texture)
+			{
+				mState.samplerTexture[type][sampler] = nullptr;
+			}
+		}
+	}
+
+	// [OpenGL ES 2.0.24] section 4.4 page 112:
+	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
+	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
+	// image was attached in the currently bound framebuffer.
+
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(framebuffer)
+	{
+		framebuffer->detachTexture(texture);
+	}
+}
+
+void Context::detachFramebuffer(GLuint framebuffer)
+{
+	// [OpenGL ES 2.0.24] section 4.4 page 107:
+	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
+	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
+
+	if(mState.framebuffer == framebuffer)
+	{
+		bindFramebuffer(0);
+	}
+}
+
+void Context::detachRenderbuffer(GLuint renderbuffer)
+{
+	// [OpenGL ES 2.0.24] section 4.4 page 109:
+	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
+	// had been executed with the target RENDERBUFFER and name of zero.
+
+	if(mState.renderbuffer.name() == renderbuffer)
+	{
+		bindRenderbuffer(0);
+	}
+
+	// [OpenGL ES 2.0.24] section 4.4 page 111:
+	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
+	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
+	// point to which this image was attached in the currently bound framebuffer.
+
+	Framebuffer *framebuffer = getFramebuffer();
+
+	if(framebuffer)
+	{
+		framebuffer->detachRenderbuffer(renderbuffer);
+	}
+}
+
+bool Context::cullSkipsDraw(GLenum drawMode)
+{
+	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
+}
+
+bool Context::isTriangleMode(GLenum drawMode)
+{
+	switch(drawMode)
+	{
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLE_STRIP:
+		return true;
+	case GL_POINTS:
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+		return false;
+	default: UNREACHABLE(drawMode);
+	}
+
+	return false;
+}
+
+void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+	mState.vertexAttribute[index].mCurrentValue[0] = x;
+	mState.vertexAttribute[index].mCurrentValue[1] = y;
+	mState.vertexAttribute[index].mCurrentValue[2] = z;
+	mState.vertexAttribute[index].mCurrentValue[3] = w;
+
+	mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::bindTexImage(egl::Surface *surface)
+{
+	es1::Texture2D *textureObject = getTexture2D();
+
+	if(textureObject)
+	{
+		textureObject->bindTexImage(surface);
+	}
+}
+
+EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+	switch(target)
+	{
+	case EGL_GL_TEXTURE_2D_KHR:
+		break;
+	case EGL_GL_RENDERBUFFER_KHR:
+		break;
+	default:
+		return EGL_BAD_PARAMETER;
+	}
+
+	if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return EGL_BAD_MATCH;
+	}
+
+	if(target == EGL_GL_TEXTURE_2D_KHR)
+	{
+		Texture *texture = getTexture(name);
+
+		if(!texture || texture->getTarget() != GL_TEXTURE_2D)
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
+		{
+			return EGL_BAD_ACCESS;
+		}
+
+		if(textureLevel != 0 && !texture->isSamplerComplete())
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+		{
+			return EGL_BAD_PARAMETER;
+		}
+	}
+	else if(target == EGL_GL_RENDERBUFFER_KHR)
+	{
+		Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+		if(!renderbuffer)
+		{
+			return EGL_BAD_PARAMETER;
+		}
+
+		if(renderbuffer->isShared())   // Already an EGLImage sibling
+		{
+			return EGL_BAD_ACCESS;
+		}
+	}
+	else UNREACHABLE(target);
+
+	return EGL_SUCCESS;
+}
+
+egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+	if(target == EGL_GL_TEXTURE_2D_KHR)
+	{
+		es1::Texture *texture = getTexture(name);
+
+		return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
+	}
+	else if(target == EGL_GL_RENDERBUFFER_KHR)
+	{
+		es1::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+		return renderbuffer->createSharedImage();
+	}
+	else UNREACHABLE(target);
+
+	return 0;
+}
+
+Device *Context::getDevice()
+{
+	return device;
+}
+
+void Context::setMatrixMode(GLenum mode)
+{
+	matrixMode = mode;
+}
+
+sw::MatrixStack &Context::currentMatrixStack()
+{
+	switch(matrixMode)
+	{
+	case GL_MODELVIEW:
+		return modelViewStack;
+	case GL_PROJECTION:
+		return projectionStack;
+	case GL_TEXTURE:
+		switch(mState.activeSampler)
+		{
+		case 0: return textureStack0;
+		case 1: return textureStack1;
+		}
+		break;
+	}
+
+	UNREACHABLE(matrixMode);
+	return textureStack0;
+}
+
+void Context::loadIdentity()
+{
+	currentMatrixStack().identity();
+}
+
+void Context::load(const GLfloat *m)
+{
+	currentMatrixStack().load(m);
+}
+
+void Context::pushMatrix()
+{
+	if(!currentMatrixStack().push())
+	{
+		return error(GL_STACK_OVERFLOW);
+	}
+}
+
+void Context::popMatrix()
+{
+	if(!currentMatrixStack().pop())
+	{
+		return error(GL_STACK_OVERFLOW);
+	}
+}
+
+void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	currentMatrixStack().rotate(angle, x, y, z);
+}
+
+void Context::translate(GLfloat x, GLfloat y, GLfloat z)
+{
+	currentMatrixStack().translate(x, y, z);
+}
+
+void Context::scale(GLfloat x, GLfloat y, GLfloat z)
+{
+	currentMatrixStack().scale(x, y, z);
+}
+
+void Context::multiply(const GLfloat *m)
+{
+	currentMatrixStack().multiply(m);
+}
+
+void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
+}
+
+void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
+}
+
+void Context::setClipPlane(int index, const float plane[4])
+{
+	sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);
+	device->setClipPlane(index, &clipPlane.A);
+}
+
+void Context::setClipPlaneEnabled(int index, bool enable)
+{
+	clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);
+	device->setClipFlags(clipFlags);
+}
+
+bool Context::isClipPlaneEnabled(int index) const
+{
+	return (clipFlags & (1 << index)) != 0;
+}
+
+void Context::setColorLogicOpEnabled(bool enable)
+{
+	colorLogicOpEnabled = enable;
+}
+
+bool Context::isColorLogicOpEnabled() const
+{
+	return colorLogicOpEnabled;
+}
+
+void Context::setLogicalOperation(GLenum logicOp)
+{
+	logicalOperation = logicOp;
+}
+
+void Context::setLineSmoothEnabled(bool enable)
+{
+	lineSmoothEnabled = enable;
+}
+
+bool Context::isLineSmoothEnabled() const
+{
+	return lineSmoothEnabled;
+}
+
+void Context::setColorMaterialEnabled(bool enable)
+{
+	colorMaterialEnabled = enable;
+}
+
+bool Context::isColorMaterialEnabled() const
+{
+	return colorMaterialEnabled;
+}
+
+void Context::setNormalizeEnabled(bool enable)
+{
+	normalizeEnabled = enable;
+}
+
+bool Context::isNormalizeEnabled() const
+{
+	return normalizeEnabled;
+}
+
+void Context::setRescaleNormalEnabled(bool enable)
+{
+	rescaleNormalEnabled = enable;
+}
+
+bool Context::isRescaleNormalEnabled() const
+{
+	return rescaleNormalEnabled;
+}
+
+void Context::setVertexArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;
+}
+
+bool Context::isVertexArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::Position].mArrayEnabled;
+}
+
+void Context::setNormalArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;
+}
+
+bool Context::isNormalArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::Normal].mArrayEnabled;
+}
+
+void Context::setColorArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;
+}
+
+bool Context::isColorArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::Color0].mArrayEnabled;
+}
+
+void Context::setPointSizeArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;
+}
+
+bool Context::isPointSizeArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;
+}
+
+void Context::setTextureCoordArrayEnabled(bool enable)
+{
+	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;
+}
+
+bool Context::isTextureCoordArrayEnabled() const
+{
+	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;
+}
+
+void Context::setMultisampleEnabled(bool enable)
+{
+	multisampleEnabled = enable;
+}
+
+bool Context::isMultisampleEnabled() const
+{
+	return multisampleEnabled;
+}
+
+void Context::setSampleAlphaToOneEnabled(bool enable)
+{
+	sampleAlphaToOneEnabled = enable;
+}
+
+bool Context::isSampleAlphaToOneEnabled() const
+{
+	return sampleAlphaToOneEnabled;
+}
+
+void Context::setPointSpriteEnabled(bool enable)
+{
+	pointSpriteEnabled = enable;
+}
+
+bool Context::isPointSpriteEnabled() const
+{
+	return pointSpriteEnabled;
+}
+
+void Context::setPointSmoothEnabled(bool enable)
+{
+	pointSmoothEnabled = enable;
+}
+
+bool Context::isPointSmoothEnabled() const
+{
+	return pointSmoothEnabled;
+}
+
+void Context::setPointSizeMin(float min)
+{
+	pointSizeMin = min;
+}
+
+void Context::setPointSizeMax(float max)
+{
+	pointSizeMax = max;
+}
+
+void Context::setPointDistanceAttenuation(float a, float b, float c)
+{
+	pointDistanceAttenuation = {a, b, c};
+}
+
+void Context::setPointFadeThresholdSize(float threshold)
+{
+	pointFadeThresholdSize = threshold;
+}
+
+void Context::clientActiveTexture(GLenum texture)
+{
+	clientTexture = texture;
+}
+
+GLenum Context::getClientActiveTexture() const
+{
+	return clientTexture;
+}
+
+unsigned int Context::getActiveTexture() const
+{
+	return mState.activeSampler;
+}
+
+}
+
+egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)
+{
+	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext
+	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));
+}
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index 90293e3..9051e02 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -1,680 +1,683 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Context.h: Defines the Context class, managing all GL state and performing

-// rendering operations. It is the GLES2 specific implementation of EGLContext.

-

-#ifndef LIBGLES_CM_CONTEXT_H_

-#define LIBGLES_CM_CONTEXT_H_

-

-#include "libEGL/Context.hpp"

-#include "ResourceManager.h"

-#include "common/NameSpace.hpp"

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-#include "Renderer/Sampler.hpp"

-#include "common/MatrixStack.hpp"

-

-#include <GLES/gl.h>

-#include <GLES/glext.h>

-#include <EGL/egl.h>

-

-#include <map>

-#include <string>

-

-namespace egl

-{

-class Display;

-class Surface;

-class Config;

-}

-

-namespace es1

-{

-struct TranslatedAttribute;

-struct TranslatedIndexData;

-

-class Device;

-class Buffer;

-class Texture;

-class Texture2D;

-class TextureExternal;

-class Framebuffer;

-class Renderbuffer;

-class RenderbufferStorage;

-class Colorbuffer;

-class Depthbuffer;

-class StreamingIndexBuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-class VertexDataManager;

-class IndexDataManager;

-

-enum

-{

-    MAX_VERTEX_ATTRIBS = sw::VERTEX_ATTRIBUTES,

-    MAX_VARYING_VECTORS = 10,

-    MAX_TEXTURE_UNITS = 2,

-    MAX_DRAW_BUFFERS = 1,

-	MAX_LIGHTS = 8,

-	MAX_CLIP_PLANES = sw::MAX_CLIP_PLANES,

-

-	MAX_MODELVIEW_STACK_DEPTH = 32,

-	MAX_PROJECTION_STACK_DEPTH = 2,

-	MAX_TEXTURE_STACK_DEPTH = 2,

-};

-

-const GLenum compressedTextureFormats[] =

-{

-	GL_ETC1_RGB8_OES,

-#if (S3TC_SUPPORT)

-	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,

-	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,

-#endif

-};

-

-const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);

-

-const GLint multisampleCount[] = {4, 2, 1};

-const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);

-const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];

-

-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;

-const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;

-const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;

-const float SMOOTH_LINE_WIDTH_RANGE_MIN = 1.0f;

-const float SMOOTH_LINE_WIDTH_RANGE_MAX = 1.0f;

-const float SMOOTH_POINT_SIZE_RANGE_MIN = 0.125f;

-const float SMOOTH_POINT_SIZE_RANGE_MAX = 8192.0f;

-const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;

-

-struct Color

-{

-    float red;

-    float green;

-    float blue;

-    float alpha;

-};

-

-struct Point

-{

-	float x;

-	float y;

-	float z;

-	float w;

-};

-

-struct Vector

-{

-	float x;

-	float y;

-	float z;

-};

-

-struct Attenuation

-{

-	float constant;

-	float linear;

-	float quadratic;

-};

-

-struct Light

-{

-	bool enabled;

-	Color ambient;

-	Color diffuse;

-	Color specular;

-	Point position;

-	Vector direction;

-	Attenuation attenuation;

-	float spotExponent;

-	float spotCutoffAngle;

-};

-

-// Helper structure describing a single vertex attribute

-class VertexAttribute

-{

-public:

-    VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)

-    {

-        mCurrentValue[0] = 0.0f;

-        mCurrentValue[1] = 0.0f;

-        mCurrentValue[2] = 0.0f;

-        mCurrentValue[3] = 1.0f;

-    }

-

-    int typeSize() const

-    {

-        switch(mType)

-        {

-        case GL_BYTE:           return mSize * sizeof(GLbyte);

-        case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);

-        case GL_SHORT:          return mSize * sizeof(GLshort);

-        case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);

-        case GL_FIXED:          return mSize * sizeof(GLfixed);

-        case GL_FLOAT:          return mSize * sizeof(GLfloat);

-        default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);

-        }

-    }

-

-    GLsizei stride() const

-    {

-        return mStride ? mStride : typeSize();

-    }

-

-    // From glVertexAttribPointer

-    GLenum mType;

-    GLint mSize;

-    bool mNormalized;

-    GLsizei mStride;   // 0 means natural stride

-

-    union

-    {

-        const void *mPointer;

-        intptr_t mOffset;

-    };

-

-    gl::BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.

-

-    bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray

-    float mCurrentValue[4];   // From glVertexAttrib

-};

-

-typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];

-

-struct TextureUnit

-{

-	Color color;

-	GLenum environmentMode;

-	GLenum combineRGB;

-	GLenum combineAlpha;

-	GLenum src0RGB;

-	GLenum src0Alpha;

-	GLenum src1RGB;

-	GLenum src1Alpha;

-	GLenum src2RGB;

-	GLenum src2Alpha;

-	GLenum operand0RGB;

-	GLenum operand0Alpha;

-	GLenum operand1RGB;

-	GLenum operand1Alpha;

-	GLenum operand2RGB;

-	GLenum operand2Alpha;

-};

-

-// Helper structure to store all raw state

-struct State

-{

-    Color colorClearValue;

-    GLclampf depthClearValue;

-    int stencilClearValue;

-

-    bool cullFaceEnabled;

-    GLenum cullMode;

-    GLenum frontFace;

-    bool depthTestEnabled;

-    GLenum depthFunc;

-    bool blendEnabled;

-    GLenum sourceBlendRGB;

-    GLenum destBlendRGB;

-    GLenum sourceBlendAlpha;

-    GLenum destBlendAlpha;

-    GLenum blendEquationRGB;

-    GLenum blendEquationAlpha;

-    bool stencilTestEnabled;

-    GLenum stencilFunc;

-    GLint stencilRef;

-    GLuint stencilMask;

-    GLenum stencilFail;

-    GLenum stencilPassDepthFail;

-    GLenum stencilPassDepthPass;

-    GLuint stencilWritemask;

-    bool polygonOffsetFillEnabled;

-    GLfloat polygonOffsetFactor;

-    GLfloat polygonOffsetUnits;

-    bool sampleAlphaToCoverageEnabled;

-    bool sampleCoverageEnabled;

-    GLclampf sampleCoverageValue;

-    bool sampleCoverageInvert;

-    bool scissorTestEnabled;

-    bool ditherEnabled;

-	GLenum shadeModel;

-

-    GLfloat lineWidth;

-

-    GLenum generateMipmapHint;

-	GLenum perspectiveCorrectionHint;

-	GLenum fogHint;

-

-    GLint viewportX;

-    GLint viewportY;

-    GLsizei viewportWidth;

-    GLsizei viewportHeight;

-    float zNear;

-    float zFar;

-

-    GLint scissorX;

-    GLint scissorY;

-    GLsizei scissorWidth;

-    GLsizei scissorHeight;

-

-    bool colorMaskRed;

-    bool colorMaskGreen;

-    bool colorMaskBlue;

-    bool colorMaskAlpha;

-    bool depthMask;

-

-    unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0

-    gl::BindingPointer<Buffer> arrayBuffer;

-    gl::BindingPointer<Buffer> elementArrayBuffer;

-    GLuint framebuffer;

-    gl::BindingPointer<Renderbuffer> renderbuffer;

-

-    VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];

-    gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_TEXTURE_UNITS];

-

-    GLint unpackAlignment;

-    GLint packAlignment;

-

-	TextureUnit textureUnit[MAX_TEXTURE_UNITS];

-};

-

-class Context : public egl::Context

-{

-public:

-    Context(const egl::Config *config, const Context *shareContext);

-

-	virtual void makeCurrent(egl::Surface *surface);

-	virtual int getClientVersion() const;

-    virtual void finish();

-

-    void markAllStateDirty();

-

-    // State manipulation

-    void setClearColor(float red, float green, float blue, float alpha);

-    void setClearDepth(float depth);

-    void setClearStencil(int stencil);

-

-    void setCullFaceEnabled(bool enabled);

-    bool isCullFaceEnabled() const;

-    void setCullMode(GLenum mode);

-    void setFrontFace(GLenum front);

-

-    void setDepthTestEnabled(bool enabled);

-    bool isDepthTestEnabled() const;

-    void setDepthFunc(GLenum depthFunc);

-    void setDepthRange(float zNear, float zFar);

-

-	void setAlphaTestEnabled(bool enabled);

-    bool isAlphaTestEnabled() const;

-    void setAlphaFunc(GLenum alphaFunc, GLclampf reference);

-

-    void setBlendEnabled(bool enabled);

-    bool isBlendEnabled() const;

-    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);

-    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);

-

-    void setStencilTestEnabled(bool enabled);

-    bool isStencilTestEnabled() const;

-    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);

-    void setStencilWritemask(GLuint stencilWritemask);

-    void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);

-

-    void setPolygonOffsetFillEnabled(bool enabled);

-    bool isPolygonOffsetFillEnabled() const;

-    void setPolygonOffsetParams(GLfloat factor, GLfloat units);

-

-    void setSampleAlphaToCoverageEnabled(bool enabled);

-    bool isSampleAlphaToCoverageEnabled() const;

-    void setSampleCoverageEnabled(bool enabled);

-    bool isSampleCoverageEnabled() const;

-    void setSampleCoverageParams(GLclampf value, bool invert);

-

-	void setShadeModel(GLenum mode);

-    void setDitherEnabled(bool enabled);

-    bool isDitherEnabled() const;

-	void setLightingEnabled(bool enabled);

-	bool isLightingEnabled() const;

-	void setLightEnabled(int index, bool enable);

-	bool isLightEnabled(int index) const;

-	void setLightAmbient(int index, float r, float g, float b, float a);

-	void setLightDiffuse(int index, float r, float g, float b, float a);

-	void setLightSpecular(int index, float r, float g, float b, float a);

-	void setLightPosition(int index, float x, float y, float z, float w);

-	void setLightDirection(int index, float x, float y, float z);

-	void setLightAttenuationConstant(int index, float constant);

-	void setLightAttenuationLinear(int index, float linear);

-	void setLightAttenuationQuadratic(int index, float quadratic);

-	void setSpotLightExponent(int index, float exponent);

-	void setSpotLightCutoff(int index, float cutoff);

-

-	void setGlobalAmbient(float red, float green, float blue, float alpha);

-	void setMaterialAmbient(float red, float green, float blue, float alpha);

-	void setMaterialDiffuse(float red, float green, float blue, float alpha);

-	void setMaterialSpecular(float red, float green, float blue, float alpha);

-	void setMaterialEmission(float red, float green, float blue, float alpha);

-	void setMaterialShininess(float shininess);

-	void setLightModelTwoSide(bool enable);

-

-	void setFogEnabled(bool enabled);

-	bool isFogEnabled() const;

-	void setFogMode(GLenum mode);

-	void setFogDensity(float fogDensity);

-	void setFogStart(float fogStart);

-	void setFogEnd(float fogEnd);

-	void setFogColor(float r, float g, float b, float a);

-

-    void setTexture2Denabled(bool enabled);

-	bool isTexture2Denabled() const;

-	void setTextureExternalEnabled(bool enabled);

-	bool isTextureExternalEnabled() const;

-    void clientActiveTexture(GLenum texture);

-	GLenum getClientActiveTexture() const;

-	unsigned int getActiveTexture() const;

-

-	void setTextureEnvMode(GLenum texEnvMode);

-	void setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

-	void setCombineRGB(GLenum combineRGB);

-	void setCombineAlpha(GLenum combineAlpha);

-	void setOperand0RGB(GLenum operand);

-	void setOperand1RGB(GLenum operand);

-	void setOperand2RGB(GLenum operand);

-	void setOperand0Alpha(GLenum operand);

-	void setOperand1Alpha(GLenum operand);

-	void setOperand2Alpha(GLenum operand);

-	void setSrc0RGB(GLenum src);

-	void setSrc1RGB(GLenum src);

-	void setSrc2RGB(GLenum src);

-	void setSrc0Alpha(GLenum src);

-	void setSrc1Alpha(GLenum src);

-	void setSrc2Alpha(GLenum src);

-

-    void setLineWidth(GLfloat width);

-

-    void setGenerateMipmapHint(GLenum hint);

-	void setPerspectiveCorrectionHint(GLenum hint);

-	void setFogHint(GLenum hint);

-

-    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-	void setScissorTestEnabled(bool enabled);

-    bool isScissorTestEnabled() const;

-    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);

-

-    void setColorMask(bool red, bool green, bool blue, bool alpha);

-    void setDepthMask(bool mask);

-

-    void setActiveSampler(unsigned int active);

-

-    GLuint getFramebufferName() const;

-    GLuint getRenderbufferName() const;

-

-    GLuint getArrayBufferName() const;

-

-    void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);

-    const VertexAttribute &getVertexAttribState(unsigned int attribNum);

-    void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,

-                              bool normalized, GLsizei stride, const void *pointer);

-    const void *getVertexAttribPointer(unsigned int attribNum) const;

-

-    const VertexAttributeArray &getVertexAttributes();

-

-    void setUnpackAlignment(GLint alignment);

-    GLint getUnpackAlignment() const;

-

-    void setPackAlignment(GLint alignment);

-    GLint getPackAlignment() const;

-

-    // These create and destroy methods are merely pass-throughs to

-    // ResourceManager, which owns these object types

-    GLuint createBuffer();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-

-    void deleteBuffer(GLuint buffer);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-

-    // Framebuffers are owned by the Context, so these methods do not pass through

-    GLuint createFramebuffer();

-    void deleteFramebuffer(GLuint framebuffer);

-

-    void bindArrayBuffer(GLuint buffer);

-    void bindElementArrayBuffer(GLuint buffer);

-    void bindTexture2D(GLuint texture);

-    void bindTextureExternal(GLuint texture);

-    void bindFramebuffer(GLuint framebuffer);

-    void bindRenderbuffer(GLuint renderbuffer);

-

-    void setFramebufferZero(Framebuffer *framebuffer);

-

-    void setRenderbufferStorage(RenderbufferStorage *renderbuffer);

-

-    void setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);

-

-    Buffer *getBuffer(GLuint handle);

-    virtual Texture *getTexture(GLuint handle);

-    Framebuffer *getFramebuffer(GLuint handle);

-    virtual Renderbuffer *getRenderbuffer(GLuint handle);

-

-    Buffer *getArrayBuffer();

-    Buffer *getElementArrayBuffer();

-    Texture2D *getTexture2D();

-    TextureExternal *getTextureExternal();

-    Texture *getSamplerTexture(unsigned int sampler, TextureType type);

-    Framebuffer *getFramebuffer();

-

-    bool getFloatv(GLenum pname, GLfloat *params);

-    bool getIntegerv(GLenum pname, GLint *params);

-    bool getBooleanv(GLenum pname, GLboolean *params);

-    bool getPointerv(GLenum pname, const GLvoid **params);

-

-    int getQueryParameterNum(GLenum pname);

-	bool isQueryParameterInt(GLenum pname);

-	bool isQueryParameterFloat(GLenum pname);

-	bool isQueryParameterBool(GLenum pname);

-	bool isQueryParameterPointer(GLenum pname);

-

-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);

-    void clear(GLbitfield mask);

-    void drawArrays(GLenum mode, GLint first, GLsizei count);

-    void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);

-    void drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);

-    void flush();

-

-    void recordInvalidEnum();

-    void recordInvalidValue();

-    void recordInvalidOperation();

-    void recordOutOfMemory();

-    void recordInvalidFramebufferOperation();

-	void recordMatrixStackOverflow();

-	void recordMatrixStackUnderflow();

-

-    GLenum getError();

-

-    static int getSupportedMultisampleCount(int requested);

-

-	virtual void bindTexImage(egl::Surface *surface);

-	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);

-	virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);

-

-	Device *getDevice();

-

-    void setMatrixMode(GLenum mode);

-    void loadIdentity();

-	void load(const GLfloat *m);

-    void pushMatrix();

-    void popMatrix();

-    void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

-    void translate(GLfloat x, GLfloat y, GLfloat z);

-	void scale(GLfloat x, GLfloat y, GLfloat z);

-    void multiply(const GLfloat *m);

-	void frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-    void ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-

-	void setClipPlane(int index, const float plane[4]);

-	void setClipPlaneEnabled(int index, bool enable);

-	bool isClipPlaneEnabled(int index) const;

-

-	void setColorLogicOpEnabled(bool enable);

-	bool isColorLogicOpEnabled() const;

-	void setLogicalOperation(GLenum logicOp);

-

-	void setPointSmoothEnabled(bool enable);

-	bool isPointSmoothEnabled() const;

-

-	void setLineSmoothEnabled(bool enable);

-	bool isLineSmoothEnabled() const;

-

-	void setColorMaterialEnabled(bool enable);

-	bool isColorMaterialEnabled() const;

-

-	void setNormalizeEnabled(bool enable);

-	bool isNormalizeEnabled() const;

-

-	void setRescaleNormalEnabled(bool enable);

-	bool isRescaleNormalEnabled() const;

-

-	void setVertexArrayEnabled(bool enable);

-	bool isVertexArrayEnabled() const;

-

-	void setNormalArrayEnabled(bool enable);

-	bool isNormalArrayEnabled() const;

-

-	void setColorArrayEnabled(bool enable);

-	bool isColorArrayEnabled() const;

-

-	void setPointSizeArrayEnabled(bool enable);

-	bool isPointSizeArrayEnabled() const;

-

-	void setTextureCoordArrayEnabled(bool enable);

-	bool isTextureCoordArrayEnabled() const;

-

-	void setMultisampleEnabled(bool enable);

-	bool isMultisampleEnabled() const;

-

-	void setSampleAlphaToOneEnabled(bool enable);

-	bool isSampleAlphaToOneEnabled() const;

-

-	void setPointSpriteEnabled(bool enable);

-	bool isPointSpriteEnabled() const;

-	void setPointSizeMin(float min);

-	void setPointSizeMax(float max);

-	void setPointDistanceAttenuation(float a, float b, float c);

-	void setPointFadeThresholdSize(float threshold);

-

-private:

-	virtual ~Context();

-

-    bool applyRenderTarget();

-    void applyState(GLenum drawMode);

-    GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);

-    GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);

-    void applyTextures();

-	void applyTexture(int sampler, Texture *texture);

-

-    void detachBuffer(GLuint buffer);

-    void detachTexture(GLuint texture);

-    void detachFramebuffer(GLuint framebuffer);

-    void detachRenderbuffer(GLuint renderbuffer);

-

-    bool cullSkipsDraw(GLenum drawMode);

-    bool isTriangleMode(GLenum drawMode);

-

-    State mState;

-

-    gl::BindingPointer<Texture2D> mTexture2DZero;

-    gl::BindingPointer<TextureExternal> mTextureExternalZero;

-

-	gl::NameSpace<Framebuffer> mFramebufferNameSpace;

-

-    VertexDataManager *mVertexDataManager;

-    IndexDataManager *mIndexDataManager;

-

-	bool lightingEnabled;

-	Light light[MAX_LIGHTS];

-	Color globalAmbient;

-	Color materialAmbient;

-	Color materialDiffuse;

-	Color materialSpecular;

-	Color materialEmission;

-	GLfloat materialShininess;

-	bool lightModelTwoSide;

-

-    // Recorded errors

-    bool mInvalidEnum;

-    bool mInvalidValue;

-    bool mInvalidOperation;

-    bool mOutOfMemory;

-    bool mInvalidFramebufferOperation;

-	bool mMatrixStackOverflow;

-	bool mMatrixStackUnderflow;

-

-    bool mHasBeenCurrent;

-

-    // state caching flags

-    bool mDepthStateDirty;

-    bool mMaskStateDirty;

-    bool mBlendStateDirty;

-    bool mStencilStateDirty;

-    bool mPolygonOffsetStateDirty;

-    bool mSampleStateDirty;

-    bool mFrontFaceDirty;

-    bool mDitherStateDirty;

-

-	sw::MatrixStack &currentMatrixStack();

-	GLenum matrixMode;

-    sw::MatrixStack modelViewStack;

-	sw::MatrixStack projectionStack;

-	sw::MatrixStack textureStack0;

-	sw::MatrixStack textureStack1;

-

-	bool texture2Denabled[MAX_TEXTURE_UNITS];

-	bool textureExternalEnabled[MAX_TEXTURE_UNITS];

-	GLenum clientTexture;

-

-	int clipFlags;

-

-	bool alphaTestEnabled;

-	GLenum alphaTestFunc;

-	float alphaTestRef;

-

-	bool fogEnabled;

-	GLenum fogMode;

-	float fogDensity;

-	float fogStart;

-	float fogEnd;

-	Color fogColor;

-

-	bool lineSmoothEnabled;

-	bool colorMaterialEnabled;

-	bool normalizeEnabled;

-	bool rescaleNormalEnabled;

-	bool multisampleEnabled;

-	bool sampleAlphaToOneEnabled;

-

-	bool pointSpriteEnabled;

-	bool pointSmoothEnabled;

-	float pointSizeMin;

-	float pointSizeMax;

-	Attenuation pointDistanceAttenuation;

-	float pointFadeThresholdSize;

-

-	bool colorLogicOpEnabled;

-	GLenum logicalOperation;

-

-	Device *device;

-    ResourceManager *mResourceManager;

-};

-}

-

-#endif   // INCLUDE_CONTEXT_H_

+// 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.
+
+// Context.h: Defines the Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#ifndef LIBGLES_CM_CONTEXT_H_
+#define LIBGLES_CM_CONTEXT_H_
+
+#include "libEGL/Context.hpp"
+#include "ResourceManager.h"
+#include "common/NameSpace.hpp"
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+#include "Renderer/Sampler.hpp"
+#include "common/MatrixStack.hpp"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/egl.h>
+
+#include <map>
+#include <string>
+
+namespace egl
+{
+class Display;
+class Surface;
+class Config;
+}
+
+namespace es1
+{
+struct TranslatedAttribute;
+struct TranslatedIndexData;
+
+class Device;
+class Buffer;
+class Texture;
+class Texture2D;
+class TextureExternal;
+class Framebuffer;
+class Renderbuffer;
+class RenderbufferStorage;
+class Colorbuffer;
+class Depthbuffer;
+class StreamingIndexBuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+class VertexDataManager;
+class IndexDataManager;
+
+enum
+{
+	MAX_VERTEX_ATTRIBS = sw::VERTEX_ATTRIBUTES,
+	MAX_VARYING_VECTORS = 10,
+	MAX_TEXTURE_UNITS = 2,
+	MAX_DRAW_BUFFERS = 1,
+	MAX_LIGHTS = 8,
+	MAX_CLIP_PLANES = sw::MAX_CLIP_PLANES,
+
+	MAX_MODELVIEW_STACK_DEPTH = 32,
+	MAX_PROJECTION_STACK_DEPTH = 2,
+	MAX_TEXTURE_STACK_DEPTH = 2,
+};
+
+const GLenum compressedTextureFormats[] =
+{
+	GL_ETC1_RGB8_OES,
+#if (S3TC_SUPPORT)
+	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+#endif
+};
+
+const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
+
+const GLint multisampleCount[] = {4, 2, 1};
+const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);
+const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];
+
+const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;
+const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;
+const float SMOOTH_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float SMOOTH_LINE_WIDTH_RANGE_MAX = 1.0f;
+const float SMOOTH_POINT_SIZE_RANGE_MIN = 0.125f;
+const float SMOOTH_POINT_SIZE_RANGE_MAX = 8192.0f;
+const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;
+
+struct Color
+{
+	float red;
+	float green;
+	float blue;
+	float alpha;
+};
+
+struct Point
+{
+	float x;
+	float y;
+	float z;
+	float w;
+};
+
+struct Vector
+{
+	float x;
+	float y;
+	float z;
+};
+
+struct Attenuation
+{
+	float constant;
+	float linear;
+	float quadratic;
+};
+
+struct Light
+{
+	bool enabled;
+	Color ambient;
+	Color diffuse;
+	Color specular;
+	Point position;
+	Vector direction;
+	Attenuation attenuation;
+	float spotExponent;
+	float spotCutoffAngle;
+};
+
+// Helper structure describing a single vertex attribute
+class VertexAttribute
+{
+public:
+	VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mStride(0), mPointer(nullptr), mArrayEnabled(false)
+	{
+		mCurrentValue[0] = 0.0f;
+		mCurrentValue[1] = 0.0f;
+		mCurrentValue[2] = 0.0f;
+		mCurrentValue[3] = 1.0f;
+	}
+
+	int typeSize() const
+	{
+		switch(mType)
+		{
+		case GL_BYTE:           return mSize * sizeof(GLbyte);
+		case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);
+		case GL_SHORT:          return mSize * sizeof(GLshort);
+		case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
+		case GL_FIXED:          return mSize * sizeof(GLfixed);
+		case GL_FLOAT:          return mSize * sizeof(GLfloat);
+		default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);
+		}
+	}
+
+	GLsizei stride() const
+	{
+		return mStride ? mStride : typeSize();
+	}
+
+	// From glVertexAttribPointer
+	GLenum mType;
+	GLint mSize;
+	bool mNormalized;
+	GLsizei mStride;   // 0 means natural stride
+
+	union
+	{
+		const void *mPointer;
+		intptr_t mOffset;
+	};
+
+	gl::BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
+
+	bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
+	float mCurrentValue[4];   // From glVertexAttrib
+};
+
+typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
+
+struct TextureUnit
+{
+	Color color;
+	GLenum environmentMode;
+	GLenum combineRGB;
+	GLenum combineAlpha;
+	GLenum src0RGB;
+	GLenum src0Alpha;
+	GLenum src1RGB;
+	GLenum src1Alpha;
+	GLenum src2RGB;
+	GLenum src2Alpha;
+	GLenum operand0RGB;
+	GLenum operand0Alpha;
+	GLenum operand1RGB;
+	GLenum operand1Alpha;
+	GLenum operand2RGB;
+	GLenum operand2Alpha;
+};
+
+// Helper structure to store all raw state
+struct State
+{
+	Color colorClearValue;
+	GLclampf depthClearValue;
+	int stencilClearValue;
+
+	bool cullFaceEnabled;
+	GLenum cullMode;
+	GLenum frontFace;
+	bool depthTestEnabled;
+	GLenum depthFunc;
+	bool blendEnabled;
+	GLenum sourceBlendRGB;
+	GLenum destBlendRGB;
+	GLenum sourceBlendAlpha;
+	GLenum destBlendAlpha;
+	GLenum blendEquationRGB;
+	GLenum blendEquationAlpha;
+	bool stencilTestEnabled;
+	GLenum stencilFunc;
+	GLint stencilRef;
+	GLuint stencilMask;
+	GLenum stencilFail;
+	GLenum stencilPassDepthFail;
+	GLenum stencilPassDepthPass;
+	GLuint stencilWritemask;
+	bool polygonOffsetFillEnabled;
+	GLfloat polygonOffsetFactor;
+	GLfloat polygonOffsetUnits;
+	bool sampleAlphaToCoverageEnabled;
+	bool sampleCoverageEnabled;
+	GLclampf sampleCoverageValue;
+	bool sampleCoverageInvert;
+	bool scissorTestEnabled;
+	bool ditherEnabled;
+	GLenum shadeModel;
+
+	GLfloat lineWidth;
+
+	GLenum generateMipmapHint;
+	GLenum perspectiveCorrectionHint;
+	GLenum fogHint;
+
+	GLint viewportX;
+	GLint viewportY;
+	GLsizei viewportWidth;
+	GLsizei viewportHeight;
+	float zNear;
+	float zFar;
+
+	GLint scissorX;
+	GLint scissorY;
+	GLsizei scissorWidth;
+	GLsizei scissorHeight;
+
+	bool colorMaskRed;
+	bool colorMaskGreen;
+	bool colorMaskBlue;
+	bool colorMaskAlpha;
+	bool depthMask;
+
+	unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0
+	gl::BindingPointer<Buffer> arrayBuffer;
+	gl::BindingPointer<Buffer> elementArrayBuffer;
+	GLuint framebuffer;
+	gl::BindingPointer<Renderbuffer> renderbuffer;
+
+	VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
+	gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_TEXTURE_UNITS];
+
+	GLint unpackAlignment;
+	GLint packAlignment;
+
+	TextureUnit textureUnit[MAX_TEXTURE_UNITS];
+};
+
+class Context : public egl::Context
+{
+public:
+	Context(const egl::Config *config, const Context *shareContext);
+
+	virtual void makeCurrent(egl::Surface *surface);
+	virtual int getClientVersion() const;
+	virtual void finish();
+
+	void markAllStateDirty();
+
+	// State manipulation
+	void setClearColor(float red, float green, float blue, float alpha);
+	void setClearDepth(float depth);
+	void setClearStencil(int stencil);
+
+	void setCullFaceEnabled(bool enabled);
+	bool isCullFaceEnabled() const;
+	void setCullMode(GLenum mode);
+	void setFrontFace(GLenum front);
+
+	void setDepthTestEnabled(bool enabled);
+	bool isDepthTestEnabled() const;
+	void setDepthFunc(GLenum depthFunc);
+	void setDepthRange(float zNear, float zFar);
+
+	void setAlphaTestEnabled(bool enabled);
+	bool isAlphaTestEnabled() const;
+	void setAlphaFunc(GLenum alphaFunc, GLclampf reference);
+
+	void setBlendEnabled(bool enabled);
+	bool isBlendEnabled() const;
+	void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
+	void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
+
+	void setStencilTestEnabled(bool enabled);
+	bool isStencilTestEnabled() const;
+	void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
+	void setStencilWritemask(GLuint stencilWritemask);
+	void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
+
+	void setPolygonOffsetFillEnabled(bool enabled);
+	bool isPolygonOffsetFillEnabled() const;
+	void setPolygonOffsetParams(GLfloat factor, GLfloat units);
+
+	void setSampleAlphaToCoverageEnabled(bool enabled);
+	bool isSampleAlphaToCoverageEnabled() const;
+	void setSampleCoverageEnabled(bool enabled);
+	bool isSampleCoverageEnabled() const;
+	void setSampleCoverageParams(GLclampf value, bool invert);
+
+	void setShadeModel(GLenum mode);
+	void setDitherEnabled(bool enabled);
+	bool isDitherEnabled() const;
+	void setLightingEnabled(bool enabled);
+	bool isLightingEnabled() const;
+	void setLightEnabled(int index, bool enable);
+	bool isLightEnabled(int index) const;
+	void setLightAmbient(int index, float r, float g, float b, float a);
+	void setLightDiffuse(int index, float r, float g, float b, float a);
+	void setLightSpecular(int index, float r, float g, float b, float a);
+	void setLightPosition(int index, float x, float y, float z, float w);
+	void setLightDirection(int index, float x, float y, float z);
+	void setLightAttenuationConstant(int index, float constant);
+	void setLightAttenuationLinear(int index, float linear);
+	void setLightAttenuationQuadratic(int index, float quadratic);
+	void setSpotLightExponent(int index, float exponent);
+	void setSpotLightCutoff(int index, float cutoff);
+
+	void setGlobalAmbient(float red, float green, float blue, float alpha);
+	void setMaterialAmbient(float red, float green, float blue, float alpha);
+	void setMaterialDiffuse(float red, float green, float blue, float alpha);
+	void setMaterialSpecular(float red, float green, float blue, float alpha);
+	void setMaterialEmission(float red, float green, float blue, float alpha);
+	void setMaterialShininess(float shininess);
+	void setLightModelTwoSide(bool enable);
+
+	void setFogEnabled(bool enabled);
+	bool isFogEnabled() const;
+	void setFogMode(GLenum mode);
+	void setFogDensity(float fogDensity);
+	void setFogStart(float fogStart);
+	void setFogEnd(float fogEnd);
+	void setFogColor(float r, float g, float b, float a);
+
+	void setTexture2Denabled(bool enabled);
+	bool isTexture2Denabled() const;
+	void setTextureExternalEnabled(bool enabled);
+	bool isTextureExternalEnabled() const;
+	void clientActiveTexture(GLenum texture);
+	GLenum getClientActiveTexture() const;
+	unsigned int getActiveTexture() const;
+
+	void setTextureEnvMode(GLenum texEnvMode);
+	void setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+	void setCombineRGB(GLenum combineRGB);
+	void setCombineAlpha(GLenum combineAlpha);
+	void setOperand0RGB(GLenum operand);
+	void setOperand1RGB(GLenum operand);
+	void setOperand2RGB(GLenum operand);
+	void setOperand0Alpha(GLenum operand);
+	void setOperand1Alpha(GLenum operand);
+	void setOperand2Alpha(GLenum operand);
+	void setSrc0RGB(GLenum src);
+	void setSrc1RGB(GLenum src);
+	void setSrc2RGB(GLenum src);
+	void setSrc0Alpha(GLenum src);
+	void setSrc1Alpha(GLenum src);
+	void setSrc2Alpha(GLenum src);
+
+	void setLineWidth(GLfloat width);
+
+	void setGenerateMipmapHint(GLenum hint);
+	void setPerspectiveCorrectionHint(GLenum hint);
+	void setFogHint(GLenum hint);
+
+	void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setScissorTestEnabled(bool enabled);
+	bool isScissorTestEnabled() const;
+	void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
+
+	void setColorMask(bool red, bool green, bool blue, bool alpha);
+	void setDepthMask(bool mask);
+
+	void setActiveSampler(unsigned int active);
+
+	GLuint getFramebufferName() const;
+	GLuint getRenderbufferName() const;
+
+	GLuint getArrayBufferName() const;
+
+	void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);
+	const VertexAttribute &getVertexAttribState(unsigned int attribNum);
+	void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
+	                          bool normalized, GLsizei stride, const void *pointer);
+	const void *getVertexAttribPointer(unsigned int attribNum) const;
+
+	const VertexAttributeArray &getVertexAttributes();
+
+	void setUnpackAlignment(GLint alignment);
+	GLint getUnpackAlignment() const;
+
+	void setPackAlignment(GLint alignment);
+	GLint getPackAlignment() const;
+
+	// These create and destroy methods are merely pass-throughs to
+	// ResourceManager, which owns these object types
+	GLuint createBuffer();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+
+	void deleteBuffer(GLuint buffer);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+
+	// Framebuffers are owned by the Context, so these methods do not pass through
+	GLuint createFramebuffer();
+	void deleteFramebuffer(GLuint framebuffer);
+
+	void bindArrayBuffer(GLuint buffer);
+	void bindElementArrayBuffer(GLuint buffer);
+	void bindTexture2D(GLuint texture);
+	void bindTextureExternal(GLuint texture);
+	void bindFramebuffer(GLuint framebuffer);
+	void bindRenderbuffer(GLuint renderbuffer);
+
+	void setFramebufferZero(Framebuffer *framebuffer);
+
+	void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
+
+	void setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+	Buffer *getBuffer(GLuint handle);
+	virtual Texture *getTexture(GLuint handle);
+	Framebuffer *getFramebuffer(GLuint handle);
+	virtual Renderbuffer *getRenderbuffer(GLuint handle);
+
+	Buffer *getArrayBuffer();
+	Buffer *getElementArrayBuffer();
+	Texture2D *getTexture2D();
+	TextureExternal *getTextureExternal();
+	Texture *getSamplerTexture(unsigned int sampler, TextureType type);
+	Framebuffer *getFramebuffer();
+
+	bool getFloatv(GLenum pname, GLfloat *params);
+	bool getIntegerv(GLenum pname, GLint *params);
+	bool getBooleanv(GLenum pname, GLboolean *params);
+	bool getPointerv(GLenum pname, const GLvoid **params);
+
+	int getQueryParameterNum(GLenum pname);
+	bool isQueryParameterInt(GLenum pname);
+	bool isQueryParameterFloat(GLenum pname);
+	bool isQueryParameterBool(GLenum pname);
+	bool isQueryParameterPointer(GLenum pname);
+
+	void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
+	void clear(GLbitfield mask);
+	void drawArrays(GLenum mode, GLint first, GLsizei count);
+	void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
+	void drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+	void flush();
+
+	void recordInvalidEnum();
+	void recordInvalidValue();
+	void recordInvalidOperation();
+	void recordOutOfMemory();
+	void recordInvalidFramebufferOperation();
+	void recordMatrixStackOverflow();
+	void recordMatrixStackUnderflow();
+
+	GLenum getError();
+
+	static int getSupportedMultisampleCount(int requested);
+
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+	virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+
+	Device *getDevice();
+
+	void setMatrixMode(GLenum mode);
+	void loadIdentity();
+	void load(const GLfloat *m);
+	void pushMatrix();
+	void popMatrix();
+	void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+	void translate(GLfloat x, GLfloat y, GLfloat z);
+	void scale(GLfloat x, GLfloat y, GLfloat z);
+	void multiply(const GLfloat *m);
+	void frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+	void ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+
+	void setClipPlane(int index, const float plane[4]);
+	void setClipPlaneEnabled(int index, bool enable);
+	bool isClipPlaneEnabled(int index) const;
+
+	void setColorLogicOpEnabled(bool enable);
+	bool isColorLogicOpEnabled() const;
+	void setLogicalOperation(GLenum logicOp);
+
+	void setPointSmoothEnabled(bool enable);
+	bool isPointSmoothEnabled() const;
+
+	void setLineSmoothEnabled(bool enable);
+	bool isLineSmoothEnabled() const;
+
+	void setColorMaterialEnabled(bool enable);
+	bool isColorMaterialEnabled() const;
+
+	void setNormalizeEnabled(bool enable);
+	bool isNormalizeEnabled() const;
+
+	void setRescaleNormalEnabled(bool enable);
+	bool isRescaleNormalEnabled() const;
+
+	void setVertexArrayEnabled(bool enable);
+	bool isVertexArrayEnabled() const;
+
+	void setNormalArrayEnabled(bool enable);
+	bool isNormalArrayEnabled() const;
+
+	void setColorArrayEnabled(bool enable);
+	bool isColorArrayEnabled() const;
+
+	void setPointSizeArrayEnabled(bool enable);
+	bool isPointSizeArrayEnabled() const;
+
+	void setTextureCoordArrayEnabled(bool enable);
+	bool isTextureCoordArrayEnabled() const;
+
+	void setMultisampleEnabled(bool enable);
+	bool isMultisampleEnabled() const;
+
+	void setSampleAlphaToOneEnabled(bool enable);
+	bool isSampleAlphaToOneEnabled() const;
+
+	void setPointSpriteEnabled(bool enable);
+	bool isPointSpriteEnabled() const;
+	void setPointSizeMin(float min);
+	void setPointSizeMax(float max);
+	void setPointDistanceAttenuation(float a, float b, float c);
+	void setPointFadeThresholdSize(float threshold);
+
+private:
+	virtual ~Context();
+
+	bool applyRenderTarget();
+	void applyState(GLenum drawMode);
+	GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
+	GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+	void applyTextures();
+	void applyTexture(int sampler, Texture *texture);
+
+	void detachBuffer(GLuint buffer);
+	void detachTexture(GLuint texture);
+	void detachFramebuffer(GLuint framebuffer);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	bool cullSkipsDraw(GLenum drawMode);
+	bool isTriangleMode(GLenum drawMode);
+
+	State mState;
+
+	gl::BindingPointer<Texture2D> mTexture2DZero;
+	gl::BindingPointer<TextureExternal> mTextureExternalZero;
+
+	gl::NameSpace<Framebuffer> mFramebufferNameSpace;
+
+	VertexDataManager *mVertexDataManager;
+	IndexDataManager *mIndexDataManager;
+
+	bool lightingEnabled;
+	Light light[MAX_LIGHTS];
+	Color globalAmbient;
+	Color materialAmbient;
+	Color materialDiffuse;
+	Color materialSpecular;
+	Color materialEmission;
+	GLfloat materialShininess;
+	bool lightModelTwoSide;
+
+	// Recorded errors
+	bool mInvalidEnum;
+	bool mInvalidValue;
+	bool mInvalidOperation;
+	bool mOutOfMemory;
+	bool mInvalidFramebufferOperation;
+	bool mMatrixStackOverflow;
+	bool mMatrixStackUnderflow;
+
+	bool mHasBeenCurrent;
+
+	// state caching flags
+	bool mDepthStateDirty;
+	bool mMaskStateDirty;
+	bool mBlendStateDirty;
+	bool mStencilStateDirty;
+	bool mPolygonOffsetStateDirty;
+	bool mSampleStateDirty;
+	bool mFrontFaceDirty;
+	bool mDitherStateDirty;
+
+	sw::MatrixStack &currentMatrixStack();
+	GLenum matrixMode;
+	sw::MatrixStack modelViewStack;
+	sw::MatrixStack projectionStack;
+	sw::MatrixStack textureStack0;
+	sw::MatrixStack textureStack1;
+
+	bool texture2Denabled[MAX_TEXTURE_UNITS];
+	bool textureExternalEnabled[MAX_TEXTURE_UNITS];
+	GLenum clientTexture;
+
+	int clipFlags;
+
+	bool alphaTestEnabled;
+	GLenum alphaTestFunc;
+	float alphaTestRef;
+
+	bool fogEnabled;
+	GLenum fogMode;
+	float fogDensity;
+	float fogStart;
+	float fogEnd;
+	Color fogColor;
+
+	bool lineSmoothEnabled;
+	bool colorMaterialEnabled;
+	bool normalizeEnabled;
+	bool rescaleNormalEnabled;
+	bool multisampleEnabled;
+	bool sampleAlphaToOneEnabled;
+
+	bool pointSpriteEnabled;
+	bool pointSmoothEnabled;
+	float pointSizeMin;
+	float pointSizeMax;
+	Attenuation pointDistanceAttenuation;
+	float pointFadeThresholdSize;
+
+	bool colorLogicOpEnabled;
+	GLenum logicalOperation;
+
+	Device *device;
+	ResourceManager *mResourceManager;
+};
+}
+
+#endif   // INCLUDE_CONTEXT_H_
diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp
index 65f29fc..7a7f022 100644
--- a/src/OpenGL/libGLES_CM/Device.cpp
+++ b/src/OpenGL/libGLES_CM/Device.cpp
@@ -1,608 +1,611 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-#include "Device.hpp"

-

-#include "common/Image.hpp"

-#include "Texture.h"

-

-#include "Renderer/Renderer.hpp"

-#include "Renderer/Clipper.hpp"

-#include "Shader/PixelShader.hpp"

-#include "Shader/VertexShader.hpp"

-#include "Main/Config.hpp"

-#include "Main/FrameBuffer.hpp"

-#include "Common/Math.hpp"

-#include "Common/Configurator.hpp"

-#include "Common/Timer.hpp"

-#include "../common/debug.h"

-

-namespace es1

-{

-	using namespace sw;

-

-	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)

-	{

-		renderTarget = nullptr;

-		depthBuffer = nullptr;

-		stencilBuffer = nullptr;

-

-		setDepthBufferEnable(true);

-		setFillMode(FILL_SOLID);

-		setShadingMode(SHADING_GOURAUD);

-		setDepthWriteEnable(true);

-		setAlphaTestEnable(false);

-		setSourceBlendFactor(BLEND_ONE);

-		setDestBlendFactor(BLEND_ZERO);

-		setCullMode(CULL_COUNTERCLOCKWISE);

-		setDepthCompare(DEPTH_LESSEQUAL);

-		setAlphaReference(0.0f);

-		setAlphaCompare(ALPHA_ALWAYS);

-		setAlphaBlendEnable(false);

-		setFogEnable(false);

-		setSpecularEnable(true);

-		setLocalViewer(false);

-		setFogColor(0);

-		setPixelFogMode(FOG_NONE);

-		setFogStart(0.0f);

-		setFogEnd(1.0f);

-		setFogDensity(1.0f);

-		setRangeFogEnable(false);

-		setStencilEnable(false);

-		setStencilFailOperation(OPERATION_KEEP);

-		setStencilZFailOperation(OPERATION_KEEP);

-		setStencilPassOperation(OPERATION_KEEP);

-		setStencilCompare(STENCIL_ALWAYS);

-		setStencilReference(0);

-		setStencilMask(0xFFFFFFFF);

-		setStencilWriteMask(0xFFFFFFFF);

-		setVertexFogMode(FOG_NONE);

-		setClipFlags(0);

-		setPointSize(1.0f);

-		setPointSizeMin(0.125f);

-        setPointSizeMax(8192.0f);

-		setColorWriteMask(0, 0x0000000F);

-		setBlendOperation(BLENDOP_ADD);

-		scissorEnable = false;

-		setSlopeDepthBias(0.0f);

-		setTwoSidedStencil(false);

-		setStencilFailOperationCCW(OPERATION_KEEP);

-		setStencilZFailOperationCCW(OPERATION_KEEP);

-		setStencilPassOperationCCW(OPERATION_KEEP);

-		setStencilCompareCCW(STENCIL_ALWAYS);

-		setColorWriteMask(1, 0x0000000F);

-		setColorWriteMask(2, 0x0000000F);

-		setColorWriteMask(3, 0x0000000F);

-		setBlendConstant(0xFFFFFFFF);

-		setWriteSRGB(false);

-		setDepthBias(0.0f);

-		setSeparateAlphaBlendEnable(false);

-		setSourceBlendFactorAlpha(BLEND_ONE);

-		setDestBlendFactorAlpha(BLEND_ZERO);

-		setBlendOperationAlpha(BLENDOP_ADD);

-		setPointSpriteEnable(true);

-

-		for(int i = 0; i < 16; i++)

-		{

-			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);

-			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);

-			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);

-			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);

-			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);

-		}

-

-		for(int i = 0; i < 4; i++)

-		{

-			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);

-			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);

-			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);

-			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);

-			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);

-		}

-

-		for(int i = 0; i < 6; i++)

-		{

-			float plane[4] = {0, 0, 0, 0};

-

-			setClipPlane(i, plane);

-		}

-	}

-

-	Device::~Device()

-	{

-		if(renderTarget)

-		{

-			renderTarget->release();

-			renderTarget = nullptr;

-		}

-

-		if(depthBuffer)

-		{

-			depthBuffer->release();

-			depthBuffer = nullptr;

-		}

-

-		if(stencilBuffer)

-		{

-			stencilBuffer->release();

-			stencilBuffer = nullptr;

-		}

-

-		delete context;

-	}

-

-	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)

-	{

-		if(!renderTarget || !rgbaMask)

-		{

-			return;

-		}

-

-		float rgba[4];

-		rgba[0] = red;

-		rgba[1] = green;

-		rgba[2] = blue;

-		rgba[3] = alpha;

-

-		sw::SliceRect clearRect = renderTarget->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);

-	}

-

-	void Device::clearDepth(float z)

-	{

-		if(!depthBuffer)

-		{

-			return;

-		}

-

-		z = clamp01(z);

-		sw::SliceRect clearRect = depthBuffer->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	void Device::clearStencil(unsigned int stencil, unsigned int mask)

-	{

-		if(!stencilBuffer)

-		{

-			return;

-		}

-

-		sw::SliceRect clearRect = stencilBuffer->getRect();

-

-		if(scissorEnable)

-		{

-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);

-		}

-

-		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());

-	}

-

-	egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return nullptr;

-		}

-

-		bool lockable = true;

-

-		switch(format)

-		{

-	//	case FORMAT_D15S1:

-		case FORMAT_D24S8:

-		case FORMAT_D24X8:

-	//	case FORMAT_D24X4S4:

-		case FORMAT_D24FS8:

-		case FORMAT_D32:

-		case FORMAT_D16:

-			lockable = false;

-			break;

-	//	case FORMAT_S8_LOCKABLE:

-	//	case FORMAT_D16_LOCKABLE:

-		case FORMAT_D32F_LOCKABLE:

-	//	case FORMAT_D32_LOCKABLE:

-		case FORMAT_DF24S8:

-		case FORMAT_DF16S8:

-			lockable = true;

-			break;

-		default:

-			UNREACHABLE(format);

-		}

-

-		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return nullptr;

-		}

-

-		return surface;

-	}

-

-	egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)

-	{

-		if(height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters: %dx%d", width, height);

-			return nullptr;

-		}

-

-		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return nullptr;

-		}

-

-		return surface;

-	}

-

-	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		draw(type, indexOffset, primitiveCount);

-	}

-

-	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)

-	{

-		if(!bindResources() || !primitiveCount)

-		{

-			return;

-		}

-

-		setIndexBuffer(nullptr);

-

-		draw(type, 0, primitiveCount);

-	}

-

-	void Device::setScissorEnable(bool enable)

-	{

-		scissorEnable = enable;

-	}

-

-	void Device::setRenderTarget(int index, egl::Image *renderTarget)

-	{

-		if(renderTarget)

-		{

-			renderTarget->addRef();

-		}

-

-		if(this->renderTarget)

-		{

-			this->renderTarget->release();

-		}

-

-		this->renderTarget = renderTarget;

-

-		Renderer::setRenderTarget(index, renderTarget);

-	}

-

-	void Device::setDepthBuffer(egl::Image *depthBuffer)

-	{

-		if(this->depthBuffer == depthBuffer)

-		{

-			return;

-		}

-

-		if(depthBuffer)

-		{

-			depthBuffer->addRef();

-		}

-

-		if(this->depthBuffer)

-		{

-			this->depthBuffer->release();

-		}

-

-		this->depthBuffer = depthBuffer;

-

-		Renderer::setDepthBuffer(depthBuffer);

-	}

-

-	void Device::setStencilBuffer(egl::Image *stencilBuffer)

-	{

-		if(this->stencilBuffer == stencilBuffer)

-		{

-			return;

-		}

-

-		if(stencilBuffer)

-		{

-			stencilBuffer->addRef();

-		}

-

-		if(this->stencilBuffer)

-		{

-			this->stencilBuffer->release();

-		}

-

-		this->stencilBuffer = stencilBuffer;

-

-		Renderer::setStencilBuffer(stencilBuffer);

-	}

-

-	void Device::setScissorRect(const sw::Rect &rect)

-	{

-		scissorRect = rect;

-	}

-

-	void Device::setViewport(const Viewport &viewport)

-	{

-		this->viewport = viewport;

-	}

-

-	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)

-	{

-		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))

-		{

-			ERR("Invalid parameters");

-			return false;

-		}

-

-		int sWidth = source->getWidth();

-		int sHeight = source->getHeight();

-		int dWidth = dest->getWidth();

-		int dHeight = dest->getHeight();

-

-		SliceRect sRect;

-		SliceRect dRect;

-

-		if(sourceRect)

-		{

-			sRect = *sourceRect;

-		}

-		else

-		{

-			sRect.y0 = 0;

-			sRect.x0 = 0;

-			sRect.y1 = sHeight;

-			sRect.x1 = sWidth;

-		}

-

-		if(destRect)

-		{

-			dRect = *destRect;

-		}

-		else

-		{

-			dRect.y0 = 0;

-			dRect.x0 = 0;

-			dRect.y1 = dHeight;

-			dRect.x1 = dWidth;

-		}

-

-		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);

-		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();

-		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat());

-		bool alpha0xFF = false;

-

-		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||

-		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))

-		{

-			equalFormats = true;

-			alpha0xFF = true;

-		}

-

-		if(depthStencil)   // Copy entirely, internally   // FIXME: Check

-		{

-			if(source->hasDepth())

-			{

-				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getInternalPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockInternal();

-				dest->unlockInternal();

-			}

-

-			if(source->hasStencil())

-			{

-				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);

-				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);

-

-				unsigned int width = source->getWidth();

-				unsigned int height = source->getHeight();

-				unsigned int pitch = source->getStencilPitchB();

-

-				for(unsigned int y = 0; y < height; y++)

-				{

-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes

-

-					sourceBuffer += pitch;

-					destBuffer += pitch;

-				}

-

-				source->unlockStencil();

-				dest->unlockStencil();

-			}

-		}

-		else if(!scaling && equalFormats)

-		{

-			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);

-			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);

-			unsigned int sourcePitch = source->getInternalPitchB();

-			unsigned int destPitch = dest->getInternalPitchB();

-

-			unsigned int width = dRect.x1 - dRect.x0;

-			unsigned int height = dRect.y1 - dRect.y0;

-			unsigned int bytes = width * egl::Image::bytes(source->getInternalFormat());

-

-			for(unsigned int y = 0; y < height; y++)

-			{

-				memcpy(destBytes, sourceBytes, bytes);

-

-				if(alpha0xFF)

-				{

-					for(unsigned int x = 0; x < width; x++)

-					{

-						destBytes[4 * x + 3] = 0xFF;

-					}

-				}

-

-				sourceBytes += sourcePitch;

-				destBytes += destPitch;

-			}

-

-			source->unlockInternal();

-			dest->unlockInternal();

-		}

-		else

-		{

-			blit(source, sRect, dest, dRect, scaling && filter);

-		}

-

-		return true;

-	}

-

-	bool Device::bindResources()

-	{

-		if(!bindViewport())

-		{

-			return false;   // Zero-area target region

-		}

-

-		return true;

-	}

-

-	bool Device::bindViewport()

-	{

-		if(viewport.width <= 0 || viewport.height <= 0)

-		{

-			return false;

-		}

-

-		if(scissorEnable)

-		{

-			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)

-			{

-				return false;

-			}

-

-			sw::Rect scissor;

-			scissor.x0 = scissorRect.x0;

-			scissor.x1 = scissorRect.x1;

-			scissor.y0 = scissorRect.y0;

-			scissor.y1 = scissorRect.y1;

-

-			setScissor(scissor);

-		}

-		else

-		{

-			sw::Rect scissor;

-			scissor.x0 = viewport.x0;

-			scissor.x1 = viewport.x0 + viewport.width;

-			scissor.y0 = viewport.y0;

-			scissor.y1 = viewport.y0 + viewport.height;

-

-			if(renderTarget)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, renderTarget->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, renderTarget->getHeight());

-			}

-

-			if(depthBuffer)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());

-			}

-

-			if(stencilBuffer)

-			{

-				scissor.x0 = max(scissor.x0, 0);

-				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());

-				scissor.y0 = max(scissor.y0, 0);

-				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());

-			}

-

-			setScissor(scissor);

-		}

-

-		sw::Viewport view;

-		view.x0 = (float)viewport.x0;

-		view.y0 = (float)viewport.y0;

-		view.width = (float)viewport.width;

-		view.height = (float)viewport.height;

-		view.minZ = viewport.minZ;

-		view.maxZ = viewport.maxZ;

-

-		Renderer::setViewport(view);

-

-		return true;

-	}

-

-	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)

-	{

-		if(!rect)

-		{

-			return true;

-		}

-

-		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)

-		{

-			return false;

-		}

-

-		if(rect->x0 < 0 || rect->y0 < 0)

-		{

-			return false;

-		}

-

-		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())

-		{

-			return false;

-		}

-

-		return true;

-	}

-

-	void Device::finish()

-	{

-		synchronize();

-	}

-}

+// 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.
+
+#include "Device.hpp"
+
+#include "common/Image.hpp"
+#include "Texture.h"
+
+#include "Renderer/Renderer.hpp"
+#include "Renderer/Clipper.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+#include "Main/Config.hpp"
+#include "Main/FrameBuffer.hpp"
+#include "Common/Math.hpp"
+#include "Common/Configurator.hpp"
+#include "Common/Timer.hpp"
+#include "../common/debug.h"
+
+namespace es1
+{
+	using namespace sw;
+
+	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
+	{
+		renderTarget = nullptr;
+		depthBuffer = nullptr;
+		stencilBuffer = nullptr;
+
+		setDepthBufferEnable(true);
+		setFillMode(FILL_SOLID);
+		setShadingMode(SHADING_GOURAUD);
+		setDepthWriteEnable(true);
+		setAlphaTestEnable(false);
+		setSourceBlendFactor(BLEND_ONE);
+		setDestBlendFactor(BLEND_ZERO);
+		setCullMode(CULL_COUNTERCLOCKWISE);
+		setDepthCompare(DEPTH_LESSEQUAL);
+		setAlphaReference(0.0f);
+		setAlphaCompare(ALPHA_ALWAYS);
+		setAlphaBlendEnable(false);
+		setFogEnable(false);
+		setSpecularEnable(true);
+		setLocalViewer(false);
+		setFogColor(0);
+		setPixelFogMode(FOG_NONE);
+		setFogStart(0.0f);
+		setFogEnd(1.0f);
+		setFogDensity(1.0f);
+		setRangeFogEnable(false);
+		setStencilEnable(false);
+		setStencilFailOperation(OPERATION_KEEP);
+		setStencilZFailOperation(OPERATION_KEEP);
+		setStencilPassOperation(OPERATION_KEEP);
+		setStencilCompare(STENCIL_ALWAYS);
+		setStencilReference(0);
+		setStencilMask(0xFFFFFFFF);
+		setStencilWriteMask(0xFFFFFFFF);
+		setVertexFogMode(FOG_NONE);
+		setClipFlags(0);
+		setPointSize(1.0f);
+		setPointSizeMin(0.125f);
+        setPointSizeMax(8192.0f);
+		setColorWriteMask(0, 0x0000000F);
+		setBlendOperation(BLENDOP_ADD);
+		scissorEnable = false;
+		setSlopeDepthBias(0.0f);
+		setTwoSidedStencil(false);
+		setStencilFailOperationCCW(OPERATION_KEEP);
+		setStencilZFailOperationCCW(OPERATION_KEEP);
+		setStencilPassOperationCCW(OPERATION_KEEP);
+		setStencilCompareCCW(STENCIL_ALWAYS);
+		setColorWriteMask(1, 0x0000000F);
+		setColorWriteMask(2, 0x0000000F);
+		setColorWriteMask(3, 0x0000000F);
+		setBlendConstant(0xFFFFFFFF);
+		setWriteSRGB(false);
+		setDepthBias(0.0f);
+		setSeparateAlphaBlendEnable(false);
+		setSourceBlendFactorAlpha(BLEND_ONE);
+		setDestBlendFactorAlpha(BLEND_ZERO);
+		setBlendOperationAlpha(BLENDOP_ADD);
+		setPointSpriteEnable(true);
+
+		for(int i = 0; i < 16; i++)
+		{
+			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
+			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);
+			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);
+			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);
+			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);
+		}
+
+		for(int i = 0; i < 4; i++)
+		{
+			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
+			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);
+			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);
+			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);
+			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);
+		}
+
+		for(int i = 0; i < 6; i++)
+		{
+			float plane[4] = {0, 0, 0, 0};
+
+			setClipPlane(i, plane);
+		}
+	}
+
+	Device::~Device()
+	{
+		if(renderTarget)
+		{
+			renderTarget->release();
+			renderTarget = nullptr;
+		}
+
+		if(depthBuffer)
+		{
+			depthBuffer->release();
+			depthBuffer = nullptr;
+		}
+
+		if(stencilBuffer)
+		{
+			stencilBuffer->release();
+			stencilBuffer = nullptr;
+		}
+
+		delete context;
+	}
+
+	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
+	{
+		if(!renderTarget || !rgbaMask)
+		{
+			return;
+		}
+
+		float rgba[4];
+		rgba[0] = red;
+		rgba[1] = green;
+		rgba[2] = blue;
+		rgba[3] = alpha;
+
+		sw::SliceRect clearRect = renderTarget->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);
+	}
+
+	void Device::clearDepth(float z)
+	{
+		if(!depthBuffer)
+		{
+			return;
+		}
+
+		z = clamp01(z);
+		sw::SliceRect clearRect = depthBuffer->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		depthBuffer->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	void Device::clearStencil(unsigned int stencil, unsigned int mask)
+	{
+		if(!stencilBuffer)
+		{
+			return;
+		}
+
+		sw::SliceRect clearRect = stencilBuffer->getRect();
+
+		if(scissorEnable)
+		{
+			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
+		}
+
+		stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
+	}
+
+	egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return nullptr;
+		}
+
+		bool lockable = true;
+
+		switch(format)
+		{
+	//	case FORMAT_D15S1:
+		case FORMAT_D24S8:
+		case FORMAT_D24X8:
+	//	case FORMAT_D24X4S4:
+		case FORMAT_D24FS8:
+		case FORMAT_D32:
+		case FORMAT_D16:
+			lockable = false;
+			break;
+	//	case FORMAT_S8_LOCKABLE:
+	//	case FORMAT_D16_LOCKABLE:
+		case FORMAT_D32F_LOCKABLE:
+	//	case FORMAT_D32_LOCKABLE:
+		case FORMAT_DF24S8:
+		case FORMAT_DF16S8:
+			lockable = true;
+			break;
+		default:
+			UNREACHABLE(format);
+		}
+
+		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return nullptr;
+		}
+
+		return surface;
+	}
+
+	egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
+	{
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters: %dx%d", width, height);
+			return nullptr;
+		}
+
+		egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return nullptr;
+		}
+
+		return surface;
+	}
+
+	void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		draw(type, indexOffset, primitiveCount);
+	}
+
+	void Device::drawPrimitive(sw::DrawType type, unsigned int primitiveCount)
+	{
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		setIndexBuffer(nullptr);
+
+		draw(type, 0, primitiveCount);
+	}
+
+	void Device::setScissorEnable(bool enable)
+	{
+		scissorEnable = enable;
+	}
+
+	void Device::setRenderTarget(int index, egl::Image *renderTarget)
+	{
+		if(renderTarget)
+		{
+			renderTarget->addRef();
+		}
+
+		if(this->renderTarget)
+		{
+			this->renderTarget->release();
+		}
+
+		this->renderTarget = renderTarget;
+
+		Renderer::setRenderTarget(index, renderTarget);
+	}
+
+	void Device::setDepthBuffer(egl::Image *depthBuffer)
+	{
+		if(this->depthBuffer == depthBuffer)
+		{
+			return;
+		}
+
+		if(depthBuffer)
+		{
+			depthBuffer->addRef();
+		}
+
+		if(this->depthBuffer)
+		{
+			this->depthBuffer->release();
+		}
+
+		this->depthBuffer = depthBuffer;
+
+		Renderer::setDepthBuffer(depthBuffer);
+	}
+
+	void Device::setStencilBuffer(egl::Image *stencilBuffer)
+	{
+		if(this->stencilBuffer == stencilBuffer)
+		{
+			return;
+		}
+
+		if(stencilBuffer)
+		{
+			stencilBuffer->addRef();
+		}
+
+		if(this->stencilBuffer)
+		{
+			this->stencilBuffer->release();
+		}
+
+		this->stencilBuffer = stencilBuffer;
+
+		Renderer::setStencilBuffer(stencilBuffer);
+	}
+
+	void Device::setScissorRect(const sw::Rect &rect)
+	{
+		scissorRect = rect;
+	}
+
+	void Device::setViewport(const Viewport &viewport)
+	{
+		this->viewport = viewport;
+	}
+
+	bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, bool filter)
+	{
+		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		int sWidth = source->getWidth();
+		int sHeight = source->getHeight();
+		int dWidth = dest->getWidth();
+		int dHeight = dest->getHeight();
+
+		SliceRect sRect;
+		SliceRect dRect;
+
+		if(sourceRect)
+		{
+			sRect = *sourceRect;
+		}
+		else
+		{
+			sRect.y0 = 0;
+			sRect.x0 = 0;
+			sRect.y1 = sHeight;
+			sRect.x1 = sWidth;
+		}
+
+		if(destRect)
+		{
+			dRect = *destRect;
+		}
+		else
+		{
+			dRect.y0 = 0;
+			dRect.x0 = 0;
+			dRect.y1 = dHeight;
+			dRect.x1 = dWidth;
+		}
+
+		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
+		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
+		bool depthStencil = egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat());
+		bool alpha0xFF = false;
+
+		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
+		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
+		{
+			equalFormats = true;
+			alpha0xFF = true;
+		}
+
+		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
+		{
+			if(source->hasDepth())
+			{
+				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getInternalPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockInternal();
+				dest->unlockInternal();
+			}
+
+			if(source->hasStencil())
+			{
+				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);
+
+				unsigned int width = source->getWidth();
+				unsigned int height = source->getHeight();
+				unsigned int pitch = source->getStencilPitchB();
+
+				for(unsigned int y = 0; y < height; y++)
+				{
+					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
+
+					sourceBuffer += pitch;
+					destBuffer += pitch;
+				}
+
+				source->unlockStencil();
+				dest->unlockStencil();
+			}
+		}
+		else if(!scaling && equalFormats)
+		{
+			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);
+			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+
+			unsigned int width = dRect.x1 - dRect.x0;
+			unsigned int height = dRect.y1 - dRect.y0;
+			unsigned int bytes = width * egl::Image::bytes(source->getInternalFormat());
+
+			for(unsigned int y = 0; y < height; y++)
+			{
+				memcpy(destBytes, sourceBytes, bytes);
+
+				if(alpha0xFF)
+				{
+					for(unsigned int x = 0; x < width; x++)
+					{
+						destBytes[4 * x + 3] = 0xFF;
+					}
+				}
+
+				sourceBytes += sourcePitch;
+				destBytes += destPitch;
+			}
+
+			source->unlockInternal();
+			dest->unlockInternal();
+		}
+		else
+		{
+			blit(source, sRect, dest, dRect, scaling && filter);
+		}
+
+		return true;
+	}
+
+	bool Device::bindResources()
+	{
+		if(!bindViewport())
+		{
+			return false;   // Zero-area target region
+		}
+
+		return true;
+	}
+
+	bool Device::bindViewport()
+	{
+		if(viewport.width <= 0 || viewport.height <= 0)
+		{
+			return false;
+		}
+
+		if(scissorEnable)
+		{
+			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)
+			{
+				return false;
+			}
+
+			sw::Rect scissor;
+			scissor.x0 = scissorRect.x0;
+			scissor.x1 = scissorRect.x1;
+			scissor.y0 = scissorRect.y0;
+			scissor.y1 = scissorRect.y1;
+
+			setScissor(scissor);
+		}
+		else
+		{
+			sw::Rect scissor;
+			scissor.x0 = viewport.x0;
+			scissor.x1 = viewport.x0 + viewport.width;
+			scissor.y0 = viewport.y0;
+			scissor.y1 = viewport.y0 + viewport.height;
+
+			if(renderTarget)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, renderTarget->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, renderTarget->getHeight());
+			}
+
+			if(depthBuffer)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, depthBuffer->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, depthBuffer->getHeight());
+			}
+
+			if(stencilBuffer)
+			{
+				scissor.x0 = max(scissor.x0, 0);
+				scissor.x1 = min(scissor.x1, stencilBuffer->getWidth());
+				scissor.y0 = max(scissor.y0, 0);
+				scissor.y1 = min(scissor.y1, stencilBuffer->getHeight());
+			}
+
+			setScissor(scissor);
+		}
+
+		sw::Viewport view;
+		view.x0 = (float)viewport.x0;
+		view.y0 = (float)viewport.y0;
+		view.width = (float)viewport.width;
+		view.height = (float)viewport.height;
+		view.minZ = viewport.minZ;
+		view.maxZ = viewport.maxZ;
+
+		Renderer::setViewport(view);
+
+		return true;
+	}
+
+	bool Device::validRectangle(const sw::Rect *rect, sw::Surface *surface)
+	{
+		if(!rect)
+		{
+			return true;
+		}
+
+		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
+		{
+			return false;
+		}
+
+		if(rect->x0 < 0 || rect->y0 < 0)
+		{
+			return false;
+		}
+
+		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	void Device::finish()
+	{
+		synchronize();
+	}
+}
diff --git a/src/OpenGL/libGLES_CM/Device.hpp b/src/OpenGL/libGLES_CM/Device.hpp
index 15872ca..8b6ea46 100644
--- a/src/OpenGL/libGLES_CM/Device.hpp
+++ b/src/OpenGL/libGLES_CM/Device.hpp
@@ -1,78 +1,81 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-#ifndef gl_Device_hpp

-#define gl_Device_hpp

-

-#include "Renderer/Renderer.hpp"

-

-namespace egl

-{

-	class Image;

-}

-

-namespace es1

-{

-	class Texture;

-

-	struct Viewport

-	{

-		int x0;

-		int y0;

-		unsigned int width;

-		unsigned int height;

-		float minZ;

-		float maxZ;

-	};

-

-	class Device : public sw::Renderer

-	{

-	public:

-		explicit Device(sw::Context *context);

-

-		virtual ~Device();

-

-		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);

-		virtual void clearDepth(float z);

-		virtual void clearStencil(unsigned int stencil, unsigned int mask);

-		virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-		virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);

-		virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);

-		virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount);

-		virtual void setScissorEnable(bool enable);

-		virtual void setRenderTarget(int index, egl::Image *renderTarget);

-		virtual void setDepthBuffer(egl::Image *depthBuffer);

-		virtual void setStencilBuffer(egl::Image *stencilBuffer);

-		virtual void setScissorRect(const sw::Rect &rect);

-		virtual void setViewport(const Viewport &viewport);

-

-		virtual bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, bool filter);

-		virtual void finish();

-

-	private:

-		sw::Context *const context;

-

-		bool bindResources();

-		bool bindViewport();   // Also adjusts for scissoring

-

-		bool validRectangle(const sw::Rect *rect, sw::Surface *surface);

-

-		Viewport viewport;

-		sw::Rect scissorRect;

-		bool scissorEnable;

-

-		egl::Image *renderTarget;

-		egl::Image *depthBuffer;

-		egl::Image *stencilBuffer;

-	};

-}

-

-#endif   // gl_Device_hpp

+// 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.
+
+#ifndef gl_Device_hpp
+#define gl_Device_hpp
+
+#include "Renderer/Renderer.hpp"
+
+namespace egl
+{
+	class Image;
+}
+
+namespace es1
+{
+	class Texture;
+
+	struct Viewport
+	{
+		int x0;
+		int y0;
+		unsigned int width;
+		unsigned int height;
+		float minZ;
+		float maxZ;
+	};
+
+	class Device : public sw::Renderer
+	{
+	public:
+		explicit Device(sw::Context *context);
+
+		virtual ~Device();
+
+		virtual void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
+		virtual void clearDepth(float z);
+		virtual void clearStencil(unsigned int stencil, unsigned int mask);
+		virtual egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+		virtual egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
+		virtual void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);
+		virtual void drawPrimitive(sw::DrawType type, unsigned int primiveCount);
+		virtual void setScissorEnable(bool enable);
+		virtual void setRenderTarget(int index, egl::Image *renderTarget);
+		virtual void setDepthBuffer(egl::Image *depthBuffer);
+		virtual void setStencilBuffer(egl::Image *stencilBuffer);
+		virtual void setScissorRect(const sw::Rect &rect);
+		virtual void setViewport(const Viewport &viewport);
+
+		virtual bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, bool filter);
+		virtual void finish();
+
+	private:
+		sw::Context *const context;
+
+		bool bindResources();
+		bool bindViewport();   // Also adjusts for scissoring
+
+		bool validRectangle(const sw::Rect *rect, sw::Surface *surface);
+
+		Viewport viewport;
+		sw::Rect scissorRect;
+		bool scissorEnable;
+
+		egl::Image *renderTarget;
+		egl::Image *depthBuffer;
+		egl::Image *stencilBuffer;
+	};
+}
+
+#endif   // gl_Device_hpp
diff --git a/src/OpenGL/libGLES_CM/Framebuffer.cpp b/src/OpenGL/libGLES_CM/Framebuffer.cpp
index 25db3d6..5dfa67c 100644
--- a/src/OpenGL/libGLES_CM/Framebuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Framebuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    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.
 
 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
diff --git a/src/OpenGL/libGLES_CM/Framebuffer.h b/src/OpenGL/libGLES_CM/Framebuffer.h
index fa9a684..39f227c 100644
--- a/src/OpenGL/libGLES_CM/Framebuffer.h
+++ b/src/OpenGL/libGLES_CM/Framebuffer.h
@@ -1,91 +1,94 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer

-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.

-

-#ifndef LIBGLES_CM_FRAMEBUFFER_H_

-#define LIBGLES_CM_FRAMEBUFFER_H_

-

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-class Renderbuffer;

-class Colorbuffer;

-class Depthbuffer;

-class Stencilbuffer;

-class DepthStencilbuffer;

-

-class Framebuffer

-{

-public:

-    Framebuffer();

-

-    virtual ~Framebuffer();

-

-    void setColorbuffer(GLenum type, GLuint colorbuffer);

-    void setDepthbuffer(GLenum type, GLuint depthbuffer);

-    void setStencilbuffer(GLenum type, GLuint stencilbuffer);

-

-    void detachTexture(GLuint texture);

-    void detachRenderbuffer(GLuint renderbuffer);

-

-    egl::Image *getRenderTarget();

-    egl::Image *getDepthBuffer();

-	egl::Image *getStencilBuffer();

-

-    Renderbuffer *getColorbuffer();

-    Renderbuffer *getDepthbuffer();

-    Renderbuffer *getStencilbuffer();

-

-    GLenum getColorbufferType();

-    GLenum getDepthbufferType();

-    GLenum getStencilbufferType();

-

-    GLuint getColorbufferName();

-    GLuint getDepthbufferName();

-    GLuint getStencilbufferName();

-

-    bool hasStencil();

-

-	virtual GLenum completeness();

-	GLenum completeness(int &width, int &height, int &samples);

-

-	GLenum getImplementationColorReadFormat();

-	GLenum getImplementationColorReadType();

-

-protected:

-    GLenum mColorbufferType;

-    gl::BindingPointer<Renderbuffer> mColorbufferPointer;

-

-    GLenum mDepthbufferType;

-    gl::BindingPointer<Renderbuffer> mDepthbufferPointer;

-

-    GLenum mStencilbufferType;

-    gl::BindingPointer<Renderbuffer> mStencilbufferPointer;

-

-private:

-    Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;

-};

-

-class DefaultFramebuffer : public Framebuffer

-{

-public:

-    DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);

-};

-

-}

-

-#endif   // LIBGLES_CM_FRAMEBUFFER_H_

+// 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.
+
+// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
+
+#ifndef LIBGLES_CM_FRAMEBUFFER_H_
+#define LIBGLES_CM_FRAMEBUFFER_H_
+
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+class Renderbuffer;
+class Colorbuffer;
+class Depthbuffer;
+class Stencilbuffer;
+class DepthStencilbuffer;
+
+class Framebuffer
+{
+public:
+	Framebuffer();
+
+	virtual ~Framebuffer();
+
+	void setColorbuffer(GLenum type, GLuint colorbuffer);
+	void setDepthbuffer(GLenum type, GLuint depthbuffer);
+	void setStencilbuffer(GLenum type, GLuint stencilbuffer);
+
+	void detachTexture(GLuint texture);
+	void detachRenderbuffer(GLuint renderbuffer);
+
+	egl::Image *getRenderTarget();
+	egl::Image *getDepthBuffer();
+	egl::Image *getStencilBuffer();
+
+	Renderbuffer *getColorbuffer();
+	Renderbuffer *getDepthbuffer();
+	Renderbuffer *getStencilbuffer();
+
+	GLenum getColorbufferType();
+	GLenum getDepthbufferType();
+	GLenum getStencilbufferType();
+
+	GLuint getColorbufferName();
+	GLuint getDepthbufferName();
+	GLuint getStencilbufferName();
+
+	bool hasStencil();
+
+	virtual GLenum completeness();
+	GLenum completeness(int &width, int &height, int &samples);
+
+	GLenum getImplementationColorReadFormat();
+	GLenum getImplementationColorReadType();
+
+protected:
+	GLenum mColorbufferType;
+	gl::BindingPointer<Renderbuffer> mColorbufferPointer;
+
+	GLenum mDepthbufferType;
+	gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
+
+	GLenum mStencilbufferType;
+	gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
+
+private:
+	Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+public:
+	DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+};
+
+}
+
+#endif   // LIBGLES_CM_FRAMEBUFFER_H_
diff --git a/src/OpenGL/libGLES_CM/IndexDataManager.cpp b/src/OpenGL/libGLES_CM/IndexDataManager.cpp
index 3e31314..874e17a 100644
--- a/src/OpenGL/libGLES_CM/IndexDataManager.cpp
+++ b/src/OpenGL/libGLES_CM/IndexDataManager.cpp
@@ -1,241 +1,244 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// IndexDataManager.cpp: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#include "IndexDataManager.h"

-

-#include "Buffer.h"

-#include "common/debug.h"

-

-#include <string.h>

-#include <algorithm>

-

-namespace

-{

-    enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };

-}

-

-namespace es1

-{

-

-IndexDataManager::IndexDataManager()

-{

-    mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming index buffer.");

-    }

-}

-

-IndexDataManager::~IndexDataManager()

-{

-    delete mStreamingBuffer;

-}

-

-void copyIndices(GLenum type, const void *input, GLsizei count, void *output)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        memcpy(output, input, count * sizeof(GLubyte));

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        memcpy(output, input, count * sizeof(GLushort));

-    }

-    else UNREACHABLE(type);

-}

-

-template<class IndexType>

-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    *minIndex = indices[0];

-    *maxIndex = indices[0];

-

-    for(GLsizei i = 0; i < count; i++)

-    {

-        if(*minIndex > indices[i]) *minIndex = indices[i];

-        if(*maxIndex < indices[i]) *maxIndex = indices[i];

-    }

-}

-

-void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)

-{

-    if(type == GL_UNSIGNED_BYTE)

-    {

-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);

-    }

-    else if(type == GL_UNSIGNED_SHORT)

-    {

-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);

-    }

-    else UNREACHABLE(type);

-}

-

-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    intptr_t offset = reinterpret_cast<intptr_t>(indices);

-

-    if(buffer != NULL)

-    {

-        if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))

-        {

-            return GL_INVALID_OPERATION;

-        }

-

-        indices = static_cast<const GLubyte*>(buffer->data()) + offset;

-    }

-

-    StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;

-

-	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-    if(staticBuffer)

-    {

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = staticBuffer;

-		translated->indexOffset = offset;

-    }

-    else

-    {

-		unsigned int streamOffset = 0;

-        int convertCount = count;

-

-        streamingBuffer->reserveSpace(convertCount * typeSize(type), type);

-        void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);

-        

-        if(output == NULL)

-        {

-            ERR("Failed to map index buffer.");

-            return GL_OUT_OF_MEMORY;

-        }

-

-        copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);

-        streamingBuffer->unmap();

-

-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);

-

-		translated->indexBuffer = streamingBuffer->getResource();

-		translated->indexOffset = streamOffset;

-    }

-

-    return GL_NO_ERROR;

-}

-

-std::size_t IndexDataManager::typeSize(GLenum type)

-{

-    switch(type)

-    {

-    case GL_UNSIGNED_SHORT: return sizeof(GLushort);

-    case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);

-    default: UNREACHABLE(type); return sizeof(GLushort);

-    }

-}

-

-StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)

-{

-	if(initialSize > 0)

-    {

-		mIndexBuffer = new sw::Resource(initialSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", initialSize);

-        }

-    }

-

-    mWritePosition = 0;

-}

-

-StreamingIndexBuffer::~StreamingIndexBuffer()

-{

-	if(mIndexBuffer)

-    {

-        mIndexBuffer->destruct();

-    }

-}

-

-void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mIndexBuffer)

-    {

-        mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;

-     

-        if(!mapPtr)

-        {

-            ERR(" Lock failed");

-            return NULL;

-        }

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingIndexBuffer::unmap()

-{

-    if(mIndexBuffer)

-    {

-        mIndexBuffer->unlock();

-    }

-}

-

-void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)

-{

-    if(requiredSpace > mBufferSize)

-    {

-        if(mIndexBuffer)

-        {

-            mIndexBuffer->destruct();

-            mIndexBuffer = 0;

-        }

-

-        mBufferSize = std::max(requiredSpace, 2 * mBufferSize);

-

-		mIndexBuffer = new sw::Resource(mBufferSize + 16);

-

-        if(!mIndexBuffer)

-        {

-            ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle

-    {

-		if(mIndexBuffer)

-		{

-			mIndexBuffer->destruct();

-			mIndexBuffer = new sw::Resource(mBufferSize + 16);

-		}

-

-        mWritePosition = 0;

-    }

-}

-

-sw::Resource *StreamingIndexBuffer::getResource() const

-{

-    return mIndexBuffer;

-}

-

-}

+// 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.
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#include "IndexDataManager.h"
+
+#include "Buffer.h"
+#include "common/debug.h"
+
+#include <string.h>
+#include <algorithm>
+
+namespace
+{
+	enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
+}
+
+namespace es1
+{
+
+IndexDataManager::IndexDataManager()
+{
+	mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming index buffer.");
+	}
+}
+
+IndexDataManager::~IndexDataManager()
+{
+	delete mStreamingBuffer;
+}
+
+void copyIndices(GLenum type, const void *input, GLsizei count, void *output)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		memcpy(output, input, count * sizeof(GLubyte));
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		memcpy(output, input, count * sizeof(GLushort));
+	}
+	else UNREACHABLE(type);
+}
+
+template<class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	*minIndex = indices[0];
+	*maxIndex = indices[0];
+
+	for(GLsizei i = 0; i < count; i++)
+	{
+		if(*minIndex > indices[i]) *minIndex = indices[i];
+		if(*maxIndex < indices[i]) *maxIndex = indices[i];
+	}
+}
+
+void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+	if(type == GL_UNSIGNED_BYTE)
+	{
+		computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+	}
+	else if(type == GL_UNSIGNED_SHORT)
+	{
+		computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+	}
+	else UNREACHABLE(type);
+}
+
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	intptr_t offset = reinterpret_cast<intptr_t>(indices);
+
+	if(buffer != NULL)
+	{
+		if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
+		{
+			return GL_INVALID_OPERATION;
+		}
+
+		indices = static_cast<const GLubyte*>(buffer->data()) + offset;
+	}
+
+	StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
+
+	sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;
+
+	if(staticBuffer)
+	{
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = staticBuffer;
+		translated->indexOffset = offset;
+	}
+	else
+	{
+		unsigned int streamOffset = 0;
+		int convertCount = count;
+
+		streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
+		void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
+
+		if(output == NULL)
+		{
+			ERR("Failed to map index buffer.");
+			return GL_OUT_OF_MEMORY;
+		}
+
+		copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+		streamingBuffer->unmap();
+
+		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+		translated->indexBuffer = streamingBuffer->getResource();
+		translated->indexOffset = streamOffset;
+	}
+
+	return GL_NO_ERROR;
+}
+
+std::size_t IndexDataManager::typeSize(GLenum type)
+{
+	switch(type)
+	{
+	case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+	case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
+	default: UNREACHABLE(type); return sizeof(GLushort);
+	}
+}
+
+StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)
+{
+	if(initialSize > 0)
+	{
+		mIndexBuffer = new sw::Resource(initialSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", initialSize);
+		}
+	}
+
+	mWritePosition = 0;
+}
+
+StreamingIndexBuffer::~StreamingIndexBuffer()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->destruct();
+	}
+}
+
+void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = NULL;
+
+	if(mIndexBuffer)
+	{
+		mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;
+
+		if(!mapPtr)
+		{
+			ERR(" Lock failed");
+			return NULL;
+		}
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingIndexBuffer::unmap()
+{
+	if(mIndexBuffer)
+	{
+		mIndexBuffer->unlock();
+	}
+}
+
+void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)
+{
+	if(requiredSpace > mBufferSize)
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = 0;
+		}
+
+		mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
+
+		mIndexBuffer = new sw::Resource(mBufferSize + 16);
+
+		if(!mIndexBuffer)
+		{
+			ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle
+	{
+		if(mIndexBuffer)
+		{
+			mIndexBuffer->destruct();
+			mIndexBuffer = new sw::Resource(mBufferSize + 16);
+		}
+
+		mWritePosition = 0;
+	}
+}
+
+sw::Resource *StreamingIndexBuffer::getResource() const
+{
+	return mIndexBuffer;
+}
+
+}
diff --git a/src/OpenGL/libGLES_CM/IndexDataManager.h b/src/OpenGL/libGLES_CM/IndexDataManager.h
index 9ef6a96..d7e83d6 100644
--- a/src/OpenGL/libGLES_CM/IndexDataManager.h
+++ b/src/OpenGL/libGLES_CM/IndexDataManager.h
@@ -1,68 +1,71 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// IndexDataManager.h: Defines the IndexDataManager, a class that

-// runs the Buffer translation process for index buffers.

-

-#ifndef LIBGLES_CM_INDEXDATAMANAGER_H_

-#define LIBGLES_CM_INDEXDATAMANAGER_H_

-

-#include "Context.h"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-

-struct TranslatedIndexData

-{

-    unsigned int minIndex;

-    unsigned int maxIndex;

-    unsigned int indexOffset;

-

-    sw::Resource *indexBuffer;

-};

-

-class StreamingIndexBuffer

-{

-  public:

-    StreamingIndexBuffer(unsigned int initialSize);

-    virtual ~StreamingIndexBuffer();

-

-    void *map(unsigned int requiredSpace, unsigned int *offset);

-	void unmap();

-    void reserveSpace(unsigned int requiredSpace, GLenum type);

-

-	sw::Resource *getResource() const;

-

-  private:

-    sw::Resource *mIndexBuffer;

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-};

-

-class IndexDataManager

-{

-  public:

-    IndexDataManager();

-    virtual ~IndexDataManager();

-

-    GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);

-

-	static std::size_t typeSize(GLenum type);

-

-  private:

-    StreamingIndexBuffer *mStreamingBuffer;

-};

-

-}

-

-#endif   // LIBGLES_CM_INDEXDATAMANAGER_H_

+// 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.
+
+// IndexDataManager.h: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#ifndef LIBGLES_CM_INDEXDATAMANAGER_H_
+#define LIBGLES_CM_INDEXDATAMANAGER_H_
+
+#include "Context.h"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+
+struct TranslatedIndexData
+{
+	unsigned int minIndex;
+	unsigned int maxIndex;
+	unsigned int indexOffset;
+
+	sw::Resource *indexBuffer;
+};
+
+class StreamingIndexBuffer
+{
+public:
+	StreamingIndexBuffer(unsigned int initialSize);
+	virtual ~StreamingIndexBuffer();
+
+	void *map(unsigned int requiredSpace, unsigned int *offset);
+	void unmap();
+	void reserveSpace(unsigned int requiredSpace, GLenum type);
+
+	sw::Resource *getResource() const;
+
+private:
+	sw::Resource *mIndexBuffer;
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+};
+
+class IndexDataManager
+{
+public:
+	IndexDataManager();
+	virtual ~IndexDataManager();
+
+	GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
+
+	static std::size_t typeSize(GLenum type);
+
+private:
+	StreamingIndexBuffer *mStreamingBuffer;
+};
+
+}
+
+#endif   // LIBGLES_CM_INDEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.cpp b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
index fccb011..96bf733 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2013 TransGaming Inc.
+// 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
 //
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    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.
 
 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
@@ -27,7 +30,7 @@
 
 // The default case for classes inherited from RenderbufferInterface is not to
 // need to do anything upon the reference count to the parent Renderbuffer incrementing
-// or decrementing. 
+// or decrementing.
 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
 {
 }
@@ -75,19 +78,19 @@
 
 RenderbufferTexture2D::~RenderbufferTexture2D()
 {
-	mTexture2D = NULL;
+	mTexture2D = nullptr;
 }
 
 // Textures need to maintain their own reference count for references via
 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
 {
-    mTexture2D->addProxyRef(proxy);
+	mTexture2D->addProxyRef(proxy);
 }
 
 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
 {
-    mTexture2D->releaseProxy(proxy);
+	mTexture2D->releaseProxy(proxy);
 }
 
 // Increments refcount on image.
@@ -101,12 +104,12 @@
 // caller must release() the returned image
 egl::Image *RenderbufferTexture2D::createSharedImage()
 {
-    return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
+	return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
 }
 
 bool RenderbufferTexture2D::isShared() const
 {
-    return mTexture2D->isShared(GL_TEXTURE_2D, 0);
+	return mTexture2D->isShared(GL_TEXTURE_2D, 0);
 }
 
 GLsizei RenderbufferTexture2D::getWidth() const
@@ -138,7 +141,7 @@
 
 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
 {
-	ASSERT(instance != NULL);
+	ASSERT(instance);
 	mInstance = instance;
 }
 
@@ -151,16 +154,16 @@
 // its own reference count, so we pass it on here.
 void Renderbuffer::addRef()
 {
-    mInstance->addProxyRef(this);
+	mInstance->addProxyRef(this);
 
-    Object::addRef();
+	Object::addRef();
 }
 
 void Renderbuffer::release()
 {
-    mInstance->releaseProxy(this);
+	mInstance->releaseProxy(this);
 
-    Object::release();
+	Object::release();
 }
 
 // Increments refcount on image.
@@ -174,12 +177,12 @@
 // caller must Release() the returned image
 egl::Image *Renderbuffer::createSharedImage()
 {
-    return mInstance->createSharedImage();
+	return mInstance->createSharedImage();
 }
 
 bool Renderbuffer::isShared() const
 {
-    return mInstance->isShared();
+	return mInstance->isShared();
 }
 
 GLsizei Renderbuffer::getWidth() const
@@ -239,7 +242,7 @@
 
 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
 {
-	ASSERT(newStorage != NULL);
+	ASSERT(newStorage);
 
 	delete mInstance;
 	mInstance = newStorage;
@@ -288,7 +291,7 @@
 	if(renderTarget)
 	{
 		renderTarget->addRef();
-		
+
 		mWidth = renderTarget->getWidth();
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
@@ -346,18 +349,18 @@
 // caller must release() the returned image
 egl::Image *Colorbuffer::createSharedImage()
 {
-    if(mRenderTarget)
-    {
-        mRenderTarget->addRef();
-        mRenderTarget->markShared();
-    }
+	if(mRenderTarget)
+	{
+		mRenderTarget->addRef();
+		mRenderTarget->markShared();
+	}
 
-    return mRenderTarget;
+	return mRenderTarget;
 }
 
 bool Colorbuffer::isShared() const
 {
-    return mRenderTarget->isShared();
+	return mRenderTarget->isShared();
 }
 
 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
@@ -377,7 +380,7 @@
 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
 {
 	Device *device = getDevice();
-	
+
 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
 
 	if(width > 0 && height > 0)
@@ -422,18 +425,18 @@
 // caller must release() the returned image
 egl::Image *DepthStencilbuffer::createSharedImage()
 {
-    if(mDepthStencil)
-    {
-        mDepthStencil->addRef();
-        mDepthStencil->markShared();
-    }
+	if(mDepthStencil)
+	{
+		mDepthStencil->addRef();
+		mDepthStencil->markShared();
+	}
 
-    return mDepthStencil;
+	return mDepthStencil;
 }
 
 bool DepthStencilbuffer::isShared() const
 {
-    return mDepthStencil->isShared();
+	return mDepthStencil->isShared();
 }
 
 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
@@ -441,7 +444,7 @@
 	if(depthStencil)
 	{
 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                     // will expect one of the valid renderbuffer formats for use in 
+		                                     // will expect one of the valid renderbuffer formats for use in
 		                                     // glRenderbufferStorage
 	}
 }
@@ -451,7 +454,7 @@
 	if(mDepthStencil)
 	{
 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                     // will expect one of the valid renderbuffer formats for use in 
+		                                     // will expect one of the valid renderbuffer formats for use in
 		                                     // glRenderbufferStorage
 	}
 }
@@ -465,7 +468,7 @@
 	if(depthStencil)
 	{
 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                  // will expect one of the valid renderbuffer formats for use in 
+		                                  // will expect one of the valid renderbuffer formats for use in
 		                                  // glRenderbufferStorage
 	}
 }
@@ -475,7 +478,7 @@
 	if(mDepthStencil)
 	{
 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
-		                                  // will expect one of the valid renderbuffer formats for use in 
+		                                  // will expect one of the valid renderbuffer formats for use in
 		                                  // glRenderbufferStorage
 	}
 }
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.h b/src/OpenGL/libGLES_CM/Renderbuffer.h
index a0b1709..6bb462f 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.h
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.h
@@ -1,202 +1,205 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the

-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,

-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer

-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.

-

-#ifndef LIBGLES_CM_RENDERBUFFER_H_

-#define LIBGLES_CM_RENDERBUFFER_H_

-

-#include "common/Object.hpp"

-#include "common/Image.hpp"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-class Texture2D;

-class Renderbuffer;

-class Colorbuffer;

-class DepthStencilbuffer;

-

-class RenderbufferInterface

-{

-public:

-	RenderbufferInterface();

-

-	virtual ~RenderbufferInterface() {};

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget() = 0;

-    virtual egl::Image *createSharedImage() = 0;

-    virtual bool isShared() const = 0;

-

-	virtual GLsizei getWidth() const = 0;

-	virtual GLsizei getHeight() const = 0;

-	virtual GLenum getFormat() const = 0;

-	virtual sw::Format getInternalFormat() const = 0;

-	virtual GLsizei getSamples() const = 0;

-

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-};

-

-class RenderbufferTexture2D : public RenderbufferInterface

-{

-public:

-	RenderbufferTexture2D(Texture2D *texture);

-

-	virtual ~RenderbufferTexture2D();

-

-	virtual void addProxyRef(const Renderbuffer *proxy);

-    virtual void releaseProxy(const Renderbuffer *proxy);

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-private:

-	gl::BindingPointer<Texture2D> mTexture2D;

-};

-

-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage

-// is called. The specific concrete type depends on whether the internal format is

-// colour depth, stencil or packed depth/stencil.

-class RenderbufferStorage : public RenderbufferInterface

-{

-public:

-	RenderbufferStorage();

-

-	virtual ~RenderbufferStorage() = 0;

-

-	virtual egl::Image *getRenderTarget() = 0;

-    virtual egl::Image *createSharedImage() = 0;

-    virtual bool isShared() const = 0;

-

-	virtual GLsizei getWidth() const;

-	virtual GLsizei getHeight() const;

-	virtual GLenum getFormat() const;

-	virtual sw::Format getInternalFormat() const;

-	virtual GLsizei getSamples() const;

-

-protected:

-	GLsizei mWidth;

-	GLsizei mHeight;

-	GLenum format;

-	sw::Format internalFormat;

-	GLsizei mSamples;

-};

-

-// Renderbuffer implements the GL renderbuffer object.

-// It's only a proxy for a RenderbufferInterface instance; the internal object

-// can change whenever glRenderbufferStorage is called.

-class Renderbuffer : public gl::NamedObject

-{

-public:

-	Renderbuffer(GLuint name, RenderbufferInterface *storage);

-

-	virtual ~Renderbuffer();

-

-	// These functions from Object are overloaded here because

-    // Textures need to maintain their own count of references to them via

-    // Renderbuffers/RenderbufferTextures. These functions invoke those

-    // reference counting functions on the RenderbufferInterface.

-    virtual void addRef();

-    virtual void release();

-

-	egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-	GLsizei getWidth() const;

-	GLsizei getHeight() const;

-	GLenum getFormat() const;

-	sw::Format getInternalFormat() const;

-	GLuint getRedSize() const;

-	GLuint getGreenSize() const;

-	GLuint getBlueSize() const;

-	GLuint getAlphaSize() const;

-	GLuint getDepthSize() const;

-	GLuint getStencilSize() const;

-	GLsizei getSamples() const;

-

-	void setStorage(RenderbufferStorage *newStorage);

-

-private:

-	RenderbufferInterface *mInstance;

-};

-

-class Colorbuffer : public RenderbufferStorage

-{

-public:

-	explicit Colorbuffer(egl::Image *renderTarget);

-	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);

-

-	virtual ~Colorbuffer();

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-private:

-	egl::Image *mRenderTarget;

-};

-

-class DepthStencilbuffer : public RenderbufferStorage

-{

-public:

-	explicit DepthStencilbuffer(egl::Image *depthStencil);

-	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	~DepthStencilbuffer();

-

-	virtual egl::Image *getRenderTarget();

-    virtual egl::Image *createSharedImage();

-    virtual bool isShared() const;

-

-protected:

-	egl::Image *mDepthStencil;

-};

-

-class Depthbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Depthbuffer(egl::Image *depthStencil);

-	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Depthbuffer();

-};

-

-class Stencilbuffer : public DepthStencilbuffer

-{

-public:

-	explicit Stencilbuffer(egl::Image *depthStencil);

-	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);

-

-	virtual ~Stencilbuffer();

-};

-}

-

-#endif   // LIBGLES_CM_RENDERBUFFER_H_

+// 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.
+
+// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#ifndef LIBGLES_CM_RENDERBUFFER_H_
+#define LIBGLES_CM_RENDERBUFFER_H_
+
+#include "common/Object.hpp"
+#include "common/Image.hpp"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+class Texture2D;
+class Renderbuffer;
+class Colorbuffer;
+class DepthStencilbuffer;
+
+class RenderbufferInterface
+{
+public:
+	RenderbufferInterface();
+
+	virtual ~RenderbufferInterface() {};
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget() = 0;
+    virtual egl::Image *createSharedImage() = 0;
+    virtual bool isShared() const = 0;
+
+	virtual GLsizei getWidth() const = 0;
+	virtual GLsizei getHeight() const = 0;
+	virtual GLenum getFormat() const = 0;
+	virtual sw::Format getInternalFormat() const = 0;
+	virtual GLsizei getSamples() const = 0;
+
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+};
+
+class RenderbufferTexture2D : public RenderbufferInterface
+{
+public:
+	RenderbufferTexture2D(Texture2D *texture);
+
+	virtual ~RenderbufferTexture2D();
+
+	virtual void addProxyRef(const Renderbuffer *proxy);
+    virtual void releaseProxy(const Renderbuffer *proxy);
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+private:
+	gl::BindingPointer<Texture2D> mTexture2D;
+};
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage : public RenderbufferInterface
+{
+public:
+	RenderbufferStorage();
+
+	virtual ~RenderbufferStorage() = 0;
+
+	virtual egl::Image *getRenderTarget() = 0;
+    virtual egl::Image *createSharedImage() = 0;
+    virtual bool isShared() const = 0;
+
+	virtual GLsizei getWidth() const;
+	virtual GLsizei getHeight() const;
+	virtual GLenum getFormat() const;
+	virtual sw::Format getInternalFormat() const;
+	virtual GLsizei getSamples() const;
+
+protected:
+	GLsizei mWidth;
+	GLsizei mHeight;
+	GLenum format;
+	sw::Format internalFormat;
+	GLsizei mSamples;
+};
+
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a proxy for a RenderbufferInterface instance; the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public gl::NamedObject
+{
+public:
+	Renderbuffer(GLuint name, RenderbufferInterface *storage);
+
+	virtual ~Renderbuffer();
+
+	// These functions from Object are overloaded here because
+    // Textures need to maintain their own count of references to them via
+    // Renderbuffers/RenderbufferTextures. These functions invoke those
+    // reference counting functions on the RenderbufferInterface.
+    virtual void addRef();
+    virtual void release();
+
+	egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+	GLsizei getWidth() const;
+	GLsizei getHeight() const;
+	GLenum getFormat() const;
+	sw::Format getInternalFormat() const;
+	GLuint getRedSize() const;
+	GLuint getGreenSize() const;
+	GLuint getBlueSize() const;
+	GLuint getAlphaSize() const;
+	GLuint getDepthSize() const;
+	GLuint getStencilSize() const;
+	GLsizei getSamples() const;
+
+	void setStorage(RenderbufferStorage *newStorage);
+
+private:
+	RenderbufferInterface *mInstance;
+};
+
+class Colorbuffer : public RenderbufferStorage
+{
+public:
+	explicit Colorbuffer(egl::Image *renderTarget);
+	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+
+	virtual ~Colorbuffer();
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+private:
+	egl::Image *mRenderTarget;
+};
+
+class DepthStencilbuffer : public RenderbufferStorage
+{
+public:
+	explicit DepthStencilbuffer(egl::Image *depthStencil);
+	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	~DepthStencilbuffer();
+
+	virtual egl::Image *getRenderTarget();
+    virtual egl::Image *createSharedImage();
+    virtual bool isShared() const;
+
+protected:
+	egl::Image *mDepthStencil;
+};
+
+class Depthbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Depthbuffer(egl::Image *depthStencil);
+	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Depthbuffer();
+};
+
+class Stencilbuffer : public DepthStencilbuffer
+{
+public:
+	explicit Stencilbuffer(egl::Image *depthStencil);
+	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+
+	virtual ~Stencilbuffer();
+};
+}
+
+#endif   // LIBGLES_CM_RENDERBUFFER_H_
diff --git a/src/OpenGL/libGLES_CM/ResourceManager.cpp b/src/OpenGL/libGLES_CM/ResourceManager.cpp
index 54d71b9..7f0936c 100644
--- a/src/OpenGL/libGLES_CM/ResourceManager.cpp
+++ b/src/OpenGL/libGLES_CM/ResourceManager.cpp
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    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.
 
 // ResourceManager.cpp: Implements the ResourceManager class, which tracks and
 // retrieves objects which may be shared by multiple Contexts.
@@ -22,138 +25,138 @@
 {
 ResourceManager::ResourceManager()
 {
-    mRefCount = 1;
+	mRefCount = 1;
 }
 
 ResourceManager::~ResourceManager()
 {
-    while(!mBufferNameSpace.empty())
-    {
-        deleteBuffer(mBufferNameSpace.firstName());
-    }
+	while(!mBufferNameSpace.empty())
+	{
+		deleteBuffer(mBufferNameSpace.firstName());
+	}
 
-    while(!mRenderbufferNameSpace.empty())
-    {
-        deleteRenderbuffer(mRenderbufferNameSpace.firstName());
-    }
+	while(!mRenderbufferNameSpace.empty())
+	{
+		deleteRenderbuffer(mRenderbufferNameSpace.firstName());
+	}
 
-    while(!mTextureNameSpace.empty())
-    {
-        deleteTexture(mTextureNameSpace.firstName());
-    }
+	while(!mTextureNameSpace.empty())
+	{
+		deleteTexture(mTextureNameSpace.firstName());
+	}
 }
 
 void ResourceManager::addRef()
 {
-    mRefCount++;
+	mRefCount++;
 }
 
 void ResourceManager::release()
 {
-    if(--mRefCount == 0)
-    {
-        delete this;
-    }
+	if(--mRefCount == 0)
+	{
+		delete this;
+	}
 }
 
 // Returns an unused buffer name
 GLuint ResourceManager::createBuffer()
 {
-    return mBufferNameSpace.allocate();
+	return mBufferNameSpace.allocate();
 }
 
 // Returns an unused texture name
 GLuint ResourceManager::createTexture()
 {
-    return mTextureNameSpace.allocate();
+	return mTextureNameSpace.allocate();
 }
 
 // Returns an unused renderbuffer name
 GLuint ResourceManager::createRenderbuffer()
 {
-    return mRenderbufferNameSpace.allocate();
+	return mRenderbufferNameSpace.allocate();
 }
 
 void ResourceManager::deleteBuffer(GLuint buffer)
 {
-    Buffer *bufferObject = mBufferNameSpace.remove(buffer);
+	Buffer *bufferObject = mBufferNameSpace.remove(buffer);
 
-    if(bufferObject)
-    {
+	if(bufferObject)
+	{
 		bufferObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteTexture(GLuint texture)
 {
-    Texture *textureObject = mTextureNameSpace.remove(texture);
+	Texture *textureObject = mTextureNameSpace.remove(texture);
 
-    if(textureObject)
-    {
+	if(textureObject)
+	{
 		textureObject->release();
-    }
+	}
 }
 
 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
 {
-    Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
+	Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
 
-    if(renderbufferObject)
-    {
+	if(renderbufferObject)
+	{
 		renderbufferObject->release();
-    }
+	}
 }
 
 Buffer *ResourceManager::getBuffer(unsigned int handle)
 {
-    return mBufferNameSpace.find(handle);
+	return mBufferNameSpace.find(handle);
 }
 
 Texture *ResourceManager::getTexture(unsigned int handle)
 {
-    return mTextureNameSpace.find(handle);
+	return mTextureNameSpace.find(handle);
 }
 
 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
 {
-    return mRenderbufferNameSpace.find(handle);
+	return mRenderbufferNameSpace.find(handle);
 }
 
 void ResourceManager::checkBufferAllocation(unsigned int buffer)
 {
-    if(buffer != 0 && !getBuffer(buffer))
-    {
-        Buffer *bufferObject = new Buffer(buffer);
+	if(buffer != 0 && !getBuffer(buffer))
+	{
+		Buffer *bufferObject = new Buffer(buffer);
 		bufferObject->addRef();
 
 		mBufferNameSpace.insert(buffer, bufferObject);
-    }
+	}
 }
 
 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
 {
-    if(!getTexture(texture) && texture != 0)
-    {
-        Texture *textureObject;
+	if(!getTexture(texture) && texture != 0)
+	{
+		Texture *textureObject;
 
-        if(type == TEXTURE_2D)
-        {
-            textureObject = new Texture2D(texture);
-        }
-        else if(type == TEXTURE_EXTERNAL)
-        {
-            textureObject = new TextureExternal(texture);
-        }
-        else
-        {
-            UNREACHABLE(type);
-            return;
-        }
+		if(type == TEXTURE_2D)
+		{
+			textureObject = new Texture2D(texture);
+		}
+		else if(type == TEXTURE_EXTERNAL)
+		{
+			textureObject = new TextureExternal(texture);
+		}
+		else
+		{
+			UNREACHABLE(type);
+			return;
+		}
 
 		textureObject->addRef();
 
 		mTextureNameSpace.insert(texture, textureObject);
-    }
+	}
 }
 
 void ResourceManager::checkRenderbufferAllocation(GLuint handle)
diff --git a/src/OpenGL/libGLES_CM/ResourceManager.h b/src/OpenGL/libGLES_CM/ResourceManager.h
index 22d719f..7520580 100644
--- a/src/OpenGL/libGLES_CM/ResourceManager.h
+++ b/src/OpenGL/libGLES_CM/ResourceManager.h
@@ -1,75 +1,78 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// ResourceManager.h : Defines the ResourceManager class, which tracks objects

-// shared by multiple GL contexts.

-

-#ifndef LIBGLES_CM_RESOURCEMANAGER_H_

-#define LIBGLES_CM_RESOURCEMANAGER_H_

-

-#include "common/NameSpace.hpp"

-

-#include <GLES/gl.h>

-

-#include <map>

-

-namespace es1

-{

-class Buffer;

-class Texture;

-class Renderbuffer;

-

-enum TextureType

-{

-    TEXTURE_2D,

-    TEXTURE_CUBE,

-    TEXTURE_EXTERNAL,

-

-    TEXTURE_TYPE_COUNT,

-    TEXTURE_UNKNOWN

-};

-

-class ResourceManager

-{

-public:

-    ResourceManager();

-    ~ResourceManager();

-

-    void addRef();

-    void release();

-

-    GLuint createBuffer();

-    GLuint createTexture();

-    GLuint createRenderbuffer();

-

-    void deleteBuffer(GLuint buffer);

-    void deleteTexture(GLuint texture);

-    void deleteRenderbuffer(GLuint renderbuffer);

-

-    Buffer *getBuffer(GLuint handle);

-    Texture *getTexture(GLuint handle);

-    Renderbuffer *getRenderbuffer(GLuint handle);

-

-    void checkBufferAllocation(unsigned int buffer);

-    void checkTextureAllocation(GLuint texture, TextureType type);

-	void checkRenderbufferAllocation(GLuint handle);

-

-private:

-    std::size_t mRefCount;

-

-    gl::NameSpace<Buffer> mBufferNameSpace;

-	gl::NameSpace<Texture> mTextureNameSpace;

-    gl::NameSpace<Renderbuffer> mRenderbufferNameSpace;

-};

-

-}

-

-#endif // LIBGLES_CM_RESOURCEMANAGER_H_

+// 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.
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGLES_CM_RESOURCEMANAGER_H_
+#define LIBGLES_CM_RESOURCEMANAGER_H_
+
+#include "common/NameSpace.hpp"
+
+#include <GLES/gl.h>
+
+#include <map>
+
+namespace es1
+{
+class Buffer;
+class Texture;
+class Renderbuffer;
+
+enum TextureType
+{
+	TEXTURE_2D,
+	TEXTURE_CUBE,
+	TEXTURE_EXTERNAL,
+
+	TEXTURE_TYPE_COUNT,
+	TEXTURE_UNKNOWN
+};
+
+class ResourceManager
+{
+public:
+	ResourceManager();
+	~ResourceManager();
+
+	void addRef();
+	void release();
+
+	GLuint createBuffer();
+	GLuint createTexture();
+	GLuint createRenderbuffer();
+
+	void deleteBuffer(GLuint buffer);
+	void deleteTexture(GLuint texture);
+	void deleteRenderbuffer(GLuint renderbuffer);
+
+	Buffer *getBuffer(GLuint handle);
+	Texture *getTexture(GLuint handle);
+	Renderbuffer *getRenderbuffer(GLuint handle);
+
+	void checkBufferAllocation(unsigned int buffer);
+	void checkTextureAllocation(GLuint texture, TextureType type);
+	void checkRenderbufferAllocation(GLuint handle);
+
+private:
+	std::size_t mRefCount;
+
+	gl::NameSpace<Buffer> mBufferNameSpace;
+	gl::NameSpace<Texture> mTextureNameSpace;
+	gl::NameSpace<Renderbuffer> mRenderbufferNameSpace;
+};
+
+}
+
+#endif // LIBGLES_CM_RESOURCEMANAGER_H_
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 3729d9b..b8817a0 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -1,860 +1,863 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Texture.cpp: Implements the Texture class and its derived classes

-// Texture2D and TextureCubeMap. Implements GL texture objects and related

-// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

-

-#include "Texture.h"

-

-#include "main.h"

-#include "mathutil.h"

-#include "Framebuffer.h"

-#include "Device.hpp"

-#include "libEGL/Display.h"

-#include "libEGL/Surface.h"

-#include "common/debug.h"

-

-#include <algorithm>

-

-namespace es1

-{

-

-Texture::Texture(GLuint name) : egl::Texture(name)

-{

-    mMinFilter = GL_NEAREST_MIPMAP_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_REPEAT;

-    mWrapT = GL_REPEAT;

-	mMaxAnisotropy = 1.0f;

-	generateMipmap = GL_FALSE;

-	cropRectU = 0;

-	cropRectV = 0;

-	cropRectW = 0;

-	cropRectH = 0;

-

-	resource = new sw::Resource(0);

-}

-

-Texture::~Texture()

-{

-	resource->destruct();

-}

-

-sw::Resource *Texture::getResource() const

-{

-	return resource;

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMinFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMinFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful filter state update (valid enum parameter)

-bool Texture::setMagFilter(GLenum filter)

-{

-    switch(filter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        mMagFilter = filter;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapS(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_REPEAT:

-    case GL_MIRRORED_REPEAT_OES:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_CLAMP_TO_EDGE:

-        mWrapS = wrap;

-        return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful wrap state update (valid enum parameter)

-bool Texture::setWrapT(GLenum wrap)

-{

-    switch(wrap)

-    {

-    case GL_REPEAT:

-    case GL_MIRRORED_REPEAT_OES:

-        if(getTarget() == GL_TEXTURE_EXTERNAL_OES)

-        {

-            return false;

-        }

-        // Fall through

-    case GL_CLAMP_TO_EDGE:

-         mWrapT = wrap;

-         return true;

-    default:

-        return false;

-    }

-}

-

-// Returns true on successful max anisotropy update (valid anisotropy value)

-bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)

-{

-    textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);

-

-    if(textureMaxAnisotropy < 1.0f)

-    {

-        return false;

-    }

-

-	if(mMaxAnisotropy != textureMaxAnisotropy)

-    {

-        mMaxAnisotropy = textureMaxAnisotropy;

-    }

-

-    return true;

-}

-

-void Texture::setGenerateMipmap(GLboolean enable)

-{

-	generateMipmap = enable;

-}

-

-void Texture::setCropRect(GLint u, GLint v, GLint w, GLint h)

-{

-	cropRectU = u;

-	cropRectV = v;

-	cropRectW = w;

-	cropRectH = h;

-}

-

-GLenum Texture::getMinFilter() const

-{

-    return mMinFilter;

-}

-

-GLenum Texture::getMagFilter() const

-{

-    return mMagFilter;

-}

-

-GLenum Texture::getWrapS() const

-{

-    return mWrapS;

-}

-

-GLenum Texture::getWrapT() const

-{

-    return mWrapT;

-}

-

-GLfloat Texture::getMaxAnisotropy() const

-{

-    return mMaxAnisotropy;

-}

-

-GLboolean Texture::getGenerateMipmap() const

-{

-	return generateMipmap;

-}

-

-GLint Texture::getCropRectU() const

-{

-	return cropRectU;

-}

-

-GLint Texture::getCropRectV() const

-{

-	return cropRectV;

-}

-

-GLint Texture::getCropRectW() const

-{

-	return cropRectW;

-}

-

-GLint Texture::getCropRectH() const

-{

-	return cropRectH;

-}

-

-egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)

-{

-    egl::Image *image = getRenderTarget(target, level);   // Increments reference count

-

-    if(image)

-    {

-        image->markShared();

-    }

-

-    return image;

-}

-

-void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)

-{

-    if(pixels && image)

-    {

-		egl::Image::UnpackInfo unpackInfo;

-		unpackInfo.alignment = unpackAlignment;

-		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackInfo, pixels);

-    }

-}

-

-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)

-{

-    if(pixels && image)

-    {

-		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);

-    }

-}

-

-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(IsCompressed(image->getFormat()))

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		egl::Image::UnpackInfo unpackInfo;

-		unpackInfo.alignment = unpackAlignment;

-		image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels);

-    }

-}

-

-void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)

-{

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    if(format != image->getFormat())

-    {

-        return error(GL_INVALID_OPERATION);

-    }

-

-    if(pixels)

-    {

-		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);

-    }

-}

-

-bool Texture::copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest)

-{

-    Device *device = getDevice();

-

-    sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);

-    sw::SliceRect sourceSliceRect(sourceRect);

-    bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);

-

-    if(!success)

-    {

-        return error(GL_OUT_OF_MEMORY, false);

-    }

-

-    return true;

-}

-

-bool Texture::isMipmapFiltered() const

-{

-	switch(mMinFilter)

-    {

-    case GL_NEAREST:

-    case GL_LINEAR:

-        return false;

-    case GL_NEAREST_MIPMAP_NEAREST:

-    case GL_LINEAR_MIPMAP_NEAREST:

-    case GL_NEAREST_MIPMAP_LINEAR:

-    case GL_LINEAR_MIPMAP_LINEAR:

-        return true;

-    default: UNREACHABLE(mMinFilter);

-    }

-

-	return false;

-}

-

-Texture2D::Texture2D(GLuint name) : Texture(name)

-{

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		image[i] = nullptr;

-	}

-

-    mSurface = nullptr;

-

-	mColorbufferProxy = nullptr;

-	mProxyRefs = 0;

-}

-

-Texture2D::~Texture2D()

-{

-	resource->lock(sw::DESTRUCT);

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i])

-		{

-			image[i]->unbind(this);

-			image[i] = nullptr;

-		}

-	}

-

-	resource->unlock();

-

-    if(mSurface)

-    {

-        mSurface->setBoundTexture(nullptr);

-        mSurface = nullptr;

-    }

-

-	mColorbufferProxy = nullptr;

-}

-

-// We need to maintain a count of references to renderbuffers acting as

-// proxies for this texture, so that we do not attempt to use a pointer

-// to a renderbuffer proxy which has been deleted.

-void Texture2D::addProxyRef(const Renderbuffer *proxy)

-{

-    mProxyRefs++;

-}

-

-void Texture2D::releaseProxy(const Renderbuffer *proxy)

-{

-    if(mProxyRefs > 0)

-	{

-        mProxyRefs--;

-	}

-

-    if(mProxyRefs == 0)

-	{

-		mColorbufferProxy = nullptr;

-	}

-}

-

-void Texture2D::sweep()

-{

-	int imageCount = 0;

-

-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)

-	{

-		if(image[i] && image[i]->isChildOf(this))

-		{

-			if(!image[i]->hasSingleReference())

-			{

-				return;

-			}

-

-			imageCount++;

-		}

-	}

-

-	if(imageCount == referenceCount)

-	{

-		destroy();

-	}

-}

-

-GLenum Texture2D::getTarget() const

-{

-    return GL_TEXTURE_2D;

-}

-

-GLsizei Texture2D::getWidth(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getWidth() : 0;

-}

-

-GLsizei Texture2D::getHeight(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-    return image[level] ? image[level]->getHeight() : 0;

-}

-

-GLenum Texture2D::getFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getFormat() : GL_NONE;

-}

-

-GLenum Texture2D::getType(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getType() : GL_NONE;

-}

-

-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const

-{

-	ASSERT(target == GL_TEXTURE_2D);

-	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;

-}

-

-int Texture2D::getLevelCount() const

-{

-	ASSERT(isSamplerComplete());

-	int levels = 0;

-

-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])

-	{

-		levels++;

-	}

-

-	return levels;

-}

-

-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, type);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setImage(format, type, unpackAlignment, pixels, image[level]);

-}

-

-void Texture2D::bindTexImage(egl::Surface *surface)

-{

-    GLenum format;

-

-    switch(surface->getInternalFormat())

-    {

-    case sw::FORMAT_A8R8G8B8:

-		format = GL_BGRA_EXT;

-        break;

-	case sw::FORMAT_A8B8G8R8:

-        format = GL_RGBA;

-        break;

-    case sw::FORMAT_X8B8G8R8:

-	case sw::FORMAT_X8R8G8B8:

-        format = GL_RGB;

-        break;

-    default:

-        UNIMPLEMENTED();

-        return;

-    }

-

-	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-

-	image[0] = surface->getRenderTarget();

-

-    mSurface = surface;

-    mSurface->setBoundTexture(this);

-}

-

-void Texture2D::releaseTexImage()

-{

-    for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)

-	{

-		if(image[level])

-		{

-			image[level]->release();

-			image[level] = nullptr;

-		}

-	}

-}

-

-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)

-{

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    Texture::setCompressedImage(imageSize, pixels, image[level]);

-}

-

-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)

-{

-	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);

-}

-

-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)

-{

-    Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);

-}

-

-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-    egl::Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	if(image[level])

-	{

-		image[level]->release();

-	}

-

-	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);

-

-	if(!image[level])

-	{

-		return error(GL_OUT_OF_MEMORY);

-	}

-

-    if(width != 0 && height != 0)

-    {

-		sw::Rect sourceRect = {x, y, x + width, y + height};

-		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-        copy(renderTarget, sourceRect, format, 0, 0, image[level]);

-    }

-

-	renderTarget->release();

-}

-

-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)

-{

-	if(!image[level])

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-    if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())

-    {

-        return error(GL_INVALID_VALUE);

-    }

-

-    egl::Image *renderTarget = source->getRenderTarget();

-

-    if(!renderTarget)

-    {

-        ERR("Failed to retrieve the render target.");

-        return error(GL_OUT_OF_MEMORY);

-    }

-

-	sw::Rect sourceRect = {x, y, x + width, y + height};

-	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());

-

-	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);

-

-	renderTarget->release();

-}

-

-void Texture2D::setImage(egl::Image *sharedImage)

-{

-	sharedImage->addRef();

-

-    if(image[0])

-    {

-        image[0]->release();

-    }

-

-    image[0] = sharedImage;

-}

-

-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.

-bool Texture2D::isSamplerComplete() const

-{

-	if(!image[0])

-	{

-		return false;

-	}

-

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    if(width <= 0 || height <= 0)

-    {

-        return false;

-    }

-

-    if(isMipmapFiltered())

-    {

-        if(!generateMipmap && !isMipmapComplete())

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.

-bool Texture2D::isMipmapComplete() const

-{

-    GLsizei width = image[0]->getWidth();

-    GLsizei height = image[0]->getHeight();

-

-    int q = log2(std::max(width, height));

-

-    for(int level = 1; level <= q; level++)

-    {

-		if(!image[level])

-		{

-			return false;

-		}

-

-        if(image[level]->getFormat() != image[0]->getFormat())

-        {

-            return false;

-        }

-

-        if(image[level]->getType() != image[0]->getType())

-        {

-            return false;

-        }

-

-        if(image[level]->getWidth() != std::max(1, width >> level))

-        {

-            return false;

-        }

-

-        if(image[level]->getHeight() != std::max(1, height >> level))

-        {

-            return false;

-        }

-    }

-

-    return true;

-}

-

-bool Texture2D::isCompressed(GLenum target, GLint level) const

-{

-    return IsCompressed(getFormat(target, level));

-}

-

-bool Texture2D::isDepth(GLenum target, GLint level) const

-{

-    return IsDepthTexture(getFormat(target, level));

-}

-

-void Texture2D::generateMipmaps()

-{

-	if(!image[0])

-	{

-		return;   // FIXME: error?

-	}

-

-    unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));

-

-	for(unsigned int i = 1; i <= q; i++)

-    {

-		if(image[i])

-		{

-			image[i]->release();

-		}

-

-		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());

-

-		if(!image[i])

-		{

-			return error(GL_OUT_OF_MEMORY);

-		}

-

-		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);

-    }

-}

-

-void Texture2D::autoGenerateMipmaps()

-{

-	if(generateMipmap && image[0]->hasDirtyMipmaps())

-	{

-		generateMipmaps();

-		image[0]->cleanMipmaps();

-	}

-}

-

-egl::Image *Texture2D::getImage(unsigned int level)

-{

-	return image[level];

-}

-

-Renderbuffer *Texture2D::getRenderbuffer(GLenum target)

-{

-    if(target != GL_TEXTURE_2D)

-    {

-        return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);

-    }

-

-    if(!mColorbufferProxy)

-    {

-        mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));

-    }

-

-    return mColorbufferProxy;

-}

-

-egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)

-{

-    ASSERT(target == GL_TEXTURE_2D);

-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-	if(image[level])

-	{

-		image[level]->addRef();

-	}

-

-	return image[level];

-}

-

-bool Texture2D::isShared(GLenum target, unsigned int level) const

-{

-    ASSERT(target == GL_TEXTURE_2D);

-    ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

-

-    if(mSurface)   // Bound to an EGLSurface

-    {

-        return true;

-    }

-

-    if(!image[level])

-    {

-        return false;

-    }

-

-    return image[level]->isShared();

-}

-

-TextureExternal::TextureExternal(GLuint name) : Texture2D(name)

-{

-    mMinFilter = GL_LINEAR;

-    mMagFilter = GL_LINEAR;

-    mWrapS = GL_CLAMP_TO_EDGE;

-    mWrapT = GL_CLAMP_TO_EDGE;

-}

-

-TextureExternal::~TextureExternal()

-{

-}

-

-GLenum TextureExternal::getTarget() const

-{

-    return GL_TEXTURE_EXTERNAL_OES;

-}

-

-}

-

-egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

-{

-	if(config)

-	{

-		return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);

-	}

-

-	return nullptr;

-}

-

-egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-{

-	if(height > sw::OUTLINE_RESOLUTION)

-	{

-		ERR("Invalid parameters: %dx%d", width, height);

-		return 0;

-	}

-

-	bool lockable = true;

-

-	switch(format)

-	{

-//	case sw::FORMAT_D15S1:

-	case sw::FORMAT_D24S8:

-	case sw::FORMAT_D24X8:

-//	case sw::FORMAT_D24X4S4:

-	case sw::FORMAT_D24FS8:

-	case sw::FORMAT_D32:

-	case sw::FORMAT_D16:

-		lockable = false;

-		break;

-//	case sw::FORMAT_S8_LOCKABLE:

-//	case sw::FORMAT_D16_LOCKABLE:

-	case sw::FORMAT_D32F_LOCKABLE:

-//	case sw::FORMAT_D32_LOCKABLE:

-	case sw::FORMAT_DF24S8:

-	case sw::FORMAT_DF16S8:

-		lockable = true;

-		break;

-	default:

-		UNREACHABLE(format);

-	}

-

-	egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);

-

-	if(!surface)

-	{

-		ERR("Out of memory");

-		return nullptr;

-	}

-

-	return surface;

-}

+// 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.
+
+// Texture.cpp: Implements the Texture class and its derived classes
+// Texture2D and TextureCubeMap. Implements GL texture objects and related
+// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#include "Texture.h"
+
+#include "main.h"
+#include "mathutil.h"
+#include "Framebuffer.h"
+#include "Device.hpp"
+#include "libEGL/Display.h"
+#include "libEGL/Surface.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+namespace es1
+{
+
+Texture::Texture(GLuint name) : egl::Texture(name)
+{
+	mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_REPEAT;
+	mWrapT = GL_REPEAT;
+	mMaxAnisotropy = 1.0f;
+	generateMipmap = GL_FALSE;
+	cropRectU = 0;
+	cropRectV = 0;
+	cropRectW = 0;
+	cropRectH = 0;
+
+	resource = new sw::Resource(0);
+}
+
+Texture::~Texture()
+{
+	resource->destruct();
+}
+
+sw::Resource *Texture::getResource() const
+{
+	return resource;
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMinFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMinFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful filter state update (valid enum parameter)
+bool Texture::setMagFilter(GLenum filter)
+{
+	switch(filter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		mMagFilter = filter;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapS(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT_OES:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		mWrapS = wrap;
+		return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful wrap state update (valid enum parameter)
+bool Texture::setWrapT(GLenum wrap)
+{
+	switch(wrap)
+	{
+	case GL_REPEAT:
+	case GL_MIRRORED_REPEAT_OES:
+		if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+		{
+			return false;
+		}
+		// Fall through
+	case GL_CLAMP_TO_EDGE:
+		 mWrapT = wrap;
+		 return true;
+	default:
+		return false;
+	}
+}
+
+// Returns true on successful max anisotropy update (valid anisotropy value)
+bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
+{
+	textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);
+
+	if(textureMaxAnisotropy < 1.0f)
+	{
+		return false;
+	}
+
+	if(mMaxAnisotropy != textureMaxAnisotropy)
+	{
+		mMaxAnisotropy = textureMaxAnisotropy;
+	}
+
+	return true;
+}
+
+void Texture::setGenerateMipmap(GLboolean enable)
+{
+	generateMipmap = enable;
+}
+
+void Texture::setCropRect(GLint u, GLint v, GLint w, GLint h)
+{
+	cropRectU = u;
+	cropRectV = v;
+	cropRectW = w;
+	cropRectH = h;
+}
+
+GLenum Texture::getMinFilter() const
+{
+	return mMinFilter;
+}
+
+GLenum Texture::getMagFilter() const
+{
+	return mMagFilter;
+}
+
+GLenum Texture::getWrapS() const
+{
+	return mWrapS;
+}
+
+GLenum Texture::getWrapT() const
+{
+	return mWrapT;
+}
+
+GLfloat Texture::getMaxAnisotropy() const
+{
+	return mMaxAnisotropy;
+}
+
+GLboolean Texture::getGenerateMipmap() const
+{
+	return generateMipmap;
+}
+
+GLint Texture::getCropRectU() const
+{
+	return cropRectU;
+}
+
+GLint Texture::getCropRectV() const
+{
+	return cropRectV;
+}
+
+GLint Texture::getCropRectW() const
+{
+	return cropRectW;
+}
+
+GLint Texture::getCropRectH() const
+{
+	return cropRectH;
+}
+
+egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)
+{
+	egl::Image *image = getRenderTarget(target, level);   // Increments reference count
+
+	if(image)
+	{
+		image->markShared();
+	}
+
+	return image;
+}
+
+void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
+{
+	if(pixels && image)
+	{
+		egl::Image::UnpackInfo unpackInfo;
+		unpackInfo.alignment = unpackAlignment;
+		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackInfo, pixels);
+	}
+}
+
+void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)
+{
+	if(pixels && image)
+	{
+		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);
+	}
+}
+
+void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(IsCompressed(image->getFormat()))
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		egl::Image::UnpackInfo unpackInfo;
+		unpackInfo.alignment = unpackAlignment;
+		image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels);
+	}
+}
+
+void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)
+{
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(format != image->getFormat())
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(pixels)
+	{
+		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
+	}
+}
+
+bool Texture::copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest)
+{
+	Device *device = getDevice();
+
+	sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);
+	sw::SliceRect sourceSliceRect(sourceRect);
+	bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);
+
+	if(!success)
+	{
+		return error(GL_OUT_OF_MEMORY, false);
+	}
+
+	return true;
+}
+
+bool Texture::isMipmapFiltered() const
+{
+	switch(mMinFilter)
+	{
+	case GL_NEAREST:
+	case GL_LINEAR:
+		return false;
+	case GL_NEAREST_MIPMAP_NEAREST:
+	case GL_LINEAR_MIPMAP_NEAREST:
+	case GL_NEAREST_MIPMAP_LINEAR:
+	case GL_LINEAR_MIPMAP_LINEAR:
+		return true;
+	default: UNREACHABLE(mMinFilter);
+	}
+
+	return false;
+}
+
+Texture2D::Texture2D(GLuint name) : Texture(name)
+{
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		image[i] = nullptr;
+	}
+
+	mSurface = nullptr;
+
+	mColorbufferProxy = nullptr;
+	mProxyRefs = 0;
+}
+
+Texture2D::~Texture2D()
+{
+	resource->lock(sw::DESTRUCT);
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i])
+		{
+			image[i]->unbind(this);
+			image[i] = nullptr;
+		}
+	}
+
+	resource->unlock();
+
+	if(mSurface)
+	{
+		mSurface->setBoundTexture(nullptr);
+		mSurface = nullptr;
+	}
+
+	mColorbufferProxy = nullptr;
+}
+
+// We need to maintain a count of references to renderbuffers acting as
+// proxies for this texture, so that we do not attempt to use a pointer
+// to a renderbuffer proxy which has been deleted.
+void Texture2D::addProxyRef(const Renderbuffer *proxy)
+{
+	mProxyRefs++;
+}
+
+void Texture2D::releaseProxy(const Renderbuffer *proxy)
+{
+	if(mProxyRefs > 0)
+	{
+		mProxyRefs--;
+	}
+
+	if(mProxyRefs == 0)
+	{
+		mColorbufferProxy = nullptr;
+	}
+}
+
+void Texture2D::sweep()
+{
+	int imageCount = 0;
+
+	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+	{
+		if(image[i] && image[i]->isChildOf(this))
+		{
+			if(!image[i]->hasSingleReference())
+			{
+				return;
+			}
+
+			imageCount++;
+		}
+	}
+
+	if(imageCount == referenceCount)
+	{
+		destroy();
+	}
+}
+
+GLenum Texture2D::getTarget() const
+{
+	return GL_TEXTURE_2D;
+}
+
+GLsizei Texture2D::getWidth(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getWidth() : 0;
+}
+
+GLsizei Texture2D::getHeight(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getHeight() : 0;
+}
+
+GLenum Texture2D::getFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getFormat() : GL_NONE;
+}
+
+GLenum Texture2D::getType(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getType() : GL_NONE;
+}
+
+sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
+}
+
+int Texture2D::getLevelCount() const
+{
+	ASSERT(isSamplerComplete());
+	int levels = 0;
+
+	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+	{
+		levels++;
+	}
+
+	return levels;
+}
+
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, type);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setImage(format, type, unpackAlignment, pixels, image[level]);
+}
+
+void Texture2D::bindTexImage(egl::Surface *surface)
+{
+	GLenum format;
+
+	switch(surface->getInternalFormat())
+	{
+	case sw::FORMAT_A8R8G8B8:
+		format = GL_BGRA_EXT;
+		break;
+	case sw::FORMAT_A8B8G8R8:
+		format = GL_RGBA;
+		break;
+	case sw::FORMAT_X8B8G8R8:
+	case sw::FORMAT_X8R8G8B8:
+		format = GL_RGB;
+		break;
+	default:
+		UNIMPLEMENTED();
+		return;
+	}
+
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+
+	image[0] = surface->getRenderTarget();
+
+	mSurface = surface;
+	mSurface->setBoundTexture(this);
+}
+
+void Texture2D::releaseTexImage()
+{
+	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+	{
+		if(image[level])
+		{
+			image[level]->release();
+			image[level] = nullptr;
+		}
+	}
+}
+
+void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	Texture::setCompressedImage(imageSize, pixels, image[level]);
+}
+
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+{
+	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);
+}
+
+void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+	Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);
+}
+
+void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	egl::Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(image[level])
+	{
+		image[level]->release();
+	}
+
+	image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);
+
+	if(!image[level])
+	{
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	if(width != 0 && height != 0)
+	{
+		sw::Rect sourceRect = {x, y, x + width, y + height};
+		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+		copy(renderTarget, sourceRect, format, 0, 0, image[level]);
+	}
+
+	renderTarget->release();
+}
+
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+{
+	if(!image[level])
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	egl::Image *renderTarget = source->getRenderTarget();
+
+	if(!renderTarget)
+	{
+		ERR("Failed to retrieve the render target.");
+		return error(GL_OUT_OF_MEMORY);
+	}
+
+	sw::Rect sourceRect = {x, y, x + width, y + height};
+	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
+
+	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);
+
+	renderTarget->release();
+}
+
+void Texture2D::setImage(egl::Image *sharedImage)
+{
+	sharedImage->addRef();
+
+	if(image[0])
+	{
+		image[0]->release();
+	}
+
+	image[0] = sharedImage;
+}
+
+// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+bool Texture2D::isSamplerComplete() const
+{
+	if(!image[0])
+	{
+		return false;
+	}
+
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	if(width <= 0 || height <= 0)
+	{
+		return false;
+	}
+
+	if(isMipmapFiltered())
+	{
+		if(!generateMipmap && !isMipmapComplete())
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture2D::isMipmapComplete() const
+{
+	GLsizei width = image[0]->getWidth();
+	GLsizei height = image[0]->getHeight();
+
+	int q = log2(std::max(width, height));
+
+	for(int level = 1; level <= q; level++)
+	{
+		if(!image[level])
+		{
+			return false;
+		}
+
+		if(image[level]->getFormat() != image[0]->getFormat())
+		{
+			return false;
+		}
+
+		if(image[level]->getType() != image[0]->getType())
+		{
+			return false;
+		}
+
+		if(image[level]->getWidth() != std::max(1, width >> level))
+		{
+			return false;
+		}
+
+		if(image[level]->getHeight() != std::max(1, height >> level))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool Texture2D::isCompressed(GLenum target, GLint level) const
+{
+	return IsCompressed(getFormat(target, level));
+}
+
+bool Texture2D::isDepth(GLenum target, GLint level) const
+{
+	return IsDepthTexture(getFormat(target, level));
+}
+
+void Texture2D::generateMipmaps()
+{
+	if(!image[0])
+	{
+		return;   // FIXME: error?
+	}
+
+	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+
+	for(unsigned int i = 1; i <= q; i++)
+	{
+		if(image[i])
+		{
+			image[i]->release();
+		}
+
+		image[i] = new egl::Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+
+		if(!image[i])
+		{
+			return error(GL_OUT_OF_MEMORY);
+		}
+
+		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);
+	}
+}
+
+void Texture2D::autoGenerateMipmaps()
+{
+	if(generateMipmap && image[0]->hasDirtyMipmaps())
+	{
+		generateMipmaps();
+		image[0]->cleanMipmaps();
+	}
+}
+
+egl::Image *Texture2D::getImage(unsigned int level)
+{
+	return image[level];
+}
+
+Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
+{
+	if(target != GL_TEXTURE_2D)
+	{
+		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+	}
+
+	if(!mColorbufferProxy)
+	{
+		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));
+	}
+
+	return mColorbufferProxy;
+}
+
+egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(image[level])
+	{
+		image[level]->addRef();
+	}
+
+	return image[level];
+}
+
+bool Texture2D::isShared(GLenum target, unsigned int level) const
+{
+	ASSERT(target == GL_TEXTURE_2D);
+	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+	if(mSurface)   // Bound to an EGLSurface
+	{
+		return true;
+	}
+
+	if(!image[level])
+	{
+		return false;
+	}
+
+	return image[level]->isShared();
+}
+
+TextureExternal::TextureExternal(GLuint name) : Texture2D(name)
+{
+	mMinFilter = GL_LINEAR;
+	mMagFilter = GL_LINEAR;
+	mWrapS = GL_CLAMP_TO_EDGE;
+	mWrapT = GL_CLAMP_TO_EDGE;
+}
+
+TextureExternal::~TextureExternal()
+{
+}
+
+GLenum TextureExternal::getTarget() const
+{
+	return GL_TEXTURE_EXTERNAL_OES;
+}
+
+}
+
+egl::Image *createBackBuffer(int width, int height, const egl::Config *config)
+{
+	if(config)
+	{
+		return new egl::Image(width, height, config->mRenderTargetFormat, config->mSamples, false);
+	}
+
+	return nullptr;
+}
+
+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+{
+	if(height > sw::OUTLINE_RESOLUTION)
+	{
+		ERR("Invalid parameters: %dx%d", width, height);
+		return 0;
+	}
+
+	bool lockable = true;
+
+	switch(format)
+	{
+//	case sw::FORMAT_D15S1:
+	case sw::FORMAT_D24S8:
+	case sw::FORMAT_D24X8:
+//	case sw::FORMAT_D24X4S4:
+	case sw::FORMAT_D24FS8:
+	case sw::FORMAT_D32:
+	case sw::FORMAT_D16:
+		lockable = false;
+		break;
+//	case sw::FORMAT_S8_LOCKABLE:
+//	case sw::FORMAT_D16_LOCKABLE:
+	case sw::FORMAT_D32F_LOCKABLE:
+//	case sw::FORMAT_D32_LOCKABLE:
+	case sw::FORMAT_DF24S8:
+	case sw::FORMAT_DF16S8:
+		lockable = true;
+		break;
+	default:
+		UNREACHABLE(format);
+	}
+
+	egl::Image *surface = new egl::Image(width, height, format, multiSampleDepth, lockable);
+
+	if(!surface)
+	{
+		ERR("Out of memory");
+		return nullptr;
+	}
+
+	return surface;
+}
diff --git a/src/OpenGL/libGLES_CM/Texture.h b/src/OpenGL/libGLES_CM/Texture.h
index 6d53711..f28022d 100644
--- a/src/OpenGL/libGLES_CM/Texture.h
+++ b/src/OpenGL/libGLES_CM/Texture.h
@@ -1,197 +1,200 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// Texture.h: Defines the abstract Texture class and its concrete derived

-// classes Texture2D and TextureCubeMap. Implements GL texture objects and

-// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

-

-#ifndef LIBGLES_CM_TEXTURE_H_

-#define LIBGLES_CM_TEXTURE_H_

-

-#include "Renderbuffer.h"

-#include "common/Object.hpp"

-#include "utilities.h"

-#include "libEGL/Texture.hpp"

-#include "common/debug.h"

-

-#include <GLES/gl.h>

-

-#include <vector>

-

-namespace egl

-{

-class Surface;

-class Config;

-}

-

-namespace es1

-{

-class Framebuffer;

-

-enum

-{

-	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,

-    IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),

-	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,

-};

-

-class Texture : public egl::Texture

-{

-public:

-    explicit Texture(GLuint name);

-

-	sw::Resource *getResource() const;

-

-	virtual void addProxyRef(const Renderbuffer *proxy) = 0;

-    virtual void releaseProxy(const Renderbuffer *proxy) = 0;

-

-    virtual GLenum getTarget() const = 0;

-

-    bool setMinFilter(GLenum filter);

-    bool setMagFilter(GLenum filter);

-    bool setWrapS(GLenum wrap);

-    bool setWrapT(GLenum wrap);

-	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);

-	void setGenerateMipmap(GLboolean enable);

-	void setCropRect(GLint u, GLint v, GLint w, GLint h);

-

-    GLenum getMinFilter() const;

-    GLenum getMagFilter() const;

-    GLenum getWrapS() const;

-    GLenum getWrapT() const;

-	GLfloat getMaxAnisotropy() const;

-	GLboolean getGenerateMipmap() const;

-	GLint getCropRectU() const;

-    GLint getCropRectV() const;

-    GLint getCropRectW() const;

-    GLint getCropRectH() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const = 0;

-    virtual GLsizei getHeight(GLenum target, GLint level) const = 0;

-    virtual GLenum getFormat(GLenum target, GLint level) const = 0;

-    virtual GLenum getType(GLenum target, GLint level) const = 0;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;

-	virtual int getLevelCount() const = 0;

-

-    virtual bool isSamplerComplete() const = 0;

-    virtual bool isCompressed(GLenum target, GLint level) const = 0;

-	virtual bool isDepth(GLenum target, GLint level) const = 0;

-

-    virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;

-    virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;

-    virtual egl::Image *createSharedImage(GLenum target, unsigned int level);

-    virtual bool isShared(GLenum target, unsigned int level) const = 0;

-

-    virtual void generateMipmaps() = 0;

-	virtual void autoGenerateMipmaps() = 0;

-

-    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

-

-protected:

-	virtual ~Texture();

-

-    void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

-    void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

-    void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);

-    void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);

-

-	bool copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest);

-

-	bool isMipmapFiltered() const;

-

-    GLenum mMinFilter;

-    GLenum mMagFilter;

-    GLenum mWrapS;

-    GLenum mWrapT;

-	GLfloat mMaxAnisotropy;

-	GLboolean generateMipmap;

-	GLint cropRectU;

-	GLint cropRectV;

-	GLint cropRectW;

-	GLint cropRectH;

-

-	sw::Resource *resource;

-};

-

-class Texture2D : public Texture

-{

-public:

-    explicit Texture2D(GLuint name);

-

-	void addProxyRef(const Renderbuffer *proxy) override;

-    void releaseProxy(const Renderbuffer *proxy) override;

-	void sweep() override;

-

-    virtual GLenum getTarget() const;

-

-    virtual GLsizei getWidth(GLenum target, GLint level) const;

-    virtual GLsizei getHeight(GLenum target, GLint level) const;

-    virtual GLenum getFormat(GLenum target, GLint level) const;

-    virtual GLenum getType(GLenum target, GLint level) const;

-    virtual sw::Format getInternalFormat(GLenum target, GLint level) const;

-	virtual int getLevelCount() const;

-

-    void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);

-    void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);

-    void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);

-    void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);

-

-	void setImage(egl::Image *image);

-

-    virtual bool isSamplerComplete() const;

-    virtual bool isCompressed(GLenum target, GLint level) const;

-	virtual bool isDepth(GLenum target, GLint level) const;

-    virtual void bindTexImage(egl::Surface *surface);

-    virtual void releaseTexImage();

-

-    virtual void generateMipmaps();

-	virtual void autoGenerateMipmaps();

-

-	virtual Renderbuffer *getRenderbuffer(GLenum target);

-    virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);

-	virtual bool isShared(GLenum target, unsigned int level) const;

-

-    egl::Image *getImage(unsigned int level);

-

-protected:

-	virtual ~Texture2D();

-

-	bool isMipmapComplete() const;

-

-	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-

-    egl::Surface *mSurface;

-

-	// A specific internal reference count is kept for colorbuffer proxy references,

-    // because, as the renderbuffer acting as proxy will maintain a binding pointer

-    // back to this texture, there would be a circular reference if we used a binding

-    // pointer here. This reference count will cause the pointer to be set to NULL if

-    // the count drops to zero, but will not cause deletion of the Renderbuffer.

-    Renderbuffer *mColorbufferProxy;

-    unsigned int mProxyRefs;

-};

-

-class TextureExternal : public Texture2D

-{

-public:

-    explicit TextureExternal(GLuint name);

-

-    virtual GLenum getTarget() const;

-

-protected:

-	virtual ~TextureExternal();

-};

-}

-

-#endif   // LIBGLES_CM_TEXTURE_H_

+// 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.
+
+// Texture.h: Defines the abstract Texture class and its concrete derived
+// classes Texture2D and TextureCubeMap. Implements GL texture objects and
+// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#ifndef LIBGLES_CM_TEXTURE_H_
+#define LIBGLES_CM_TEXTURE_H_
+
+#include "Renderbuffer.h"
+#include "common/Object.hpp"
+#include "utilities.h"
+#include "libEGL/Texture.hpp"
+#include "common/debug.h"
+
+#include <GLES/gl.h>
+
+#include <vector>
+
+namespace egl
+{
+class Surface;
+class Config;
+}
+
+namespace es1
+{
+class Framebuffer;
+
+enum
+{
+	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
+	IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
+	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
+};
+
+class Texture : public egl::Texture
+{
+public:
+	explicit Texture(GLuint name);
+
+	sw::Resource *getResource() const;
+
+	virtual void addProxyRef(const Renderbuffer *proxy) = 0;
+	virtual void releaseProxy(const Renderbuffer *proxy) = 0;
+
+	virtual GLenum getTarget() const = 0;
+
+	bool setMinFilter(GLenum filter);
+	bool setMagFilter(GLenum filter);
+	bool setWrapS(GLenum wrap);
+	bool setWrapT(GLenum wrap);
+	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);
+	void setGenerateMipmap(GLboolean enable);
+	void setCropRect(GLint u, GLint v, GLint w, GLint h);
+
+	GLenum getMinFilter() const;
+	GLenum getMagFilter() const;
+	GLenum getWrapS() const;
+	GLenum getWrapT() const;
+	GLfloat getMaxAnisotropy() const;
+	GLboolean getGenerateMipmap() const;
+	GLint getCropRectU() const;
+	GLint getCropRectV() const;
+	GLint getCropRectW() const;
+	GLint getCropRectH() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
+	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
+	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
+	virtual GLenum getType(GLenum target, GLint level) const = 0;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
+	virtual int getLevelCount() const = 0;
+
+	virtual bool isSamplerComplete() const = 0;
+	virtual bool isCompressed(GLenum target, GLint level) const = 0;
+	virtual bool isDepth(GLenum target, GLint level) const = 0;
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;
+	virtual egl::Image *createSharedImage(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const = 0;
+
+	virtual void generateMipmaps() = 0;
+	virtual void autoGenerateMipmaps() = 0;
+
+	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
+
+protected:
+	virtual ~Texture();
+
+	void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
+	void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
+	void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);
+	void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);
+
+	bool copy(egl::Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, egl::Image *dest);
+
+	bool isMipmapFiltered() const;
+
+	GLenum mMinFilter;
+	GLenum mMagFilter;
+	GLenum mWrapS;
+	GLenum mWrapT;
+	GLfloat mMaxAnisotropy;
+	GLboolean generateMipmap;
+	GLint cropRectU;
+	GLint cropRectV;
+	GLint cropRectW;
+	GLint cropRectH;
+
+	sw::Resource *resource;
+};
+
+class Texture2D : public Texture
+{
+public:
+	explicit Texture2D(GLuint name);
+
+	void addProxyRef(const Renderbuffer *proxy) override;
+	void releaseProxy(const Renderbuffer *proxy) override;
+	void sweep() override;
+
+	virtual GLenum getTarget() const;
+
+	virtual GLsizei getWidth(GLenum target, GLint level) const;
+	virtual GLsizei getHeight(GLenum target, GLint level) const;
+	virtual GLenum getFormat(GLenum target, GLint level) const;
+	virtual GLenum getType(GLenum target, GLint level) const;
+	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
+	virtual int getLevelCount() const;
+
+	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+	void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+
+	void setImage(egl::Image *image);
+
+	virtual bool isSamplerComplete() const;
+	virtual bool isCompressed(GLenum target, GLint level) const;
+	virtual bool isDepth(GLenum target, GLint level) const;
+	virtual void bindTexImage(egl::Surface *surface);
+	virtual void releaseTexImage();
+
+	virtual void generateMipmaps();
+	virtual void autoGenerateMipmaps();
+
+	virtual Renderbuffer *getRenderbuffer(GLenum target);
+	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);
+	virtual bool isShared(GLenum target, unsigned int level) const;
+
+	egl::Image *getImage(unsigned int level);
+
+protected:
+	virtual ~Texture2D();
+
+	bool isMipmapComplete() const;
+
+	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+	egl::Surface *mSurface;
+
+	// A specific internal reference count is kept for colorbuffer proxy references,
+	// because, as the renderbuffer acting as proxy will maintain a binding pointer
+	// back to this texture, there would be a circular reference if we used a binding
+	// pointer here. This reference count will cause the pointer to be set to null if
+	// the count drops to zero, but will not cause deletion of the Renderbuffer.
+	Renderbuffer *mColorbufferProxy;
+	unsigned int mProxyRefs;
+};
+
+class TextureExternal : public Texture2D
+{
+public:
+	explicit TextureExternal(GLuint name);
+
+	virtual GLenum getTarget() const;
+
+protected:
+	virtual ~TextureExternal();
+};
+}
+
+#endif   // LIBGLES_CM_TEXTURE_H_
diff --git a/src/OpenGL/libGLES_CM/VertexDataManager.cpp b/src/OpenGL/libGLES_CM/VertexDataManager.cpp
index 99e8a7f..20eb6b9 100644
--- a/src/OpenGL/libGLES_CM/VertexDataManager.cpp
+++ b/src/OpenGL/libGLES_CM/VertexDataManager.cpp
@@ -1,328 +1,331 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#include "VertexDataManager.h"

-

-#include "Buffer.h"

-#include "IndexDataManager.h"

-#include "common/debug.h"

-

-#include <algorithm>

-

-namespace

-{

-    enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};

-}

-

-namespace es1

-{

-

-VertexDataManager::VertexDataManager(Context *context) : mContext(context)

-{

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        mDirtyCurrentValue[i] = true;

-        mCurrentValueBuffer[i] = NULL;

-    }

-

-    mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);

-

-    if(!mStreamingBuffer)

-    {

-        ERR("Failed to allocate the streaming vertex buffer.");

-    }

-}

-

-VertexDataManager::~VertexDataManager()

-{

-    delete mStreamingBuffer;

-

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        delete mCurrentValueBuffer[i];

-    }

-}

-

-unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)

-{

-    Buffer *buffer = attribute.mBoundBuffer;

-

-    int inputStride = attribute.stride();

-    int elementSize = attribute.typeSize();

-    unsigned int streamOffset = 0;

-

-    char *output = nullptr;

-

-    if(vertexBuffer)

-    {

-        output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);

-    }

-

-    if(!output)

-    {

-        ERR("Failed to map vertex buffer.");

-        return ~0u;

-    }

-

-    const char *input = nullptr;

-

-    if(buffer)

-    {

-        int offset = attribute.mOffset;

-

-        input = static_cast<const char*>(buffer->data()) + offset;

-    }

-    else

-    {

-        input = static_cast<const char*>(attribute.mPointer);

-    }

-

-    input += inputStride * start;

-

-    if(inputStride == elementSize)

-    {

-        memcpy(output, input, count * inputStride);

-    }

-    else

-    {

-		for(int i = 0; i < count; i++)

-		{

-			memcpy(output, input, elementSize);

-			output += elementSize;

-			input += inputStride;

-		}

-    }

-

-    vertexBuffer->unmap();

-

-    return streamOffset;

-}

-

-GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)

-{

-    if(!mStreamingBuffer)

-    {

-        return GL_OUT_OF_MEMORY;

-    }

-

-    const VertexAttributeArray &attribs = mContext->getVertexAttributes();

-

-    // Determine the required storage size per used buffer

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(attribs[i].mArrayEnabled)

-        {

-            if(!attribs[i].mBoundBuffer)

-            {

-                mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);

-            }

-        }

-    }

-

-    mStreamingBuffer->reserveRequiredSpace();

-

-    // Perform the vertex data translations

-    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)

-    {

-        if(attribs[i].mArrayEnabled)

-        {

-            Buffer *buffer = attribs[i].mBoundBuffer;

-

-            if(!buffer && attribs[i].mPointer == NULL)

-            {

-                // This is an application error that would normally result in a crash, but we catch it and return an error

-                ERR("An enabled vertex array has no buffer and no pointer.");

-                return GL_INVALID_OPERATION;

-            }

-

-            sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;

-

-            if(staticBuffer)

-            {

-				translated[i].vertexBuffer = staticBuffer;

-				translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;

-				translated[i].stride = attribs[i].stride();

-            }

-            else

-            {

-                unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);

-

-				if(streamOffset == ~0u)

-				{

-					return GL_OUT_OF_MEMORY;

-				}

-

-				translated[i].vertexBuffer = mStreamingBuffer->getResource();

-				translated[i].offset = streamOffset;

-				translated[i].stride = attribs[i].typeSize();

-            }

-

-			switch(attribs[i].mType)

-			{

-			case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;

-			case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;

-			case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;

-			case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;

-			case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;

-			case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;

-			case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;

-			case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-			default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;

-			}

-

-			translated[i].count = attribs[i].mSize;

-			translated[i].normalized = attribs[i].mNormalized;

-        }

-        else

-        {

-            if(mDirtyCurrentValue[i])

-            {

-                delete mCurrentValueBuffer[i];

-                mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);

-                mDirtyCurrentValue[i] = false;

-            }

-

-            translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();

-

-            translated[i].type = sw::STREAMTYPE_FLOAT;

-			translated[i].count = 4;

-            translated[i].stride = 0;

-            translated[i].offset = 0;

-        }

-    }

-

-    return GL_NO_ERROR;

-}

-

-VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(NULL)

-{

-    if(size > 0)

-    {

-        mVertexBuffer = new sw::Resource(size + 1024);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", size);

-        }

-    }

-}

-

-VertexBuffer::~VertexBuffer()

-{

-    if(mVertexBuffer)

-    {

-        mVertexBuffer->destruct();

-    }

-}

-

-void VertexBuffer::unmap()

-{

-    if(mVertexBuffer)

-    {

-		mVertexBuffer->unlock();

-    }

-}

-

-sw::Resource *VertexBuffer::getResource() const

-{

-    return mVertexBuffer;

-}

-

-ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))

-{

-    if(mVertexBuffer)

-    {

-		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);

-

-        vector[0] = x;

-        vector[1] = y;

-        vector[2] = z;

-        vector[3] = w;

-

-        mVertexBuffer->unlock();

-    }

-}

-

-ConstantVertexBuffer::~ConstantVertexBuffer()

-{

-}

-

-StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)

-{

-    mBufferSize = size;

-    mWritePosition = 0;

-    mRequiredSpace = 0;

-}

-

-StreamingVertexBuffer::~StreamingVertexBuffer()

-{

-}

-

-void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)

-{

-    mRequiredSpace += requiredSpace;

-}

-

-void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)

-{

-    void *mapPtr = NULL;

-

-    if(mVertexBuffer)

-    {

-		// We can use a private lock because we never overwrite the content

-		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;

-

-        *offset = mWritePosition;

-        mWritePosition += requiredSpace;

-    }

-

-    return mapPtr;

-}

-

-void StreamingVertexBuffer::reserveRequiredSpace()

-{

-    if(mRequiredSpace > mBufferSize)

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-            mVertexBuffer = 0;

-        }

-

-        mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.

-

-		mVertexBuffer = new sw::Resource(mBufferSize);

-

-        if(!mVertexBuffer)

-        {

-            ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-    else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle

-    {

-        if(mVertexBuffer)

-        {

-            mVertexBuffer->destruct();

-			mVertexBuffer = new sw::Resource(mBufferSize);

-        }

-

-        mWritePosition = 0;

-    }

-

-    mRequiredSpace = 0;

-}

-

-}

+// 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.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#include "VertexDataManager.h"
+
+#include "Buffer.h"
+#include "IndexDataManager.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+namespace
+{
+	enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};
+}
+
+namespace es1
+{
+
+VertexDataManager::VertexDataManager(Context *context) : mContext(context)
+{
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		mDirtyCurrentValue[i] = true;
+		mCurrentValueBuffer[i] = nullptr;
+	}
+
+	mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
+
+	if(!mStreamingBuffer)
+	{
+		ERR("Failed to allocate the streaming vertex buffer.");
+	}
+}
+
+VertexDataManager::~VertexDataManager()
+{
+	delete mStreamingBuffer;
+
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		delete mCurrentValueBuffer[i];
+	}
+}
+
+unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
+{
+	Buffer *buffer = attribute.mBoundBuffer;
+
+	int inputStride = attribute.stride();
+	int elementSize = attribute.typeSize();
+	unsigned int streamOffset = 0;
+
+	char *output = nullptr;
+
+	if(vertexBuffer)
+	{
+		output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);
+	}
+
+	if(!output)
+	{
+		ERR("Failed to map vertex buffer.");
+		return ~0u;
+	}
+
+	const char *input = nullptr;
+
+	if(buffer)
+	{
+		int offset = attribute.mOffset;
+
+		input = static_cast<const char*>(buffer->data()) + offset;
+	}
+	else
+	{
+		input = static_cast<const char*>(attribute.mPointer);
+	}
+
+	input += inputStride * start;
+
+	if(inputStride == elementSize)
+	{
+		memcpy(output, input, count * inputStride);
+	}
+	else
+	{
+		for(int i = 0; i < count; i++)
+		{
+			memcpy(output, input, elementSize);
+			output += elementSize;
+			input += inputStride;
+		}
+	}
+
+	vertexBuffer->unmap();
+
+	return streamOffset;
+}
+
+GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
+{
+	if(!mStreamingBuffer)
+	{
+		return GL_OUT_OF_MEMORY;
+	}
+
+	const VertexAttributeArray &attribs = mContext->getVertexAttributes();
+
+	// Determine the required storage size per used buffer
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(attribs[i].mArrayEnabled)
+		{
+			if(!attribs[i].mBoundBuffer)
+			{
+				mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);
+			}
+		}
+	}
+
+	mStreamingBuffer->reserveRequiredSpace();
+
+	// Perform the vertex data translations
+	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+	{
+		if(attribs[i].mArrayEnabled)
+		{
+			Buffer *buffer = attribs[i].mBoundBuffer;
+
+			if(!buffer && attribs[i].mPointer == nullptr)
+			{
+				// This is an application error that would normally result in a crash, but we catch it and return an error
+				ERR("An enabled vertex array has no buffer and no pointer.");
+				return GL_INVALID_OPERATION;
+			}
+
+			sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
+
+			if(staticBuffer)
+			{
+				translated[i].vertexBuffer = staticBuffer;
+				translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;
+				translated[i].stride = attribs[i].stride();
+			}
+			else
+			{
+				unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
+
+				if(streamOffset == ~0u)
+				{
+					return GL_OUT_OF_MEMORY;
+				}
+
+				translated[i].vertexBuffer = mStreamingBuffer->getResource();
+				translated[i].offset = streamOffset;
+				translated[i].stride = attribs[i].typeSize();
+			}
+
+			switch(attribs[i].mType)
+			{
+			case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;
+			case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;
+			case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;
+			case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;
+			case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;
+			case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;
+			case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;
+			case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+			default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;
+			}
+
+			translated[i].count = attribs[i].mSize;
+			translated[i].normalized = attribs[i].mNormalized;
+		}
+		else
+		{
+			if(mDirtyCurrentValue[i])
+			{
+				delete mCurrentValueBuffer[i];
+				mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
+				mDirtyCurrentValue[i] = false;
+			}
+
+			translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();
+
+			translated[i].type = sw::STREAMTYPE_FLOAT;
+			translated[i].count = 4;
+			translated[i].stride = 0;
+			translated[i].offset = 0;
+		}
+	}
+
+	return GL_NO_ERROR;
+}
+
+VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(nullptr)
+{
+	if(size > 0)
+	{
+		mVertexBuffer = new sw::Resource(size + 1024);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", size);
+		}
+	}
+}
+
+VertexBuffer::~VertexBuffer()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->destruct();
+	}
+}
+
+void VertexBuffer::unmap()
+{
+	if(mVertexBuffer)
+	{
+		mVertexBuffer->unlock();
+	}
+}
+
+sw::Resource *VertexBuffer::getResource() const
+{
+	return mVertexBuffer;
+}
+
+ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))
+{
+	if(mVertexBuffer)
+	{
+		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);
+
+		vector[0] = x;
+		vector[1] = y;
+		vector[2] = z;
+		vector[3] = w;
+
+		mVertexBuffer->unlock();
+	}
+}
+
+ConstantVertexBuffer::~ConstantVertexBuffer()
+{
+}
+
+StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)
+{
+	mBufferSize = size;
+	mWritePosition = 0;
+	mRequiredSpace = 0;
+}
+
+StreamingVertexBuffer::~StreamingVertexBuffer()
+{
+}
+
+void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)
+{
+	mRequiredSpace += requiredSpace;
+}
+
+void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)
+{
+	void *mapPtr = nullptr;
+
+	if(mVertexBuffer)
+	{
+		// We can use a private lock because we never overwrite the content
+		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;
+
+		*offset = mWritePosition;
+		mWritePosition += requiredSpace;
+	}
+
+	return mapPtr;
+}
+
+void StreamingVertexBuffer::reserveRequiredSpace()
+{
+	if(mRequiredSpace > mBufferSize)
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = 0;
+		}
+
+		mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
+
+		mVertexBuffer = new sw::Resource(mBufferSize);
+
+		if(!mVertexBuffer)
+		{
+			ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+	else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
+	{
+		if(mVertexBuffer)
+		{
+			mVertexBuffer->destruct();
+			mVertexBuffer = new sw::Resource(mBufferSize);
+		}
+
+		mWritePosition = 0;
+	}
+
+	mRequiredSpace = 0;
+}
+
+}
diff --git a/src/OpenGL/libGLES_CM/VertexDataManager.h b/src/OpenGL/libGLES_CM/VertexDataManager.h
index cce6865..55ab849 100644
--- a/src/OpenGL/libGLES_CM/VertexDataManager.h
+++ b/src/OpenGL/libGLES_CM/VertexDataManager.h
@@ -1,98 +1,101 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2012 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// VertexDataManager.h: Defines the VertexDataManager, a class that

-// runs the Buffer translation process.

-

-#ifndef LIBGLES_CM_VERTEXDATAMANAGER_H_

-#define LIBGLES_CM_VERTEXDATAMANAGER_H_

-

-#include "Context.h"

-#include "Device.hpp"

-

-#include <GLES/gl.h>

-

-namespace es1

-{

-

-struct TranslatedAttribute

-{

-    sw::StreamType type;

-	int count;

-	bool normalized;

-

-    unsigned int offset;

-    unsigned int stride;   // 0 means not to advance the read pointer at all

-

-    sw::Resource *vertexBuffer;

-};

-

-class VertexBuffer

-{

-  public:

-    VertexBuffer(unsigned int size);

-    virtual ~VertexBuffer();

-

-    void unmap();

-

-    sw::Resource *getResource() const;

-

-  protected:

-    sw::Resource *mVertexBuffer;

-};

-

-class ConstantVertexBuffer : public VertexBuffer

-{

-  public:

-    ConstantVertexBuffer(float x, float y, float z, float w);

-    ~ConstantVertexBuffer();

-};

-

-class StreamingVertexBuffer : public VertexBuffer

-{

-  public:

-    StreamingVertexBuffer(unsigned int size);

-    ~StreamingVertexBuffer();

-

-    void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);

-    void reserveRequiredSpace();

-    void addRequiredSpace(unsigned int requiredSpace);

-

-  protected:

-    unsigned int mBufferSize;

-    unsigned int mWritePosition;

-    unsigned int mRequiredSpace;

-};

-

-class VertexDataManager

-{

-  public:

-    VertexDataManager(Context *context);

-    virtual ~VertexDataManager();

-

-    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }

-

-    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);

-

-  private:

-    unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);

-

-    Context *const mContext;

-

-    StreamingVertexBuffer *mStreamingBuffer;

-

-    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];

-    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];

-};

-

-}

-

-#endif   // LIBGLES_CM_VERTEXDATAMANAGER_H_

+// 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.
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBGLES_CM_VERTEXDATAMANAGER_H_
+#define LIBGLES_CM_VERTEXDATAMANAGER_H_
+
+#include "Context.h"
+#include "Device.hpp"
+
+#include <GLES/gl.h>
+
+namespace es1
+{
+
+struct TranslatedAttribute
+{
+	sw::StreamType type;
+	int count;
+	bool normalized;
+
+	unsigned int offset;
+	unsigned int stride;   // 0 means not to advance the read pointer at all
+
+	sw::Resource *vertexBuffer;
+};
+
+class VertexBuffer
+{
+public:
+	VertexBuffer(unsigned int size);
+	virtual ~VertexBuffer();
+
+	void unmap();
+
+	sw::Resource *getResource() const;
+
+protected:
+	sw::Resource *mVertexBuffer;
+};
+
+class ConstantVertexBuffer : public VertexBuffer
+{
+public:
+	ConstantVertexBuffer(float x, float y, float z, float w);
+	~ConstantVertexBuffer();
+};
+
+class StreamingVertexBuffer : public VertexBuffer
+{
+public:
+	StreamingVertexBuffer(unsigned int size);
+	~StreamingVertexBuffer();
+
+	void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);
+	void reserveRequiredSpace();
+	void addRequiredSpace(unsigned int requiredSpace);
+
+protected:
+	unsigned int mBufferSize;
+	unsigned int mWritePosition;
+	unsigned int mRequiredSpace;
+};
+
+class VertexDataManager
+{
+public:
+	VertexDataManager(Context *context);
+	virtual ~VertexDataManager();
+
+	void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
+
+	GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
+
+private:
+	unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
+
+	Context *const mContext;
+
+	StreamingVertexBuffer *mStreamingBuffer;
+
+	bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
+	ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
+};
+
+}
+
+#endif   // LIBGLES_CM_VERTEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index 0c9dd62..1f01fb3 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -1,4770 +1,4773 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-// libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions.

-

-#include "main.h"

-#include "mathutil.h"

-#include "utilities.h"

-#include "Buffer.h"

-#include "Context.h"

-#include "Framebuffer.h"

-#include "Renderbuffer.h"

-#include "Texture.h"

-#include "common/debug.h"

-#include "Common/SharedLibrary.hpp"

-#include "Common/Version.h"

-

-#include <EGL/egl.h>

-#include <EGL/eglext.h>

-

-#include <GLES/gl.h>

-#include <GLES/glext.h>

-

-#include <limits>

-

-namespace es1

-{

-

-static bool validImageSize(GLint level, GLsizei width, GLsizei height)

-{

-	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

-	{

-		return false;

-	}

-

-	return true;

-}

-

-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)

-{

-	if(!texture)

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed != texture->isCompressed(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(format != GL_NONE_OES && format != texture->getFormat(target, level))

-	{

-		return error(GL_INVALID_OPERATION, false);

-	}

-

-	if(compressed)

-	{

-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||

-		   (height % 4 != 0 && height != texture->getHeight(target, 0)))

-		{

-			return error(GL_INVALID_OPERATION, false);

-		}

-	}

-

-	if(xoffset + width > texture->getWidth(target, level) ||

-	   yoffset + height > texture->getHeight(target, level))

-	{

-		return error(GL_INVALID_VALUE, false);

-	}

-

-	return true;

-}

-

-void ActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		context->setActiveSampler(texture - GL_TEXTURE0);

-	}

-}

-

-void AlphaFunc(GLenum func, GLclampf ref)

-{

-	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);

-

-	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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setAlphaFunc(func, clamp01(ref));

-	}

-}

-

-void AlphaFuncx(GLenum func, GLclampx ref)

-{

-	AlphaFunc(func, (float)ref / 0x10000);

-}

-

-void BindBuffer(GLenum target, GLuint buffer)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			context->bindArrayBuffer(buffer);

-			return;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			context->bindElementArrayBuffer(buffer);

-			return;

-		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_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->bindFramebuffer(framebuffer);

-	}

-}

-

-void BindFramebufferOES(GLenum target, GLuint framebuffer)

-{

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

-

-	if(target != GL_FRAMEBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->bindFramebuffer(framebuffer);

-	}

-}

-

-void BindRenderbufferOES(GLenum target, GLuint renderbuffer)

-{

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

-

-	if(target != GL_RENDERBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))

-		{

-			// [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.

-			return error(GL_INVALID_OPERATION);

-		}

-

-		context->bindRenderbuffer(renderbuffer);

-	}

-}

-

-void BindTexture(GLenum target, GLuint texture)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *textureObject = context->getTexture(texture);

-

-		if(textureObject && textureObject->getTarget() != target && texture != 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			context->bindTexture2D(texture);

-			return;

-		case GL_TEXTURE_EXTERNAL_OES:

-			context->bindTextureExternal(texture);

-			return;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

-

-void BlendEquationOES(GLenum mode)

-{

-	BlendEquationSeparateOES(mode, mode);

-}

-

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)

-{

-	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

-

-	switch(modeRGB)

-	{

-	case GL_FUNC_ADD_OES:

-	case GL_FUNC_SUBTRACT_OES:

-	case GL_FUNC_REVERSE_SUBTRACT_OES:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(modeAlpha)

-	{

-	case GL_FUNC_ADD_OES:

-	case GL_FUNC_SUBTRACT_OES:

-	case GL_FUNC_REVERSE_SUBTRACT_OES:

-	case GL_MIN_EXT:

-	case GL_MAX_EXT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setBlendEquation(modeRGB, modeAlpha);

-	}

-}

-

-void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

-

-void BlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);

-}

-

-void BlendFuncSeparateOES(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);

-

-	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_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:

-		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_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:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::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);

-	}

-

-	switch(usage)

-	{

-	case GL_STATIC_DRAW:

-	case GL_DYNAMIC_DRAW:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			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);

-	}

-

-	if(data == NULL)

-	{

-		return;

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(!buffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		if((size_t)size + offset > buffer->size())

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

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

-	}

-}

-

-GLenum CheckFramebufferStatusOES(GLenum target)

-{

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

-

-	if(target != GL_FRAMEBUFFER_OES)

-	{

-		return error(GL_INVALID_ENUM, 0);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

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

-

-		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);

-	}

-

-	es1::Context *context = es1::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);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)

-{

-	ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);

-}

-

-void ClearDepthf(GLclampf depth)

-{

-	TRACE("(GLclampf depth = %f)", depth);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setClearDepth(depth);

-	}

-}

-

-void ClearDepthx(GLclampx depth)

-{

-	ClearDepthf((float)depth / 0x10000);

-}

-

-void ClearStencil(GLint s)

-{

-	TRACE("(GLint s = %d)", s);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setClearStencil(s);

-	}

-}

-

-void ClientActiveTexture(GLenum texture)

-{

-	TRACE("(GLenum texture = 0x%X)", texture);

-

-	switch(texture)

-	{

-	case GL_TEXTURE0:

-	case GL_TEXTURE1:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->clientActiveTexture(texture);

-	}

-}

-

-void ClipPlanef(GLenum plane, const GLfloat *equation)

-{

-	TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane);

-

-	int index = plane - GL_CLIP_PLANE0;

-

-	if(index < 0 || index >= MAX_CLIP_PLANES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setClipPlane(index, equation);

-	}

-}

-

-void ClipPlanex(GLenum plane, const GLfixed *equation)

-{

-	GLfloat equationf[4] =

-	{

-		(float)equation[0] / 0x10000,

-		(float)equation[1] / 0x10000,

-		(float)equation[2] / 0x10000,

-		(float)equation[3] / 0x10000,

-	};

-

-	ClipPlanef(plane, equationf);

-}

-

-void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

-{

-	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);

-	}

-}

-

-void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)

-{

-	Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);

-}

-

-void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)

-{

-	Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);

-}

-

-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);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-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 >= es1::MAX_VERTEX_ATTRIBS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(size < 1 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(type)

-	{

-	case GL_BYTE:

-	case GL_UNSIGNED_BYTE:

-	case GL_SHORT:

-	case GL_UNSIGNED_SHORT:

-	case GL_FIXED:

-	case GL_FLOAT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(stride < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);

-	}

-}

-

-void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

-

-	if(size != 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	VertexAttribPointer(sw::Color0, size, type, true, stride, pointer);

-}

-

-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(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(!validImageSize(level, width, height) || imageSize < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	switch(internalformat)

-	{

-	case GL_ETC1_RGB8_OES:

-		break;

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		if(!S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_DEPTH_COMPONENT16_OES:

-	case GL_DEPTH_COMPONENT32_OES:

-	case GL_DEPTH_STENCIL_OES:

-	case GL_DEPTH24_STENCIL8_OES:

-		return error(GL_INVALID_OPERATION);

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es1::IMPLEMENTATION_MAX_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)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);

-		}

-		else 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(!es1::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es1::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);

-	}

-

-	switch(format)

-	{

-	case GL_ETC1_RGB8_OES:

-		break;

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		if(!S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width == 0 || height == 0 || !data)

-	{

-		return;

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(imageSize != egl::ComputeCompressedSize(width, height, format))

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		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);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))

-			{

-				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, 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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

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

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-		}

-

-		if(context->getFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es1::Renderbuffer *source = framebuffer->getColorbuffer();

-		GLenum colorbufferFormat = source->getFormat();

-

-		// [OpenGL ES 2.0.24] table 3.9

-		switch(internalformat)

-		{

-		case GL_ALPHA:

-			if(colorbufferFormat != GL_ALPHA &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4_OES &&

-			   colorbufferFormat != GL_RGB5_A1_OES &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE:

-		case GL_RGB:

-			if(colorbufferFormat != GL_RGB &&

-			   colorbufferFormat != GL_RGB565_OES &&

-			   colorbufferFormat != GL_RGB8_OES &&

-			   colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4_OES &&

-			   colorbufferFormat != GL_RGB5_A1_OES &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-			if(colorbufferFormat != GL_RGBA &&

-			   colorbufferFormat != GL_RGBA4_OES &&

-			   colorbufferFormat != GL_RGB5_A1_OES &&

-			   colorbufferFormat != GL_RGBA8_OES)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			break;

-		case GL_ETC1_RGB8_OES:

-			return error(GL_INVALID_OPERATION);

-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-			if(S3TC_SUPPORT)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->copyImage(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(!es1::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es1::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);

-	}

-

-	if(width == 0 || height == 0)

-	{

-		return;

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-

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

-

-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)

-		{

-			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);

-		}

-

-		es1::Renderbuffer *source = framebuffer->getColorbuffer();

-

-		if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		es1::Texture *texture = NULL;

-

-		if(target == GL_TEXTURE_2D)

-		{

-			texture = context->getTexture2D();

-		}

-		else UNREACHABLE(target);

-

-		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))

-		{

-			return;

-		}

-

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

-	}

-}

-

-void CullFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_FRONT:

-	case GL_BACK:

-	case GL_FRONT_AND_BACK:

-		{

-			es1::Context *context = es1::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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteBuffer(buffers[i]);

-		}

-	}

-}

-

-void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			if(framebuffers[i] != 0)

-			{

-				context->deleteFramebuffer(framebuffers[i]);

-			}

-		}

-	}

-}

-

-void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)

-{

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

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			context->deleteRenderbuffer(renderbuffers[i]);

-		}

-	}

-}

-

-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);

-	}

-

-	es1::Context *context = es1::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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setDepthFunc(func);

-	}

-}

-

-void DepthMask(GLboolean flag)

-{

-	TRACE("(GLboolean flag = %d)", flag);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setDepthMask(flag != GL_FALSE);

-	}

-}

-

-void DepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setDepthRange(zNear, zFar);

-	}

-}

-

-void DepthRangex(GLclampx zNear, GLclampx zFar)

-{

-	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);

-}

-

-void Disable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	es1::Context *context = es1::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_LIGHTING:                 context->setLightingEnabled(false);              break;

-		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;

-		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;

-		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;

-		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;

-		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;

-		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;

-		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;

-		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;

-		case GL_FOG:                      context->setFogEnabled(false);                   break;

-		case GL_TEXTURE_2D:               context->setTexture2Denabled(false);             break;

-		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(false);       break;

-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;

-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;

-		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(false);           break;

-		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(false);            break;

-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;

-		case GL_NORMALIZE:                context->setNormalizeEnabled(false);             break;

-		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(false);         break;

-		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(false);           break;

-		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(false);           break;

-		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(false);            break;

-		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(false);        break;

-		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(false);     break;

-		case GL_MULTISAMPLE:              context->setMultisampleEnabled(false);           break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(false);      break;

-		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false);          break;

-		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false);          break;

-		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false);          break;

-		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false);          break;

-		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false);          break;

-		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false);          break;

-		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(false);           break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void DisableClientState(GLenum array)

-{

-	TRACE("(GLenum array = 0x%X)", array);

-

-	switch(array)

-	{

-	case GL_VERTEX_ARRAY:

-	case GL_NORMAL_ARRAY:

-	case GL_COLOR_ARRAY:

-	case GL_POINT_SIZE_ARRAY_OES:

-	case GL_TEXTURE_COORD_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		switch(array)

-		{

-		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, false);                            break;

-		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;

-		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;

-		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false);                           break;

-		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;

-		default:                      UNREACHABLE(array);

-		}

-	}

-}

-

-void DrawArrays(GLenum mode, GLint first, GLsizei count)

-{

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

-

-	if(count < 0 || first < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		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);

-

-	if(count < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT:

-		case GL_UNSIGNED_INT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

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

-	}

-}

-

-void Enable(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	es1::Context *context = es1::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_LIGHTING:                 context->setLightingEnabled(true);              break;

-		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;

-		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;

-		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;

-		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;

-		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;

-		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;

-		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;

-		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;

-		case GL_FOG:                      context->setFogEnabled(true);                   break;

-		case GL_TEXTURE_2D:               context->setTexture2Denabled(true);             break;

-		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(true);       break;

-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;

-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;

-		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(true);           break;

-		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(true);            break;

-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;

-		case GL_NORMALIZE:                context->setNormalizeEnabled(true);             break;

-		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(true);         break;

-		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(true);           break;

-		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(true);           break;

-		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(true);            break;

-		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(true);        break;

-		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(true);     break;

-		case GL_MULTISAMPLE:              context->setMultisampleEnabled(true);           break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(true);      break;

-		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true);          break;

-		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true);          break;

-		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true);          break;

-		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true);          break;

-		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true);          break;

-		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true);          break;

-		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(true);           break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void EnableClientState(GLenum array)

-{

-	TRACE("(GLenum array = 0x%X)", array);

-

-	switch(array)

-	{

-	case GL_VERTEX_ARRAY:

-	case GL_NORMAL_ARRAY:

-	case GL_COLOR_ARRAY:

-	case GL_POINT_SIZE_ARRAY_OES:

-	case GL_TEXTURE_COORD_ARRAY:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-

-		switch(array)

-		{

-		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, true);                            break;

-		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;

-		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;

-		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true);                           break;

-		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;

-		default:                      UNREACHABLE(array);

-		}

-	}

-}

-

-void Finish(void)

-{

-	TRACE("()");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->finish();

-	}

-}

-

-void Flush(void)

-{

-	TRACE("()");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->flush();

-	}

-}

-

-void FramebufferRenderbufferOES(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_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

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

-		GLuint framebufferName = context->getFramebufferName();

-

-		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0_OES:

-			framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);

-			break;

-		case GL_DEPTH_ATTACHMENT_OES:

-			framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);

-			break;

-		case GL_STENCIL_ATTACHMENT_OES:

-			framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void FramebufferTexture2DOES(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_OES)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	switch(attachment)

-	{

-	case GL_COLOR_ATTACHMENT0_OES:

-	case GL_DEPTH_ATTACHMENT_OES:

-	case GL_STENCIL_ATTACHMENT_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(texture == 0)

-		{

-			textarget = GL_NONE_OES;

-		}

-		else

-		{

-			es1::Texture *tex = context->getTexture(texture);

-

-			if(tex == NULL)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			if(tex->isCompressed(textarget, level))

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			switch(textarget)

-			{

-			case GL_TEXTURE_2D:

-				if(tex->getTarget() != GL_TEXTURE_2D)

-				{

-					return error(GL_INVALID_OPERATION);

-				}

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(level != 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-		}

-

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

-		GLuint framebufferName = context->getFramebufferName();

-

-		if(framebufferName == 0 || !framebuffer)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0_OES:  framebuffer->setColorbuffer(textarget, texture);   break;

-		case GL_DEPTH_ATTACHMENT_OES:   framebuffer->setDepthbuffer(textarget, texture);   break;

-		case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;

-		}

-	}

-}

-

-void Fogf(GLenum pname, GLfloat param)

-{

-	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			switch((GLenum)param)

-			{

-			case GL_LINEAR:

-			case GL_EXP:

-			case GL_EXP2:

-				context->setFogMode((GLenum)param);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FOG_DENSITY:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setFogDensity(param);

-			break;

-		case GL_FOG_START:

-			context->setFogStart(param);

-			break;

-		case GL_FOG_END:

-			context->setFogEnd(param);

-			break;

-		case GL_FOG_COLOR:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glFogfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Fogfv(GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			switch((GLenum)params[0])

-			{

-			case GL_LINEAR:

-			case GL_EXP:

-			case GL_EXP2:

-				context->setFogMode((GLenum)params[0]);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FOG_DENSITY:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setFogDensity(params[0]);

-			break;

-		case GL_FOG_START:

-			context->setFogStart(params[0]);

-			break;

-		case GL_FOG_END:

-			context->setFogEnd(params[0]);

-			break;

-		case GL_FOG_COLOR:

-			context->setFogColor(params[0], params[1], params[2], params[3]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Fogx(GLenum pname, GLfixed param)

-{

-	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_FOG_MODE:

-			switch((GLenum)param)

-			{

-			case GL_LINEAR:

-			case GL_EXP:

-			case GL_EXP2:

-				context->setFogMode((GLenum)param);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FOG_DENSITY:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setFogDensity((float)param / 0x10000);

-			break;

-		case GL_FOG_START:

-			context->setFogStart((float)param / 0x10000);

-			break;

-		case GL_FOG_END:

-			context->setFogEnd((float)param / 0x10000);

-			break;

-		case GL_FOG_COLOR:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glFogxv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Fogxv(GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void FrontFace(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	switch(mode)

-	{

-	case GL_CW:

-	case GL_CCW:

-		{

-			es1::Context *context = es1::getContext();

-

-			if(context)

-			{

-				context->setFrontFace(mode);

-			}

-		}

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-}

-

-void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);

-

-	if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->frustum(left, right, bottom, top, zNear, zFar);

-	}

-}

-

-void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);

-}

-

-void GenerateMipmapOES(GLenum target)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		texture->generateMipmaps();

-	}

-}

-

-void GenBuffers(GLsizei n, GLuint* buffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			buffers[i] = context->createBuffer();

-		}

-	}

-}

-

-void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			framebuffers[i] = context->createFramebuffer();

-		}

-	}

-}

-

-void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)

-{

-	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

-

-	if(n < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		for(int i = 0; i < n; i++)

-		{

-			textures[i] = context->createTexture();

-		}

-	}

-}

-

-void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(target != GL_RENDERBUFFER_OES)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(context->getRenderbufferName() == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-

-		switch(pname)

-		{

-		case GL_RENDERBUFFER_WIDTH_OES:           *params = renderbuffer->getWidth();       break;

-		case GL_RENDERBUFFER_HEIGHT_OES:          *params = renderbuffer->getHeight();      break;

-		case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat();      break;

-		case GL_RENDERBUFFER_RED_SIZE_OES:        *params = renderbuffer->getRedSize();     break;

-		case GL_RENDERBUFFER_GREEN_SIZE_OES:      *params = renderbuffer->getGreenSize();   break;

-		case GL_RENDERBUFFER_BLUE_SIZE_OES:       *params = renderbuffer->getBlueSize();    break;

-		case GL_RENDERBUFFER_ALPHA_SIZE_OES:      *params = renderbuffer->getAlphaSize();   break;

-		case GL_RENDERBUFFER_DEPTH_SIZE_OES:      *params = renderbuffer->getDepthSize();   break;

-		case GL_RENDERBUFFER_STENCIL_SIZE_OES:    *params = renderbuffer->getStencilSize(); break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetBooleanv(GLenum pname, GLboolean* params)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(!(context->getBooleanv(pname, params)))

-		{

-			int numParams = context->getQueryParameterNum(pname);

-

-			if(numParams < 0)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(numParams == 0)

-			{

-				return;

-			}

-

-			if(context->isQueryParameterFloat(pname))

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(floatParams[i] == 0.0f)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] floatParams;

-			}

-			else if(context->isQueryParameterInt(pname))

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(intParams[i] == 0)

-						params[i] = GL_FALSE;

-					else

-						params[i] = GL_TRUE;

-				}

-

-				delete [] intParams;

-			}

-			else UNREACHABLE(pname);

-		}

-	}

-}

-

-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Buffer *buffer;

-

-		switch(target)

-		{

-		case GL_ARRAY_BUFFER:

-			buffer = context->getArrayBuffer();

-			break;

-		case GL_ELEMENT_ARRAY_BUFFER:

-			buffer = context->getElementArrayBuffer();

-			break;

-		default:

-			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);

-		}

-

-		switch(pname)

-		{

-		case GL_BUFFER_USAGE:

-			*params = buffer->usage();

-			break;

-		case GL_BUFFER_SIZE:

-			*params = buffer->size();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetClipPlanef(GLenum pname, GLfloat eqn[4])

-{

-	UNIMPLEMENTED();

-}

-

-void GetClipPlanex(GLenum pname, GLfixed eqn[4])

-{

-	UNIMPLEMENTED();

-}

-

-GLenum GetError(void)

-{

-	TRACE("()");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		return context->getError();

-	}

-

-	return GL_NO_ERROR;

-}

-

-void GetFixedv(GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetFloatv(GLenum pname, GLfloat* params)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(!(context->getFloatv(pname, params)))

-		{

-			int numParams = context->getQueryParameterNum(pname);

-

-			if(numParams < 0)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(numParams == 0)

-			{

-				return;

-			}

-

-			if(context->isQueryParameterBool(pname))

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0.0f;

-					else

-						params[i] = 1.0f;

-				}

-

-				delete [] boolParams;

-			}

-			else if(context->isQueryParameterInt(pname))

-			{

-				GLint *intParams = NULL;

-				intParams = new GLint[numParams];

-

-				context->getIntegerv(pname, intParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					params[i] = (GLfloat)intParams[i];

-				}

-

-				delete [] intParams;

-			}

-			else UNREACHABLE(pname);

-		}

-	}

-}

-

-void GetFramebufferAttachmentParameterivOES(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);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(target != GL_FRAMEBUFFER_OES)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(context->getFramebufferName() == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

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

-

-		GLenum attachmentType;

-		GLuint attachmentHandle;

-		switch(attachment)

-		{

-		case GL_COLOR_ATTACHMENT0_OES:

-			attachmentType = framebuffer->getColorbufferType();

-			attachmentHandle = framebuffer->getColorbufferName();

-			break;

-		case GL_DEPTH_ATTACHMENT_OES:

-			attachmentType = framebuffer->getDepthbufferType();

-			attachmentHandle = framebuffer->getDepthbufferName();

-			break;

-		case GL_STENCIL_ATTACHMENT_OES:

-			attachmentType = framebuffer->getStencilbufferType();

-			attachmentHandle = framebuffer->getStencilbufferName();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		GLenum attachmentObjectType;   // Type category

-		if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)

-		{

-			attachmentObjectType = attachmentType;

-		}

-		else if(es1::IsTextureTarget(attachmentType))

-		{

-			attachmentObjectType = GL_TEXTURE;

-		}

-		else UNREACHABLE(attachmentType);

-

-		switch(pname)

-		{

-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:

-			*params = attachmentObjectType;

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:

-			if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)

-			{

-				*params = attachmentHandle;

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:

-			if(attachmentObjectType == GL_TEXTURE)

-			{

-				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0

-			}

-			else

-			{

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetIntegerv(GLenum pname, GLint* params)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(!(context->getIntegerv(pname, params)))

-		{

-			int numParams = context->getQueryParameterNum(pname);

-

-			if(numParams < 0)

-			{

-				return error(GL_INVALID_ENUM);

-			}

-

-			if(numParams == 0)

-			{

-				return;

-			}

-

-			if(context->isQueryParameterBool(pname))

-			{

-				GLboolean *boolParams = NULL;

-				boolParams = new GLboolean[numParams];

-

-				context->getBooleanv(pname, boolParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(boolParams[i] == GL_FALSE)

-						params[i] = 0;

-					else

-						params[i] = 1;

-				}

-

-				delete [] boolParams;

-			}

-			else if(context->isQueryParameterFloat(pname))

-			{

-				GLfloat *floatParams = NULL;

-				floatParams = new GLfloat[numParams];

-

-				context->getFloatv(pname, floatParams);

-

-				for(int i = 0; i < numParams; ++i)

-				{

-					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)

-					{

-						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);

-					}

-					else

-					{

-						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));

-					}

-				}

-

-				delete [] floatParams;

-			}

-			else UNREACHABLE(pname);

-		}

-	}

-}

-

-void GetLightfv(GLenum light, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetLightxv(GLenum light, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetPointerv(GLenum pname, GLvoid **params)

-{

-	TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))

-		{

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-const GLubyte* GetString(GLenum name)

-{

-	TRACE("(GLenum name = 0x%X)", name);

-

-	switch(name)

-	{

-	case GL_VENDOR:

-		return (GLubyte*)"TransGaming Inc.";

-	case GL_RENDERER:

-		return (GLubyte*)"Google SwiftShader";

-	case GL_VERSION:

-		return (GLubyte*)"OpenGL ES 1.1 SwiftShader " VERSION_STRING;

-	case GL_EXTENSIONS:

-		// Keep list sorted in following order:

-		// OES extensions

-		// EXT extensions

-		// Vendor extensions

-		return (GLubyte*)

-			"GL_OES_blend_equation_separate "

-			"GL_OES_blend_func_separate "

-			"GL_OES_blend_subtract "

-			"GL_OES_compressed_ETC1_RGB8_texture "

-			"GL_OES_depth_texture "

-			"GL_OES_EGL_image "

-			"GL_OES_EGL_image_external "

-			"GL_OES_EGL_sync "

-			"GL_OES_element_index_uint "

-			"GL_OES_framebuffer_object "

-			"GL_OES_packed_depth_stencil "

-			"GL_OES_read_format "

-			"GL_OES_rgb8_rgba8 "

-			"GL_OES_stencil8 "

-			"GL_OES_stencil_wrap "

-			"GL_OES_texture_mirrored_repeat "

-			"GL_OES_texture_npot "

-			"GL_EXT_blend_minmax "

-			"GL_EXT_read_format_bgra "

-			#if (S3TC_SUPPORT)

-			"GL_EXT_texture_compression_dxt1 "

-			"GL_ANGLE_texture_compression_dxt3 "

-			"GL_ANGLE_texture_compression_dxt5 "

-			#endif

-			"GL_EXT_texture_filter_anisotropic "

-			"GL_EXT_texture_format_BGRA8888";

-	default:

-		return error(GL_INVALID_ENUM, (GLubyte*)NULL);

-	}

-}

-

-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			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_MAX_ANISOTROPY_EXT:

-			*params = texture->getMaxAnisotropy();

-			break;

-		case GL_GENERATE_MIPMAP:

-			*params = (GLfloat)texture->getGenerateMipmap();

-			break;

-		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:

-			*params = (GLfloat)1;

-			break;

-		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);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			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_MAX_ANISOTROPY_EXT:

-			*params = (GLint)texture->getMaxAnisotropy();

-			break;

-		case GL_GENERATE_MIPMAP:

-			*params = (GLint)texture->getGenerateMipmap();

-			break;

-		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:

-			*params = 1;

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetTexEnviv(GLenum env, GLenum pname, GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_GENERATE_MIPMAP_HINT:

-			context->setGenerateMipmapHint(mode);

-			break;

-		case GL_PERSPECTIVE_CORRECTION_HINT:

-			context->setPerspectiveCorrectionHint(mode);

-			break;

-		case GL_FOG_HINT:

-			context->setFogHint(mode);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-GLboolean IsBuffer(GLuint buffer)

-{

-	TRACE("(GLuint buffer = %d)", buffer);

-

-	es1::Context *context = es1::getContext();

-

-	if(context && buffer)

-	{

-		es1::Buffer *bufferObject = context->getBuffer(buffer);

-

-		if(bufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsEnabled(GLenum cap)

-{

-	TRACE("(GLenum cap = 0x%X)", cap);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(cap)

-		{

-		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;

-		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;

-		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;

-		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;

-		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;

-		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;

-		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;

-		case GL_BLEND:                    return context->isBlendEnabled();                 break;

-		case GL_DITHER:                   return context->isDitherEnabled();                break;

-		case GL_LIGHTING:                 return context->isLightingEnabled();              break;

-		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;

-		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;

-		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;

-		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;

-		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;

-		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;

-		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;

-		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;

-		case GL_FOG:                      return context->isFogEnabled();                   break;

-		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;

-		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;

-		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;

-		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;

-		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;

-		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;

-		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;

-		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;

-		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;

-		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;

-		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;

-		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;

-		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;

-		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;

-		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;

-		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;

-		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;

-		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;

-		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;

-		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;

-		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;

-		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;

-		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;

-		default:

-			return error(GL_INVALID_ENUM, GL_FALSE);

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsFramebufferOES(GLuint framebuffer)

-{

-	TRACE("(GLuint framebuffer = %d)", framebuffer);

-

-	es1::Context *context = es1::getContext();

-

-	if(context && framebuffer)

-	{

-		es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);

-

-		if(framebufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsTexture(GLuint texture)

-{

-	TRACE("(GLuint texture = %d)", texture);

-

-	es1::Context *context = es1::getContext();

-

-	if(context && texture)

-	{

-		es1::Texture *textureObject = context->getTexture(texture);

-

-		if(textureObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-GLboolean IsRenderbufferOES(GLuint renderbuffer)

-{

-	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

-

-	es1::Context *context = es1::getContext();

-

-	if(context && renderbuffer)

-	{

-		es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);

-

-		if(renderbufferObject)

-		{

-			return GL_TRUE;

-		}

-	}

-

-	return GL_FALSE;

-}

-

-void LightModelf(GLenum pname, GLfloat param)

-{

-	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(param != 0.0f);

-			break;

-		case GL_LIGHT_MODEL_AMBIENT:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void LightModelfv(GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_AMBIENT:

-			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(params[0] != 0.0f);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void LightModelx(GLenum pname, GLfixed param)

-{

-	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(param != 0);

-			break;

-		case GL_LIGHT_MODEL_AMBIENT:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelxv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void LightModelxv(GLenum pname, const GLfixed *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_LIGHT_MODEL_AMBIENT:

-			context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);

-			break;

-		case GL_LIGHT_MODEL_TWO_SIDE:

-			context->setLightModelTwoSide(params[0] != 0);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Lightf(GLenum light, GLenum pname, GLfloat param)

-{

-	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);

-

-	int index = light - GL_LIGHT0;

-

-	if(index < 0 || index >= es1::MAX_LIGHTS)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_SPOT_EXPONENT:

-			if(param < 0.0f || param > 128.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightExponent(index, param);

-			break;

-		case GL_SPOT_CUTOFF:

-			if((param < 0.0f || param > 90.0f) && param != 180.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightCutoff(index, param);

-			break;

-		case GL_CONSTANT_ATTENUATION:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationConstant(index, param);

-			break;

-		case GL_LINEAR_ATTENUATION:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationLinear(index, param);

-			break;

-		case GL_QUADRATIC_ATTENUATION:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationQuadratic(index, param);

-			break;

-		case GL_AMBIENT:

-		case GL_DIFFUSE:

-		case GL_SPECULAR:

-		case GL_POSITION:

-		case GL_SPOT_DIRECTION:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Lightfv(GLenum light, GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		int index = light - GL_LIGHT0;

-

-		if(index < 0 || index > es1::MAX_LIGHTS)

-		{

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_AMBIENT:               context->setLightAmbient(index, params[0], params[1], params[2], params[3]);  break;

-		case GL_DIFFUSE:               context->setLightDiffuse(index, params[0], params[1], params[2], params[3]);  break;

-		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;

-		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;

-		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;

-		case GL_SPOT_EXPONENT:

-			if(params[0] < 0.0f || params[0] > 128.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightExponent(index, params[0]);

-			break;

-		case GL_SPOT_CUTOFF:

-			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setSpotLightCutoff(index, params[0]);

-			break;

-		case GL_CONSTANT_ATTENUATION:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationConstant(index, params[0]);

-			break;

-		case GL_LINEAR_ATTENUATION:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationLinear(index, params[0]);

-			break;

-		case GL_QUADRATIC_ATTENUATION:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setLightAttenuationQuadratic(index, params[0]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Lightx(GLenum light, GLenum pname, GLfixed param)

-{

-	UNIMPLEMENTED();

-}

-

-void Lightxv(GLenum light, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void LineWidth(GLfloat width)

-{

-	TRACE("(GLfloat width = %f)", width);

-

-	if(width <= 0.0f)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setLineWidth(width);

-	}

-}

-

-void LineWidthx(GLfixed width)

-{

-	LineWidth((float)width / 0x10000);

-}

-

-void LoadIdentity(void)

-{

-	TRACE("()");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->loadIdentity();

-	}

-}

-

-void LoadMatrixf(const GLfloat *m)

-{

-	TRACE("(const GLfloat *m)");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->load(m);

-	}

-}

-

-void LoadMatrixx(const GLfixed *m)

-{

-	GLfloat matrix[16] =

-	{

-		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,

-		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,

-		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,

-		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000

-	};

-

-	LoadMatrixf(matrix);

-}

-

-void LogicOp(GLenum opcode)

-{

-	TRACE("(GLenum opcode = 0x%X)", opcode);

-

-	switch(opcode)

-	{

-	case GL_CLEAR:

-	case GL_SET:

-	case GL_COPY:

-	case GL_COPY_INVERTED:

-	case GL_NOOP:

-	case GL_INVERT:

-	case GL_AND:

-	case GL_NAND:

-	case GL_OR:

-	case GL_NOR:

-	case GL_XOR:

-	case GL_EQUIV:

-	case GL_AND_REVERSE:

-	case GL_AND_INVERTED:

-	case GL_OR_REVERSE:

-	case GL_OR_INVERTED:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setLogicalOperation(opcode);

-	}

-}

-

-void Materialf(GLenum face, GLenum pname, GLfloat param)

-{

-	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);

-

-	if(face != GL_FRONT_AND_BACK)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_SHININESS:

-			if(param < 0.0f || param > 128.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setMaterialShininess(param);

-			break;

-		case GL_AMBIENT:

-		case GL_DIFFUSE:

-		case GL_AMBIENT_AND_DIFFUSE:

-		case GL_SPECULAR:

-		case GL_EMISSION:

-			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Materialfv(GLenum face, GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);

-

-	if(face != GL_FRONT_AND_BACK)

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_AMBIENT:

-			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_DIFFUSE:

-			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_AMBIENT_AND_DIFFUSE:

-			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);

-			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_SPECULAR:

-			context->setMaterialSpecular(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_EMISSION:

-			context->setMaterialEmission(params[0], params[1], params[2], params[3]);

-			break;

-		case GL_SHININESS:

-			context->setMaterialShininess(params[0]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Materialx(GLenum face, GLenum pname, GLfixed param)

-{

-	UNIMPLEMENTED();

-}

-

-void Materialxv(GLenum face, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void MatrixMode(GLenum mode)

-{

-	TRACE("(GLenum mode = 0x%X)", mode);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setMatrixMode(mode);

-	}

-}

-

-void MultMatrixf(const GLfloat *m)

-{

-	TRACE("(const GLfloat *m)");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->multiply(m);

-	}

-}

-

-void MultMatrixx(const GLfixed *m)

-{

-	GLfloat matrix[16] =

-	{

-		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,

-		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,

-		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,

-		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000

-	};

-

-	MultMatrixf(matrix);

-}

-

-void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)

-{

-	TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);

-

-	switch(target)

-	{

-	case GL_TEXTURE0:

-	case GL_TEXTURE1:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);

-	}

-}

-

-void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)

-{

-	UNIMPLEMENTED();

-}

-

-void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)

-{

-	TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);

-	}

-}

-

-void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)

-{

-	UNIMPLEMENTED();

-}

-

-void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);

-

-	VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);

-}

-

-void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);

-

-	if(left == right || bottom == top || zNear == zFar)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->ortho(left, right, bottom, top, zNear, zFar);

-	}

-}

-

-void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);

-}

-

-void PixelStorei(GLenum pname, GLint param)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		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;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterf(GLenum pname, GLfloat param)

-{

-	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin(param);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax(param);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(param < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize(param);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterfv(GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin(params[0]);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax(params[0]);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			context->setPointDistanceAttenuation(params[0], params[1], params[2]);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(params[0] < 0.0f)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize(params[0]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterx(GLenum pname, GLfixed param)

-{

-	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin((float)param / 0x10000);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax((float)param / 0x10000);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(param < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize((float)param / 0x10000);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			return error(GL_INVALID_ENUM);   // Needs three parameters, should call glPointParameterxv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointParameterxv(GLenum pname, const GLfixed *params)

-{

-	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(pname)

-		{

-		case GL_POINT_SIZE_MIN:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMin((float)params[0] / 0x10000);

-			break;

-		case GL_POINT_SIZE_MAX:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointSizeMax((float)params[0] / 0x10000);

-			break;

-		case GL_POINT_DISTANCE_ATTENUATION:

-			context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);

-			break;

-		case GL_POINT_FADE_THRESHOLD_SIZE:

-			if(params[0] < 0)

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			context->setPointFadeThresholdSize((float)params[0] / 0x10000);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void PointSize(GLfloat size)

-{

-	TRACE("(GLfloat size = %f)", size);

-

-	if(size <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setVertexAttrib(sw::PointSize, size, size, size, size);

-	}

-}

-

-void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);

-

-	switch(type)

-	{

-	case GL_FIXED:

-	case GL_FLOAT:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);

-}

-

-void PointSizex(GLfixed size)

-{

-	PointSize((float)size / 0x10000);

-}

-

-void PolygonOffset(GLfloat factor, GLfloat units)

-{

-	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setPolygonOffsetParams(factor, units);

-	}

-}

-

-void PolygonOffsetx(GLfixed factor, GLfixed units)

-{

-	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);

-}

-

-void PopMatrix(void)

-{

-	TRACE("()");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->popMatrix();

-	}

-}

-

-void PushMatrix(void)

-{

-	TRACE("()");

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->pushMatrix();

-	}

-}

-

-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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->readPixels(x, y, width, height, format, type, NULL, pixels);

-	}

-}

-

-void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",

-	      target, internalformat, width, height);

-

-	switch(target)

-	{

-	case GL_RENDERBUFFER_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width < 0 || height < 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||

-		   height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)

-		{

-			return error(GL_INVALID_VALUE);

-		}

-

-		GLuint handle = context->getRenderbufferName();

-		if(handle == 0)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16_OES:

-			context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0));

-			break;

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-			context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));

-			break;

-		case GL_STENCIL_INDEX8_OES:

-			context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));

-			break;

-		case GL_DEPTH24_STENCIL8_OES:

-			context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0));

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->rotate(angle, x, y, z);

-	}

-}

-

-void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)

-{

-	Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);

-}

-

-void SampleCoverage(GLclampf value, GLboolean invert)

-{

-	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

-

-	es1::Context* context = es1::getContext();

-

-	if(context)

-	{

-		context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);

-	}

-}

-

-void SampleCoveragex(GLclampx value, GLboolean invert)

-{

-	SampleCoverage((float)value / 0x10000, invert);

-}

-

-void Scalef(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->scale(x, y, z);

-	}

-}

-

-void Scalex(GLfixed x, GLfixed y, GLfixed z)

-{

-	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);

-}

-

-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);

-	}

-

-	es1::Context* context = es1::getContext();

-

-	if(context)

-	{

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

-	}

-}

-

-void ShadeModel(GLenum mode)

-{

-	switch(mode)

-	{

-	case GL_FLAT:

-	case GL_SMOOTH:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setShadeModel(mode);

-	}

-}

-

-void StencilFunc(GLenum func, GLint ref, GLuint mask)

-{

-	TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)",  func, ref, mask);

-

-	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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setStencilParams(func, ref, mask);

-	}

-}

-

-void StencilMask(GLuint mask)

-{

-	TRACE("(GLuint mask = %d)", mask);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setStencilWritemask(mask);

-	}

-}

-

-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

-	TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);

-

-	switch(fail)

-	{

-	case GL_ZERO:

-	case GL_KEEP:

-	case GL_REPLACE:

-	case GL_INCR:

-	case GL_DECR:

-	case GL_INVERT:

-	case GL_INCR_WRAP_OES:

-	case GL_DECR_WRAP_OES:

-		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_OES:

-	case GL_DECR_WRAP_OES:

-		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_OES:

-	case GL_DECR_WRAP_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setStencilOperations(fail, zfail, zpass);

-	}

-}

-

-void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

-

-	if(size < 2 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		GLenum texture = context->getClientActiveTexture();

-		VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);

-	}

-}

-

-void TexEnvi(GLenum target, GLenum pname, GLint param);

-

-void TexEnvf(GLenum target, GLenum pname, GLfloat param)

-{

-	TexEnvi(target, pname, (GLint)param);

-}

-

-void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		GLint iParam = (GLint)roundf(params[0]);

-

-		switch(target)

-		{

-		case GL_POINT_SPRITE_OES:

-			UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_ENV:

-			switch(pname)

-			{

-			case GL_TEXTURE_ENV_MODE:

-				switch(iParam)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_DECAL:

-				case GL_BLEND:

-				case GL_ADD:

-				case GL_COMBINE:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setTextureEnvMode(iParam);

-				break;

-			case GL_TEXTURE_ENV_COLOR:

-				context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));

-				break;

-			case GL_COMBINE_RGB:

-				switch(iParam)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-				case GL_DOT3_RGB:

-				case GL_DOT3_RGBA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineRGB(iParam);

-				break;

-			case GL_COMBINE_ALPHA:

-				switch(iParam)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineAlpha(iParam);

-				break;

-			case GL_RGB_SCALE:

-				if(iParam != 1 && iParam != 2 && iParam != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(iParam != 1) UNIMPLEMENTED();

-				break;

-			case GL_ALPHA_SCALE:

-				if(iParam != 1 && iParam != 2 && iParam != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(iParam != 1) UNIMPLEMENTED();

-				break;

-			case GL_OPERAND0_RGB:

-				switch(iParam)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0RGB(iParam);

-				break;

-			case GL_OPERAND1_RGB:

-				switch(iParam)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1RGB(iParam);

-				break;

-			case GL_OPERAND2_RGB:

-				switch(iParam)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2RGB(iParam);

-				break;

-			case GL_OPERAND0_ALPHA:

-				switch(iParam)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0Alpha(iParam);

-				break;

-			case GL_OPERAND1_ALPHA:

-				switch(iParam)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1Alpha(iParam);

-				break;

-			case GL_OPERAND2_ALPHA:

-				switch(iParam)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2Alpha(iParam);

-				break;

-			case GL_SRC0_RGB:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0RGB(iParam);

-				break;

-			case GL_SRC1_RGB:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1RGB(iParam);

-				break;

-			case GL_SRC2_RGB:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2RGB(iParam);

-				break;

-			case GL_SRC0_ALPHA:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0Alpha(iParam);

-				break;

-			case GL_SRC1_ALPHA:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1Alpha(iParam);

-				break;

-			case GL_SRC2_ALPHA:

-				switch(iParam)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2Alpha(iParam);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexEnvi(GLenum target, GLenum pname, GLint param)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_POINT_SPRITE_OES:

-			UNIMPLEMENTED();

-			break;

-		case GL_TEXTURE_ENV:

-			switch(pname)

-			{

-			case GL_TEXTURE_ENV_MODE:

-				switch((GLenum)param)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_DECAL:

-				case GL_BLEND:

-				case GL_ADD:

-				case GL_COMBINE:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setTextureEnvMode((GLenum)param);

-				break;

-			case GL_TEXTURE_ENV_COLOR:

-				return error(GL_INVALID_ENUM);   // Needs four values, should call glTexEnviv() instead

-				break;

-			case GL_COMBINE_RGB:

-				switch((GLenum)param)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-				case GL_DOT3_RGB:

-				case GL_DOT3_RGBA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineRGB((GLenum)param);

-				break;

-			case GL_COMBINE_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_REPLACE:

-				case GL_MODULATE:

-				case GL_ADD:

-				case GL_ADD_SIGNED:

-				case GL_INTERPOLATE:

-				case GL_SUBTRACT:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setCombineAlpha((GLenum)param);

-				break;

-			case GL_RGB_SCALE:

-				if(param != 1 && param != 2 && param != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(param != 1) UNIMPLEMENTED();

-				break;

-			case GL_ALPHA_SCALE:

-				if(param != 1 && param != 2 && param != 4)

-				{

-					return error(GL_INVALID_VALUE);

-				}

-				if(param != 1) UNIMPLEMENTED();

-				break;

-			case GL_OPERAND0_RGB:

-				switch((GLenum)param)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0RGB((GLenum)param);

-				break;

-			case GL_OPERAND1_RGB:

-				switch((GLenum)param)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1RGB((GLenum)param);

-				break;

-			case GL_OPERAND2_RGB:

-				switch((GLenum)param)

-				{

-				case GL_SRC_COLOR:

-				case GL_ONE_MINUS_SRC_COLOR:

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2RGB((GLenum)param);

-				break;

-			case GL_OPERAND0_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand0Alpha((GLenum)param);

-				break;

-			case GL_OPERAND1_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand1Alpha((GLenum)param);

-				break;

-			case GL_OPERAND2_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_SRC_ALPHA:

-				case GL_ONE_MINUS_SRC_ALPHA:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setOperand2Alpha((GLenum)param);

-				break;

-			case GL_SRC0_RGB:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0RGB((GLenum)param);

-				break;

-			case GL_SRC1_RGB:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1RGB((GLenum)param);

-				break;

-			case GL_SRC2_RGB:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2RGB((GLenum)param);

-				break;

-			case GL_SRC0_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc0Alpha((GLenum)param);

-				break;

-			case GL_SRC1_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc1Alpha((GLenum)param);

-				break;

-			case GL_SRC2_ALPHA:

-				switch((GLenum)param)

-				{

-				case GL_TEXTURE:

-				case GL_CONSTANT:

-				case GL_PRIMARY_COLOR:

-				case GL_PREVIOUS:

-					break;

-				default:

-					error(GL_INVALID_ENUM);

-				}

-

-				context->setSrc2Alpha((GLenum)param);

-				break;

-			default:

-				return error(GL_INVALID_ENUM);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexEnvx(GLenum target, GLenum pname, GLfixed param)

-{

-	TexEnvi(target, pname, (GLint)param);

-}

-

-void TexEnviv(GLenum target, GLenum pname, const GLint *params)

-{

-	UNIMPLEMENTED();

-}

-

-void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	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* pixels =  %p)",

-	      target, level, internalformat, width, height, border, format, type, pixels);

-

-	if(!validImageSize(level, width, height))

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(internalformat != (GLint)format)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	switch(format)

-	{

-	case GL_ALPHA:

-	case GL_LUMINANCE:

-	case GL_LUMINANCE_ALPHA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGB:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_5_6_5:

-		case GL_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_RGBA:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-		case GL_FLOAT:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_BGRA_EXT:

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	case GL_ETC1_RGB8_OES:

-		return error(GL_INVALID_OPERATION);

-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:

-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:

-		if(S3TC_SUPPORT)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-		else

-		{

-			return error(GL_INVALID_ENUM);

-		}

-	case GL_DEPTH_STENCIL_OES:

-		switch(type)

-		{

-		case GL_UNSIGNED_INT_24_8_OES:

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-		break;

-	default:

-		return error(GL_INVALID_VALUE);

-	}

-

-	if(border != 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||

-			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))

-			{

-				return error(GL_INVALID_VALUE);

-			}

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(!texture)

-			{

-				return error(GL_INVALID_OPERATION);

-			}

-

-			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void TexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

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

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			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_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_GENERATE_MIPMAP:

-			texture->setGenerateMipmap((GLboolean)param);

-			break;

-		case GL_TEXTURE_CROP_RECT_OES:

-			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	TexParameterf(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);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		case GL_TEXTURE_EXTERNAL_OES:

-			texture = context->getTextureExternal();

-			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_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_GENERATE_MIPMAP:

-			texture->setGenerateMipmap((GLboolean)param);

-			break;

-		case GL_TEXTURE_CROP_RECT_OES:

-			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);

-

-	switch(pname)

-	{

-	case GL_TEXTURE_CROP_RECT_OES:

-		break;

-	default:

-		return TexParameteri(target, pname, params[0]);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture *texture;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:

-			texture = context->getTexture2D();

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-

-		switch(pname)

-		{

-		case GL_TEXTURE_CROP_RECT_OES:

-			texture->setCropRect(params[0], params[1], params[2], params[3]);

-			break;

-		default:

-			return error(GL_INVALID_ENUM);

-		}

-	}

-}

-

-void TexParameterx(GLenum target, GLenum pname, GLfixed param)

-{

-	TexParameteri(target, pname, (GLint)param);

-}

-

-void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	UNIMPLEMENTED();

-}

-

-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                   GLenum format, GLenum type, const GLvoid* pixels)

-{

-	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* pixels = %p)",

-	      target, level, xoffset, yoffset, width, height, format, type, pixels);

-

-	if(!es1::IsTextureTarget(target))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(level < 0 || level >= es1::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);

-	}

-

-	if(!es1::CheckTextureFormatType(format, type))

-	{

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(width == 0 || height == 0 || !pixels)

-	{

-		return;

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		if(target == GL_TEXTURE_2D)

-		{

-			es1::Texture2D *texture = context->getTexture2D();

-

-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))

-			{

-				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);

-			}

-		}

-		else UNREACHABLE(target);

-	}

-}

-

-void Translatef(GLfloat x, GLfloat y, GLfloat z)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->translate(x, y, z);

-	}

-}

-

-void Translatex(GLfixed x, GLfixed y, GLfixed z)

-{

-	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);

-}

-

-void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

-

-	if(size < 2 || size > 4)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	VertexAttribPointer(sw::Position, size, type, false, stride, pointer);

-}

-

-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);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->setViewportParams(x, y, width, height);

-	}

-}

-

-void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

-{

-	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);

-

-	switch(target)

-	{

-	case GL_TEXTURE_2D:

-	case GL_TEXTURE_EXTERNAL_OES:

-		break;

-	default:

-		return error(GL_INVALID_ENUM);

-	}

-

-	if(!image)

-	{

-		return error(GL_INVALID_OPERATION);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		es1::Texture2D *texture = 0;

-

-		switch(target)

-		{

-		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;

-		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;

-		default:                      UNREACHABLE(target);

-		}

-

-		if(!texture)

-		{

-			return error(GL_INVALID_OPERATION);

-		}

-

-		egl::Image *glImage = static_cast<egl::Image*>(image);

-

-		texture->setImage(glImage);

-	}

-}

-

-void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)

-{

-	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);

-

-	UNIMPLEMENTED();

-}

-

-void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)

-{

-	TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);

-

-	if(width <= 0 || height <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);

-	}

-}

-

-void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexsvOES(const GLshort *coords)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexivOES(const GLint *coords)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexxvOES(const GLfixed *coords)

-{

-	UNIMPLEMENTED();

-}

-

-void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)

-{

-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);

-

-	if(width <= 0 || height <= 0)

-	{

-		return error(GL_INVALID_VALUE);

-	}

-

-	es1::Context *context = es1::getContext();

-

-	if(context)

-	{

-		context->drawTexture(x, y, z, width, height);

-	}

-}

-

-void DrawTexfvOES(const GLfloat *coords)

-{

-	UNIMPLEMENTED();

-}

-

-}

-

-extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)

-{

-	struct Extension

-	{

-		const char *name;

-		__eglMustCastToProperFunctionPointerType address;

-	};

-

-	static const Extension glExtensions[] =

-	{

-		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}

-

-		EXTENSION(glEGLImageTargetTexture2DOES),

-		EXTENSION(glEGLImageTargetRenderbufferStorageOES),

-		EXTENSION(glIsRenderbufferOES),

-		EXTENSION(glBindRenderbufferOES),

-		EXTENSION(glDeleteRenderbuffersOES),

-		EXTENSION(glGenRenderbuffersOES),

-		EXTENSION(glRenderbufferStorageOES),

-		EXTENSION(glGetRenderbufferParameterivOES),

-		EXTENSION(glIsFramebufferOES),

-		EXTENSION(glBindFramebufferOES),

-		EXTENSION(glDeleteFramebuffersOES),

-		EXTENSION(glGenFramebuffersOES),

-		EXTENSION(glCheckFramebufferStatusOES),

-		EXTENSION(glFramebufferRenderbufferOES),

-		EXTENSION(glFramebufferTexture2DOES),

-		EXTENSION(glGetFramebufferAttachmentParameterivOES),

-		EXTENSION(glGenerateMipmapOES),

-		EXTENSION(glBlendEquationOES),

-		EXTENSION(glBlendEquationSeparateOES),

-		EXTENSION(glBlendFuncSeparateOES),

-		EXTENSION(glPointSizePointerOES),

-

-		#undef EXTENSION

-	};

-

-	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)

-	{

-		if(strcmp(procname, glExtensions[ext].name) == 0)

-		{

-			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;

-		}

-	}

-

-	return NULL;

-}

+// 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.
+// libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions.
+
+#include "main.h"
+#include "mathutil.h"
+#include "utilities.h"
+#include "Buffer.h"
+#include "Context.h"
+#include "Framebuffer.h"
+#include "Renderbuffer.h"
+#include "Texture.h"
+#include "common/debug.h"
+#include "Common/SharedLibrary.hpp"
+#include "Common/Version.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <limits>
+
+namespace es1
+{
+
+static bool validImageSize(GLint level, GLsizei width, GLsizei height)
+{
+	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)
+{
+	if(!texture)
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(compressed != texture->isCompressed(target, level))
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(format != GL_NONE_OES && format != texture->getFormat(target, level))
+	{
+		return error(GL_INVALID_OPERATION, false);
+	}
+
+	if(compressed)
+	{
+		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+		   (height % 4 != 0 && height != texture->getHeight(target, 0)))
+		{
+			return error(GL_INVALID_OPERATION, false);
+		}
+	}
+
+	if(xoffset + width > texture->getWidth(target, level) ||
+	   yoffset + height > texture->getHeight(target, level))
+	{
+		return error(GL_INVALID_VALUE, false);
+	}
+
+	return true;
+}
+
+void ActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->setActiveSampler(texture - GL_TEXTURE0);
+	}
+}
+
+void AlphaFunc(GLenum func, GLclampf ref)
+{
+	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
+
+	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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setAlphaFunc(func, clamp01(ref));
+	}
+}
+
+void AlphaFuncx(GLenum func, GLclampx ref)
+{
+	AlphaFunc(func, (float)ref / 0x10000);
+}
+
+void BindBuffer(GLenum target, GLuint buffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			context->bindArrayBuffer(buffer);
+			return;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			context->bindElementArrayBuffer(buffer);
+			return;
+		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_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->bindFramebuffer(framebuffer);
+	}
+}
+
+void BindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
+
+	if(target != GL_FRAMEBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->bindFramebuffer(framebuffer);
+	}
+}
+
+void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
+
+	if(target != GL_RENDERBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
+		{
+			// [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.
+			return error(GL_INVALID_OPERATION);
+		}
+
+		context->bindRenderbuffer(renderbuffer);
+	}
+}
+
+void BindTexture(GLenum target, GLuint texture)
+{
+	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject && textureObject->getTarget() != target && texture != 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			context->bindTexture2D(texture);
+			return;
+		case GL_TEXTURE_EXTERNAL_OES:
+			context->bindTextureExternal(texture);
+			return;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+
+void BlendEquationOES(GLenum mode)
+{
+	BlendEquationSeparateOES(mode, mode);
+}
+
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
+
+	switch(modeRGB)
+	{
+	case GL_FUNC_ADD_OES:
+	case GL_FUNC_SUBTRACT_OES:
+	case GL_FUNC_REVERSE_SUBTRACT_OES:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(modeAlpha)
+	{
+	case GL_FUNC_ADD_OES:
+	case GL_FUNC_SUBTRACT_OES:
+	case GL_FUNC_REVERSE_SUBTRACT_OES:
+	case GL_MIN_EXT:
+	case GL_MAX_EXT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setBlendEquation(modeRGB, modeAlpha);
+	}
+}
+
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+void BlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
+}
+
+void BlendFuncSeparateOES(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);
+
+	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_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:
+		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_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:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::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);
+	}
+
+	switch(usage)
+	{
+	case GL_STATIC_DRAW:
+	case GL_DYNAMIC_DRAW:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			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);
+	}
+
+	if(!data)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(!buffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		if((size_t)size + offset > buffer->size())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		buffer->bufferSubData(data, size, offset);
+	}
+}
+
+GLenum CheckFramebufferStatusOES(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	if(target != GL_FRAMEBUFFER_OES)
+	{
+		return error(GL_INVALID_ENUM, 0);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		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);
+	}
+
+	es1::Context *context = es1::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);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClearColor(red, green, blue, alpha);
+	}
+}
+
+void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+	ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
+}
+
+void ClearDepthf(GLclampf depth)
+{
+	TRACE("(GLclampf depth = %f)", depth);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClearDepth(depth);
+	}
+}
+
+void ClearDepthx(GLclampx depth)
+{
+	ClearDepthf((float)depth / 0x10000);
+}
+
+void ClearStencil(GLint s)
+{
+	TRACE("(GLint s = %d)", s);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClearStencil(s);
+	}
+}
+
+void ClientActiveTexture(GLenum texture)
+{
+	TRACE("(GLenum texture = 0x%X)", texture);
+
+	switch(texture)
+	{
+	case GL_TEXTURE0:
+	case GL_TEXTURE1:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->clientActiveTexture(texture);
+	}
+}
+
+void ClipPlanef(GLenum plane, const GLfloat *equation)
+{
+	TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane);
+
+	int index = plane - GL_CLIP_PLANE0;
+
+	if(index < 0 || index >= MAX_CLIP_PLANES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setClipPlane(index, equation);
+	}
+}
+
+void ClipPlanex(GLenum plane, const GLfixed *equation)
+{
+	GLfloat equationf[4] =
+	{
+		(float)equation[0] / 0x10000,
+		(float)equation[1] / 0x10000,
+		(float)equation[2] / 0x10000,
+		(float)equation[3] / 0x10000,
+	};
+
+	ClipPlanef(plane, equationf);
+}
+
+void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
+	}
+}
+
+void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+	Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);
+}
+
+void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+	Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
+}
+
+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);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
+	}
+}
+
+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 >= es1::MAX_VERTEX_ATTRIBS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(size < 1 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(type)
+	{
+	case GL_BYTE:
+	case GL_UNSIGNED_BYTE:
+	case GL_SHORT:
+	case GL_UNSIGNED_SHORT:
+	case GL_FIXED:
+	case GL_FLOAT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(stride < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+	}
+}
+
+void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	if(size != 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	VertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
+}
+
+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(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(!validImageSize(level, width, height) || imageSize < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	switch(internalformat)
+	{
+	case GL_ETC1_RGB8_OES:
+		break;
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		if(!S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_DEPTH_COMPONENT16_OES:
+	case GL_DEPTH_COMPONENT32_OES:
+	case GL_DEPTH_STENCIL_OES:
+	case GL_DEPTH24_STENCIL8_OES:
+		return error(GL_INVALID_OPERATION);
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es1::IMPLEMENTATION_MAX_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)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+		}
+		else 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(!es1::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es1::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);
+	}
+
+	switch(format)
+	{
+	case GL_ETC1_RGB8_OES:
+		break;
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		if(!S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width == 0 || height == 0 || !data)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(imageSize != egl::ComputeCompressedSize(width, height, format))
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		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);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, 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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+		}
+
+		if(context->getFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Renderbuffer *source = framebuffer->getColorbuffer();
+		GLenum colorbufferFormat = source->getFormat();
+
+		// [OpenGL ES 2.0.24] table 3.9
+		switch(internalformat)
+		{
+		case GL_ALPHA:
+			if(colorbufferFormat != GL_ALPHA &&
+			   colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4_OES &&
+			   colorbufferFormat != GL_RGB5_A1_OES &&
+			   colorbufferFormat != GL_RGBA8_OES)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_LUMINANCE:
+		case GL_RGB:
+			if(colorbufferFormat != GL_RGB &&
+			   colorbufferFormat != GL_RGB565_OES &&
+			   colorbufferFormat != GL_RGB8_OES &&
+			   colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4_OES &&
+			   colorbufferFormat != GL_RGB5_A1_OES &&
+			   colorbufferFormat != GL_RGBA8_OES)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_LUMINANCE_ALPHA:
+		case GL_RGBA:
+			if(colorbufferFormat != GL_RGBA &&
+			   colorbufferFormat != GL_RGBA4_OES &&
+			   colorbufferFormat != GL_RGB5_A1_OES &&
+			   colorbufferFormat != GL_RGBA8_OES)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			break;
+		case GL_ETC1_RGB8_OES:
+			return error(GL_INVALID_OPERATION);
+		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+			if(S3TC_SUPPORT)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->copyImage(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(!es1::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es1::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);
+	}
+
+	if(width == 0 || height == 0)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
+		{
+			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
+		}
+
+		es1::Renderbuffer *source = framebuffer->getColorbuffer();
+
+		if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Texture *texture = nullptr;
+
+		if(target == GL_TEXTURE_2D)
+		{
+			texture = context->getTexture2D();
+		}
+		else UNREACHABLE(target);
+
+		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))
+		{
+			return;
+		}
+
+		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
+	}
+}
+
+void CullFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_FRONT:
+	case GL_BACK:
+	case GL_FRONT_AND_BACK:
+		{
+			es1::Context *context = es1::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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteBuffer(buffers[i]);
+		}
+	}
+}
+
+void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			if(framebuffers[i] != 0)
+			{
+				context->deleteFramebuffer(framebuffers[i]);
+			}
+		}
+	}
+}
+
+void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			context->deleteRenderbuffer(renderbuffers[i]);
+		}
+	}
+}
+
+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);
+	}
+
+	es1::Context *context = es1::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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setDepthFunc(func);
+	}
+}
+
+void DepthMask(GLboolean flag)
+{
+	TRACE("(GLboolean flag = %d)", flag);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setDepthMask(flag != GL_FALSE);
+	}
+}
+
+void DepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setDepthRange(zNear, zFar);
+	}
+}
+
+void DepthRangex(GLclampx zNear, GLclampx zFar)
+{
+	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
+}
+
+void Disable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es1::Context *context = es1::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_LIGHTING:                 context->setLightingEnabled(false);              break;
+		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;
+		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;
+		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;
+		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;
+		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;
+		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;
+		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;
+		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;
+		case GL_FOG:                      context->setFogEnabled(false);                   break;
+		case GL_TEXTURE_2D:               context->setTexture2Denabled(false);             break;
+		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(false);       break;
+		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;
+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;
+		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(false);           break;
+		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(false);            break;
+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;
+		case GL_NORMALIZE:                context->setNormalizeEnabled(false);             break;
+		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(false);         break;
+		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(false);           break;
+		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(false);           break;
+		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(false);            break;
+		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(false);        break;
+		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(false);     break;
+		case GL_MULTISAMPLE:              context->setMultisampleEnabled(false);           break;
+		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(false);      break;
+		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false);          break;
+		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false);          break;
+		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false);          break;
+		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false);          break;
+		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false);          break;
+		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false);          break;
+		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(false);           break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void DisableClientState(GLenum array)
+{
+	TRACE("(GLenum array = 0x%X)", array);
+
+	switch(array)
+	{
+	case GL_VERTEX_ARRAY:
+	case GL_NORMAL_ARRAY:
+	case GL_COLOR_ARRAY:
+	case GL_POINT_SIZE_ARRAY_OES:
+	case GL_TEXTURE_COORD_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		switch(array)
+		{
+		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, false);                            break;
+		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;
+		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;
+		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false);                           break;
+		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
+		default:                      UNREACHABLE(array);
+		}
+	}
+}
+
+void DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
+
+	if(count < 0 || first < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		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);
+
+	if(count < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT:
+		case GL_UNSIGNED_INT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		context->drawElements(mode, count, type, indices);
+	}
+}
+
+void Enable(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es1::Context *context = es1::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_LIGHTING:                 context->setLightingEnabled(true);              break;
+		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;
+		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;
+		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;
+		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;
+		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;
+		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;
+		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;
+		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;
+		case GL_FOG:                      context->setFogEnabled(true);                   break;
+		case GL_TEXTURE_2D:               context->setTexture2Denabled(true);             break;
+		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(true);       break;
+		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;
+		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;
+		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(true);           break;
+		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(true);            break;
+		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;
+		case GL_NORMALIZE:                context->setNormalizeEnabled(true);             break;
+		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(true);         break;
+		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(true);           break;
+		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(true);           break;
+		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(true);            break;
+		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(true);        break;
+		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(true);     break;
+		case GL_MULTISAMPLE:              context->setMultisampleEnabled(true);           break;
+		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(true);      break;
+		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true);          break;
+		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true);          break;
+		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true);          break;
+		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true);          break;
+		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true);          break;
+		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true);          break;
+		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(true);           break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void EnableClientState(GLenum array)
+{
+	TRACE("(GLenum array = 0x%X)", array);
+
+	switch(array)
+	{
+	case GL_VERTEX_ARRAY:
+	case GL_NORMAL_ARRAY:
+	case GL_COLOR_ARRAY:
+	case GL_POINT_SIZE_ARRAY_OES:
+	case GL_TEXTURE_COORD_ARRAY:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+
+		switch(array)
+		{
+		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, true);                            break;
+		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;
+		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;
+		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true);                           break;
+		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
+		default:                      UNREACHABLE(array);
+		}
+	}
+}
+
+void Finish(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->finish();
+	}
+}
+
+void Flush(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->flush();
+	}
+}
+
+void FramebufferRenderbufferOES(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_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+		GLuint framebufferName = context->getFramebufferName();
+
+		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0_OES:
+			framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);
+			break;
+		case GL_DEPTH_ATTACHMENT_OES:
+			framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);
+			break;
+		case GL_STENCIL_ATTACHMENT_OES:
+			framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void FramebufferTexture2DOES(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_OES)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	switch(attachment)
+	{
+	case GL_COLOR_ATTACHMENT0_OES:
+	case GL_DEPTH_ATTACHMENT_OES:
+	case GL_STENCIL_ATTACHMENT_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(texture == 0)
+		{
+			textarget = GL_NONE_OES;
+		}
+		else
+		{
+			es1::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_2D:
+				if(tex->getTarget() != GL_TEXTURE_2D)
+				{
+					return error(GL_INVALID_OPERATION);
+				}
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(level != 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+		}
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+		GLuint framebufferName = context->getFramebufferName();
+
+		if(framebufferName == 0 || !framebuffer)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0_OES:  framebuffer->setColorbuffer(textarget, texture);   break;
+		case GL_DEPTH_ATTACHMENT_OES:   framebuffer->setDepthbuffer(textarget, texture);   break;
+		case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;
+		}
+	}
+}
+
+void Fogf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			switch((GLenum)param)
+			{
+			case GL_LINEAR:
+			case GL_EXP:
+			case GL_EXP2:
+				context->setFogMode((GLenum)param);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FOG_DENSITY:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setFogDensity(param);
+			break;
+		case GL_FOG_START:
+			context->setFogStart(param);
+			break;
+		case GL_FOG_END:
+			context->setFogEnd(param);
+			break;
+		case GL_FOG_COLOR:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glFogfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Fogfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			switch((GLenum)params[0])
+			{
+			case GL_LINEAR:
+			case GL_EXP:
+			case GL_EXP2:
+				context->setFogMode((GLenum)params[0]);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FOG_DENSITY:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setFogDensity(params[0]);
+			break;
+		case GL_FOG_START:
+			context->setFogStart(params[0]);
+			break;
+		case GL_FOG_END:
+			context->setFogEnd(params[0]);
+			break;
+		case GL_FOG_COLOR:
+			context->setFogColor(params[0], params[1], params[2], params[3]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Fogx(GLenum pname, GLfixed param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_FOG_MODE:
+			switch((GLenum)param)
+			{
+			case GL_LINEAR:
+			case GL_EXP:
+			case GL_EXP2:
+				context->setFogMode((GLenum)param);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FOG_DENSITY:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setFogDensity((float)param / 0x10000);
+			break;
+		case GL_FOG_START:
+			context->setFogStart((float)param / 0x10000);
+			break;
+		case GL_FOG_END:
+			context->setFogEnd((float)param / 0x10000);
+			break;
+		case GL_FOG_COLOR:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glFogxv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Fogxv(GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void FrontFace(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	switch(mode)
+	{
+	case GL_CW:
+	case GL_CCW:
+		{
+			es1::Context *context = es1::getContext();
+
+			if(context)
+			{
+				context->setFrontFace(mode);
+			}
+		}
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+}
+
+void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
+
+	if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->frustum(left, right, bottom, top, zNear, zFar);
+	}
+}
+
+void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
+}
+
+void GenerateMipmapOES(GLenum target)
+{
+	TRACE("(GLenum target = 0x%X)", target);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		texture->generateMipmaps();
+	}
+}
+
+void GenBuffers(GLsizei n, GLuint* buffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			buffers[i] = context->createBuffer();
+		}
+	}
+}
+
+void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			framebuffers[i] = context->createFramebuffer();
+		}
+	}
+}
+
+void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
+
+	if(n < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		for(int i = 0; i < n; i++)
+		{
+			textures[i] = context->createTexture();
+		}
+	}
+}
+
+void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(target != GL_RENDERBUFFER_OES)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(context->getRenderbufferName() == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
+
+		switch(pname)
+		{
+		case GL_RENDERBUFFER_WIDTH_OES:           *params = renderbuffer->getWidth();       break;
+		case GL_RENDERBUFFER_HEIGHT_OES:          *params = renderbuffer->getHeight();      break;
+		case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat();      break;
+		case GL_RENDERBUFFER_RED_SIZE_OES:        *params = renderbuffer->getRedSize();     break;
+		case GL_RENDERBUFFER_GREEN_SIZE_OES:      *params = renderbuffer->getGreenSize();   break;
+		case GL_RENDERBUFFER_BLUE_SIZE_OES:       *params = renderbuffer->getBlueSize();    break;
+		case GL_RENDERBUFFER_ALPHA_SIZE_OES:      *params = renderbuffer->getAlphaSize();   break;
+		case GL_RENDERBUFFER_DEPTH_SIZE_OES:      *params = renderbuffer->getDepthSize();   break;
+		case GL_RENDERBUFFER_STENCIL_SIZE_OES:    *params = renderbuffer->getStencilSize(); break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetBooleanv(GLenum pname, GLboolean* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getBooleanv(pname, params)))
+		{
+			int numParams = context->getQueryParameterNum(pname);
+
+			if(numParams < 0)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(numParams == 0)
+			{
+				return;
+			}
+
+			if(context->isQueryParameterFloat(pname))
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(floatParams[i] == 0.0f)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] floatParams;
+			}
+			else if(context->isQueryParameterInt(pname))
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(intParams[i] == 0)
+						params[i] = GL_FALSE;
+					else
+						params[i] = GL_TRUE;
+				}
+
+				delete [] intParams;
+			}
+			else UNREACHABLE(pname);
+		}
+	}
+}
+
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Buffer *buffer;
+
+		switch(target)
+		{
+		case GL_ARRAY_BUFFER:
+			buffer = context->getArrayBuffer();
+			break;
+		case GL_ELEMENT_ARRAY_BUFFER:
+			buffer = context->getElementArrayBuffer();
+			break;
+		default:
+			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);
+		}
+
+		switch(pname)
+		{
+		case GL_BUFFER_USAGE:
+			*params = buffer->usage();
+			break;
+		case GL_BUFFER_SIZE:
+			*params = buffer->size();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+	UNIMPLEMENTED();
+}
+
+void GetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+	UNIMPLEMENTED();
+}
+
+GLenum GetError(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		return context->getError();
+	}
+
+	return GL_NO_ERROR;
+}
+
+void GetFixedv(GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetFloatv(GLenum pname, GLfloat* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getFloatv(pname, params)))
+		{
+			int numParams = context->getQueryParameterNum(pname);
+
+			if(numParams < 0)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(numParams == 0)
+			{
+				return;
+			}
+
+			if(context->isQueryParameterBool(pname))
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0.0f;
+					else
+						params[i] = 1.0f;
+				}
+
+				delete [] boolParams;
+			}
+			else if(context->isQueryParameterInt(pname))
+			{
+				GLint *intParams = nullptr;
+				intParams = new GLint[numParams];
+
+				context->getIntegerv(pname, intParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					params[i] = (GLfloat)intParams[i];
+				}
+
+				delete [] intParams;
+			}
+			else UNREACHABLE(pname);
+		}
+	}
+}
+
+void GetFramebufferAttachmentParameterivOES(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);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(target != GL_FRAMEBUFFER_OES)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(context->getFramebufferName() == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		es1::Framebuffer *framebuffer = context->getFramebuffer();
+
+		GLenum attachmentType;
+		GLuint attachmentHandle;
+		switch(attachment)
+		{
+		case GL_COLOR_ATTACHMENT0_OES:
+			attachmentType = framebuffer->getColorbufferType();
+			attachmentHandle = framebuffer->getColorbufferName();
+			break;
+		case GL_DEPTH_ATTACHMENT_OES:
+			attachmentType = framebuffer->getDepthbufferType();
+			attachmentHandle = framebuffer->getDepthbufferName();
+			break;
+		case GL_STENCIL_ATTACHMENT_OES:
+			attachmentType = framebuffer->getStencilbufferType();
+			attachmentHandle = framebuffer->getStencilbufferName();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		GLenum attachmentObjectType;   // Type category
+		if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
+		{
+			attachmentObjectType = attachmentType;
+		}
+		else if(es1::IsTextureTarget(attachmentType))
+		{
+			attachmentObjectType = GL_TEXTURE;
+		}
+		else UNREACHABLE(attachmentType);
+
+		switch(pname)
+		{
+		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
+			*params = attachmentObjectType;
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
+			if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
+			{
+				*params = attachmentHandle;
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
+			if(attachmentObjectType == GL_TEXTURE)
+			{
+				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
+			}
+			else
+			{
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetIntegerv(GLenum pname, GLint* params)
+{
+	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getIntegerv(pname, params)))
+		{
+			int numParams = context->getQueryParameterNum(pname);
+
+			if(numParams < 0)
+			{
+				return error(GL_INVALID_ENUM);
+			}
+
+			if(numParams == 0)
+			{
+				return;
+			}
+
+			if(context->isQueryParameterBool(pname))
+			{
+				GLboolean *boolParams = nullptr;
+				boolParams = new GLboolean[numParams];
+
+				context->getBooleanv(pname, boolParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(boolParams[i] == GL_FALSE)
+						params[i] = 0;
+					else
+						params[i] = 1;
+				}
+
+				delete [] boolParams;
+			}
+			else if(context->isQueryParameterFloat(pname))
+			{
+				GLfloat *floatParams = nullptr;
+				floatParams = new GLfloat[numParams];
+
+				context->getFloatv(pname, floatParams);
+
+				for(int i = 0; i < numParams; ++i)
+				{
+					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
+					{
+						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
+					}
+					else
+					{
+						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
+					}
+				}
+
+				delete [] floatParams;
+			}
+			else UNREACHABLE(pname);
+		}
+	}
+}
+
+void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetPointerv(GLenum pname, GLvoid **params)
+{
+	TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
+		{
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+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:
+		return (GLubyte*)"OpenGL ES 1.1 SwiftShader " VERSION_STRING;
+	case GL_EXTENSIONS:
+		// Keep list sorted in following order:
+		// OES extensions
+		// EXT extensions
+		// Vendor extensions
+		return (GLubyte*)
+			"GL_OES_blend_equation_separate "
+			"GL_OES_blend_func_separate "
+			"GL_OES_blend_subtract "
+			"GL_OES_compressed_ETC1_RGB8_texture "
+			"GL_OES_depth_texture "
+			"GL_OES_EGL_image "
+			"GL_OES_EGL_image_external "
+			"GL_OES_EGL_sync "
+			"GL_OES_element_index_uint "
+			"GL_OES_framebuffer_object "
+			"GL_OES_packed_depth_stencil "
+			"GL_OES_read_format "
+			"GL_OES_rgb8_rgba8 "
+			"GL_OES_stencil8 "
+			"GL_OES_stencil_wrap "
+			"GL_OES_texture_mirrored_repeat "
+			"GL_OES_texture_npot "
+			"GL_EXT_blend_minmax "
+			"GL_EXT_read_format_bgra "
+			#if (S3TC_SUPPORT)
+			"GL_EXT_texture_compression_dxt1 "
+			"GL_ANGLE_texture_compression_dxt3 "
+			"GL_ANGLE_texture_compression_dxt5 "
+			#endif
+			"GL_EXT_texture_filter_anisotropic "
+			"GL_EXT_texture_format_BGRA8888";
+	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);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			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_MAX_ANISOTROPY_EXT:
+			*params = texture->getMaxAnisotropy();
+			break;
+		case GL_GENERATE_MIPMAP:
+			*params = (GLfloat)texture->getGenerateMipmap();
+			break;
+		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+			*params = (GLfloat)1;
+			break;
+		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);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			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_MAX_ANISOTROPY_EXT:
+			*params = (GLint)texture->getMaxAnisotropy();
+			break;
+		case GL_GENERATE_MIPMAP:
+			*params = (GLint)texture->getGenerateMipmap();
+			break;
+		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+			*params = 1;
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_GENERATE_MIPMAP_HINT:
+			context->setGenerateMipmapHint(mode);
+			break;
+		case GL_PERSPECTIVE_CORRECTION_HINT:
+			context->setPerspectiveCorrectionHint(mode);
+			break;
+		case GL_FOG_HINT:
+			context->setFogHint(mode);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+GLboolean IsBuffer(GLuint buffer)
+{
+	TRACE("(GLuint buffer = %d)", buffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && buffer)
+	{
+		es1::Buffer *bufferObject = context->getBuffer(buffer);
+
+		if(bufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsEnabled(GLenum cap)
+{
+	TRACE("(GLenum cap = 0x%X)", cap);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(cap)
+		{
+		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;
+		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;
+		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
+		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;
+		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;
+		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;
+		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;
+		case GL_BLEND:                    return context->isBlendEnabled();                 break;
+		case GL_DITHER:                   return context->isDitherEnabled();                break;
+		case GL_LIGHTING:                 return context->isLightingEnabled();              break;
+		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;
+		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;
+		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;
+		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;
+		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;
+		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;
+		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;
+		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;
+		case GL_FOG:                      return context->isFogEnabled();                   break;
+		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;
+		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;
+		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;
+		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;
+		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;
+		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;
+		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;
+		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;
+		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;
+		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;
+		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;
+		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;
+		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;
+		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;
+		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;
+		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;
+		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;
+		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;
+		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;
+		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;
+		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;
+		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;
+		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;
+		default:
+			return error(GL_INVALID_ENUM, GL_FALSE);
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsFramebufferOES(GLuint framebuffer)
+{
+	TRACE("(GLuint framebuffer = %d)", framebuffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && framebuffer)
+	{
+		es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
+
+		if(framebufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsTexture(GLuint texture)
+{
+	TRACE("(GLuint texture = %d)", texture);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && texture)
+	{
+		es1::Texture *textureObject = context->getTexture(texture);
+
+		if(textureObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+GLboolean IsRenderbufferOES(GLuint renderbuffer)
+{
+	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
+
+	es1::Context *context = es1::getContext();
+
+	if(context && renderbuffer)
+	{
+		es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+
+		if(renderbufferObject)
+		{
+			return GL_TRUE;
+		}
+	}
+
+	return GL_FALSE;
+}
+
+void LightModelf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(param != 0.0f);
+			break;
+		case GL_LIGHT_MODEL_AMBIENT:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void LightModelfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_AMBIENT:
+			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(params[0] != 0.0f);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void LightModelx(GLenum pname, GLfixed param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(param != 0);
+			break;
+		case GL_LIGHT_MODEL_AMBIENT:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelxv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void LightModelxv(GLenum pname, const GLfixed *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_LIGHT_MODEL_AMBIENT:
+			context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
+			break;
+		case GL_LIGHT_MODEL_TWO_SIDE:
+			context->setLightModelTwoSide(params[0] != 0);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Lightf(GLenum light, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
+
+	int index = light - GL_LIGHT0;
+
+	if(index < 0 || index >= es1::MAX_LIGHTS)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_SPOT_EXPONENT:
+			if(param < 0.0f || param > 128.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightExponent(index, param);
+			break;
+		case GL_SPOT_CUTOFF:
+			if((param < 0.0f || param > 90.0f) && param != 180.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightCutoff(index, param);
+			break;
+		case GL_CONSTANT_ATTENUATION:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationConstant(index, param);
+			break;
+		case GL_LINEAR_ATTENUATION:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationLinear(index, param);
+			break;
+		case GL_QUADRATIC_ATTENUATION:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationQuadratic(index, param);
+			break;
+		case GL_AMBIENT:
+		case GL_DIFFUSE:
+		case GL_SPECULAR:
+		case GL_POSITION:
+		case GL_SPOT_DIRECTION:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		int index = light - GL_LIGHT0;
+
+		if(index < 0 || index > es1::MAX_LIGHTS)
+		{
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_AMBIENT:               context->setLightAmbient(index, params[0], params[1], params[2], params[3]);  break;
+		case GL_DIFFUSE:               context->setLightDiffuse(index, params[0], params[1], params[2], params[3]);  break;
+		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
+		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
+		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;
+		case GL_SPOT_EXPONENT:
+			if(params[0] < 0.0f || params[0] > 128.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightExponent(index, params[0]);
+			break;
+		case GL_SPOT_CUTOFF:
+			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setSpotLightCutoff(index, params[0]);
+			break;
+		case GL_CONSTANT_ATTENUATION:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationConstant(index, params[0]);
+			break;
+		case GL_LINEAR_ATTENUATION:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationLinear(index, params[0]);
+			break;
+		case GL_QUADRATIC_ATTENUATION:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setLightAttenuationQuadratic(index, params[0]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Lightx(GLenum light, GLenum pname, GLfixed param)
+{
+	UNIMPLEMENTED();
+}
+
+void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void LineWidth(GLfloat width)
+{
+	TRACE("(GLfloat width = %f)", width);
+
+	if(width <= 0.0f)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setLineWidth(width);
+	}
+}
+
+void LineWidthx(GLfixed width)
+{
+	LineWidth((float)width / 0x10000);
+}
+
+void LoadIdentity(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->loadIdentity();
+	}
+}
+
+void LoadMatrixf(const GLfloat *m)
+{
+	TRACE("(const GLfloat *m)");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->load(m);
+	}
+}
+
+void LoadMatrixx(const GLfixed *m)
+{
+	GLfloat matrix[16] =
+	{
+		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
+		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
+		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
+		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
+	};
+
+	LoadMatrixf(matrix);
+}
+
+void LogicOp(GLenum opcode)
+{
+	TRACE("(GLenum opcode = 0x%X)", opcode);
+
+	switch(opcode)
+	{
+	case GL_CLEAR:
+	case GL_SET:
+	case GL_COPY:
+	case GL_COPY_INVERTED:
+	case GL_NOOP:
+	case GL_INVERT:
+	case GL_AND:
+	case GL_NAND:
+	case GL_OR:
+	case GL_NOR:
+	case GL_XOR:
+	case GL_EQUIV:
+	case GL_AND_REVERSE:
+	case GL_AND_INVERTED:
+	case GL_OR_REVERSE:
+	case GL_OR_INVERTED:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setLogicalOperation(opcode);
+	}
+}
+
+void Materialf(GLenum face, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
+
+	if(face != GL_FRONT_AND_BACK)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_SHININESS:
+			if(param < 0.0f || param > 128.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setMaterialShininess(param);
+			break;
+		case GL_AMBIENT:
+		case GL_DIFFUSE:
+		case GL_AMBIENT_AND_DIFFUSE:
+		case GL_SPECULAR:
+		case GL_EMISSION:
+			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
+
+	if(face != GL_FRONT_AND_BACK)
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_AMBIENT:
+			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_DIFFUSE:
+			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_AMBIENT_AND_DIFFUSE:
+			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
+			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_SPECULAR:
+			context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_EMISSION:
+			context->setMaterialEmission(params[0], params[1], params[2], params[3]);
+			break;
+		case GL_SHININESS:
+			context->setMaterialShininess(params[0]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Materialx(GLenum face, GLenum pname, GLfixed param)
+{
+	UNIMPLEMENTED();
+}
+
+void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void MatrixMode(GLenum mode)
+{
+	TRACE("(GLenum mode = 0x%X)", mode);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setMatrixMode(mode);
+	}
+}
+
+void MultMatrixf(const GLfloat *m)
+{
+	TRACE("(const GLfloat *m)");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->multiply(m);
+	}
+}
+
+void MultMatrixx(const GLfixed *m)
+{
+	GLfloat matrix[16] =
+	{
+		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
+		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
+		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
+		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
+	};
+
+	MultMatrixf(matrix);
+}
+
+void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+	TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);
+
+	switch(target)
+	{
+	case GL_TEXTURE0:
+	case GL_TEXTURE1:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
+	}
+}
+
+void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+	UNIMPLEMENTED();
+}
+
+void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+	TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
+	}
+}
+
+void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+	UNIMPLEMENTED();
+}
+
+void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
+
+	VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
+}
+
+void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
+
+	if(left == right || bottom == top || zNear == zFar)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->ortho(left, right, bottom, top, zNear, zFar);
+	}
+}
+
+void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
+}
+
+void PixelStorei(GLenum pname, GLint param)
+{
+	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		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;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterf(GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin(param);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax(param);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(param < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize(param);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterfv(GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin(params[0]);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax(params[0]);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			context->setPointDistanceAttenuation(params[0], params[1], params[2]);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(params[0] < 0.0f)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize(params[0]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterx(GLenum pname, GLfixed param)
+{
+	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin((float)param / 0x10000);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax((float)param / 0x10000);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(param < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize((float)param / 0x10000);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			return error(GL_INVALID_ENUM);   // Needs three parameters, should call glPointParameterxv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointParameterxv(GLenum pname, const GLfixed *params)
+{
+	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(pname)
+		{
+		case GL_POINT_SIZE_MIN:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMin((float)params[0] / 0x10000);
+			break;
+		case GL_POINT_SIZE_MAX:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointSizeMax((float)params[0] / 0x10000);
+			break;
+		case GL_POINT_DISTANCE_ATTENUATION:
+			context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
+			break;
+		case GL_POINT_FADE_THRESHOLD_SIZE:
+			if(params[0] < 0)
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			context->setPointFadeThresholdSize((float)params[0] / 0x10000);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void PointSize(GLfloat size)
+{
+	TRACE("(GLfloat size = %f)", size);
+
+	if(size <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setVertexAttrib(sw::PointSize, size, size, size, size);
+	}
+}
+
+void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
+
+	switch(type)
+	{
+	case GL_FIXED:
+	case GL_FLOAT:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
+}
+
+void PointSizex(GLfixed size)
+{
+	PointSize((float)size / 0x10000);
+}
+
+void PolygonOffset(GLfloat factor, GLfloat units)
+{
+	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setPolygonOffsetParams(factor, units);
+	}
+}
+
+void PolygonOffsetx(GLfixed factor, GLfixed units)
+{
+	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
+}
+
+void PopMatrix(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->popMatrix();
+	}
+}
+
+void PushMatrix(void)
+{
+	TRACE("()");
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->pushMatrix();
+	}
+}
+
+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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
+	}
+}
+
+void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+	      target, internalformat, width, height);
+
+	switch(target)
+	{
+	case GL_RENDERBUFFER_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width < 0 || height < 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+		   height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
+		GLuint handle = context->getRenderbufferName();
+		if(handle == 0)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16_OES:
+			context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0));
+			break;
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+			context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
+			break;
+		case GL_STENCIL_INDEX8_OES:
+			context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
+			break;
+		case GL_DEPTH24_STENCIL8_OES:
+			context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0));
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->rotate(angle, x, y, z);
+	}
+}
+
+void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+	Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
+}
+
+void SampleCoverage(GLclampf value, GLboolean invert)
+{
+	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
+
+	es1::Context* context = es1::getContext();
+
+	if(context)
+	{
+		context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);
+	}
+}
+
+void SampleCoveragex(GLclampx value, GLboolean invert)
+{
+	SampleCoverage((float)value / 0x10000, invert);
+}
+
+void Scalef(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->scale(x, y, z);
+	}
+}
+
+void Scalex(GLfixed x, GLfixed y, GLfixed z)
+{
+	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
+}
+
+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);
+	}
+
+	es1::Context* context = es1::getContext();
+
+	if(context)
+	{
+		context->setScissorParams(x, y, width, height);
+	}
+}
+
+void ShadeModel(GLenum mode)
+{
+	switch(mode)
+	{
+	case GL_FLAT:
+	case GL_SMOOTH:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setShadeModel(mode);
+	}
+}
+
+void StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)",  func, ref, mask);
+
+	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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setStencilParams(func, ref, mask);
+	}
+}
+
+void StencilMask(GLuint mask)
+{
+	TRACE("(GLuint mask = %d)", mask);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setStencilWritemask(mask);
+	}
+}
+
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);
+
+	switch(fail)
+	{
+	case GL_ZERO:
+	case GL_KEEP:
+	case GL_REPLACE:
+	case GL_INCR:
+	case GL_DECR:
+	case GL_INVERT:
+	case GL_INCR_WRAP_OES:
+	case GL_DECR_WRAP_OES:
+		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_OES:
+	case GL_DECR_WRAP_OES:
+		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_OES:
+	case GL_DECR_WRAP_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setStencilOperations(fail, zfail, zpass);
+	}
+}
+
+void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	if(size < 2 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLenum texture = context->getClientActiveTexture();
+		VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
+	}
+}
+
+void TexEnvi(GLenum target, GLenum pname, GLint param);
+
+void TexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+	TexEnvi(target, pname, (GLint)param);
+}
+
+void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		GLint iParam = (GLint)roundf(params[0]);
+
+		switch(target)
+		{
+		case GL_POINT_SPRITE_OES:
+			UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_ENV:
+			switch(pname)
+			{
+			case GL_TEXTURE_ENV_MODE:
+				switch(iParam)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_DECAL:
+				case GL_BLEND:
+				case GL_ADD:
+				case GL_COMBINE:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setTextureEnvMode(iParam);
+				break;
+			case GL_TEXTURE_ENV_COLOR:
+				context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
+				break;
+			case GL_COMBINE_RGB:
+				switch(iParam)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+				case GL_DOT3_RGB:
+				case GL_DOT3_RGBA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineRGB(iParam);
+				break;
+			case GL_COMBINE_ALPHA:
+				switch(iParam)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineAlpha(iParam);
+				break;
+			case GL_RGB_SCALE:
+				if(iParam != 1 && iParam != 2 && iParam != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(iParam != 1) UNIMPLEMENTED();
+				break;
+			case GL_ALPHA_SCALE:
+				if(iParam != 1 && iParam != 2 && iParam != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(iParam != 1) UNIMPLEMENTED();
+				break;
+			case GL_OPERAND0_RGB:
+				switch(iParam)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0RGB(iParam);
+				break;
+			case GL_OPERAND1_RGB:
+				switch(iParam)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1RGB(iParam);
+				break;
+			case GL_OPERAND2_RGB:
+				switch(iParam)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2RGB(iParam);
+				break;
+			case GL_OPERAND0_ALPHA:
+				switch(iParam)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0Alpha(iParam);
+				break;
+			case GL_OPERAND1_ALPHA:
+				switch(iParam)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1Alpha(iParam);
+				break;
+			case GL_OPERAND2_ALPHA:
+				switch(iParam)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2Alpha(iParam);
+				break;
+			case GL_SRC0_RGB:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0RGB(iParam);
+				break;
+			case GL_SRC1_RGB:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1RGB(iParam);
+				break;
+			case GL_SRC2_RGB:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2RGB(iParam);
+				break;
+			case GL_SRC0_ALPHA:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0Alpha(iParam);
+				break;
+			case GL_SRC1_ALPHA:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1Alpha(iParam);
+				break;
+			case GL_SRC2_ALPHA:
+				switch(iParam)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2Alpha(iParam);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexEnvi(GLenum target, GLenum pname, GLint param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_POINT_SPRITE_OES:
+			UNIMPLEMENTED();
+			break;
+		case GL_TEXTURE_ENV:
+			switch(pname)
+			{
+			case GL_TEXTURE_ENV_MODE:
+				switch((GLenum)param)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_DECAL:
+				case GL_BLEND:
+				case GL_ADD:
+				case GL_COMBINE:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setTextureEnvMode((GLenum)param);
+				break;
+			case GL_TEXTURE_ENV_COLOR:
+				return error(GL_INVALID_ENUM);   // Needs four values, should call glTexEnviv() instead
+				break;
+			case GL_COMBINE_RGB:
+				switch((GLenum)param)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+				case GL_DOT3_RGB:
+				case GL_DOT3_RGBA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineRGB((GLenum)param);
+				break;
+			case GL_COMBINE_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_REPLACE:
+				case GL_MODULATE:
+				case GL_ADD:
+				case GL_ADD_SIGNED:
+				case GL_INTERPOLATE:
+				case GL_SUBTRACT:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setCombineAlpha((GLenum)param);
+				break;
+			case GL_RGB_SCALE:
+				if(param != 1 && param != 2 && param != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(param != 1) UNIMPLEMENTED();
+				break;
+			case GL_ALPHA_SCALE:
+				if(param != 1 && param != 2 && param != 4)
+				{
+					return error(GL_INVALID_VALUE);
+				}
+				if(param != 1) UNIMPLEMENTED();
+				break;
+			case GL_OPERAND0_RGB:
+				switch((GLenum)param)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0RGB((GLenum)param);
+				break;
+			case GL_OPERAND1_RGB:
+				switch((GLenum)param)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1RGB((GLenum)param);
+				break;
+			case GL_OPERAND2_RGB:
+				switch((GLenum)param)
+				{
+				case GL_SRC_COLOR:
+				case GL_ONE_MINUS_SRC_COLOR:
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2RGB((GLenum)param);
+				break;
+			case GL_OPERAND0_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand0Alpha((GLenum)param);
+				break;
+			case GL_OPERAND1_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand1Alpha((GLenum)param);
+				break;
+			case GL_OPERAND2_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_SRC_ALPHA:
+				case GL_ONE_MINUS_SRC_ALPHA:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setOperand2Alpha((GLenum)param);
+				break;
+			case GL_SRC0_RGB:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0RGB((GLenum)param);
+				break;
+			case GL_SRC1_RGB:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1RGB((GLenum)param);
+				break;
+			case GL_SRC2_RGB:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2RGB((GLenum)param);
+				break;
+			case GL_SRC0_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc0Alpha((GLenum)param);
+				break;
+			case GL_SRC1_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc1Alpha((GLenum)param);
+				break;
+			case GL_SRC2_ALPHA:
+				switch((GLenum)param)
+				{
+				case GL_TEXTURE:
+				case GL_CONSTANT:
+				case GL_PRIMARY_COLOR:
+				case GL_PREVIOUS:
+					break;
+				default:
+					error(GL_INVALID_ENUM);
+				}
+
+				context->setSrc2Alpha((GLenum)param);
+				break;
+			default:
+				return error(GL_INVALID_ENUM);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+	TexEnvi(target, pname, (GLint)param);
+}
+
+void TexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+	UNIMPLEMENTED();
+}
+
+void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	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* pixels =  %p)",
+	      target, level, internalformat, width, height, border, format, type, pixels);
+
+	if(!validImageSize(level, width, height))
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(internalformat != (GLint)format)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	switch(format)
+	{
+	case GL_ALPHA:
+	case GL_LUMINANCE:
+	case GL_LUMINANCE_ALPHA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_RGB:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_5_6_5:
+		case GL_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_RGBA:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT_4_4_4_4:
+		case GL_UNSIGNED_SHORT_5_5_5_1:
+		case GL_FLOAT:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_BGRA_EXT:
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	case GL_ETC1_RGB8_OES:
+		return error(GL_INVALID_OPERATION);
+	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+		if(S3TC_SUPPORT)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+		else
+		{
+			return error(GL_INVALID_ENUM);
+		}
+	case GL_DEPTH_STENCIL_OES:
+		switch(type)
+		{
+		case GL_UNSIGNED_INT_24_8_OES:
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+		break;
+	default:
+		return error(GL_INVALID_VALUE);
+	}
+
+	if(border != 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
+			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
+			{
+				return error(GL_INVALID_VALUE);
+			}
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(!texture)
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+
+			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			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_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_GENERATE_MIPMAP:
+			texture->setGenerateMipmap((GLboolean)param);
+			break;
+		case GL_TEXTURE_CROP_RECT_OES:
+			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	TexParameterf(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);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		case GL_TEXTURE_EXTERNAL_OES:
+			texture = context->getTextureExternal();
+			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_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_GENERATE_MIPMAP:
+			texture->setGenerateMipmap((GLboolean)param);
+			break;
+		case GL_TEXTURE_CROP_RECT_OES:
+			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);
+
+	switch(pname)
+	{
+	case GL_TEXTURE_CROP_RECT_OES:
+		break;
+	default:
+		return TexParameteri(target, pname, params[0]);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture *texture;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:
+			texture = context->getTexture2D();
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+
+		switch(pname)
+		{
+		case GL_TEXTURE_CROP_RECT_OES:
+			texture->setCropRect(params[0], params[1], params[2], params[3]);
+			break;
+		default:
+			return error(GL_INVALID_ENUM);
+		}
+	}
+}
+
+void TexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+	TexParameteri(target, pname, (GLint)param);
+}
+
+void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	UNIMPLEMENTED();
+}
+
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type, const GLvoid* pixels)
+{
+	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* pixels = %p)",
+	      target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+	if(!es1::IsTextureTarget(target))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(level < 0 || level >= es1::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);
+	}
+
+	if(!es1::CheckTextureFormatType(format, type))
+	{
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(width == 0 || height == 0 || !pixels)
+	{
+		return;
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		if(target == GL_TEXTURE_2D)
+		{
+			es1::Texture2D *texture = context->getTexture2D();
+
+			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
+			{
+				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
+			}
+		}
+		else UNREACHABLE(target);
+	}
+}
+
+void Translatef(GLfloat x, GLfloat y, GLfloat z)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->translate(x, y, z);
+	}
+}
+
+void Translatex(GLfixed x, GLfixed y, GLfixed z)
+{
+	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
+}
+
+void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
+
+	if(size < 2 || size > 4)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
+}
+
+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);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->setViewportParams(x, y, width, height);
+	}
+}
+
+void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
+
+	switch(target)
+	{
+	case GL_TEXTURE_2D:
+	case GL_TEXTURE_EXTERNAL_OES:
+		break;
+	default:
+		return error(GL_INVALID_ENUM);
+	}
+
+	if(!image)
+	{
+		return error(GL_INVALID_OPERATION);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		es1::Texture2D *texture = 0;
+
+		switch(target)
+		{
+		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
+		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
+		default:                      UNREACHABLE(target);
+		}
+
+		if(!texture)
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
+		egl::Image *glImage = static_cast<egl::Image*>(image);
+
+		texture->setImage(glImage);
+	}
+}
+
+void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
+
+	UNIMPLEMENTED();
+}
+
+void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+	TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);
+
+	if(width <= 0 || height <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
+	}
+}
+
+void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexsvOES(const GLshort *coords)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexivOES(const GLint *coords)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexxvOES(const GLfixed *coords)
+{
+	UNIMPLEMENTED();
+}
+
+void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);
+
+	if(width <= 0 || height <= 0)
+	{
+		return error(GL_INVALID_VALUE);
+	}
+
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		context->drawTexture(x, y, z, width, height);
+	}
+}
+
+void DrawTexfvOES(const GLfloat *coords)
+{
+	UNIMPLEMENTED();
+}
+
+}
+
+extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
+{
+	struct Extension
+	{
+		const char *name;
+		__eglMustCastToProperFunctionPointerType address;
+	};
+
+	static const Extension glExtensions[] =
+	{
+		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+		EXTENSION(glEGLImageTargetTexture2DOES),
+		EXTENSION(glEGLImageTargetRenderbufferStorageOES),
+		EXTENSION(glIsRenderbufferOES),
+		EXTENSION(glBindRenderbufferOES),
+		EXTENSION(glDeleteRenderbuffersOES),
+		EXTENSION(glGenRenderbuffersOES),
+		EXTENSION(glRenderbufferStorageOES),
+		EXTENSION(glGetRenderbufferParameterivOES),
+		EXTENSION(glIsFramebufferOES),
+		EXTENSION(glBindFramebufferOES),
+		EXTENSION(glDeleteFramebuffersOES),
+		EXTENSION(glGenFramebuffersOES),
+		EXTENSION(glCheckFramebufferStatusOES),
+		EXTENSION(glFramebufferRenderbufferOES),
+		EXTENSION(glFramebufferTexture2DOES),
+		EXTENSION(glGetFramebufferAttachmentParameterivOES),
+		EXTENSION(glGenerateMipmapOES),
+		EXTENSION(glBlendEquationOES),
+		EXTENSION(glBlendEquationSeparateOES),
+		EXTENSION(glBlendFuncSeparateOES),
+		EXTENSION(glPointSizePointerOES),
+
+		#undef EXTENSION
+	};
+
+	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+	{
+		if(strcmp(procname, glExtensions[ext].name) == 0)
+		{
+			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
+		}
+	}
+
+	return nullptr;
+}
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index eddcd75..5c9657b 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -1,3 +1,17 @@
+// 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.
+
 #ifndef libGLES_CM_hpp
 #define libGLES_CM_hpp
 
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.rc b/src/OpenGL/libGLES_CM/libGLES_CM.rc
index cdbb35c..174d7b5 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.rc
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.rc
@@ -28,18 +28,18 @@
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE 
+1 TEXTINCLUDE
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE 
+2 TEXTINCLUDE
 BEGIN
     "#include ""afxres.h""\r\n"
     "#include ""../common/version.h""\0"
 END
 
-3 TEXTINCLUDE 
+3 TEXTINCLUDE
 BEGIN
     "\r\n"
     "\0"
@@ -77,7 +77,7 @@
 			#endif
             VALUE "FileVersion", VERSION_STRING
             VALUE "InternalName", "libGLES_CM"
-            VALUE "LegalCopyright", "Copyright (C) 2012 TransGaming Inc."
+            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."
             VALUE "OriginalFilename", "libGLES_CM.dll"
             VALUE "PrivateBuild", VERSION_STRING
             VALUE "ProductName", "SwiftShader libGLES_CM Dynamic Link Library"
diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index 8b91578..be2462a 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -1,1606 +1,1609 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// main.cpp: DLL entry point and management of thread-local data.

-

-#include "main.h"

-

-#include "libGLES_CM.hpp"

-#include "Framebuffer.h"

-#include "libEGL/Surface.h"

-#include "Common/Thread.hpp"

-#include "Common/SharedLibrary.hpp"

-#include "common/debug.h"

-

-#include <GLES/glext.h>

-

-#if !defined(_MSC_VER)

-#define CONSTRUCTOR __attribute__((constructor))

-#define DESTRUCTOR __attribute__((destructor))

-#else

-#define CONSTRUCTOR

-#define DESTRUCTOR

-#endif

-

-static void glAttachThread()

-{

-    TRACE("()");

-}

-

-static void glDetachThread()

-{

-    TRACE("()");

-}

-

-CONSTRUCTOR static void glAttachProcess()

-{

-    TRACE("()");

-

-    glAttachThread();

-}

-

-DESTRUCTOR static void glDetachProcess()

-{

-    TRACE("()");

-

-	glDetachThread();

-}

-

-#if defined(_WIN32)

-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)

-{

-    switch(reason)

-    {

-    case DLL_PROCESS_ATTACH:

-        glAttachProcess();

-        break;

-    case DLL_THREAD_ATTACH:

-        glAttachThread();

-        break;

-    case DLL_THREAD_DETACH:

-        glDetachThread();

-        break;

-    case DLL_PROCESS_DETACH:

-        glDetachProcess();

-        break;

-    default:

-        break;

-    }

-

-    return TRUE;

-}

-#endif

-

-namespace es1

-{

-es1::Context *getContext()

-{

-	egl::Context *context = libEGL->clientGetCurrentContext();

-

-	if(context && context->getClientVersion() == 1)

-	{

-		return static_cast<es1::Context*>(context);

-	}

-

-	return 0;

-}

-

-Device *getDevice()

-{

-    Context *context = getContext();

-

-    return context ? context->getDevice() : 0;

-}

-

-// Records an error code

-void error(GLenum errorCode)

-{

-    es1::Context *context = es1::getContext();

-

-    if(context)

-    {

-        switch(errorCode)

-        {

-        case GL_INVALID_ENUM:

-            context->recordInvalidEnum();

-            TRACE("\t! Error generated: invalid enum\n");

-            break;

-        case GL_INVALID_VALUE:

-            context->recordInvalidValue();

-            TRACE("\t! Error generated: invalid value\n");

-            break;

-        case GL_INVALID_OPERATION:

-            context->recordInvalidOperation();

-            TRACE("\t! Error generated: invalid operation\n");

-            break;

-        case GL_OUT_OF_MEMORY:

-            context->recordOutOfMemory();

-            TRACE("\t! Error generated: out of memory\n");

-            break;

-        case GL_INVALID_FRAMEBUFFER_OPERATION_OES:

-            context->recordInvalidFramebufferOperation();

-            TRACE("\t! Error generated: invalid framebuffer operation\n");

-            break;

-		case GL_STACK_OVERFLOW:

-			context->recordMatrixStackOverflow();

-            TRACE("\t! Error generated: matrix stack overflow\n");

-            break;

-		case GL_STACK_UNDERFLOW:

-			context->recordMatrixStackUnderflow();

-            TRACE("\t! Error generated: matrix stack underflow\n");

-            break;

-        default: UNREACHABLE(errorCode);

-        }

-    }

-}

-}

-

-namespace es1

-{

-void ActiveTexture(GLenum texture);

-void AlphaFunc(GLenum func, GLclampf ref);

-void AlphaFuncx(GLenum func, GLclampx ref);

-void BindBuffer(GLenum target, GLuint buffer);

-void BindFramebuffer(GLenum target, GLuint framebuffer);

-void BindFramebufferOES(GLenum target, GLuint framebuffer);

-void BindRenderbufferOES(GLenum target, GLuint renderbuffer);

-void BindTexture(GLenum target, GLuint texture);

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

-void BlendEquationOES(GLenum mode);

-void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

-void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

-void BlendFunc(GLenum sfactor, GLenum dfactor);

-void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

-void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);

-void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);

-GLenum CheckFramebufferStatusOES(GLenum target);

-void Clear(GLbitfield mask);

-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

-void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);

-void ClearDepthf(GLclampf depth);

-void ClearDepthx(GLclampx depth);

-void ClearStencil(GLint s);

-void ClientActiveTexture(GLenum texture);

-void ClipPlanef(GLenum plane, const GLfloat *equation);

-void ClipPlanex(GLenum plane, const GLfixed *equation);

-void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

-void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);

-void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);

-void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);

-void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

-void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                          GLint border, GLsizei imageSize, const GLvoid* data);

-void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                             GLenum format, GLsizei imageSize, const GLvoid* data);

-void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);

-void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);

-void CullFace(GLenum mode);

-void DeleteBuffers(GLsizei n, const GLuint* buffers);

-void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);

-void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);

-void DeleteTextures(GLsizei n, const GLuint* textures);

-void DepthFunc(GLenum func);

-void DepthMask(GLboolean flag);

-void DepthRangex(GLclampx zNear, GLclampx zFar);

-void DepthRangef(GLclampf zNear, GLclampf zFar);

-void Disable(GLenum cap);

-void DisableClientState(GLenum array);

-void DrawArrays(GLenum mode, GLint first, GLsizei count);

-void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);

-void Enable(GLenum cap);

-void EnableClientState(GLenum array);

-void Finish(void);

-void Flush(void);

-void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);

-void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);

-void Fogf(GLenum pname, GLfloat param);

-void Fogfv(GLenum pname, const GLfloat *params);

-void Fogx(GLenum pname, GLfixed param);

-void Fogxv(GLenum pname, const GLfixed *params);

-void FrontFace(GLenum mode);

-void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);

-void GenerateMipmapOES(GLenum target);

-void GenBuffers(GLsizei n, GLuint* buffers);

-void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);

-void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);

-void GenTextures(GLsizei n, GLuint* textures);

-void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);

-void GetBooleanv(GLenum pname, GLboolean* params);

-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);

-void GetClipPlanef(GLenum pname, GLfloat eqn[4]);

-void GetClipPlanex(GLenum pname, GLfixed eqn[4]);

-GLenum GetError(void);

-void GetFixedv(GLenum pname, GLfixed *params);

-void GetFloatv(GLenum pname, GLfloat* params);

-void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);

-void GetIntegerv(GLenum pname, GLint* params);

-void GetLightfv(GLenum light, GLenum pname, GLfloat *params);

-void GetLightxv(GLenum light, GLenum pname, GLfixed *params);

-void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params);

-void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params);

-void GetPointerv(GLenum pname, GLvoid **params);

-const GLubyte* GetString(GLenum name);

-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);

-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);

-void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);

-void GetTexEnviv(GLenum env, GLenum pname, GLint *params);

-void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);

-void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);

-void Hint(GLenum target, GLenum mode);

-GLboolean IsBuffer(GLuint buffer);

-GLboolean IsEnabled(GLenum cap);

-GLboolean IsFramebufferOES(GLuint framebuffer);

-GLboolean IsTexture(GLuint texture);

-GLboolean IsRenderbufferOES(GLuint renderbuffer);

-void LightModelf(GLenum pname, GLfloat param);

-void LightModelfv(GLenum pname, const GLfloat *params);

-void LightModelx(GLenum pname, GLfixed param);

-void LightModelxv(GLenum pname, const GLfixed *params);

-void Lightf(GLenum light, GLenum pname, GLfloat param);

-void Lightfv(GLenum light, GLenum pname, const GLfloat *params);

-void Lightx(GLenum light, GLenum pname, GLfixed param);

-void Lightxv(GLenum light, GLenum pname, const GLfixed *params);

-void LineWidth(GLfloat width);

-void LineWidthx(GLfixed width);

-void LoadIdentity(void);

-void LoadMatrixf(const GLfloat *m);

-void LoadMatrixx(const GLfixed *m);

-void LogicOp(GLenum opcode);

-void Materialf(GLenum face, GLenum pname, GLfloat param);

-void Materialfv(GLenum face, GLenum pname, const GLfloat *params);

-void Materialx(GLenum face, GLenum pname, GLfixed param);

-void Materialxv(GLenum face, GLenum pname, const GLfixed *params);

-void MatrixMode(GLenum mode);

-void MultMatrixf(const GLfloat *m);

-void MultMatrixx(const GLfixed *m);

-void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);

-void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);

-void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz);

-void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz);

-void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);

-void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);

-void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);

-void PixelStorei(GLenum pname, GLint param);

-void PointParameterf(GLenum pname, GLfloat param);

-void PointParameterfv(GLenum pname, const GLfloat *params);

-void PointParameterx(GLenum pname, GLfixed param);

-void PointParameterxv(GLenum pname, const GLfixed *params);

-void PointSize(GLfloat size);

-void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);

-void PointSizex(GLfixed size);

-void PolygonOffset(GLfloat factor, GLfloat units);

-void PolygonOffsetx(GLfixed factor, GLfixed units);

-void PopMatrix(void);

-void PushMatrix(void);

-void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);

-void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);

-void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

-void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);

-void SampleCoverage(GLclampf value, GLboolean invert);

-void SampleCoveragex(GLclampx value, GLboolean invert);

-void Scalef(GLfloat x, GLfloat y, GLfloat z);

-void Scalex(GLfixed x, GLfixed y, GLfixed z);

-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);

-void ShadeModel(GLenum mode);

-void StencilFunc(GLenum func, GLint ref, GLuint mask);

-void StencilMask(GLuint mask);

-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);

-void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

-void TexEnvf(GLenum target, GLenum pname, GLfloat param);

-void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params);

-void TexEnvi(GLenum target, GLenum pname, GLint param);

-void TexEnvx(GLenum target, GLenum pname, GLfixed param);

-void TexEnviv(GLenum target, GLenum pname, const GLint *params);

-void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params);

-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                GLint border, GLenum format, GLenum type, const GLvoid* pixels);

-void TexParameterf(GLenum target, GLenum pname, GLfloat param);

-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);

-void TexParameteri(GLenum target, GLenum pname, GLint param);

-void TexParameteriv(GLenum target, GLenum pname, const GLint* params);

-void TexParameterx(GLenum target, GLenum pname, GLfixed param);

-void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params);

-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                   GLenum format, GLenum type, const GLvoid* pixels);

-void Translatef(GLfloat x, GLfloat y, GLfloat z);

-void Translatex(GLfixed x, GLfixed y, GLfixed z);

-void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);

-void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);

-void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);

-void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);

-void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);

-void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);

-void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);

-void DrawTexsvOES(const GLshort *coords);

-void DrawTexivOES(const GLint *coords);

-void DrawTexxvOES(const GLfixed *coords);

-void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);

-void DrawTexfvOES(const GLfloat *coords);

-}

-

-egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext);

-extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname);

-egl::Image *createBackBuffer(int width, int height, const egl::Config *config);

-egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType window, int width, int height);

-

-extern "C"

-{

-EGLAPI EGLint EGLAPIENTRY eglGetError(void)

-{

-	return libEGL->eglGetError();

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)

-{

-	return libEGL->eglGetDisplay(display_id);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

-{

-	return libEGL->eglInitialize(dpy, major, minor);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)

-{

-	return libEGL->eglTerminate(dpy);

-}

-

-EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)

-{

-	return libEGL->eglQueryString(dpy, name);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	return libEGL->eglGetConfigs(dpy, configs, config_size, num_config);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)

-{

-	return libEGL->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglGetConfigAttrib(dpy, config, attribute, value);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateWindowSurface(dpy, config, window, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)

-{

-	return libEGL->eglCreatePbufferSurface(dpy, config, attrib_list);

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)

-{

-	return libEGL->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)

-{

-	return libEGL->eglDestroySurface(dpy, surface);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglQuerySurface(dpy, surface, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)

-{

-	return libEGL->eglBindAPI(api);

-}

-

-EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)

-{

-	return libEGL->eglQueryAPI();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)

-{

-	return libEGL->eglWaitClient();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)

-{

-	return libEGL->eglReleaseThread();

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)

-{

-	return libEGL->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)

-{

-	return libEGL->eglSurfaceAttrib(dpy, surface, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	return libEGL->eglBindTexImage(dpy, surface, buffer);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

-{

-	return libEGL->eglReleaseTexImage(dpy, surface, buffer);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)

-{

-	return libEGL->eglSwapInterval(dpy, interval);

-}

-

-EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateContext(dpy, config, share_context, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)

-{

-	return libEGL->eglDestroyContext(dpy, ctx);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)

-{

-	return libEGL->eglMakeCurrent(dpy, draw, read, ctx);

-}

-

-EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)

-{

-	return libEGL->eglGetCurrentContext();

-}

-

-EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)

-{

-	return libEGL->eglGetCurrentSurface(readdraw);

-}

-

-EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)

-{

-	return libEGL->eglGetCurrentDisplay();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglQueryContext(dpy, ctx, attribute, value);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)

-{

-	return libEGL->eglWaitGL();

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)

-{

-	return libEGL->eglWaitNative(engine);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)

-{

-	return libEGL->eglSwapBuffers(dpy, surface);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)

-{

-	return libEGL->eglCopyBuffers(dpy, surface, target);

-}

-

-EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)

-{

-	return libEGL->eglDestroyImageKHR(dpy, image);

-}

-

-EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)

-{

-	return libEGL->eglGetProcAddress(procname);

-}

-

-EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)

-{

-	return libEGL->eglCreateSyncKHR(dpy, type, attrib_list);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)

-{

-	return libEGL->eglDestroySyncKHR(dpy, sync);

-}

-

-EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)

-{

-	return libEGL->eglClientWaitSyncKHR(dpy, sync, flags, timeout);

-}

-

-EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)

-{

-	return libEGL->eglGetSyncAttribKHR(dpy, sync, attribute, value);

-}

-

-GL_API void GL_APIENTRY glActiveTexture(GLenum texture)

-{

-	return es1::ActiveTexture(texture);

-}

-

-GL_API void GL_APIENTRY glAlphaFunc(GLenum func, GLclampf ref)

-{

-	return es1::AlphaFunc(func, ref);

-}

-

-GL_API void GL_APIENTRY glAlphaFuncx(GLenum func, GLclampx ref)

-{

-	return es1::AlphaFuncx(func, ref);

-}

-

-GL_API void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)

-{

-	return es1::BindBuffer(target, buffer);

-}

-

-GL_API void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)

-{

-	return es1::BindFramebuffer(target, framebuffer);

-}

-

-GL_API void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)

-{

-	return es1::BindFramebufferOES(target, framebuffer);

-}

-

-GL_API void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)

-{

-	return es1::BindRenderbufferOES(target, renderbuffer);

-}

-

-GL_API void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)

-{

-	return es1::BindTexture(target, texture);

-}

-

-GL_API void GL_APIENTRY glBlendEquationOES(GLenum mode)

-{

-	return es1::BlendEquationSeparateOES(mode, mode);

-}

-

-GL_API void GL_APIENTRY glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)

-{

-	return es1::BlendEquationSeparateOES(modeRGB, modeAlpha);

-}

-

-GL_API void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)

-{

-	return es1::BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);

-}

-

-GL_API void GL_APIENTRY glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)

-{

-	return es1::BlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);

-}

-

-GL_API void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)

-{

-	return es1::BufferData(target, size, data, usage);

-}

-

-GL_API void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)

-{

-	return es1::BufferSubData(target, offset, size, data);

-}

-

-GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)

-{

-	return es1::CheckFramebufferStatusOES(target);

-}

-

-GL_API void GL_APIENTRY glClear(GLbitfield mask)

-{

-	return es1::Clear(mask);

-}

-

-GL_API void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

-{

-	return es1::ClearColor(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)

-{

-	return es1::ClearColorx(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glClearDepthf(GLclampf depth)

-{

-	return es1::ClearDepthf(depth);

-}

-

-GL_API void GL_APIENTRY glClearDepthx(GLclampx depth)

-{

-	return es1::ClearDepthx(depth);

-}

-

-GL_API void GL_APIENTRY glClearStencil(GLint s)

-{

-	return es1::ClearStencil(s);

-}

-

-GL_API void GL_APIENTRY glClientActiveTexture(GLenum texture)

-{

-	return es1::ClientActiveTexture(texture);

-}

-

-GL_API void GL_APIENTRY glClipPlanef(GLenum plane, const GLfloat *equation)

-{

-	return es1::ClipPlanef(plane, equation);

-}

-

-GL_API void GL_APIENTRY glClipPlanex(GLenum plane, const GLfixed *equation)

-{

-	return es1::ClipPlanex(plane, equation);

-}

-

-GL_API void GL_APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)

-{

-	return es1::Color4f(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)

-{

-	return es1::Color4ub(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)

-{

-	return es1::Color4x(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)

-{

-	return es1::ColorMask(red, green, blue, alpha);

-}

-

-GL_API void GL_APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::ColorPointer(size, type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,

-                                               GLint border, GLsizei imageSize, const GLvoid* data)

-{

-	return es1::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);

-}

-

-GL_API void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                                  GLenum format, GLsizei imageSize, const GLvoid* data)

-{

-	return es1::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);

-}

-

-GL_API void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)

-{

-	return es1::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);

-}

-

-GL_API void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es1::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);

-}

-

-GL_API void GL_APIENTRY glCullFace(GLenum mode)

-{

-	return es1::CullFace(mode);

-}

-

-GL_API void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)

-{

-	return es1::DeleteBuffers(n, buffers);

-}

-

-GL_API void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)

-{

-	return es1::DeleteFramebuffersOES(n, framebuffers);

-}

-

-GL_API void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)

-{

-	return es1::DeleteRenderbuffersOES(n, renderbuffers);

-}

-

-GL_API void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)

-{

-	return es1::DeleteTextures(n, textures);

-}

-

-GL_API void GL_APIENTRY glDepthFunc(GLenum func)

-{

-	return es1::DepthFunc(func);

-}

-

-GL_API void GL_APIENTRY glDepthMask(GLboolean flag)

-{

-	return es1::DepthMask(flag);

-}

-

-GL_API void GL_APIENTRY glDepthRangex(GLclampx zNear, GLclampx zFar)

-{

-	return es1::DepthRangex(zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)

-{

-	return es1::DepthRangef(zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glDisable(GLenum cap)

-{

-	return es1::Disable(cap);

-}

-

-GL_API void GL_APIENTRY glDisableClientState(GLenum array)

-{

-	return es1::DisableClientState(array);

-}

-

-GL_API void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)

-{

-	return es1::DrawArrays(mode, first, count);

-}

-

-GL_API void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)

-{

-	return es1::DrawElements(mode, count, type, indices);

-}

-

-GL_API void GL_APIENTRY glEnable(GLenum cap)

-{

-	return es1::Enable(cap);

-}

-

-GL_API void GL_APIENTRY glEnableClientState(GLenum array)

-{

-	return es1::EnableClientState(array);

-}

-

-GL_API void GL_APIENTRY glFinish(void)

-{

-	return es1::Finish();

-}

-

-GL_API void GL_APIENTRY glFlush(void)

-{

-	return es1::Flush();

-}

-

-GL_API void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

-{

-	return es1::FramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);

-}

-

-GL_API void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)

-{

-	return es1::FramebufferTexture2DOES(target, attachment, textarget, texture, level);

-}

-

-GL_API void GL_APIENTRY glFogf(GLenum pname, GLfloat param)

-{

-	return es1::Fogf(pname, param);

-}

-

-GL_API void GL_APIENTRY glFogfv(GLenum pname, const GLfloat *params)

-{

-	return es1::Fogfv(pname, params);

-}

-

-GL_API void GL_APIENTRY glFogx(GLenum pname, GLfixed param)

-{

-	return es1::Fogx(pname, param);

-}

-

-GL_API void GL_APIENTRY glFogxv(GLenum pname, const GLfixed *params)

-{

-	return es1::Fogxv(pname, params);

-}

-

-GL_API void GL_APIENTRY glFrontFace(GLenum mode)

-{

-	return es1::FrontFace(mode);

-}

-

-GL_API void GL_APIENTRY glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	return es1::Frustumf(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	return es1::Frustumx(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glGenerateMipmapOES(GLenum target)

-{

-	return es1::GenerateMipmapOES(target);

-}

-

-GL_API void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)

-{

-	return es1::GenBuffers(n, buffers);

-}

-

-GL_API void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)

-{

-	return es1::GenFramebuffersOES(n, framebuffers);

-}

-

-GL_API void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)

-{

-	return es1::GenRenderbuffersOES(n, renderbuffers);

-}

-

-GL_API void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)

-{

-	return es1::GenTextures(n, textures);

-}

-

-GL_API void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)

-{

-	return es1::GetRenderbufferParameterivOES(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)

-{

-	return es1::GetBooleanv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es1::GetBufferParameteriv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetClipPlanef(GLenum pname, GLfloat eqn[4])

-{

-	return es1::GetClipPlanef(pname, eqn);

-}

-

-GL_API void GL_APIENTRY glGetClipPlanex(GLenum pname, GLfixed eqn[4])

-{

-	return es1::GetClipPlanex(pname, eqn);

-}

-

-GL_API GLenum GL_APIENTRY glGetError(void)

-{

-	return es1::GetError();

-}

-

-GL_API void GL_APIENTRY glGetFixedv(GLenum pname, GLfixed *params)

-{

-	return es1::GetFixedv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)

-{

-	return es1::GetFloatv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)

-{

-	return es1::GetFramebufferAttachmentParameterivOES(target, attachment, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)

-{

-	return es1::GetIntegerv(pname, params);

-}

-

-GL_API void GL_APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)

-{

-	return es1::GetLightfv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetLightxv(GLenum light, GLenum pname, GLfixed *params)

-{

-	return es1::GetLightxv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)

-{

-	return es1::GetMaterialfv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)

-{

-	return es1::GetMaterialxv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetPointerv(GLenum pname, GLvoid **params)

-{

-	return es1::GetPointerv(pname, params);

-}

-

-GL_API const GLubyte* GL_APIENTRY glGetString(GLenum name)

-{

-	return es1::GetString(name);

-}

-

-GL_API void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)

-{

-	return es1::GetTexParameterfv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)

-{

-	return es1::GetTexParameteriv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)

-{

-	return es1::GetTexEnvfv(env, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexEnviv(GLenum env, GLenum pname, GLint *params)

-{

-	return es1::GetTexEnviv(env, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)

-{

-	return es1::GetTexEnvxv(env, pname, params);

-}

-

-GL_API void GL_APIENTRY glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)

-{

-	return es1::GetTexParameterxv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glHint(GLenum target, GLenum mode)

-{

-	return es1::Hint(target, mode);

-}

-

-GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)

-{

-	return es1::IsBuffer(buffer);

-}

-

-GL_API GLboolean GL_APIENTRY glIsEnabled(GLenum cap)

-{

-	return es1::IsEnabled(cap);

-}

-

-GL_API GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)

-{

-	return es1::IsFramebufferOES(framebuffer);

-}

-

-GL_API GLboolean GL_APIENTRY glIsTexture(GLuint texture)

-{

-	return es1::IsTexture(texture);

-}

-

-GL_API GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)

-{

-	return es1::IsRenderbufferOES(renderbuffer);

-}

-

-GL_API void GL_APIENTRY glLightModelf(GLenum pname, GLfloat param)

-{

-	return es1::LightModelf(pname, param);

-}

-

-GL_API void GL_APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)

-{

-	return es1::LightModelfv(pname, params);

-}

-

-GL_API void GL_APIENTRY glLightModelx(GLenum pname, GLfixed param)

-{

-	return es1::LightModelx(pname, param);

-}

-

-GL_API void GL_APIENTRY glLightModelxv(GLenum pname, const GLfixed *params)

-{

-	return es1::LightModelxv(pname, params);

-}

-

-GL_API void GL_APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)

-{

-	return es1::Lightf(light, pname, param);

-}

-

-GL_API void GL_APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)

-{

-	return es1::Lightfv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glLightx(GLenum light, GLenum pname, GLfixed param)

-{

-	return es1::Lightx(light, pname, param);

-}

-

-GL_API void GL_APIENTRY glLightxv(GLenum light, GLenum pname, const GLfixed *params)

-{

-	return es1::Lightxv(light, pname, params);

-}

-

-GL_API void GL_APIENTRY glLineWidth(GLfloat width)

-{

-	return es1::LineWidth(width);

-}

-

-GL_API void GL_APIENTRY glLineWidthx(GLfixed width)

-{

-	return es1::LineWidthx(width);

-}

-

-GL_API void GL_APIENTRY glLoadIdentity(void)

-{

-	return es1::LoadIdentity();

-}

-

-GL_API void GL_APIENTRY glLoadMatrixf(const GLfloat *m)

-{

-	return es1::LoadMatrixf(m);

-}

-

-GL_API void GL_APIENTRY glLoadMatrixx(const GLfixed *m)

-{

-	return es1::LoadMatrixx(m);

-}

-

-GL_API void GL_APIENTRY glLogicOp(GLenum opcode)

-{

-	return es1::LogicOp(opcode);

-}

-

-GL_API void GL_APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)

-{

-	return es1::Materialf(face, pname, param);

-}

-

-GL_API void GL_APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)

-{

-	return es1::Materialfv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glMaterialx(GLenum face, GLenum pname, GLfixed param)

-{

-	return es1::Materialx(face, pname, param);

-}

-

-GL_API void GL_APIENTRY glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)

-{

-	return es1::Materialxv(face, pname, params);

-}

-

-GL_API void GL_APIENTRY glMatrixMode(GLenum mode)

-{

-	return es1::MatrixMode(mode);

-}

-

-GL_API void GL_APIENTRY glMultMatrixf(const GLfloat *m)

-{

-	return es1::MultMatrixf(m);

-}

-

-GL_API void GL_APIENTRY glMultMatrixx(const GLfixed *m)

-{

-	return es1::MultMatrixx(m);

-}

-

-GL_API void GL_APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)

-{

-	return es1::MultiTexCoord4f(target, s, t, r, q);

-}

-

-GL_API void GL_APIENTRY glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)

-{

-	return es1::MultiTexCoord4x(target, s, t, r, q);

-}

-

-GL_API void GL_APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)

-{

-	return es1::Normal3f(nx, ny, nz);

-}

-

-GL_API void GL_APIENTRY glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)

-{

-	return es1::Normal3x(nx, ny, nz);

-}

-

-GL_API void GL_APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::NormalPointer(type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)

-{

-	return es1::Orthof(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)

-{

-	return es1::Orthox(left, right, bottom, top, zNear, zFar);

-}

-

-GL_API void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)

-{

-	return es1::PixelStorei(pname, param);

-}

-

-GL_API void GL_APIENTRY glPointParameterf(GLenum pname, GLfloat param)

-{

-	return es1::PointParameterf(pname, param);

-}

-

-GL_API void GL_APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params)

-{

-	return es1::PointParameterfv(pname, params);

-}

-

-GL_API void GL_APIENTRY glPointParameterx(GLenum pname, GLfixed param)

-{

-	return es1::PointParameterx(pname, param);

-}

-

-GL_API void GL_APIENTRY glPointParameterxv(GLenum pname, const GLfixed *params)

-{

-	return es1::PointParameterxv(pname, params);

-}

-

-GL_API void GL_APIENTRY glPointSize(GLfloat size)

-{

-	return es1::PointSize(size);

-}

-

-GL_API void GL_APIENTRY glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::PointSizePointerOES(type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glPointSizex(GLfixed size)

-{

-	return es1::PointSizex(size);

-}

-

-GL_API void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)

-{

-	return es1::PolygonOffset(factor, units);

-}

-

-GL_API void GL_APIENTRY glPolygonOffsetx(GLfixed factor, GLfixed units)

-{

-	return es1::PolygonOffsetx(factor, units);

-}

-

-GL_API void GL_APIENTRY glPopMatrix(void)

-{

-	return es1::PopMatrix();

-}

-

-GL_API void GL_APIENTRY glPushMatrix(void)

-{

-	return es1::PushMatrix();

-}

-

-GL_API void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)

-{

-	return es1::ReadPixels(x, y, width, height, format, type, pixels);

-}

-

-GL_API void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)

-{

-	return es1::RenderbufferStorageOES(target, internalformat, width, height);

-}

-

-GL_API void GL_APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

-{

-	return es1::Rotatef(angle, x, y, z);

-}

-

-GL_API void GL_APIENTRY glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)

-{

-	return es1::Rotatex(angle, x, y, z);

-}

-

-GL_API void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)

-{

-	return es1::SampleCoverage(value, invert);

-}

-

-GL_API void GL_APIENTRY glSampleCoveragex(GLclampx value, GLboolean invert)

-{

-	return es1::SampleCoveragex(value, invert);

-}

-

-GL_API void GL_APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)

-{

-	return es1::Scalef(x, y, z);

-}

-

-GL_API void GL_APIENTRY glScalex(GLfixed x, GLfixed y, GLfixed z)

-{

-	return es1::Scalex(x, y, z);

-}

-

-GL_API void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es1::Scissor(x, y, width, height);

-}

-

-GL_API void GL_APIENTRY glShadeModel(GLenum mode)

-{

-	return es1::ShadeModel(mode);

-}

-

-GL_API void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)

-{

-	return es1::StencilFunc(func, ref, mask);

-}

-

-GL_API void GL_APIENTRY glStencilMask(GLuint mask)

-{

-	return es1::StencilMask(mask);

-}

-

-GL_API void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)

-{

-	return es1::StencilOp(fail, zfail, zpass);

-}

-

-GL_API void GL_APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::TexCoordPointer(size, type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)

-{

-	return es1::TexEnvf(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)

-{

-	return es1::TexEnvfv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)

-{

-	return es1::TexEnvi(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexEnvx(GLenum target, GLenum pname, GLfixed param)

-{

-	return es1::TexEnvx(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)

-{

-	return es1::TexEnviv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	return es1::TexEnvxv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,

-                                     GLint border, GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es1::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);

-}

-

-GL_API void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)

-{

-	return es1::TexParameterf(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)

-{

-	return es1::TexParameterfv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)

-{

-	return es1::TexParameteri(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)

-{

-	return es1::TexParameteriv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexParameterx(GLenum target, GLenum pname, GLfixed param)

-{

-	return es1::TexParameterx(target, pname, param);

-}

-

-GL_API void GL_APIENTRY glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)

-{

-	return es1::TexParameterxv(target, pname, params);

-}

-

-GL_API void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,

-                                        GLenum format, GLenum type, const GLvoid* pixels)

-{

-	return es1::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);

-}

-

-GL_API void GL_APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)

-{

-	return es1::Translatef(x, y, z);

-}

-

-GL_API void GL_APIENTRY glTranslatex(GLfixed x, GLfixed y, GLfixed z)

-{

-	return es1::Translatex(x, y, z);

-}

-

-GL_API void GL_APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)

-{

-	return es1::VertexPointer(size, type, stride, pointer);

-}

-

-GL_API void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)

-{

-	return es1::Viewport(x, y, width, height);

-}

-

-GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)

-{

-	return es1::EGLImageTargetTexture2DOES(target, image);

-}

-

-GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)

-{

-	return es1::EGLImageTargetRenderbufferStorageOES(target, image);

-}

-

-GL_API void GL_APIENTRY glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)

-{

-	return es1::DrawTexsOES(x,y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)

-{

-	return es1::DrawTexiOES(x,y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)

-{

-	return es1::DrawTexxOES(x,y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexsvOES(const GLshort *coords)

-{

-	return es1::DrawTexsvOES(coords);

-}

-

-GL_API void GL_APIENTRY glDrawTexivOES(const GLint *coords)

-{

-	return es1::DrawTexivOES(coords);

-}

-

-GL_API void GL_APIENTRY glDrawTexxvOES(const GLfixed *coords)

-{

-	return es1::DrawTexxvOES(coords);

-}

-

-GL_API void GL_APIENTRY glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)

-{

-	return es1::DrawTexfOES(x, y, z, width, height);

-}

-

-GL_API void GL_APIENTRY glDrawTexfvOES(const GLfloat *coords)

-{

-	return es1::DrawTexfvOES(coords);

-}

-

-}

-

-LibGLES_CMexports::LibGLES_CMexports()

-{

-	this->glActiveTexture = es1::ActiveTexture;

-	this->glAlphaFunc = es1::AlphaFunc;

-	this->glAlphaFuncx = es1::AlphaFuncx;

-	this->glBindBuffer = es1::BindBuffer;

-	this->glBindFramebuffer = es1::BindFramebuffer;

-	this->glBindFramebufferOES = es1::BindFramebufferOES;

-	this->glBindRenderbufferOES = es1::BindRenderbufferOES;

-	this->glBindTexture = es1::BindTexture;

-	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;

-	this->glBlendEquationOES = es1::BlendEquationOES;

-	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;

-	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;

-	this->glBlendFunc = es1::BlendFunc;

-	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;

-	this->glBufferData = es1::BufferData;

-	this->glBufferSubData = es1::BufferSubData;

-	this->glCheckFramebufferStatusOES = es1::CheckFramebufferStatusOES;

-	this->glClear = es1::Clear;

-	this->glClearColor = es1::ClearColor;

-	this->glClearColorx = es1::ClearColorx;

-	this->glClearDepthf = es1::ClearDepthf;

-	this->glClearDepthx = es1::ClearDepthx;

-	this->glClearStencil = es1::ClearStencil;

-	this->glClientActiveTexture = es1::ClientActiveTexture;

-	this->glClipPlanef = es1::ClipPlanef;

-	this->glClipPlanex = es1::ClipPlanex;

-	this->glColor4f = es1::Color4f;

-	this->glColor4ub = es1::Color4ub;

-	this->glColor4x = es1::Color4x;

-	this->glColorMask = es1::ColorMask;

-	this->glColorPointer = es1::ColorPointer;

-	this->glCompressedTexImage2D = es1::CompressedTexImage2D;

-	this->glCompressedTexSubImage2D = es1::CompressedTexSubImage2D;

-	this->glCopyTexImage2D = es1::CopyTexImage2D;

-	this->glCopyTexSubImage2D = es1::CopyTexSubImage2D;

-	this->glCullFace = es1::CullFace;

-	this->glDeleteBuffers = es1::DeleteBuffers;

-	this->glDeleteFramebuffersOES = es1::DeleteFramebuffersOES;

-	this->glDeleteRenderbuffersOES = es1::DeleteRenderbuffersOES;

-	this->glDeleteTextures = es1::DeleteTextures;

-	this->glDepthFunc = es1::DepthFunc;

-	this->glDepthMask = es1::DepthMask;

-	this->glDepthRangex = es1::DepthRangex;

-	this->glDepthRangef = es1::DepthRangef;

-	this->glDisable = es1::Disable;

-	this->glDisableClientState = es1::DisableClientState;

-	this->glDrawArrays = es1::DrawArrays;

-	this->glDrawElements = es1::DrawElements;

-	this->glEnable = es1::Enable;

-	this->glEnableClientState = es1::EnableClientState;

-	this->glFinish = es1::Finish;

-	this->glFlush = es1::Flush;

-	this->glFramebufferRenderbufferOES = es1::FramebufferRenderbufferOES;

-	this->glFramebufferTexture2DOES = es1::FramebufferTexture2DOES;

-	this->glFogf = es1::Fogf;

-	this->glFogfv = es1::Fogfv;

-	this->glFogx = es1::Fogx;

-	this->glFogxv = es1::Fogxv;

-	this->glFrontFace = es1::FrontFace;

-	this->glFrustumf = es1::Frustumf;

-	this->glFrustumx = es1::Frustumx;

-	this->glGenerateMipmapOES = es1::GenerateMipmapOES;

-	this->glGenBuffers = es1::GenBuffers;

-	this->glGenFramebuffersOES = es1::GenFramebuffersOES;

-	this->glGenRenderbuffersOES = es1::GenRenderbuffersOES;

-	this->glGenTextures = es1::GenTextures;

-	this->glGetRenderbufferParameterivOES = es1::GetRenderbufferParameterivOES;

-	this->glGetBooleanv = es1::GetBooleanv;

-	this->glGetBufferParameteriv = es1::GetBufferParameteriv;

-	this->glGetClipPlanef = es1::GetClipPlanef;

-	this->glGetClipPlanex = es1::GetClipPlanex;

-	this->glGetError = es1::GetError;

-	this->glGetFixedv = es1::GetFixedv;

-	this->glGetFloatv = es1::GetFloatv;

-	this->glGetFramebufferAttachmentParameterivOES = es1::GetFramebufferAttachmentParameterivOES;

-	this->glGetIntegerv = es1::GetIntegerv;

-	this->glGetLightfv = es1::GetLightfv;

-	this->glGetLightxv = es1::GetLightxv;

-	this->glGetMaterialfv = es1::GetMaterialfv;

-	this->glGetMaterialxv = es1::GetMaterialxv;

-	this->glGetPointerv = es1::GetPointerv;

-	this->glGetString = es1::GetString;

-	this->glGetTexParameterfv = es1::GetTexParameterfv;

-	this->glGetTexParameteriv = es1::GetTexParameteriv;

-	this->glGetTexEnvfv = es1::GetTexEnvfv;

-	this->glGetTexEnviv = es1::GetTexEnviv;

-	this->glGetTexEnvxv = es1::GetTexEnvxv;

-	this->glGetTexParameterxv = es1::GetTexParameterxv;

-	this->glHint = es1::Hint;

-	this->glIsBuffer = es1::IsBuffer;

-	this->glIsEnabled = es1::IsEnabled;

-	this->glIsFramebufferOES = es1::IsFramebufferOES;

-	this->glIsTexture = es1::IsTexture;

-	this->glIsRenderbufferOES = es1::IsRenderbufferOES;

-	this->glLightModelf = es1::LightModelf;

-	this->glLightModelfv = es1::LightModelfv;

-	this->glLightModelx = es1::LightModelx;

-	this->glLightModelxv = es1::LightModelxv;

-	this->glLightf = es1::Lightf;

-	this->glLightfv = es1::Lightfv;

-	this->glLightx = es1::Lightx;

-	this->glLightxv = es1::Lightxv;

-	this->glLineWidth = es1::LineWidth;

-	this->glLineWidthx = es1::LineWidthx;

-	this->glLoadIdentity = es1::LoadIdentity;

-	this->glLoadMatrixf = es1::LoadMatrixf;

-	this->glLoadMatrixx = es1::LoadMatrixx;

-	this->glLogicOp = es1::LogicOp;

-	this->glMaterialf = es1::Materialf;

-	this->glMaterialfv = es1::Materialfv;

-	this->glMaterialx = es1::Materialx;

-	this->glMaterialxv = es1::Materialxv;

-	this->glMatrixMode = es1::MatrixMode;

-	this->glMultMatrixf = es1::MultMatrixf;

-	this->glMultMatrixx = es1::MultMatrixx;

-	this->glMultiTexCoord4f = es1::MultiTexCoord4f;

-	this->glMultiTexCoord4x = es1::MultiTexCoord4x;

-	this->glNormal3f = es1::Normal3f;

-	this->glNormal3x = es1::Normal3x;

-	this->glNormalPointer = es1::NormalPointer;

-	this->glOrthof = es1::Orthof;

-	this->glOrthox = es1::Orthox;

-	this->glPixelStorei = es1::PixelStorei;

-	this->glPointParameterf = es1::PointParameterf;

-	this->glPointParameterfv = es1::PointParameterfv;

-	this->glPointParameterx = es1::PointParameterx;

-	this->glPointParameterxv = es1::PointParameterxv;

-	this->glPointSize = es1::PointSize;

-	this->glPointSizePointerOES = es1::PointSizePointerOES;

-	this->glPointSizex = es1::PointSizex;

-	this->glPolygonOffset = es1::PolygonOffset;

-	this->glPolygonOffsetx = es1::PolygonOffsetx;

-	this->glPopMatrix = es1::PopMatrix;

-	this->glPushMatrix = es1::PushMatrix;

-	this->glReadPixels = es1::ReadPixels;

-	this->glRenderbufferStorageOES = es1::RenderbufferStorageOES;

-	this->glRotatef = es1::Rotatef;

-	this->glRotatex = es1::Rotatex;

-	this->glSampleCoverage = es1::SampleCoverage;

-	this->glSampleCoveragex = es1::SampleCoveragex;

-	this->glScalef = es1::Scalef;

-	this->glScalex = es1::Scalex;

-	this->glScissor = es1::Scissor;

-	this->glShadeModel = es1::ShadeModel;

-	this->glStencilFunc = es1::StencilFunc;

-	this->glStencilMask = es1::StencilMask;

-	this->glStencilOp = es1::StencilOp;

-	this->glTexCoordPointer = es1::TexCoordPointer;

-	this->glTexEnvf = es1::TexEnvf;

-	this->glTexEnvfv = es1::TexEnvfv;

-	this->glTexEnvi = es1::TexEnvi;

-	this->glTexEnvx = es1::TexEnvx;

-	this->glTexEnviv = es1::TexEnviv;

-	this->glTexEnvxv = es1::TexEnvxv;

-	this->glTexImage2D = es1::TexImage2D;

-	this->glTexParameterf = es1::TexParameterf;

-	this->glTexParameterfv = es1::TexParameterfv;

-	this->glTexParameteri = es1::TexParameteri;

-	this->glTexParameteriv = es1::TexParameteriv;

-	this->glTexParameterx = es1::TexParameterx;

-	this->glTexParameterxv = es1::TexParameterxv;

-	this->glTexSubImage2D = es1::TexSubImage2D;

-	this->glTranslatef = es1::Translatef;

-	this->glTranslatex = es1::Translatex;

-	this->glVertexPointer = es1::VertexPointer;

-	this->glViewport = es1::Viewport;

-	this->glEGLImageTargetTexture2DOES = es1::EGLImageTargetTexture2DOES;

-	this->glEGLImageTargetRenderbufferStorageOES = es1::EGLImageTargetRenderbufferStorageOES;

-	this->glDrawTexsOES = es1::DrawTexsOES;

-	this->glDrawTexiOES = es1::DrawTexiOES;

-	this->glDrawTexxOES = es1::DrawTexxOES;

-	this->glDrawTexsvOES = es1::DrawTexsvOES;

-	this->glDrawTexivOES = es1::DrawTexivOES;

-	this->glDrawTexxvOES = es1::DrawTexxvOES;

-	this->glDrawTexfOES = es1::DrawTexfOES;

-	this->glDrawTexfvOES = es1::DrawTexfvOES;

-

-	this->es1CreateContext = ::es1CreateContext;

-	this->es1GetProcAddress = ::es1GetProcAddress;

-	this->createBackBuffer = ::createBackBuffer;

-	this->createDepthStencil = ::createDepthStencil;

-	this->createFrameBuffer = ::createFrameBuffer;

-}

-

-extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader()

-{

-	static LibGLES_CMexports libGLES_CM;

-	return &libGLES_CM;

-}

-

-LibEGL libEGL;

+// 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.
+
+// main.cpp: DLL entry point and management of thread-local data.
+
+#include "main.h"
+
+#include "libGLES_CM.hpp"
+#include "Framebuffer.h"
+#include "libEGL/Surface.h"
+#include "Common/Thread.hpp"
+#include "Common/SharedLibrary.hpp"
+#include "common/debug.h"
+
+#include <GLES/glext.h>
+
+#if !defined(_MSC_VER)
+#define CONSTRUCTOR __attribute__((constructor))
+#define DESTRUCTOR __attribute__((destructor))
+#else
+#define CONSTRUCTOR
+#define DESTRUCTOR
+#endif
+
+static void glAttachThread()
+{
+	TRACE("()");
+}
+
+static void glDetachThread()
+{
+	TRACE("()");
+}
+
+CONSTRUCTOR static void glAttachProcess()
+{
+	TRACE("()");
+
+	glAttachThread();
+}
+
+DESTRUCTOR static void glDetachProcess()
+{
+	TRACE("()");
+
+	glDetachThread();
+}
+
+#if defined(_WIN32)
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+	switch(reason)
+	{
+	case DLL_PROCESS_ATTACH:
+		glAttachProcess();
+		break;
+	case DLL_THREAD_ATTACH:
+		glAttachThread();
+		break;
+	case DLL_THREAD_DETACH:
+		glDetachThread();
+		break;
+	case DLL_PROCESS_DETACH:
+		glDetachProcess();
+		break;
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+#endif
+
+namespace es1
+{
+es1::Context *getContext()
+{
+	egl::Context *context = libEGL->clientGetCurrentContext();
+
+	if(context && context->getClientVersion() == 1)
+	{
+		return static_cast<es1::Context*>(context);
+	}
+
+	return 0;
+}
+
+Device *getDevice()
+{
+	Context *context = getContext();
+
+	return context ? context->getDevice() : 0;
+}
+
+// Records an error code
+void error(GLenum errorCode)
+{
+	es1::Context *context = es1::getContext();
+
+	if(context)
+	{
+		switch(errorCode)
+		{
+		case GL_INVALID_ENUM:
+			context->recordInvalidEnum();
+			TRACE("\t! Error generated: invalid enum\n");
+			break;
+		case GL_INVALID_VALUE:
+			context->recordInvalidValue();
+			TRACE("\t! Error generated: invalid value\n");
+			break;
+		case GL_INVALID_OPERATION:
+			context->recordInvalidOperation();
+			TRACE("\t! Error generated: invalid operation\n");
+			break;
+		case GL_OUT_OF_MEMORY:
+			context->recordOutOfMemory();
+			TRACE("\t! Error generated: out of memory\n");
+			break;
+		case GL_INVALID_FRAMEBUFFER_OPERATION_OES:
+			context->recordInvalidFramebufferOperation();
+			TRACE("\t! Error generated: invalid framebuffer operation\n");
+			break;
+		case GL_STACK_OVERFLOW:
+			context->recordMatrixStackOverflow();
+			TRACE("\t! Error generated: matrix stack overflow\n");
+			break;
+		case GL_STACK_UNDERFLOW:
+			context->recordMatrixStackUnderflow();
+			TRACE("\t! Error generated: matrix stack underflow\n");
+			break;
+		default: UNREACHABLE(errorCode);
+		}
+	}
+}
+}
+
+namespace es1
+{
+void ActiveTexture(GLenum texture);
+void AlphaFunc(GLenum func, GLclampf ref);
+void AlphaFuncx(GLenum func, GLclampx ref);
+void BindBuffer(GLenum target, GLuint buffer);
+void BindFramebuffer(GLenum target, GLuint framebuffer);
+void BindFramebufferOES(GLenum target, GLuint framebuffer);
+void BindRenderbufferOES(GLenum target, GLuint renderbuffer);
+void BindTexture(GLenum target, GLuint texture);
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+void BlendEquationOES(GLenum mode);
+void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void BlendFunc(GLenum sfactor, GLenum dfactor);
+void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GLenum CheckFramebufferStatusOES(GLenum target);
+void Clear(GLbitfield mask);
+void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+void ClearDepthf(GLclampf depth);
+void ClearDepthx(GLclampx depth);
+void ClearStencil(GLint s);
+void ClientActiveTexture(GLenum texture);
+void ClipPlanef(GLenum plane, const GLfloat *equation);
+void ClipPlanex(GLenum plane, const GLfixed *equation);
+void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                          GLint border, GLsizei imageSize, const GLvoid* data);
+void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                             GLenum format, GLsizei imageSize, const GLvoid* data);
+void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+void CullFace(GLenum mode);
+void DeleteBuffers(GLsizei n, const GLuint* buffers);
+void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
+void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
+void DeleteTextures(GLsizei n, const GLuint* textures);
+void DepthFunc(GLenum func);
+void DepthMask(GLboolean flag);
+void DepthRangex(GLclampx zNear, GLclampx zFar);
+void DepthRangef(GLclampf zNear, GLclampf zFar);
+void Disable(GLenum cap);
+void DisableClientState(GLenum array);
+void DrawArrays(GLenum mode, GLint first, GLsizei count);
+void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+void Enable(GLenum cap);
+void EnableClientState(GLenum array);
+void Finish(void);
+void Flush(void);
+void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void Fogf(GLenum pname, GLfloat param);
+void Fogfv(GLenum pname, const GLfloat *params);
+void Fogx(GLenum pname, GLfixed param);
+void Fogxv(GLenum pname, const GLfixed *params);
+void FrontFace(GLenum mode);
+void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void GenerateMipmapOES(GLenum target);
+void GenBuffers(GLsizei n, GLuint* buffers);
+void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);
+void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
+void GenTextures(GLsizei n, GLuint* textures);
+void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
+void GetBooleanv(GLenum pname, GLboolean* params);
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetClipPlanef(GLenum pname, GLfloat eqn[4]);
+void GetClipPlanex(GLenum pname, GLfixed eqn[4]);
+GLenum GetError(void);
+void GetFixedv(GLenum pname, GLfixed *params);
+void GetFloatv(GLenum pname, GLfloat* params);
+void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+void GetIntegerv(GLenum pname, GLint* params);
+void GetLightfv(GLenum light, GLenum pname, GLfloat *params);
+void GetLightxv(GLenum light, GLenum pname, GLfixed *params);
+void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
+void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
+void GetPointerv(GLenum pname, GLvoid **params);
+const GLubyte* GetString(GLenum name);
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);
+void GetTexEnviv(GLenum env, GLenum pname, GLint *params);
+void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);
+void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
+void Hint(GLenum target, GLenum mode);
+GLboolean IsBuffer(GLuint buffer);
+GLboolean IsEnabled(GLenum cap);
+GLboolean IsFramebufferOES(GLuint framebuffer);
+GLboolean IsTexture(GLuint texture);
+GLboolean IsRenderbufferOES(GLuint renderbuffer);
+void LightModelf(GLenum pname, GLfloat param);
+void LightModelfv(GLenum pname, const GLfloat *params);
+void LightModelx(GLenum pname, GLfixed param);
+void LightModelxv(GLenum pname, const GLfixed *params);
+void Lightf(GLenum light, GLenum pname, GLfloat param);
+void Lightfv(GLenum light, GLenum pname, const GLfloat *params);
+void Lightx(GLenum light, GLenum pname, GLfixed param);
+void Lightxv(GLenum light, GLenum pname, const GLfixed *params);
+void LineWidth(GLfloat width);
+void LineWidthx(GLfixed width);
+void LoadIdentity(void);
+void LoadMatrixf(const GLfloat *m);
+void LoadMatrixx(const GLfixed *m);
+void LogicOp(GLenum opcode);
+void Materialf(GLenum face, GLenum pname, GLfloat param);
+void Materialfv(GLenum face, GLenum pname, const GLfloat *params);
+void Materialx(GLenum face, GLenum pname, GLfixed param);
+void Materialxv(GLenum face, GLenum pname, const GLfixed *params);
+void MatrixMode(GLenum mode);
+void MultMatrixf(const GLfloat *m);
+void MultMatrixx(const GLfixed *m);
+void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz);
+void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz);
+void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
+void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void PixelStorei(GLenum pname, GLint param);
+void PointParameterf(GLenum pname, GLfloat param);
+void PointParameterfv(GLenum pname, const GLfloat *params);
+void PointParameterx(GLenum pname, GLfixed param);
+void PointParameterxv(GLenum pname, const GLfixed *params);
+void PointSize(GLfloat size);
+void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);
+void PointSizex(GLfixed size);
+void PolygonOffset(GLfloat factor, GLfloat units);
+void PolygonOffsetx(GLfixed factor, GLfixed units);
+void PopMatrix(void);
+void PushMatrix(void);
+void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+void SampleCoverage(GLclampf value, GLboolean invert);
+void SampleCoveragex(GLclampx value, GLboolean invert);
+void Scalef(GLfloat x, GLfloat y, GLfloat z);
+void Scalex(GLfixed x, GLfixed y, GLfixed z);
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void ShadeModel(GLenum mode);
+void StencilFunc(GLenum func, GLint ref, GLuint mask);
+void StencilMask(GLuint mask);
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void TexEnvf(GLenum target, GLenum pname, GLfloat param);
+void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
+void TexEnvi(GLenum target, GLenum pname, GLint param);
+void TexEnvx(GLenum target, GLenum pname, GLfixed param);
+void TexEnviv(GLenum target, GLenum pname, const GLint *params);
+void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+void TexParameterf(GLenum target, GLenum pname, GLfloat param);
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+void TexParameteri(GLenum target, GLenum pname, GLint param);
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params);
+void TexParameterx(GLenum target, GLenum pname, GLfixed param);
+void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type, const GLvoid* pixels);
+void Translatef(GLfloat x, GLfloat y, GLfloat z);
+void Translatex(GLfixed x, GLfixed y, GLfixed z);
+void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);
+void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+void DrawTexsvOES(const GLshort *coords);
+void DrawTexivOES(const GLint *coords);
+void DrawTexxvOES(const GLfixed *coords);
+void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+void DrawTexfvOES(const GLfloat *coords);
+}
+
+egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext);
+extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname);
+egl::Image *createBackBuffer(int width, int height, const egl::Config *config);
+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType window, int width, int height);
+
+extern "C"
+{
+EGLAPI EGLint EGLAPIENTRY eglGetError(void)
+{
+	return libEGL->eglGetError();
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
+{
+	return libEGL->eglGetDisplay(display_id);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+	return libEGL->eglInitialize(dpy, major, minor);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
+{
+	return libEGL->eglTerminate(dpy);
+}
+
+EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
+{
+	return libEGL->eglQueryString(dpy, name);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	return libEGL->eglGetConfigs(dpy, configs, config_size, num_config);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	return libEGL->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglGetConfigAttrib(dpy, config, attribute, value);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateWindowSurface(dpy, config, window, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+	return libEGL->eglCreatePbufferSurface(dpy, config, attrib_list);
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+	return libEGL->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+	return libEGL->eglDestroySurface(dpy, surface);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglQuerySurface(dpy, surface, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
+{
+	return libEGL->eglBindAPI(api);
+}
+
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)
+{
+	return libEGL->eglQueryAPI();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)
+{
+	return libEGL->eglWaitClient();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)
+{
+	return libEGL->eglReleaseThread();
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+	return libEGL->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+	return libEGL->eglSurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	return libEGL->eglBindTexImage(dpy, surface, buffer);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	return libEGL->eglReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+	return libEGL->eglSwapInterval(dpy, interval);
+}
+
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateContext(dpy, config, share_context, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+	return libEGL->eglDestroyContext(dpy, ctx);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+	return libEGL->eglMakeCurrent(dpy, draw, read, ctx);
+}
+
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)
+{
+	return libEGL->eglGetCurrentContext();
+}
+
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
+{
+	return libEGL->eglGetCurrentSurface(readdraw);
+}
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
+{
+	return libEGL->eglGetCurrentDisplay();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglQueryContext(dpy, ctx, attribute, value);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
+{
+	return libEGL->eglWaitGL();
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
+{
+	return libEGL->eglWaitNative(engine);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+	return libEGL->eglSwapBuffers(dpy, surface);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+	return libEGL->eglCopyBuffers(dpy, surface, target);
+}
+
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+	return libEGL->eglDestroyImageKHR(dpy, image);
+}
+
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+	return libEGL->eglGetProcAddress(procname);
+}
+
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+	return libEGL->eglCreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+	return libEGL->eglDestroySyncKHR(dpy, sync);
+}
+
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+	return libEGL->eglClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+	return libEGL->eglGetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+GL_API void GL_APIENTRY glActiveTexture(GLenum texture)
+{
+	return es1::ActiveTexture(texture);
+}
+
+GL_API void GL_APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
+{
+	return es1::AlphaFunc(func, ref);
+}
+
+GL_API void GL_APIENTRY glAlphaFuncx(GLenum func, GLclampx ref)
+{
+	return es1::AlphaFuncx(func, ref);
+}
+
+GL_API void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+	return es1::BindBuffer(target, buffer);
+}
+
+GL_API void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+	return es1::BindFramebuffer(target, framebuffer);
+}
+
+GL_API void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+	return es1::BindFramebufferOES(target, framebuffer);
+}
+
+GL_API void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+	return es1::BindRenderbufferOES(target, renderbuffer);
+}
+
+GL_API void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+	return es1::BindTexture(target, texture);
+}
+
+GL_API void GL_APIENTRY glBlendEquationOES(GLenum mode)
+{
+	return es1::BlendEquationSeparateOES(mode, mode);
+}
+
+GL_API void GL_APIENTRY glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+	return es1::BlendEquationSeparateOES(modeRGB, modeAlpha);
+}
+
+GL_API void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+	return es1::BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
+}
+
+GL_API void GL_APIENTRY glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+	return es1::BlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+GL_API void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+	return es1::BufferData(target, size, data, usage);
+}
+
+GL_API void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+	return es1::BufferSubData(target, offset, size, data);
+}
+
+GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)
+{
+	return es1::CheckFramebufferStatusOES(target);
+}
+
+GL_API void GL_APIENTRY glClear(GLbitfield mask)
+{
+	return es1::Clear(mask);
+}
+
+GL_API void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+	return es1::ClearColor(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+	return es1::ClearColorx(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glClearDepthf(GLclampf depth)
+{
+	return es1::ClearDepthf(depth);
+}
+
+GL_API void GL_APIENTRY glClearDepthx(GLclampx depth)
+{
+	return es1::ClearDepthx(depth);
+}
+
+GL_API void GL_APIENTRY glClearStencil(GLint s)
+{
+	return es1::ClearStencil(s);
+}
+
+GL_API void GL_APIENTRY glClientActiveTexture(GLenum texture)
+{
+	return es1::ClientActiveTexture(texture);
+}
+
+GL_API void GL_APIENTRY glClipPlanef(GLenum plane, const GLfloat *equation)
+{
+	return es1::ClipPlanef(plane, equation);
+}
+
+GL_API void GL_APIENTRY glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+	return es1::ClipPlanex(plane, equation);
+}
+
+GL_API void GL_APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+	return es1::Color4f(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+	return es1::Color4ub(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+	return es1::Color4x(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+	return es1::ColorMask(red, green, blue, alpha);
+}
+
+GL_API void GL_APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::ColorPointer(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+                                               GLint border, GLsizei imageSize, const GLvoid* data)
+{
+	return es1::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+GL_API void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                                  GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+	return es1::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+GL_API void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+	return es1::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+GL_API void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es1::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GL_API void GL_APIENTRY glCullFace(GLenum mode)
+{
+	return es1::CullFace(mode);
+}
+
+GL_API void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+	return es1::DeleteBuffers(n, buffers);
+}
+
+GL_API void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+	return es1::DeleteFramebuffersOES(n, framebuffers);
+}
+
+GL_API void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+	return es1::DeleteRenderbuffersOES(n, renderbuffers);
+}
+
+GL_API void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+	return es1::DeleteTextures(n, textures);
+}
+
+GL_API void GL_APIENTRY glDepthFunc(GLenum func)
+{
+	return es1::DepthFunc(func);
+}
+
+GL_API void GL_APIENTRY glDepthMask(GLboolean flag)
+{
+	return es1::DepthMask(flag);
+}
+
+GL_API void GL_APIENTRY glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+	return es1::DepthRangex(zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+	return es1::DepthRangef(zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glDisable(GLenum cap)
+{
+	return es1::Disable(cap);
+}
+
+GL_API void GL_APIENTRY glDisableClientState(GLenum array)
+{
+	return es1::DisableClientState(array);
+}
+
+GL_API void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+	return es1::DrawArrays(mode, first, count);
+}
+
+GL_API void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+	return es1::DrawElements(mode, count, type, indices);
+}
+
+GL_API void GL_APIENTRY glEnable(GLenum cap)
+{
+	return es1::Enable(cap);
+}
+
+GL_API void GL_APIENTRY glEnableClientState(GLenum array)
+{
+	return es1::EnableClientState(array);
+}
+
+GL_API void GL_APIENTRY glFinish(void)
+{
+	return es1::Finish();
+}
+
+GL_API void GL_APIENTRY glFlush(void)
+{
+	return es1::Flush();
+}
+
+GL_API void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+	return es1::FramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+GL_API void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+	return es1::FramebufferTexture2DOES(target, attachment, textarget, texture, level);
+}
+
+GL_API void GL_APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+	return es1::Fogf(pname, param);
+}
+
+GL_API void GL_APIENTRY glFogfv(GLenum pname, const GLfloat *params)
+{
+	return es1::Fogfv(pname, params);
+}
+
+GL_API void GL_APIENTRY glFogx(GLenum pname, GLfixed param)
+{
+	return es1::Fogx(pname, param);
+}
+
+GL_API void GL_APIENTRY glFogxv(GLenum pname, const GLfixed *params)
+{
+	return es1::Fogxv(pname, params);
+}
+
+GL_API void GL_APIENTRY glFrontFace(GLenum mode)
+{
+	return es1::FrontFace(mode);
+}
+
+GL_API void GL_APIENTRY glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	return es1::Frustumf(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	return es1::Frustumx(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glGenerateMipmapOES(GLenum target)
+{
+	return es1::GenerateMipmapOES(target);
+}
+
+GL_API void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+	return es1::GenBuffers(n, buffers);
+}
+
+GL_API void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+	return es1::GenFramebuffersOES(n, framebuffers);
+}
+
+GL_API void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+	return es1::GenRenderbuffersOES(n, renderbuffers);
+}
+
+GL_API void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
+{
+	return es1::GenTextures(n, textures);
+}
+
+GL_API void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+	return es1::GetRenderbufferParameterivOES(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
+{
+	return es1::GetBooleanv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es1::GetBufferParameteriv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+	return es1::GetClipPlanef(pname, eqn);
+}
+
+GL_API void GL_APIENTRY glGetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+	return es1::GetClipPlanex(pname, eqn);
+}
+
+GL_API GLenum GL_APIENTRY glGetError(void)
+{
+	return es1::GetError();
+}
+
+GL_API void GL_APIENTRY glGetFixedv(GLenum pname, GLfixed *params)
+{
+	return es1::GetFixedv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
+{
+	return es1::GetFloatv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+	return es1::GetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
+{
+	return es1::GetIntegerv(pname, params);
+}
+
+GL_API void GL_APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+	return es1::GetLightfv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+	return es1::GetLightxv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+	return es1::GetMaterialfv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+	return es1::GetMaterialxv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetPointerv(GLenum pname, GLvoid **params)
+{
+	return es1::GetPointerv(pname, params);
+}
+
+GL_API const GLubyte* GL_APIENTRY glGetString(GLenum name)
+{
+	return es1::GetString(name);
+}
+
+GL_API void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+	return es1::GetTexParameterfv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+	return es1::GetTexParameteriv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+	return es1::GetTexEnvfv(env, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+	return es1::GetTexEnviv(env, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+	return es1::GetTexEnvxv(env, pname, params);
+}
+
+GL_API void GL_APIENTRY glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+	return es1::GetTexParameterxv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glHint(GLenum target, GLenum mode)
+{
+	return es1::Hint(target, mode);
+}
+
+GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
+{
+	return es1::IsBuffer(buffer);
+}
+
+GL_API GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
+{
+	return es1::IsEnabled(cap);
+}
+
+GL_API GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)
+{
+	return es1::IsFramebufferOES(framebuffer);
+}
+
+GL_API GLboolean GL_APIENTRY glIsTexture(GLuint texture)
+{
+	return es1::IsTexture(texture);
+}
+
+GL_API GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)
+{
+	return es1::IsRenderbufferOES(renderbuffer);
+}
+
+GL_API void GL_APIENTRY glLightModelf(GLenum pname, GLfloat param)
+{
+	return es1::LightModelf(pname, param);
+}
+
+GL_API void GL_APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
+{
+	return es1::LightModelfv(pname, params);
+}
+
+GL_API void GL_APIENTRY glLightModelx(GLenum pname, GLfixed param)
+{
+	return es1::LightModelx(pname, param);
+}
+
+GL_API void GL_APIENTRY glLightModelxv(GLenum pname, const GLfixed *params)
+{
+	return es1::LightModelxv(pname, params);
+}
+
+GL_API void GL_APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+	return es1::Lightf(light, pname, param);
+}
+
+GL_API void GL_APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+	return es1::Lightfv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+	return es1::Lightx(light, pname, param);
+}
+
+GL_API void GL_APIENTRY glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+	return es1::Lightxv(light, pname, params);
+}
+
+GL_API void GL_APIENTRY glLineWidth(GLfloat width)
+{
+	return es1::LineWidth(width);
+}
+
+GL_API void GL_APIENTRY glLineWidthx(GLfixed width)
+{
+	return es1::LineWidthx(width);
+}
+
+GL_API void GL_APIENTRY glLoadIdentity(void)
+{
+	return es1::LoadIdentity();
+}
+
+GL_API void GL_APIENTRY glLoadMatrixf(const GLfloat *m)
+{
+	return es1::LoadMatrixf(m);
+}
+
+GL_API void GL_APIENTRY glLoadMatrixx(const GLfixed *m)
+{
+	return es1::LoadMatrixx(m);
+}
+
+GL_API void GL_APIENTRY glLogicOp(GLenum opcode)
+{
+	return es1::LogicOp(opcode);
+}
+
+GL_API void GL_APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+	return es1::Materialf(face, pname, param);
+}
+
+GL_API void GL_APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+	return es1::Materialfv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+	return es1::Materialx(face, pname, param);
+}
+
+GL_API void GL_APIENTRY glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+	return es1::Materialxv(face, pname, params);
+}
+
+GL_API void GL_APIENTRY glMatrixMode(GLenum mode)
+{
+	return es1::MatrixMode(mode);
+}
+
+GL_API void GL_APIENTRY glMultMatrixf(const GLfloat *m)
+{
+	return es1::MultMatrixf(m);
+}
+
+GL_API void GL_APIENTRY glMultMatrixx(const GLfixed *m)
+{
+	return es1::MultMatrixx(m);
+}
+
+GL_API void GL_APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+	return es1::MultiTexCoord4f(target, s, t, r, q);
+}
+
+GL_API void GL_APIENTRY glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+	return es1::MultiTexCoord4x(target, s, t, r, q);
+}
+
+GL_API void GL_APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+	return es1::Normal3f(nx, ny, nz);
+}
+
+GL_API void GL_APIENTRY glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+	return es1::Normal3x(nx, ny, nz);
+}
+
+GL_API void GL_APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::NormalPointer(type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+	return es1::Orthof(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+	return es1::Orthox(left, right, bottom, top, zNear, zFar);
+}
+
+GL_API void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+	return es1::PixelStorei(pname, param);
+}
+
+GL_API void GL_APIENTRY glPointParameterf(GLenum pname, GLfloat param)
+{
+	return es1::PointParameterf(pname, param);
+}
+
+GL_API void GL_APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+	return es1::PointParameterfv(pname, params);
+}
+
+GL_API void GL_APIENTRY glPointParameterx(GLenum pname, GLfixed param)
+{
+	return es1::PointParameterx(pname, param);
+}
+
+GL_API void GL_APIENTRY glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+	return es1::PointParameterxv(pname, params);
+}
+
+GL_API void GL_APIENTRY glPointSize(GLfloat size)
+{
+	return es1::PointSize(size);
+}
+
+GL_API void GL_APIENTRY glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::PointSizePointerOES(type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glPointSizex(GLfixed size)
+{
+	return es1::PointSizex(size);
+}
+
+GL_API void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+	return es1::PolygonOffset(factor, units);
+}
+
+GL_API void GL_APIENTRY glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+	return es1::PolygonOffsetx(factor, units);
+}
+
+GL_API void GL_APIENTRY glPopMatrix(void)
+{
+	return es1::PopMatrix();
+}
+
+GL_API void GL_APIENTRY glPushMatrix(void)
+{
+	return es1::PushMatrix();
+}
+
+GL_API void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+	return es1::ReadPixels(x, y, width, height, format, type, pixels);
+}
+
+GL_API void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+	return es1::RenderbufferStorageOES(target, internalformat, width, height);
+}
+
+GL_API void GL_APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+	return es1::Rotatef(angle, x, y, z);
+}
+
+GL_API void GL_APIENTRY glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+	return es1::Rotatex(angle, x, y, z);
+}
+
+GL_API void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+	return es1::SampleCoverage(value, invert);
+}
+
+GL_API void GL_APIENTRY glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+	return es1::SampleCoveragex(value, invert);
+}
+
+GL_API void GL_APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+	return es1::Scalef(x, y, z);
+}
+
+GL_API void GL_APIENTRY glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+	return es1::Scalex(x, y, z);
+}
+
+GL_API void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es1::Scissor(x, y, width, height);
+}
+
+GL_API void GL_APIENTRY glShadeModel(GLenum mode)
+{
+	return es1::ShadeModel(mode);
+}
+
+GL_API void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+	return es1::StencilFunc(func, ref, mask);
+}
+
+GL_API void GL_APIENTRY glStencilMask(GLuint mask)
+{
+	return es1::StencilMask(mask);
+}
+
+GL_API void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+	return es1::StencilOp(fail, zfail, zpass);
+}
+
+GL_API void GL_APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::TexCoordPointer(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+	return es1::TexEnvf(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+	return es1::TexEnvfv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+	return es1::TexEnvi(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+	return es1::TexEnvx(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+	return es1::TexEnviv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	return es1::TexEnvxv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+                                     GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es1::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+GL_API void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+	return es1::TexParameterf(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+	return es1::TexParameterfv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+	return es1::TexParameteri(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+	return es1::TexParameteriv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+	return es1::TexParameterx(target, pname, param);
+}
+
+GL_API void GL_APIENTRY glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+	return es1::TexParameterxv(target, pname, params);
+}
+
+GL_API void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                        GLenum format, GLenum type, const GLvoid* pixels)
+{
+	return es1::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+GL_API void GL_APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+	return es1::Translatef(x, y, z);
+}
+
+GL_API void GL_APIENTRY glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+	return es1::Translatex(x, y, z);
+}
+
+GL_API void GL_APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+	return es1::VertexPointer(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+	return es1::Viewport(x, y, width, height);
+}
+
+GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+	return es1::EGLImageTargetTexture2DOES(target, image);
+}
+
+GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+	return es1::EGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+GL_API void GL_APIENTRY glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+	return es1::DrawTexsOES(x,y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+	return es1::DrawTexiOES(x,y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+	return es1::DrawTexxOES(x,y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexsvOES(const GLshort *coords)
+{
+	return es1::DrawTexsvOES(coords);
+}
+
+GL_API void GL_APIENTRY glDrawTexivOES(const GLint *coords)
+{
+	return es1::DrawTexivOES(coords);
+}
+
+GL_API void GL_APIENTRY glDrawTexxvOES(const GLfixed *coords)
+{
+	return es1::DrawTexxvOES(coords);
+}
+
+GL_API void GL_APIENTRY glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+	return es1::DrawTexfOES(x, y, z, width, height);
+}
+
+GL_API void GL_APIENTRY glDrawTexfvOES(const GLfloat *coords)
+{
+	return es1::DrawTexfvOES(coords);
+}
+
+}
+
+LibGLES_CMexports::LibGLES_CMexports()
+{
+	this->glActiveTexture = es1::ActiveTexture;
+	this->glAlphaFunc = es1::AlphaFunc;
+	this->glAlphaFuncx = es1::AlphaFuncx;
+	this->glBindBuffer = es1::BindBuffer;
+	this->glBindFramebuffer = es1::BindFramebuffer;
+	this->glBindFramebufferOES = es1::BindFramebufferOES;
+	this->glBindRenderbufferOES = es1::BindRenderbufferOES;
+	this->glBindTexture = es1::BindTexture;
+	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;
+	this->glBlendEquationOES = es1::BlendEquationOES;
+	this->glBlendEquationSeparateOES = es1::BlendEquationSeparateOES;
+	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;
+	this->glBlendFunc = es1::BlendFunc;
+	this->glBlendFuncSeparateOES = es1::BlendFuncSeparateOES;
+	this->glBufferData = es1::BufferData;
+	this->glBufferSubData = es1::BufferSubData;
+	this->glCheckFramebufferStatusOES = es1::CheckFramebufferStatusOES;
+	this->glClear = es1::Clear;
+	this->glClearColor = es1::ClearColor;
+	this->glClearColorx = es1::ClearColorx;
+	this->glClearDepthf = es1::ClearDepthf;
+	this->glClearDepthx = es1::ClearDepthx;
+	this->glClearStencil = es1::ClearStencil;
+	this->glClientActiveTexture = es1::ClientActiveTexture;
+	this->glClipPlanef = es1::ClipPlanef;
+	this->glClipPlanex = es1::ClipPlanex;
+	this->glColor4f = es1::Color4f;
+	this->glColor4ub = es1::Color4ub;
+	this->glColor4x = es1::Color4x;
+	this->glColorMask = es1::ColorMask;
+	this->glColorPointer = es1::ColorPointer;
+	this->glCompressedTexImage2D = es1::CompressedTexImage2D;
+	this->glCompressedTexSubImage2D = es1::CompressedTexSubImage2D;
+	this->glCopyTexImage2D = es1::CopyTexImage2D;
+	this->glCopyTexSubImage2D = es1::CopyTexSubImage2D;
+	this->glCullFace = es1::CullFace;
+	this->glDeleteBuffers = es1::DeleteBuffers;
+	this->glDeleteFramebuffersOES = es1::DeleteFramebuffersOES;
+	this->glDeleteRenderbuffersOES = es1::DeleteRenderbuffersOES;
+	this->glDeleteTextures = es1::DeleteTextures;
+	this->glDepthFunc = es1::DepthFunc;
+	this->glDepthMask = es1::DepthMask;
+	this->glDepthRangex = es1::DepthRangex;
+	this->glDepthRangef = es1::DepthRangef;
+	this->glDisable = es1::Disable;
+	this->glDisableClientState = es1::DisableClientState;
+	this->glDrawArrays = es1::DrawArrays;
+	this->glDrawElements = es1::DrawElements;
+	this->glEnable = es1::Enable;
+	this->glEnableClientState = es1::EnableClientState;
+	this->glFinish = es1::Finish;
+	this->glFlush = es1::Flush;
+	this->glFramebufferRenderbufferOES = es1::FramebufferRenderbufferOES;
+	this->glFramebufferTexture2DOES = es1::FramebufferTexture2DOES;
+	this->glFogf = es1::Fogf;
+	this->glFogfv = es1::Fogfv;
+	this->glFogx = es1::Fogx;
+	this->glFogxv = es1::Fogxv;
+	this->glFrontFace = es1::FrontFace;
+	this->glFrustumf = es1::Frustumf;
+	this->glFrustumx = es1::Frustumx;
+	this->glGenerateMipmapOES = es1::GenerateMipmapOES;
+	this->glGenBuffers = es1::GenBuffers;
+	this->glGenFramebuffersOES = es1::GenFramebuffersOES;
+	this->glGenRenderbuffersOES = es1::GenRenderbuffersOES;
+	this->glGenTextures = es1::GenTextures;
+	this->glGetRenderbufferParameterivOES = es1::GetRenderbufferParameterivOES;
+	this->glGetBooleanv = es1::GetBooleanv;
+	this->glGetBufferParameteriv = es1::GetBufferParameteriv;
+	this->glGetClipPlanef = es1::GetClipPlanef;
+	this->glGetClipPlanex = es1::GetClipPlanex;
+	this->glGetError = es1::GetError;
+	this->glGetFixedv = es1::GetFixedv;
+	this->glGetFloatv = es1::GetFloatv;
+	this->glGetFramebufferAttachmentParameterivOES = es1::GetFramebufferAttachmentParameterivOES;
+	this->glGetIntegerv = es1::GetIntegerv;
+	this->glGetLightfv = es1::GetLightfv;
+	this->glGetLightxv = es1::GetLightxv;
+	this->glGetMaterialfv = es1::GetMaterialfv;
+	this->glGetMaterialxv = es1::GetMaterialxv;
+	this->glGetPointerv = es1::GetPointerv;
+	this->glGetString = es1::GetString;
+	this->glGetTexParameterfv = es1::GetTexParameterfv;
+	this->glGetTexParameteriv = es1::GetTexParameteriv;
+	this->glGetTexEnvfv = es1::GetTexEnvfv;
+	this->glGetTexEnviv = es1::GetTexEnviv;
+	this->glGetTexEnvxv = es1::GetTexEnvxv;
+	this->glGetTexParameterxv = es1::GetTexParameterxv;
+	this->glHint = es1::Hint;
+	this->glIsBuffer = es1::IsBuffer;
+	this->glIsEnabled = es1::IsEnabled;
+	this->glIsFramebufferOES = es1::IsFramebufferOES;
+	this->glIsTexture = es1::IsTexture;
+	this->glIsRenderbufferOES = es1::IsRenderbufferOES;
+	this->glLightModelf = es1::LightModelf;
+	this->glLightModelfv = es1::LightModelfv;
+	this->glLightModelx = es1::LightModelx;
+	this->glLightModelxv = es1::LightModelxv;
+	this->glLightf = es1::Lightf;
+	this->glLightfv = es1::Lightfv;
+	this->glLightx = es1::Lightx;
+	this->glLightxv = es1::Lightxv;
+	this->glLineWidth = es1::LineWidth;
+	this->glLineWidthx = es1::LineWidthx;
+	this->glLoadIdentity = es1::LoadIdentity;
+	this->glLoadMatrixf = es1::LoadMatrixf;
+	this->glLoadMatrixx = es1::LoadMatrixx;
+	this->glLogicOp = es1::LogicOp;
+	this->glMaterialf = es1::Materialf;
+	this->glMaterialfv = es1::Materialfv;
+	this->glMaterialx = es1::Materialx;
+	this->glMaterialxv = es1::Materialxv;
+	this->glMatrixMode = es1::MatrixMode;
+	this->glMultMatrixf = es1::MultMatrixf;
+	this->glMultMatrixx = es1::MultMatrixx;
+	this->glMultiTexCoord4f = es1::MultiTexCoord4f;
+	this->glMultiTexCoord4x = es1::MultiTexCoord4x;
+	this->glNormal3f = es1::Normal3f;
+	this->glNormal3x = es1::Normal3x;
+	this->glNormalPointer = es1::NormalPointer;
+	this->glOrthof = es1::Orthof;
+	this->glOrthox = es1::Orthox;
+	this->glPixelStorei = es1::PixelStorei;
+	this->glPointParameterf = es1::PointParameterf;
+	this->glPointParameterfv = es1::PointParameterfv;
+	this->glPointParameterx = es1::PointParameterx;
+	this->glPointParameterxv = es1::PointParameterxv;
+	this->glPointSize = es1::PointSize;
+	this->glPointSizePointerOES = es1::PointSizePointerOES;
+	this->glPointSizex = es1::PointSizex;
+	this->glPolygonOffset = es1::PolygonOffset;
+	this->glPolygonOffsetx = es1::PolygonOffsetx;
+	this->glPopMatrix = es1::PopMatrix;
+	this->glPushMatrix = es1::PushMatrix;
+	this->glReadPixels = es1::ReadPixels;
+	this->glRenderbufferStorageOES = es1::RenderbufferStorageOES;
+	this->glRotatef = es1::Rotatef;
+	this->glRotatex = es1::Rotatex;
+	this->glSampleCoverage = es1::SampleCoverage;
+	this->glSampleCoveragex = es1::SampleCoveragex;
+	this->glScalef = es1::Scalef;
+	this->glScalex = es1::Scalex;
+	this->glScissor = es1::Scissor;
+	this->glShadeModel = es1::ShadeModel;
+	this->glStencilFunc = es1::StencilFunc;
+	this->glStencilMask = es1::StencilMask;
+	this->glStencilOp = es1::StencilOp;
+	this->glTexCoordPointer = es1::TexCoordPointer;
+	this->glTexEnvf = es1::TexEnvf;
+	this->glTexEnvfv = es1::TexEnvfv;
+	this->glTexEnvi = es1::TexEnvi;
+	this->glTexEnvx = es1::TexEnvx;
+	this->glTexEnviv = es1::TexEnviv;
+	this->glTexEnvxv = es1::TexEnvxv;
+	this->glTexImage2D = es1::TexImage2D;
+	this->glTexParameterf = es1::TexParameterf;
+	this->glTexParameterfv = es1::TexParameterfv;
+	this->glTexParameteri = es1::TexParameteri;
+	this->glTexParameteriv = es1::TexParameteriv;
+	this->glTexParameterx = es1::TexParameterx;
+	this->glTexParameterxv = es1::TexParameterxv;
+	this->glTexSubImage2D = es1::TexSubImage2D;
+	this->glTranslatef = es1::Translatef;
+	this->glTranslatex = es1::Translatex;
+	this->glVertexPointer = es1::VertexPointer;
+	this->glViewport = es1::Viewport;
+	this->glEGLImageTargetTexture2DOES = es1::EGLImageTargetTexture2DOES;
+	this->glEGLImageTargetRenderbufferStorageOES = es1::EGLImageTargetRenderbufferStorageOES;
+	this->glDrawTexsOES = es1::DrawTexsOES;
+	this->glDrawTexiOES = es1::DrawTexiOES;
+	this->glDrawTexxOES = es1::DrawTexxOES;
+	this->glDrawTexsvOES = es1::DrawTexsvOES;
+	this->glDrawTexivOES = es1::DrawTexivOES;
+	this->glDrawTexxvOES = es1::DrawTexxvOES;
+	this->glDrawTexfOES = es1::DrawTexfOES;
+	this->glDrawTexfvOES = es1::DrawTexfvOES;
+
+	this->es1CreateContext = ::es1CreateContext;
+	this->es1GetProcAddress = ::es1GetProcAddress;
+	this->createBackBuffer = ::createBackBuffer;
+	this->createDepthStencil = ::createDepthStencil;
+	this->createFrameBuffer = ::createFrameBuffer;
+}
+
+extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader()
+{
+	static LibGLES_CMexports libGLES_CM;
+	return &libGLES_CM;
+}
+
+LibEGL libEGL;
diff --git a/src/OpenGL/libGLES_CM/main.h b/src/OpenGL/libGLES_CM/main.h
index da8fed6..34092b0 100644
--- a/src/OpenGL/libGLES_CM/main.h
+++ b/src/OpenGL/libGLES_CM/main.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    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.
 
 // main.h: Management of thread-local data.
 
diff --git a/src/OpenGL/libGLES_CM/mathutil.h b/src/OpenGL/libGLES_CM/mathutil.h
index 89c2e54..7f62c5b 100644
--- a/src/OpenGL/libGLES_CM/mathutil.h
+++ b/src/OpenGL/libGLES_CM/mathutil.h
@@ -1,13 +1,16 @@
-// SwiftShader Software Renderer
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
 //
-// All rights reserved. No part of this software may be copied, distributed, transmitted,
-// transcribed, stored in a retrieval system, translated into any human or computer
-// language by any means, or disclosed to third parties without the explicit written
-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
-// or implied, including but not limited to any patent rights, are granted to you.
+//    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.
 
 // mathutil.h: Math and bit manipulation functions.
 
@@ -21,27 +24,27 @@
 {
 inline bool isPow2(int x)
 {
-    return (x & (x - 1)) == 0 && (x != 0);
+	return (x & (x - 1)) == 0 && (x != 0);
 }
 
 inline int log2(int x)
 {
-    int r = 0;
-    while((x >> r) > 1) r++;
-    return r;
+	int r = 0;
+	while((x >> r) > 1) r++;
+	return r;
 }
 
 inline unsigned int ceilPow2(unsigned int x)
 {
-    if(x != 0) x--;
-    x |= x >> 1;
-    x |= x >> 2;
-    x |= x >> 4;
-    x |= x >> 8;
-    x |= x >> 16;
-    x++;
+	if(x != 0) x--;
+	x |= x >> 1;
+	x |= x >> 2;
+	x |= x >> 4;
+	x |= x >> 8;
+	x |= x >> 16;
+	x++;
 
-    return x;
+	return x;
 }
 
 using sw::clamp;
@@ -50,20 +53,20 @@
 template<const int n>
 inline unsigned int unorm(float x)
 {
-    const unsigned int max = 0xFFFFFFFF >> (32 - n);
+	const unsigned int max = 0xFFFFFFFF >> (32 - n);
 
-    if(x > 1)
-    {
-        return max;
-    }
-    else if(x < 0)
-    {
-        return 0;
-    }
-    else
-    {
-        return (unsigned int)(max * x + 0.5f);
-    }
+	if(x > 1)
+	{
+		return max;
+	}
+	else if(x < 0)
+	{
+		return 0;
+	}
+	else
+	{
+		return (unsigned int)(max * x + 0.5f);
+	}
 }
 }
 
diff --git a/src/OpenGL/libGLES_CM/utilities.cpp b/src/OpenGL/libGLES_CM/utilities.cpp
index 3dbedde..b03f15c 100644
--- a/src/OpenGL/libGLES_CM/utilities.cpp
+++ b/src/OpenGL/libGLES_CM/utilities.cpp
@@ -1,720 +1,723 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// utilities.cpp: Conversion functions and other utility routines.

-

-#include "utilities.h"

-

-#include "mathutil.h"

-#include "Context.h"

-#include "common/debug.h"

-

-#include <limits>

-#include <stdio.h>

-

-namespace es1

-{

-	bool IsCompressed(GLenum format)

-	{

-		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||

-		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||

-               format == GL_ETC1_RGB8_OES;

-	}

-

-	bool IsDepthTexture(GLenum format)

-	{

-		return format == GL_DEPTH_STENCIL_OES;

-	}

-

-	bool IsStencilTexture(GLenum format)

-	{

-		return format == GL_DEPTH_STENCIL_OES;

-	}

-

-	bool IsCubemapTextureTarget(GLenum target)

-	{

-		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES);

-	}

-

-	int CubeFaceIndex(GLenum cubeFace)

-	{

-		switch(cubeFace)

-		{

-		case GL_TEXTURE_CUBE_MAP_OES:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES: return 0;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES: return 1;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES: return 2;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES: return 3;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES: return 4;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES: return 5;

-		default: UNREACHABLE(cubeFace); return 0;

-		}

-	}

-

-	bool IsTextureTarget(GLenum target)

-	{

-		return target == GL_TEXTURE_2D;

-	}

-

-	// Verify that format/type are one of the combinations from table 3.4.

-	bool CheckTextureFormatType(GLenum format, GLenum type)

-	{

-		switch(type)

-		{

-		case GL_UNSIGNED_BYTE:

-			switch(format)

-			{

-			case GL_RGBA:

-			case GL_BGRA_EXT:

-			case GL_RGB:

-			case GL_ALPHA:

-			case GL_LUMINANCE:

-			case GL_LUMINANCE_ALPHA:

-				return true;

-			default:

-				return false;

-			}

-		case GL_FLOAT:

-		case GL_UNSIGNED_SHORT_4_4_4_4:

-		case GL_UNSIGNED_SHORT_5_5_5_1:

-			return (format == GL_RGBA);

-		case GL_UNSIGNED_SHORT_5_6_5:

-			return (format == GL_RGB);

-		case GL_UNSIGNED_INT_24_8_OES:

-			return (format == GL_DEPTH_STENCIL_OES);

-		default:

-			return false;

-		}

-	}

-

-	bool IsColorRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-			return true;

-		case GL_DEPTH_COMPONENT16_OES:

-		case GL_STENCIL_INDEX8_OES:

-		case GL_DEPTH24_STENCIL8_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsDepthRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16_OES:

-		case GL_DEPTH24_STENCIL8_OES:

-			return true;

-		case GL_STENCIL_INDEX8_OES:

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsStencilRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_STENCIL_INDEX8_OES:

-		case GL_DEPTH24_STENCIL8_OES:

-			return true;

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-		case GL_DEPTH_COMPONENT16_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsAlpha(GLenum texFormat)

-	{

-		switch(texFormat)

-		{

-		case GL_ALPHA:

-			return true;

-		default:

-			return false;

-		}

-	}

-

-	bool IsRGB(GLenum texFormat)

-	{

-		switch(texFormat)

-		{

-		case GL_LUMINANCE:

-		case GL_RGB:

-		case GL_RGB565_OES:   // GL_OES_framebuffer_object

-		case GL_RGB8_OES:     // GL_OES_rgb8_rgba8

-		case SW_YV12_BT601:

-		case SW_YV12_BT709:

-		case SW_YV12_JFIF:

-			return true;

-		default:

-			return false;

-		}

-	}

-

-	bool IsRGBA(GLenum texFormat)

-	{

-		switch(texFormat)

-		{

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-		case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888

-		case GL_RGBA4_OES:     // GL_OES_framebuffer_object

-		case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object

-		case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8

-			return true;

-		default:

-			return false;

-		}

-	}

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::DEPTH_NEVER;

-		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;

-		case GL_LESS:     return sw::DEPTH_LESS;

-		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;

-		case GL_EQUAL:    return sw::DEPTH_EQUAL;

-		case GL_GREATER:  return sw::DEPTH_GREATER;

-		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::DEPTH_ALWAYS;

-	}

-

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::STENCIL_NEVER;

-		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;

-		case GL_LESS:     return sw::STENCIL_LESS;

-		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;

-		case GL_EQUAL:    return sw::STENCIL_EQUAL;

-		case GL_GREATER:  return sw::STENCIL_GREATER;

-		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::STENCIL_ALWAYS;

-	}

-

-	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::ALPHA_NEVER;

-		case GL_ALWAYS:   return sw::ALPHA_ALWAYS;

-		case GL_LESS:     return sw::ALPHA_LESS;

-		case GL_LEQUAL:   return sw::ALPHA_LESSEQUAL;

-		case GL_EQUAL:    return sw::ALPHA_EQUAL;

-		case GL_GREATER:  return sw::ALPHA_GREATER;

-		case GL_GEQUAL:   return sw::ALPHA_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::ALPHA_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::ALPHA_ALWAYS;

-	}

-

-	sw::Color<float> ConvertColor(es1::Color color)

-	{

-		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);

-	}

-

-	sw::BlendFactor ConvertBlendFunc(GLenum blend)

-	{

-		switch(blend)

-		{

-		case GL_ZERO:                     return sw::BLEND_ZERO;

-		case GL_ONE:                      return sw::BLEND_ONE;

-		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;

-		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;

-		case GL_DST_COLOR:                return sw::BLEND_DEST;

-		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;

-		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;

-		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;

-		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;

-		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;

-		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;

-		default: UNREACHABLE(blend);

-		}

-

-		return sw::BLEND_ZERO;

-	}

-

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp)

-	{

-		switch(blendOp)

-		{

-		case GL_FUNC_ADD_OES:              return sw::BLENDOP_ADD;

-		case GL_FUNC_SUBTRACT_OES:         return sw::BLENDOP_SUB;

-		case GL_FUNC_REVERSE_SUBTRACT_OES: return sw::BLENDOP_INVSUB;

-		case GL_MIN_EXT:                   return sw::BLENDOP_MIN;

-		case GL_MAX_EXT:                   return sw::BLENDOP_MAX;

-		default: UNREACHABLE(blendOp);

-		}

-

-		return sw::BLENDOP_ADD;

-	}

-

-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)

-	{

-		switch(logicalOperation)

-		{

-		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;

-		case GL_SET:           return sw::LOGICALOP_SET;

-		case GL_COPY:          return sw::LOGICALOP_COPY;

-		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;

-		case GL_NOOP:          return sw::LOGICALOP_NOOP;

-		case GL_INVERT:        return sw::LOGICALOP_INVERT;

-		case GL_AND:           return sw::LOGICALOP_AND;

-		case GL_NAND:          return sw::LOGICALOP_NAND;

-		case GL_OR:            return sw::LOGICALOP_OR;

-		case GL_NOR:           return sw::LOGICALOP_NOR;

-		case GL_XOR:           return sw::LOGICALOP_XOR;

-		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;

-		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;

-		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;

-		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;

-		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;

-		default: UNREACHABLE(logicalOperation);

-		}

-

-		return sw::LOGICALOP_COPY;

-	}

-

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)

-	{

-		switch(stencilOp)

-		{

-		case GL_ZERO:          return sw::OPERATION_ZERO;

-		case GL_KEEP:          return sw::OPERATION_KEEP;

-		case GL_REPLACE:       return sw::OPERATION_REPLACE;

-		case GL_INCR:          return sw::OPERATION_INCRSAT;

-		case GL_DECR:          return sw::OPERATION_DECRSAT;

-		case GL_INVERT:        return sw::OPERATION_INVERT;

-		case GL_INCR_WRAP_OES: return sw::OPERATION_INCR;

-		case GL_DECR_WRAP_OES: return sw::OPERATION_DECR;

-		default: UNREACHABLE(stencilOp);

-		}

-

-		return sw::OPERATION_KEEP;

-	}

-

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap)

-	{

-		switch(wrap)

-		{

-		case GL_REPEAT:              return sw::ADDRESSING_WRAP;

-		case GL_CLAMP_TO_EDGE:       return sw::ADDRESSING_CLAMP;

-		case GL_MIRRORED_REPEAT_OES: return sw::ADDRESSING_MIRROR;

-		default: UNREACHABLE(wrap);

-		}

-

-		return sw::ADDRESSING_WRAP;

-	}

-

-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)

-	{

-		switch(cullFace)

-		{

-		case GL_FRONT:

-			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);

-		case GL_BACK:

-			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);

-		case GL_FRONT_AND_BACK:

-			return sw::CULL_NONE;   // culling will be handled during draw

-		default: UNREACHABLE(cullFace);

-		}

-

-		return sw::CULL_COUNTERCLOCKWISE;

-	}

-

-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)

-	{

-		return (red   ? 0x00000001 : 0) |

-			   (green ? 0x00000002 : 0) |

-			   (blue  ? 0x00000004 : 0) |

-			   (alpha ? 0x00000008 : 0);

-	}

-

-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)

-	{

-		switch(minFilter)

-		{

-		case GL_NEAREST:

-		case GL_LINEAR:

-			return sw::MIPMAP_NONE;

-			break;

-		case GL_NEAREST_MIPMAP_NEAREST:

-		case GL_LINEAR_MIPMAP_NEAREST:

-			return sw::MIPMAP_POINT;

-			break;

-		case GL_NEAREST_MIPMAP_LINEAR:

-		case GL_LINEAR_MIPMAP_LINEAR:

-			return sw::MIPMAP_LINEAR;

-			break;

-		default:

-			UNREACHABLE(minFilter);

-			return sw::MIPMAP_NONE;

-		}

-	}

-

-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)

-	{

-		if(maxAnisotropy > 1.0f)

-		{

-			return sw::FILTER_ANISOTROPIC;

-		}

-

-		sw::FilterType magFilterType = sw::FILTER_POINT;

-		switch(magFilter)

-		{

-		case GL_NEAREST: magFilterType = sw::FILTER_POINT;  break;

-		case GL_LINEAR:  magFilterType = sw::FILTER_LINEAR; break;

-		default: UNREACHABLE(magFilter);

-		}

-

-		switch(minFilter)

-		{

-		case GL_NEAREST:

-		case GL_NEAREST_MIPMAP_NEAREST:

-		case GL_NEAREST_MIPMAP_LINEAR:

-			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;

-		case GL_LINEAR:

-		case GL_LINEAR_MIPMAP_NEAREST:

-		case GL_LINEAR_MIPMAP_LINEAR:

-			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;

-		default:

-			UNREACHABLE(minFilter);

-			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;

-		}

-	}

-

-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType,  sw::DrawType &drawType, int &primitiveCount)

-	{

-		switch(primitiveType)

-		{

-		case GL_POINTS:

-			drawType = sw::DRAW_POINTLIST;

-			primitiveCount = elementCount;

-			break;

-		case GL_LINES:

-			drawType = sw::DRAW_LINELIST;

-			primitiveCount = elementCount / 2;

-			break;

-		case GL_LINE_LOOP:

-			drawType = sw::DRAW_LINELOOP;

-			primitiveCount = elementCount;

-			break;

-		case GL_LINE_STRIP:

-			drawType = sw::DRAW_LINESTRIP;

-			primitiveCount = elementCount - 1;

-			break;

-		case GL_TRIANGLES:

-			drawType = sw::DRAW_TRIANGLELIST;

-			primitiveCount = elementCount / 3;

-			break;

-		case GL_TRIANGLE_STRIP:

-			drawType = sw::DRAW_TRIANGLESTRIP;

-			primitiveCount = elementCount - 2;

-			break;

-		case GL_TRIANGLE_FAN:

-			drawType = sw::DRAW_TRIANGLEFAN;

-			primitiveCount = elementCount - 2;

-			break;

-		default:

-			return false;

-		}

-

-		sw::DrawType elementSize;

-		switch(elementType)

-		{

-		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;

-		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;

-		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;

-		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;

-		default: return false;

-		}

-

-		drawType = sw::DrawType(drawType | elementSize);

-

-		return true;

-	}

-

-	sw::Format ConvertRenderbufferFormat(GLenum format)

-	{

-		switch(format)

-		{

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;

-		case GL_RGB565_OES:           return sw::FORMAT_R5G6B5;

-		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;

-		case GL_DEPTH_COMPONENT16_OES:

-		case GL_STENCIL_INDEX8_OES:

-		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;

-		default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;

-		}

-	}

-

-	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)

-	{

-		switch(operation)

-		{

-		case GL_REPLACE:        return sw::TextureStage::STAGE_SELECTARG1;

-		case GL_MODULATE:       return sw::TextureStage::STAGE_MODULATE;

-		case GL_ADD:            return sw::TextureStage::STAGE_ADD;

-		case GL_ADD_SIGNED:     return sw::TextureStage::STAGE_ADDSIGNED;

-		case GL_INTERPOLATE:    return sw::TextureStage::STAGE_LERP;

-		case GL_SUBTRACT:       return sw::TextureStage::STAGE_SUBTRACT;

-		case GL_DOT3_RGB:       return sw::TextureStage::STAGE_DOT3;

-		case GL_DOT3_RGBA:      return sw::TextureStage::STAGE_DOT3;

-		default: UNREACHABLE(operation); return sw::TextureStage::STAGE_SELECTARG1;

-		}

-	}

-

-	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument)

-	{

-		switch(argument)

-		{

-		case GL_TEXTURE:        return sw::TextureStage::SOURCE_TEXTURE;

-		case GL_CONSTANT:       return sw::TextureStage::SOURCE_CONSTANT;

-		case GL_PRIMARY_COLOR:  return sw::TextureStage::SOURCE_DIFFUSE;

-		case GL_PREVIOUS:       return sw::TextureStage::SOURCE_CURRENT;

-		default: UNREACHABLE(argument); return sw::TextureStage::SOURCE_CURRENT;

-		}

-	}

-

-	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand)

-	{

-		switch(operand)

-		{

-		case GL_SRC_COLOR:           return sw::TextureStage::MODIFIER_COLOR;

-		case GL_ONE_MINUS_SRC_COLOR: return sw::TextureStage::MODIFIER_INVCOLOR;

-		case GL_SRC_ALPHA:           return sw::TextureStage::MODIFIER_ALPHA;

-		case GL_ONE_MINUS_SRC_ALPHA: return sw::TextureStage::MODIFIER_INVALPHA;

-		default: UNREACHABLE(operand);      return sw::TextureStage::MODIFIER_COLOR;

-		}

-	}

-}

-

-namespace sw2es

-{

-	unsigned int GetStencilSize(sw::Format stencilFormat)

-	{

-		switch(stencilFormat)

-		{

-		case sw::FORMAT_D24FS8:

-		case sw::FORMAT_D24S8:

-		case sw::FORMAT_D32FS8_TEXTURE:

-			return 8;

-	//	case sw::FORMAT_D24X4S4:

-	//		return 4;

-	//	case sw::FORMAT_D15S1:

-	//		return 1;

-	//	case sw::FORMAT_D16_LOCKABLE:

-		case sw::FORMAT_D32:

-		case sw::FORMAT_D24X8:

-		case sw::FORMAT_D32F_LOCKABLE:

-		case sw::FORMAT_D16:

-			return 0;

-	//	case sw::FORMAT_D32_LOCKABLE:  return 0;

-	//	case sw::FORMAT_S8_LOCKABLE:   return 8;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetAlphaSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 2;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-			return 1;

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-		case sw::FORMAT_R5G6B5:

-			return 0;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetRedSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-		case sw::FORMAT_R5G6B5:

-			return 5;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetGreenSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-			return 5;

-		case sw::FORMAT_R5G6B5:

-			return 6;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetBlueSize(sw::Format colorFormat)

-	{

-		switch(colorFormat)

-		{

-		case sw::FORMAT_A16B16G16R16F:

-			return 16;

-		case sw::FORMAT_A32B32G32R32F:

-			return 32;

-		case sw::FORMAT_A2R10G10B10:

-			return 10;

-		case sw::FORMAT_A8R8G8B8:

-		case sw::FORMAT_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-		case sw::FORMAT_R5G6B5:

-			return 5;

-		default:

-			return 0;

-		}

-	}

-

-	unsigned int GetDepthSize(sw::Format depthFormat)

-	{

-		switch(depthFormat)

-		{

-	//	case sw::FORMAT_D16_LOCKABLE:   return 16;

-		case sw::FORMAT_D32:            return 32;

-	//	case sw::FORMAT_D15S1:          return 15;

-		case sw::FORMAT_D24S8:          return 24;

-		case sw::FORMAT_D24X8:          return 24;

-	//	case sw::FORMAT_D24X4S4:        return 24;

-		case sw::FORMAT_D16:            return 16;

-		case sw::FORMAT_D32F_LOCKABLE:  return 32;

-		case sw::FORMAT_D24FS8:         return 24;

-	//	case sw::FORMAT_D32_LOCKABLE:   return 32;

-	//	case sw::FORMAT_S8_LOCKABLE:    return 0;

-		case sw::FORMAT_D32FS8_TEXTURE: return 32;

-		default:                        return 0;

-		}

-	}

-

-	GLenum ConvertBackBufferFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_A4R4G4B4: return GL_RGBA4_OES;

-		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;

-		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;

-		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1_OES;

-		case sw::FORMAT_R5G6B5:   return GL_RGB565_OES;

-		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;

-		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_RGBA4_OES;

-	}

-

-	GLenum ConvertDepthStencilFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_D16:

-		case sw::FORMAT_D24X8:

-		case sw::FORMAT_D32:

-			return GL_DEPTH_COMPONENT16_OES;

-		case sw::FORMAT_D24S8:

-			return GL_DEPTH24_STENCIL8_OES;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_DEPTH24_STENCIL8_OES;

-	}

-}

+// 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.
+
+// utilities.cpp: Conversion functions and other utility routines.
+
+#include "utilities.h"
+
+#include "mathutil.h"
+#include "Context.h"
+#include "common/debug.h"
+
+#include <limits>
+#include <stdio.h>
+
+namespace es1
+{
+	bool IsCompressed(GLenum format)
+	{
+		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+               format == GL_ETC1_RGB8_OES;
+	}
+
+	bool IsDepthTexture(GLenum format)
+	{
+		return format == GL_DEPTH_STENCIL_OES;
+	}
+
+	bool IsStencilTexture(GLenum format)
+	{
+		return format == GL_DEPTH_STENCIL_OES;
+	}
+
+	bool IsCubemapTextureTarget(GLenum target)
+	{
+		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES);
+	}
+
+	int CubeFaceIndex(GLenum cubeFace)
+	{
+		switch(cubeFace)
+		{
+		case GL_TEXTURE_CUBE_MAP_OES:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES: return 0;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES: return 1;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES: return 2;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES: return 3;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES: return 4;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES: return 5;
+		default: UNREACHABLE(cubeFace); return 0;
+		}
+	}
+
+	bool IsTextureTarget(GLenum target)
+	{
+		return target == GL_TEXTURE_2D;
+	}
+
+	// Verify that format/type are one of the combinations from table 3.4.
+	bool CheckTextureFormatType(GLenum format, GLenum type)
+	{
+		switch(type)
+		{
+		case GL_UNSIGNED_BYTE:
+			switch(format)
+			{
+			case GL_RGBA:
+			case GL_BGRA_EXT:
+			case GL_RGB:
+			case GL_ALPHA:
+			case GL_LUMINANCE:
+			case GL_LUMINANCE_ALPHA:
+				return true;
+			default:
+				return false;
+			}
+		case GL_FLOAT:
+		case GL_UNSIGNED_SHORT_4_4_4_4:
+		case GL_UNSIGNED_SHORT_5_5_5_1:
+			return (format == GL_RGBA);
+		case GL_UNSIGNED_SHORT_5_6_5:
+			return (format == GL_RGB);
+		case GL_UNSIGNED_INT_24_8_OES:
+			return (format == GL_DEPTH_STENCIL_OES);
+		default:
+			return false;
+		}
+	}
+
+	bool IsColorRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+			return true;
+		case GL_DEPTH_COMPONENT16_OES:
+		case GL_STENCIL_INDEX8_OES:
+		case GL_DEPTH24_STENCIL8_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsDepthRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16_OES:
+		case GL_DEPTH24_STENCIL8_OES:
+			return true;
+		case GL_STENCIL_INDEX8_OES:
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsStencilRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_STENCIL_INDEX8_OES:
+		case GL_DEPTH24_STENCIL8_OES:
+			return true;
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+		case GL_DEPTH_COMPONENT16_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsAlpha(GLenum texFormat)
+	{
+		switch(texFormat)
+		{
+		case GL_ALPHA:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	bool IsRGB(GLenum texFormat)
+	{
+		switch(texFormat)
+		{
+		case GL_LUMINANCE:
+		case GL_RGB:
+		case GL_RGB565_OES:   // GL_OES_framebuffer_object
+		case GL_RGB8_OES:     // GL_OES_rgb8_rgba8
+		case SW_YV12_BT601:
+		case SW_YV12_BT709:
+		case SW_YV12_JFIF:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	bool IsRGBA(GLenum texFormat)
+	{
+		switch(texFormat)
+		{
+		case GL_LUMINANCE_ALPHA:
+		case GL_RGBA:
+		case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888
+		case GL_RGBA4_OES:     // GL_OES_framebuffer_object
+		case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object
+		case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8
+			return true;
+		default:
+			return false;
+		}
+	}
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::DEPTH_NEVER;
+		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
+		case GL_LESS:     return sw::DEPTH_LESS;
+		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
+		case GL_EQUAL:    return sw::DEPTH_EQUAL;
+		case GL_GREATER:  return sw::DEPTH_GREATER;
+		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::DEPTH_ALWAYS;
+	}
+
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::STENCIL_NEVER;
+		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
+		case GL_LESS:     return sw::STENCIL_LESS;
+		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
+		case GL_EQUAL:    return sw::STENCIL_EQUAL;
+		case GL_GREATER:  return sw::STENCIL_GREATER;
+		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::STENCIL_ALWAYS;
+	}
+
+	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::ALPHA_NEVER;
+		case GL_ALWAYS:   return sw::ALPHA_ALWAYS;
+		case GL_LESS:     return sw::ALPHA_LESS;
+		case GL_LEQUAL:   return sw::ALPHA_LESSEQUAL;
+		case GL_EQUAL:    return sw::ALPHA_EQUAL;
+		case GL_GREATER:  return sw::ALPHA_GREATER;
+		case GL_GEQUAL:   return sw::ALPHA_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::ALPHA_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::ALPHA_ALWAYS;
+	}
+
+	sw::Color<float> ConvertColor(es1::Color color)
+	{
+		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
+	}
+
+	sw::BlendFactor ConvertBlendFunc(GLenum blend)
+	{
+		switch(blend)
+		{
+		case GL_ZERO:                     return sw::BLEND_ZERO;
+		case GL_ONE:                      return sw::BLEND_ONE;
+		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
+		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
+		case GL_DST_COLOR:                return sw::BLEND_DEST;
+		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
+		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
+		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
+		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
+		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
+		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
+		default: UNREACHABLE(blend);
+		}
+
+		return sw::BLEND_ZERO;
+	}
+
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
+	{
+		switch(blendOp)
+		{
+		case GL_FUNC_ADD_OES:              return sw::BLENDOP_ADD;
+		case GL_FUNC_SUBTRACT_OES:         return sw::BLENDOP_SUB;
+		case GL_FUNC_REVERSE_SUBTRACT_OES: return sw::BLENDOP_INVSUB;
+		case GL_MIN_EXT:                   return sw::BLENDOP_MIN;
+		case GL_MAX_EXT:                   return sw::BLENDOP_MAX;
+		default: UNREACHABLE(blendOp);
+		}
+
+		return sw::BLENDOP_ADD;
+	}
+
+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)
+	{
+		switch(logicalOperation)
+		{
+		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;
+		case GL_SET:           return sw::LOGICALOP_SET;
+		case GL_COPY:          return sw::LOGICALOP_COPY;
+		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;
+		case GL_NOOP:          return sw::LOGICALOP_NOOP;
+		case GL_INVERT:        return sw::LOGICALOP_INVERT;
+		case GL_AND:           return sw::LOGICALOP_AND;
+		case GL_NAND:          return sw::LOGICALOP_NAND;
+		case GL_OR:            return sw::LOGICALOP_OR;
+		case GL_NOR:           return sw::LOGICALOP_NOR;
+		case GL_XOR:           return sw::LOGICALOP_XOR;
+		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;
+		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;
+		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;
+		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;
+		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;
+		default: UNREACHABLE(logicalOperation);
+		}
+
+		return sw::LOGICALOP_COPY;
+	}
+
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
+	{
+		switch(stencilOp)
+		{
+		case GL_ZERO:          return sw::OPERATION_ZERO;
+		case GL_KEEP:          return sw::OPERATION_KEEP;
+		case GL_REPLACE:       return sw::OPERATION_REPLACE;
+		case GL_INCR:          return sw::OPERATION_INCRSAT;
+		case GL_DECR:          return sw::OPERATION_DECRSAT;
+		case GL_INVERT:        return sw::OPERATION_INVERT;
+		case GL_INCR_WRAP_OES: return sw::OPERATION_INCR;
+		case GL_DECR_WRAP_OES: return sw::OPERATION_DECR;
+		default: UNREACHABLE(stencilOp);
+		}
+
+		return sw::OPERATION_KEEP;
+	}
+
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
+	{
+		switch(wrap)
+		{
+		case GL_REPEAT:              return sw::ADDRESSING_WRAP;
+		case GL_CLAMP_TO_EDGE:       return sw::ADDRESSING_CLAMP;
+		case GL_MIRRORED_REPEAT_OES: return sw::ADDRESSING_MIRROR;
+		default: UNREACHABLE(wrap);
+		}
+
+		return sw::ADDRESSING_WRAP;
+	}
+
+	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
+	{
+		switch(cullFace)
+		{
+		case GL_FRONT:
+			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
+		case GL_BACK:
+			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
+		case GL_FRONT_AND_BACK:
+			return sw::CULL_NONE;   // culling will be handled during draw
+		default: UNREACHABLE(cullFace);
+		}
+
+		return sw::CULL_COUNTERCLOCKWISE;
+	}
+
+	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+	{
+		return (red   ? 0x00000001 : 0) |
+			   (green ? 0x00000002 : 0) |
+			   (blue  ? 0x00000004 : 0) |
+			   (alpha ? 0x00000008 : 0);
+	}
+
+	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
+	{
+		switch(minFilter)
+		{
+		case GL_NEAREST:
+		case GL_LINEAR:
+			return sw::MIPMAP_NONE;
+			break;
+		case GL_NEAREST_MIPMAP_NEAREST:
+		case GL_LINEAR_MIPMAP_NEAREST:
+			return sw::MIPMAP_POINT;
+			break;
+		case GL_NEAREST_MIPMAP_LINEAR:
+		case GL_LINEAR_MIPMAP_LINEAR:
+			return sw::MIPMAP_LINEAR;
+			break;
+		default:
+			UNREACHABLE(minFilter);
+			return sw::MIPMAP_NONE;
+		}
+	}
+
+	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
+	{
+		if(maxAnisotropy > 1.0f)
+		{
+			return sw::FILTER_ANISOTROPIC;
+		}
+
+		sw::FilterType magFilterType = sw::FILTER_POINT;
+		switch(magFilter)
+		{
+		case GL_NEAREST: magFilterType = sw::FILTER_POINT;  break;
+		case GL_LINEAR:  magFilterType = sw::FILTER_LINEAR; break;
+		default: UNREACHABLE(magFilter);
+		}
+
+		switch(minFilter)
+		{
+		case GL_NEAREST:
+		case GL_NEAREST_MIPMAP_NEAREST:
+		case GL_NEAREST_MIPMAP_LINEAR:
+			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+		case GL_LINEAR:
+		case GL_LINEAR_MIPMAP_NEAREST:
+		case GL_LINEAR_MIPMAP_LINEAR:
+			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
+		default:
+			UNREACHABLE(minFilter);
+			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+		}
+	}
+
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType,  sw::DrawType &drawType, int &primitiveCount)
+	{
+		switch(primitiveType)
+		{
+		case GL_POINTS:
+			drawType = sw::DRAW_POINTLIST;
+			primitiveCount = elementCount;
+			break;
+		case GL_LINES:
+			drawType = sw::DRAW_LINELIST;
+			primitiveCount = elementCount / 2;
+			break;
+		case GL_LINE_LOOP:
+			drawType = sw::DRAW_LINELOOP;
+			primitiveCount = elementCount;
+			break;
+		case GL_LINE_STRIP:
+			drawType = sw::DRAW_LINESTRIP;
+			primitiveCount = elementCount - 1;
+			break;
+		case GL_TRIANGLES:
+			drawType = sw::DRAW_TRIANGLELIST;
+			primitiveCount = elementCount / 3;
+			break;
+		case GL_TRIANGLE_STRIP:
+			drawType = sw::DRAW_TRIANGLESTRIP;
+			primitiveCount = elementCount - 2;
+			break;
+		case GL_TRIANGLE_FAN:
+			drawType = sw::DRAW_TRIANGLEFAN;
+			primitiveCount = elementCount - 2;
+			break;
+		default:
+			return false;
+		}
+
+		sw::DrawType elementSize;
+		switch(elementType)
+		{
+		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
+		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
+		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
+		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
+		default: return false;
+		}
+
+		drawType = sw::DrawType(drawType | elementSize);
+
+		return true;
+	}
+
+	sw::Format ConvertRenderbufferFormat(GLenum format)
+	{
+		switch(format)
+		{
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;
+		case GL_RGB565_OES:           return sw::FORMAT_R5G6B5;
+		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;
+		case GL_DEPTH_COMPONENT16_OES:
+		case GL_STENCIL_INDEX8_OES:
+		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
+		default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;
+		}
+	}
+
+	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)
+	{
+		switch(operation)
+		{
+		case GL_REPLACE:        return sw::TextureStage::STAGE_SELECTARG1;
+		case GL_MODULATE:       return sw::TextureStage::STAGE_MODULATE;
+		case GL_ADD:            return sw::TextureStage::STAGE_ADD;
+		case GL_ADD_SIGNED:     return sw::TextureStage::STAGE_ADDSIGNED;
+		case GL_INTERPOLATE:    return sw::TextureStage::STAGE_LERP;
+		case GL_SUBTRACT:       return sw::TextureStage::STAGE_SUBTRACT;
+		case GL_DOT3_RGB:       return sw::TextureStage::STAGE_DOT3;
+		case GL_DOT3_RGBA:      return sw::TextureStage::STAGE_DOT3;
+		default: UNREACHABLE(operation); return sw::TextureStage::STAGE_SELECTARG1;
+		}
+	}
+
+	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument)
+	{
+		switch(argument)
+		{
+		case GL_TEXTURE:        return sw::TextureStage::SOURCE_TEXTURE;
+		case GL_CONSTANT:       return sw::TextureStage::SOURCE_CONSTANT;
+		case GL_PRIMARY_COLOR:  return sw::TextureStage::SOURCE_DIFFUSE;
+		case GL_PREVIOUS:       return sw::TextureStage::SOURCE_CURRENT;
+		default: UNREACHABLE(argument); return sw::TextureStage::SOURCE_CURRENT;
+		}
+	}
+
+	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand)
+	{
+		switch(operand)
+		{
+		case GL_SRC_COLOR:           return sw::TextureStage::MODIFIER_COLOR;
+		case GL_ONE_MINUS_SRC_COLOR: return sw::TextureStage::MODIFIER_INVCOLOR;
+		case GL_SRC_ALPHA:           return sw::TextureStage::MODIFIER_ALPHA;
+		case GL_ONE_MINUS_SRC_ALPHA: return sw::TextureStage::MODIFIER_INVALPHA;
+		default: UNREACHABLE(operand);      return sw::TextureStage::MODIFIER_COLOR;
+		}
+	}
+}
+
+namespace sw2es
+{
+	unsigned int GetStencilSize(sw::Format stencilFormat)
+	{
+		switch(stencilFormat)
+		{
+		case sw::FORMAT_D24FS8:
+		case sw::FORMAT_D24S8:
+		case sw::FORMAT_D32FS8_TEXTURE:
+			return 8;
+	//	case sw::FORMAT_D24X4S4:
+	//		return 4;
+	//	case sw::FORMAT_D15S1:
+	//		return 1;
+	//	case sw::FORMAT_D16_LOCKABLE:
+		case sw::FORMAT_D32:
+		case sw::FORMAT_D24X8:
+		case sw::FORMAT_D32F_LOCKABLE:
+		case sw::FORMAT_D16:
+			return 0;
+	//	case sw::FORMAT_D32_LOCKABLE:  return 0;
+	//	case sw::FORMAT_S8_LOCKABLE:   return 8;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetAlphaSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 2;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+			return 1;
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+		case sw::FORMAT_R5G6B5:
+			return 0;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetRedSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+		case sw::FORMAT_R5G6B5:
+			return 5;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetGreenSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+			return 5;
+		case sw::FORMAT_R5G6B5:
+			return 6;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetBlueSize(sw::Format colorFormat)
+	{
+		switch(colorFormat)
+		{
+		case sw::FORMAT_A16B16G16R16F:
+			return 16;
+		case sw::FORMAT_A32B32G32R32F:
+			return 32;
+		case sw::FORMAT_A2R10G10B10:
+			return 10;
+		case sw::FORMAT_A8R8G8B8:
+		case sw::FORMAT_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+		case sw::FORMAT_R5G6B5:
+			return 5;
+		default:
+			return 0;
+		}
+	}
+
+	unsigned int GetDepthSize(sw::Format depthFormat)
+	{
+		switch(depthFormat)
+		{
+	//	case sw::FORMAT_D16_LOCKABLE:   return 16;
+		case sw::FORMAT_D32:            return 32;
+	//	case sw::FORMAT_D15S1:          return 15;
+		case sw::FORMAT_D24S8:          return 24;
+		case sw::FORMAT_D24X8:          return 24;
+	//	case sw::FORMAT_D24X4S4:        return 24;
+		case sw::FORMAT_D16:            return 16;
+		case sw::FORMAT_D32F_LOCKABLE:  return 32;
+		case sw::FORMAT_D24FS8:         return 24;
+	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
+	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
+		case sw::FORMAT_D32FS8_TEXTURE: return 32;
+		default:                        return 0;
+		}
+	}
+
+	GLenum ConvertBackBufferFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_A4R4G4B4: return GL_RGBA4_OES;
+		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
+		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
+		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1_OES;
+		case sw::FORMAT_R5G6B5:   return GL_RGB565_OES;
+		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
+		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_RGBA4_OES;
+	}
+
+	GLenum ConvertDepthStencilFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_D16:
+		case sw::FORMAT_D24X8:
+		case sw::FORMAT_D32:
+			return GL_DEPTH_COMPONENT16_OES;
+		case sw::FORMAT_D24S8:
+			return GL_DEPTH24_STENCIL8_OES;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_DEPTH24_STENCIL8_OES;
+	}
+}
diff --git a/src/OpenGL/libGLES_CM/utilities.h b/src/OpenGL/libGLES_CM/utilities.h
index ef1d6ff..ec2a257 100644
--- a/src/OpenGL/libGLES_CM/utilities.h
+++ b/src/OpenGL/libGLES_CM/utilities.h
@@ -1,82 +1,85 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 TransGaming Inc.

-//

-// All rights reserved. No part of this software may be copied, distributed, transmitted,

-// transcribed, stored in a retrieval system, translated into any human or computer

-// language by any means, or disclosed to third parties without the explicit written

-// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express

-// or implied, including but not limited to any patent rights, are granted to you.

-//

-

-// utilities.h: Conversion functions and other utility routines.

-

-#ifndef LIBGLES_CM_UTILITIES_H

-#define LIBGLES_CM_UTILITIES_H

-

-#include "Device.hpp"

-#include "common/Image.hpp"

-#include "Texture.h"

-

-#include <GLES/gl.h>

-#include <GLES/glext.h>

-

-#include <string>

-

-namespace es1

-{

-	struct Color;

-

-	bool IsCompressed(GLenum format);

-	bool IsDepthTexture(GLenum format);

-	bool IsStencilTexture(GLenum format);

-	bool IsCubemapTextureTarget(GLenum target);

-	int CubeFaceIndex(GLenum cubeTarget);

-	bool IsTextureTarget(GLenum target);

-	bool CheckTextureFormatType(GLenum format, GLenum type);

-

-	bool IsColorRenderable(GLenum internalformat);

-	bool IsDepthRenderable(GLenum internalformat);

-	bool IsStencilRenderable(GLenum internalformat);

-

-	bool IsAlpha(GLenum texFormat);

-	bool IsRGB(GLenum texFormat);

-	bool IsRGBA(GLenum texFormat);

-}

-

-namespace es2sw

-{

-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);

-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);

-	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison);

-	sw::Color<float> ConvertColor(es1::Color color);

-	sw::BlendFactor ConvertBlendFunc(GLenum blend);

-	sw::BlendOperation ConvertBlendOp(GLenum blendOp);

-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);

-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap);

-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);

-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);

-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);

-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);

-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount);

-	sw::Format ConvertRenderbufferFormat(GLenum format);

-	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation);

-	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument);

-	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand);

-}

-

-namespace sw2es

-{

-	GLuint GetAlphaSize(sw::Format colorFormat);

-	GLuint GetRedSize(sw::Format colorFormat);

-	GLuint GetGreenSize(sw::Format colorFormat);

-	GLuint GetBlueSize(sw::Format colorFormat);

-	GLuint GetDepthSize(sw::Format depthFormat);

-	GLuint GetStencilSize(sw::Format stencilFormat);

-

-	GLenum ConvertBackBufferFormat(sw::Format format);

-	GLenum ConvertDepthStencilFormat(sw::Format format);

-}

-

-#endif  // LIBGLES_CM_UTILITIES_H

+// 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.
+
+// utilities.h: Conversion functions and other utility routines.
+
+#ifndef LIBGLES_CM_UTILITIES_H
+#define LIBGLES_CM_UTILITIES_H
+
+#include "Device.hpp"
+#include "common/Image.hpp"
+#include "Texture.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <string>
+
+namespace es1
+{
+	struct Color;
+
+	bool IsCompressed(GLenum format);
+	bool IsDepthTexture(GLenum format);
+	bool IsStencilTexture(GLenum format);
+	bool IsCubemapTextureTarget(GLenum target);
+	int CubeFaceIndex(GLenum cubeTarget);
+	bool IsTextureTarget(GLenum target);
+	bool CheckTextureFormatType(GLenum format, GLenum type);
+
+	bool IsColorRenderable(GLenum internalformat);
+	bool IsDepthRenderable(GLenum internalformat);
+	bool IsStencilRenderable(GLenum internalformat);
+
+	bool IsAlpha(GLenum texFormat);
+	bool IsRGB(GLenum texFormat);
+	bool IsRGBA(GLenum texFormat);
+}
+
+namespace es2sw
+{
+	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);
+	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);
+	sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison);
+	sw::Color<float> ConvertColor(es1::Color color);
+	sw::BlendFactor ConvertBlendFunc(GLenum blend);
+	sw::BlendOperation ConvertBlendOp(GLenum blendOp);
+	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
+	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap);
+	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
+	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
+	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount);
+	sw::Format ConvertRenderbufferFormat(GLenum format);
+	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation);
+	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument);
+	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand);
+}
+
+namespace sw2es
+{
+	GLuint GetAlphaSize(sw::Format colorFormat);
+	GLuint GetRedSize(sw::Format colorFormat);
+	GLuint GetGreenSize(sw::Format colorFormat);
+	GLuint GetBlueSize(sw::Format colorFormat);
+	GLuint GetDepthSize(sw::Format depthFormat);
+	GLuint GetStencilSize(sw::Format stencilFormat);
+
+	GLenum ConvertBackBufferFormat(sw::Format format);
+	GLenum ConvertDepthStencilFormat(sw::Format format);
+}
+
+#endif  // LIBGLES_CM_UTILITIES_H