Update to June 11 2013 code drop.

This should fix the hang bug we've been seeing.
diff --git a/src/GLES2/libGLESv2/Buffer.cpp b/src/GLES2/libGLESv2/Buffer.cpp
index e98d8eb..fc535ac 100644
--- a/src/GLES2/libGLESv2/Buffer.cpp
+++ b/src/GLES2/libGLESv2/Buffer.cpp
@@ -61,11 +61,6 @@
 		if(data)
 		{
 			memcpy((void*)mContents->getBuffer(), data, size);
-			memset((char*)mContents->getBuffer() + size, 0, padding);
-		}
-		else
-		{
-			memset((void*)mContents->getBuffer(), 0, size + padding);
 		}
 	}
 }
diff --git a/src/GLES2/libGLESv2/Context.cpp b/src/GLES2/libGLESv2/Context.cpp
index 445962c..a50e3a1 100644
--- a/src/GLES2/libGLESv2/Context.cpp
+++ b/src/GLES2/libGLESv2/Context.cpp
@@ -1336,7 +1336,7 @@
                 switch(pname)

                 {

                 case GL_SAMPLE_BUFFERS:

-                    if(samples != 0)

+                    if(samples > 1)

                     {

                         *params = 1;

                     }

@@ -1346,11 +1346,11 @@
                     }

                     break;

                 case GL_SAMPLES:

-                    *params = samples;

+                    *params = samples & ~1;

                     break;

                 }

             }

-            else 

+            else

             {

                 *params = 0;

             }

@@ -2366,12 +2366,16 @@
 		                        (mState.colorMaskGreen ? 0x2 : 0) | 

 		                        (mState.colorMaskBlue ? 0x4 : 0) |

 		                        (mState.colorMaskAlpha ? 0x8 : 0);

-		device->clearColor(color, rgbaMask);

+

+		if(rgbaMask != 0)

+		{

+			device->clearColor(color, rgbaMask);

+		}

 	}

 

 	if(mask & GL_DEPTH_BUFFER_BIT)

 	{

-		if(mState.depthMask)

+		if(mState.depthMask != 0)

 		{

 			device->clearDepth(depth);

 		}

@@ -2379,7 +2383,10 @@
 

 	if(mask & GL_STENCIL_BUFFER_BIT)

 	{

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

+		if(mState.stencilWritemask != 0)

+		{

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

+		}

 	}

 }

 

@@ -2567,14 +2574,14 @@
     return GL_NO_ERROR;

 }

 

-int Context::getNearestSupportedSamples(sw::Format format, int requested) const

+int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)

 {

     if(requested <= 1)

     {

-        return requested;

+        return 1;

     }

 	

-	if(requested <= 2)

+	if(requested == 2)

 	{

 		return 2;

 	}

@@ -2790,7 +2797,7 @@
         return error(GL_INVALID_FRAMEBUFFER_OPERATION);

     }

 

-    if(drawBufferSamples != 0)

+    if(drawBufferSamples > 1)

     {

         return error(GL_INVALID_OPERATION);

     }

@@ -2950,7 +2957,7 @@
             return error(GL_INVALID_OPERATION);

         }

         

-        if(partialBufferCopy && readBufferSamples != 0)

+        if(partialBufferCopy && readBufferSamples > 1)

         {

             return error(GL_INVALID_OPERATION);

         }

@@ -3004,8 +3011,8 @@
             return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted

         }

 

-        if((drawDSBuffer && drawDSBuffer->getSamples() != 0) || 

-           (readDSBuffer && readDSBuffer->getSamples() != 0))

+        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 

+           (readDSBuffer && readDSBuffer->getSamples() > 1))

         {

             return error(GL_INVALID_OPERATION);

         }

diff --git a/src/GLES2/libGLESv2/Context.h b/src/GLES2/libGLESv2/Context.h
index 1ca0d55..d998f62 100644
--- a/src/GLES2/libGLESv2/Context.h
+++ b/src/GLES2/libGLESv2/Context.h
@@ -409,7 +409,7 @@
 

     GLenum getError();

 

-    int getNearestSupportedSamples(sw::Format format, int requested) const;

+    static int getSupportedMultiSampleDepth(sw::Format format, int requested);

     const char *getExtensionString() const;

     

     void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 

diff --git a/src/GLES2/libGLESv2/Device.cpp b/src/GLES2/libGLESv2/Device.cpp
index 64b888d..e7b1ec9 100644
--- a/src/GLES2/libGLESv2/Device.cpp
+++ b/src/GLES2/libGLESv2/Device.cpp
@@ -280,8 +280,6 @@
 			return 0;

 		}

 

-		surface->addRef();

-

 		return surface;

 	}

 

@@ -302,8 +300,6 @@
 			ERR("Out of memory");

 			return 0;

 		}

-

-		surface->addRef();

 		

 		return surface;

 	}

diff --git a/src/GLES2/libGLESv2/Image.cpp b/src/GLES2/libGLESv2/Image.cpp
index 0b8220e..5b43aae 100644
--- a/src/GLES2/libGLESv2/Image.cpp
+++ b/src/GLES2/libGLESv2/Image.cpp
@@ -11,6 +11,7 @@
 
 #include "Image.hpp"
 
+#include "Texture.h"
 #include "utilities.h"
 #include "../common/debug.h"
 #include "Common/Thread.hpp"
@@ -19,14 +20,29 @@
 
 namespace gl
 {
-	Image::Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type) : sw::Surface(parentTexture, width, height, 1, selectInternalFormat(format, type), true, true), width(width), height(height), internalFormat(selectInternalFormat(format, type)), format(format), type(type), multiSampleDepth(1)
+	static sw::Resource *getParentResource(Texture *texture)
 	{
-		referenceCount = 0;
+		if(texture)
+		{
+			return texture->getResource();
+		}
+
+		return 0;
 	}
 
-	Image::Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget) : sw::Surface(parentTexture, width, height, multiSampleDepth, internalFormat, lockable, renderTarget), width(width), height(height), internalFormat(internalFormat), format(format), type(type), multiSampleDepth(multiSampleDepth)
+	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
+		: parentTexture(parentTexture), width(width), height(height), format(format), type(type)
+		, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
+		, sw::Surface(getParentResource(parentTexture), width, height, 1, selectInternalFormat(format, type), true, true)
 	{
-		referenceCount = 0;
+		referenceCount = 1;
+	}
+
+	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget)
+		: parentTexture(parentTexture), width(width), height(height), internalFormat(internalFormat), format(format), type(type), multiSampleDepth(multiSampleDepth)
+		, sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget)
+	{
+		referenceCount = 1;
 	}
 
 	Image::~Image()
@@ -81,11 +97,21 @@
 
 	void Image::addRef()
 	{
+		if(parentTexture)
+		{
+			return parentTexture->addRef();
+		}
+
 		sw::atomicIncrement(&referenceCount);
 	}
 
 	void Image::release()
 	{
+		if(parentTexture)
+		{
+			return parentTexture->release();
+		}
+
 		if(referenceCount > 0)
 		{
 			sw::atomicDecrement(&referenceCount);
@@ -97,6 +123,13 @@
 		}
 	}
 
+	void Image::unbind()
+	{
+		parentTexture = 0;
+
+		release();
+	}
+
 	sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
 	{
 		#if S3TC_SUPPORT
@@ -163,6 +196,18 @@
 			}
 			else UNREACHABLE();
 		}
+		else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
+		{
+			return sw::FORMAT_A8R8G8B8;
+		}
+		else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
+		{
+			return sw::FORMAT_A8R8G8B8;
+		}
+		else if(type == GL_UNSIGNED_SHORT_5_6_5)
+		{
+			return sw::FORMAT_X8R8G8B8;
+		}
 		else UNREACHABLE();
 
 		return sw::FORMAT_A8R8G8B8;
@@ -288,9 +333,9 @@
 				break;
 			default: UNREACHABLE();
 			}
-
-			unlock();
 		}
+
+		unlock();
 	}
 
 	void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
@@ -653,8 +698,8 @@
 			{
 				memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
 			}
-
-            unlock();
         }
+
+		unlock();
 	}
 }
\ No newline at end of file
diff --git a/src/GLES2/libGLESv2/Image.hpp b/src/GLES2/libGLESv2/Image.hpp
index baf963d..1520504 100644
--- a/src/GLES2/libGLESv2/Image.hpp
+++ b/src/GLES2/libGLESv2/Image.hpp
@@ -19,11 +19,13 @@
 
 namespace gl
 {
+	class Texture;
+
 	class Image : public sw::Surface
 	{
 	public:
-		Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
-		Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget);
+		Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
+		Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget);
 
 		void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
 		void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
@@ -41,6 +43,7 @@
 
 		virtual void addRef();
 		virtual void release();
+		void unbind();   // Break parent ownership and release
 
 		static sw::Format selectInternalFormat(GLenum format, GLenum type);
 		static int bytes(sw::Format format);
@@ -71,6 +74,8 @@
 		void loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
 		void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer);
 
+		Texture *parentTexture;
+
 		const GLsizei width;
 		const GLsizei height;
 		const GLenum format;
diff --git a/src/GLES2/libGLESv2/Program.cpp b/src/GLES2/libGLESv2/Program.cpp
index a1ad45e..41fa7bf 100644
--- a/src/GLES2/libGLESv2/Program.cpp
+++ b/src/GLES2/libGLESv2/Program.cpp
@@ -35,7 +35,7 @@
 		return buffer;

 	}

 

-	Uniform::Uniform(GLenum type, const std::string &name, unsigned int arraySize) : type(type), name(name), arraySize(arraySize)

+	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize)

 	{

 		int bytes = UniformTypeSize(type) * size();

 		data = new unsigned char[bytes];

@@ -1132,7 +1132,6 @@
 					if(in + registers > MAX_VARYING_VECTORS)

 					{

 						appendToInfoLog("Too many varyings");

-

 						return false;

 					}

 

@@ -1141,7 +1140,6 @@
 						if(out + registers > MAX_VARYING_VECTORS)

 						{

 							appendToInfoLog("Too many varyings");

-

 							return false;

 						}

 

@@ -1239,7 +1237,6 @@
 				if(rows + location > MAX_VERTEX_ATTRIBS)

 				{

 					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);

-

 					return false;

 				}

 

@@ -1263,7 +1260,6 @@
 				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)

 				{

 					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());

-

 					return false;   // Fail to link

 				}

 

@@ -1306,7 +1302,7 @@
 		{

 			const sh::Uniform &uniform = activeUniforms[uniformIndex];

 

-			if(!defineUniform(shader->getType(), uniform.type, uniform.name, uniform.arraySize, uniform.registerIndex))

+			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex))

 			{

 				return false;

 			}

@@ -1315,7 +1311,7 @@
 		return true;

 	}

 

-	bool Program::defineUniform(GLenum shader, GLenum type, const std::string &name, unsigned int arraySize, int registerIndex)

+	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)

 	{

 		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE)

 	    {

@@ -1367,12 +1363,19 @@
 

 			if(uniform->type != type)

 			{

+				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());

+				return false;

+			}

+

+			if(uniform->precision != precision)

+			{

+				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());

 				return false;

 			}

 		}

 		else

 		{

-			uniform = new Uniform(type, name, arraySize);

+			uniform = new Uniform(type, precision, name, arraySize);

 		}

 

 		if(!uniform)

@@ -1880,15 +1883,17 @@
 

 		if(!infoLog)

 		{

-			infoLog = new char[infoLength + 1];

+			infoLog = new char[infoLength + 2];

 			strcpy(infoLog, info);

+			strcpy(infoLog + infoLength, "\n");

 		}

 		else

 		{

 			size_t logLength = strlen(infoLog);

-			char *newLog = new char[logLength + infoLength + 1];

+			char *newLog = new char[logLength + infoLength + 2];

 			strcpy(newLog, infoLog);

 			strcpy(newLog + logLength, info);

+			strcpy(newLog + logLength + infoLength, "\n");

 

 			delete[] infoLog;

 			infoLog = newLog;

@@ -2045,7 +2050,7 @@
 		}

 	}

 

-	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

+	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const

 	{

 		// Skip over inactive attributes

 		unsigned int activeAttribute = 0;

@@ -2083,7 +2088,7 @@
 		*type = linkedAttribute[attribute].type;

 	}

 

-	GLint Program::getActiveAttributeCount()

+	GLint Program::getActiveAttributeCount() const

 	{

 		int count = 0;

 

@@ -2098,7 +2103,7 @@
 		return count;

 	}

 

-	GLint Program::getActiveAttributeMaxLength()

+	GLint Program::getActiveAttributeMaxLength() const

 	{

 		int maxLength = 0;

 

@@ -2113,7 +2118,7 @@
 		return maxLength;

 	}

 

-	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

+	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const

 	{

 		if(bufsize > 0)

 		{

@@ -2138,12 +2143,12 @@
 		*type = uniforms[index]->type;

 	}

 

-	GLint Program::getActiveUniformCount()

+	GLint Program::getActiveUniformCount() const

 	{

 		return uniforms.size();

 	}

 

-	GLint Program::getActiveUniformMaxLength()

+	GLint Program::getActiveUniformMaxLength() const

 	{

 		int maxLength = 0;

 

diff --git a/src/GLES2/libGLESv2/Program.h b/src/GLES2/libGLESv2/Program.h
index 404a208..33e358c 100644
--- a/src/GLES2/libGLESv2/Program.h
+++ b/src/GLES2/libGLESv2/Program.h
@@ -1,6 +1,6 @@
 // SwiftShader Software Renderer

 //

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

+// 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

@@ -34,7 +34,7 @@
 	// Helper struct representing a single shader uniform

 	struct Uniform

 	{

-		Uniform(GLenum type, const std::string &name, unsigned int arraySize);

+		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize);

 

 		~Uniform();

 

@@ -43,6 +43,7 @@
 		int registerCount() const;

 

 		const GLenum type;

+		const GLenum precision;

 		const std::string name;

 		const unsigned int arraySize;

 

@@ -109,13 +110,13 @@
 		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);

 		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);

 

-		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);

-		GLint getActiveAttributeCount();

-		GLint getActiveAttributeMaxLength();

+		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

+		GLint getActiveAttributeCount() const;

+		GLint getActiveAttributeMaxLength() const;

 

-		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);

-		GLint getActiveUniformCount();

-		GLint getActiveUniformMaxLength();

+		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;

+		GLint getActiveUniformCount() const;

+		GLint getActiveUniformMaxLength() const;

 

 		void addRef();

 		void release();

@@ -139,7 +140,7 @@
 		int getAttributeBinding(const std::string &name);

 

 		bool linkUniforms(Shader *shader);

-		bool defineUniform(GLenum shader, GLenum type, const std::string &_name, unsigned int arraySize, int registerIndex);

+		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex);

 		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);

 		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);

 		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);

diff --git a/src/GLES2/libGLESv2/Renderbuffer.cpp b/src/GLES2/libGLESv2/Renderbuffer.cpp
index 133b592..79df223 100644
--- a/src/GLES2/libGLESv2/Renderbuffer.cpp
+++ b/src/GLES2/libGLESv2/Renderbuffer.cpp
@@ -332,7 +332,7 @@
 		mHeight = renderTarget->getHeight();
 		internalFormat = renderTarget->getInternalFormat();
 		format = sw2es::ConvertBackBufferFormat(internalFormat);
-		mSamples = renderTarget->getMultiSampleDepth();
+		mSamples = renderTarget->getMultiSampleDepth() & ~1;
 	}
 }
 
@@ -341,14 +341,7 @@
 	Device *device = getDevice();
 
 	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
-	int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
-
-	if(supportedSamples == -1)
-	{
-		error(GL_OUT_OF_MEMORY);
-
-		return;
-	}
+	int supportedSamples = Context::getSupportedMultiSampleDepth(requestedFormat, samples);
 
 	if(width > 0 && height > 0)
 	{
@@ -365,7 +358,7 @@
 	mHeight = height;
 	this->format = format;
 	internalFormat = requestedFormat;
-	mSamples = supportedSamples;
+	mSamples = supportedSamples & ~1;
 }
 
 Colorbuffer::~Colorbuffer()
@@ -398,7 +391,7 @@
 		mHeight = depthStencil->getHeight();
 		internalFormat = depthStencil->getInternalFormat();
 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
-		mSamples = depthStencil->getMultiSampleDepth();
+		mSamples = depthStencil->getMultiSampleDepth() & ~1;
 	}
 }
 
@@ -408,14 +401,7 @@
 
 	mDepthStencil = NULL;
 	
-	int supportedSamples = getContext()->getNearestSupportedSamples(sw::FORMAT_D24S8, samples);
-
-	if(supportedSamples == -1)
-	{
-		error(GL_OUT_OF_MEMORY);
-
-		return;
-	}
+	int supportedSamples = Context::getSupportedMultiSampleDepth(sw::FORMAT_D24S8, samples);
 
 	if(width > 0 && height > 0)
 	{
@@ -432,7 +418,7 @@
 	mHeight = height;
 	format = GL_DEPTH24_STENCIL8_OES;
 	internalFormat = sw::FORMAT_D24S8;
-	mSamples = supportedSamples;
+	mSamples = supportedSamples & ~1;
 }
 
 DepthStencilbuffer::~DepthStencilbuffer()
diff --git a/src/GLES2/libGLESv2/Shader.cpp b/src/GLES2/libGLESv2/Shader.cpp
index f144a24..e4cb5ee 100644
--- a/src/GLES2/libGLESv2/Shader.cpp
+++ b/src/GLES2/libGLESv2/Shader.cpp
@@ -1,6 +1,6 @@
 // SwiftShader Software Renderer
 //
-// Copyright(c) 2005-2012 TransGaming Inc.
+// 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
@@ -24,16 +24,12 @@
 
 namespace gl
 {
-void *Shader::mFragmentCompiler = NULL;
-void *Shader::mVertexCompiler = NULL;
-
 Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
 {
     mSource = NULL;
     mInfoLog = NULL;
 
 	clear();
-	initializeCompiler();
 
     mRefCount = 0;
     mDeleteStatus = false;
@@ -156,6 +152,30 @@
     }
 }
 
+TranslatorASM *Shader::createCompiler(ShShaderType type)
+{
+	ShInitialize();
+
+	TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC);
+
+	ShBuiltInResources resources;
+	ShInitBuiltInResources(&resources);     
+	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
+	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
+	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
+	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
+	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
+	resources.OES_standard_derivatives = 1;
+	resources.OES_fragment_precision_high = 1;
+	resources.MaxCallStackDepth = 16;
+	assembler->Init(resources);
+
+	return assembler;
+}
+
 void Shader::clear()
 {
     delete[] mInfoLog;
@@ -210,43 +230,8 @@
     mDeleteStatus = true;
 }
 
-// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void Shader::initializeCompiler()
-{
-    if(!mFragmentCompiler)
-    {
-        int result = ShInitialize();
-
-        if(result)
-        {
-            ShBuiltInResources resources;
-            ShInitBuiltInResources(&resources);
-            Context *context = getContext();            
-
-            resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
-            resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
-            resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
-            resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
-            resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
-            resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-            resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
-            resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
-            resources.OES_standard_derivatives = 1;
-
-            mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources);
-            mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources);
-        }
-    }
-}
-
 void Shader::releaseCompiler()
 {
-    ShDestruct(mFragmentCompiler);
-    ShDestruct(mVertexCompiler);
-
-    mFragmentCompiler = NULL;
-    mVertexCompiler = NULL;
-
     ShFinalize();
 }
 
@@ -386,25 +371,11 @@
 void VertexShader::compile()
 {
 	clear();
-	initializeCompiler();
 
 	delete vertexShader;
 	vertexShader = new sw::VertexShader();
 
-	TranslatorASM *assembler = new TranslatorASM(this, SH_VERTEX_SHADER, SH_GLES2_SPEC);
-
-	ShBuiltInResources resources;
-	ShInitBuiltInResources(&resources);     
-	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
-	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
-	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
-	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
-	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
-	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
-	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
-	resources.OES_standard_derivatives = 1;
-	assembler->Init(resources);
+	TranslatorASM *compiler = createCompiler(SH_VERTEX_SHADER);
 
 	// Ensure we don't pass a NULL source to the compiler
     char *source = "\0";
@@ -413,7 +384,7 @@
         source = mSource;
     }
 
-	int success = ShCompile(assembler, &source, 1, SH_OBJECT_CODE);
+	int success = ShCompile(compiler, &source, 1, SH_OBJECT_CODE);
 
 	if(false)
 	{
@@ -433,13 +404,13 @@
 		vertexShader = 0;
 
 		int infoLogLen = 0;
-        ShGetInfo(assembler, SH_INFO_LOG_LENGTH, &infoLogLen);
+        ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
         mInfoLog = new char[infoLogLen];
-        ShGetInfoLog(assembler, mInfoLog);
+        ShGetInfoLog(compiler, mInfoLog);
         TRACE("\n%s", mInfoLog);
 	}
 
-	delete assembler;
+	delete compiler;
 }
 
 int VertexShader::getSemanticIndex(const std::string &attributeName)
@@ -486,25 +457,11 @@
 void FragmentShader::compile()
 {
 	clear();
-	initializeCompiler();
 
 	delete pixelShader;
 	pixelShader = new sw::PixelShader();
 
-	TranslatorASM *assembler = new TranslatorASM(this, SH_FRAGMENT_SHADER, SH_GLES2_SPEC);
-
-	ShBuiltInResources resources;
-	ShInitBuiltInResources(&resources);     
-	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
-	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
-	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
-	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
-	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
-	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
-	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
-	resources.OES_standard_derivatives = 1;
-	assembler->Init(resources);
+	TranslatorASM *compiler = createCompiler(SH_FRAGMENT_SHADER);
 
 	// Ensure we don't pass a NULL source to the compiler
     char *source = "\0";
@@ -513,7 +470,7 @@
         source = mSource;
     }
 
-	int success = ShCompile(assembler, &source, 1, SH_OBJECT_CODE);
+	int success = ShCompile(compiler, &source, 1, SH_OBJECT_CODE);
 	
 	if(false)
 	{
@@ -533,13 +490,13 @@
 		pixelShader = 0;
 
 		int infoLogLen = 0;
-        ShGetInfo(assembler, SH_INFO_LOG_LENGTH, &infoLogLen);
+        ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
         mInfoLog = new char[infoLogLen];
-        ShGetInfoLog(assembler, mInfoLog);
+        ShGetInfoLog(compiler, mInfoLog);
         TRACE("\n%s", mInfoLog);
 	}
 
-	delete assembler;
+	delete compiler;
 }
 
 sw::Shader *FragmentShader::getShader() const
diff --git a/src/GLES2/libGLESv2/Shader.h b/src/GLES2/libGLESv2/Shader.h
index 6629c39..b6e7e70 100644
--- a/src/GLES2/libGLESv2/Shader.h
+++ b/src/GLES2/libGLESv2/Shader.h
@@ -1,6 +1,6 @@
 // SwiftShader Software Renderer

 //

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

+// 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

@@ -97,8 +97,8 @@
     static void releaseCompiler();

 

 protected:

+	TranslatorASM *createCompiler(ShShaderType type);

 	void clear();

-	void initializeCompiler();

 

     static GLenum parseType(const std::string &type);

     static bool compareVarying(const Varying &x, const Varying &y);

@@ -116,9 +116,6 @@
     bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use

 

 	ResourceManager *mResourceManager;

-

-	static void *mFragmentCompiler;

-	static void *mVertexCompiler;

 };

 

 class VertexShader : public Shader

diff --git a/src/GLES2/libGLESv2/Texture.cpp b/src/GLES2/libGLESv2/Texture.cpp
index dedc7cb..a6f3886 100644
--- a/src/GLES2/libGLESv2/Texture.cpp
+++ b/src/GLES2/libGLESv2/Texture.cpp
@@ -284,7 +284,7 @@
 	{

 		if(image[i])

 		{

-			image[i]->release();

+			image[i]->unbind();

 			image[i] = 0;

 		}

 	}

@@ -378,18 +378,16 @@
 {

 	if(image[level])

 	{

-		image[level]->release();

+		image[level]->unbind();

 	}

 

-	image[level] = new Image(resource, width, height, format, type);

+	image[level] = new Image(this, width, height, format, type);

 

 	if(!image[level])

 	{

 		return error(GL_OUT_OF_MEMORY);

 	}

 

-	image[level]->addRef();

-

     Texture::setImage(format, type, unpackAlignment, pixels, image[level]);

 }

 

@@ -414,7 +412,7 @@
 	{

 		if(image[level])

 		{

-			image[level]->release();

+			image[level]->unbind();

 			image[level] = 0;

 		}

 	}

@@ -431,7 +429,7 @@
 	{

 		if(image[level])

 		{

-			image[level]->release();

+			image[level]->unbind();

 			image[level] = 0;

 		}

 	}

@@ -441,18 +439,16 @@
 {

 	if(image[level])

 	{

-		image[level]->release();

+		image[level]->unbind();

 	}

 

-	image[level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE);

+	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

 

 	if(!image[level])

 	{

 		return error(GL_OUT_OF_MEMORY);

 	}

 

-	image[level]->addRef();

-

     Texture::setCompressedImage(imageSize, pixels, image[level]);

 }

 

@@ -478,18 +474,16 @@
 

 	if(image[level])

 	{

-		image[level]->release();

+		image[level]->unbind();

 	}

 

-	image[level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE);

+	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

 

 	if(!image[level])

 	{

 		return error(GL_OUT_OF_MEMORY);

 	}

 

-	image[level]->addRef();

-

     if(width != 0 && height != 0)

     {

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

@@ -618,18 +612,16 @@
     {

 		if(image[i])

 		{

-			image[i]->release();

+			image[i]->unbind();

 		}

 

-		image[i] = new Image(resource, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());

+		image[i] = new 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);

 		}

 

-		image[i]->addRef();

-

 		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);

     }

 }

@@ -693,7 +685,7 @@
 		{

 			if(image[f][i])

 			{

-				image[f][i]->release();

+				image[f][i]->unbind();

 				image[f][i] = 0;

 			}

 		}

@@ -801,18 +793,16 @@
 

 	if(image[face][level])

 	{

-		image[face][level]->release();

+		image[face][level]->unbind();

 	}

 

-	image[face][level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE);

+	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

 

 	if(!image[face][level])

 	{

 		return error(GL_OUT_OF_MEMORY);

 	}

 

-	image[face][level]->addRef();

-

     Texture::setCompressedImage(imageSize, pixels, image[face][level]);

 }

 

@@ -939,18 +929,16 @@
 

 	if(image[face][level])

 	{

-		image[face][level]->release();

+		image[face][level]->unbind();

 	}

 

-	image[face][level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE);

+	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

 

 	if(!image[face][level])

 	{

 		return error(GL_OUT_OF_MEMORY);

 	}

 

-	image[face][level]->addRef();

-

     Texture::setImage(format, type, unpackAlignment, pixels, image[face][level]);

 }

 

@@ -968,18 +956,16 @@
 

 	if(image[face][level])

 	{

-		image[face][level]->release();

+		image[face][level]->unbind();

 	}

 

-	image[face][level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE);

+	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);

 

 	if(!image[face][level])

 	{

 		return error(GL_OUT_OF_MEMORY);

 	}

 

-	image[face][level]->addRef();

-

     if(width != 0 && height != 0)

     {

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

@@ -1048,18 +1034,16 @@
 		{

 			if(image[f][i])

 			{

-				image[f][i]->release();

+				image[f][i]->unbind();

 			}

 

-			image[f][i] = new Image(resource, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());

+			image[f][i] = new Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());

 

 			if(!image[f][i])

 			{

 				return error(GL_OUT_OF_MEMORY);

 			}

 

-			image[f][i]->addRef();

-

 			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true);

 		}

 	}

diff --git a/src/GLES2/libGLESv2/Texture.h b/src/GLES2/libGLESv2/Texture.h
index d62a537..302c7f0 100644
--- a/src/GLES2/libGLESv2/Texture.h
+++ b/src/GLES2/libGLESv2/Texture.h
@@ -90,8 +90,6 @@
     virtual void generateMipmaps() = 0;

     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

 

-    static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1);   // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.

-

 protected:

     void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);

     void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);

@@ -116,7 +114,7 @@
 public:

     explicit Texture2D(GLuint id);

 

-    ~Texture2D();

+    virtual ~Texture2D();

 

 	virtual bool isTexture2D();

 

@@ -172,7 +170,7 @@
 public:

     explicit TextureCubeMap(GLuint id);

 

-    ~TextureCubeMap();

+    virtual ~TextureCubeMap();

 

 	virtual bool isTextureCubeMap();

 

diff --git a/src/GLES2/libGLESv2/libGLESv2.cbp b/src/GLES2/libGLESv2/libGLESv2.cbp
index 8f5d976..443c986 100644
--- a/src/GLES2/libGLESv2/libGLESv2.cbp
+++ b/src/GLES2/libGLESv2/libGLESv2.cbp
@@ -141,12 +141,12 @@
 		<Unit filename="./../../Common/Version.h" />
 		<Unit filename="./../common/debug.cpp" />
 		<Unit filename="./../common/debug.h" />
+		<Unit filename="../compiler/AnalyzeCallDepth.cpp" />
+		<Unit filename="../compiler/AnalyzeCallDepth.h" />
 		<Unit filename="../compiler/BaseTypes.h" />
 		<Unit filename="../compiler/Common.h" />
 		<Unit filename="../compiler/Compiler.cpp" />
 		<Unit filename="../compiler/ConstantUnion.h" />
-		<Unit filename="../compiler/DetectRecursion.cpp" />
-		<Unit filename="../compiler/DetectRecursion.h" />
 		<Unit filename="../compiler/Diagnostics.cpp" />
 		<Unit filename="../compiler/Diagnostics.h" />
 		<Unit filename="../compiler/DirectiveHandler.cpp" />
diff --git a/src/GLES2/libGLESv2/libGLESv2.cpp b/src/GLES2/libGLESv2/libGLESv2.cpp
index 0448330..96f004e 100644
--- a/src/GLES2/libGLESv2/libGLESv2.cpp
+++ b/src/GLES2/libGLESv2/libGLESv2.cpp
@@ -24,6 +24,7 @@
 #include "Query.h"

 #include "common/debug.h"

 #include "Common/Version.h"

+#include "Main/Register.hpp"

 

 #define GL_APICALL

 #include <GLES2/gl2.h>

@@ -1119,7 +1120,7 @@
                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);

             }

 

-            if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)

+            if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

             {

                 return error(GL_INVALID_OPERATION);

             }

@@ -1255,7 +1256,7 @@
                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);

             }

 

-            if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)

+            if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)

             {

                 return error(GL_INVALID_OPERATION);

             }

@@ -3200,26 +3201,17 @@
 

             switch(pname)

             {

-              case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;

-              case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;

-              case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;

-              case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;

-              case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;

-              case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;

-              case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;

-              case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;

-              case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;

-              case GL_RENDERBUFFER_SAMPLES_ANGLE:

-                if(gl::IMPLEMENTATION_MAX_SAMPLES != 0)

-                {

-                    *params = renderbuffer->getSamples();

-                }

-                else

-                {

-                    return error(GL_INVALID_ENUM);

-                }

-                break;

-              default:

+            case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;

+            case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;

+            case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;

+            case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;

+            case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;

+            case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;

+            case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;

+            case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;

+            case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;

+            case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;

+            default:

                 return error(GL_INVALID_ENUM);

             }

         }

@@ -6118,4 +6110,9 @@
     }

 }

 

+void GL_APIENTRY Register(const char *licenseKey)

+{

+	RegisterLicenseKey(licenseKey);

+}

+

 }

diff --git a/src/GLES2/libGLESv2/libGLESv2.vcxproj b/src/GLES2/libGLESv2/libGLESv2.vcxproj
index 924cd42..622d914 100644
--- a/src/GLES2/libGLESv2/libGLESv2.vcxproj
+++ b/src/GLES2/libGLESv2/libGLESv2.vcxproj
@@ -80,13 +80,10 @@
       <BrowseInformation>true</BrowseInformation>

     </ClCompile>

     <Link>

-      <AdditionalDependencies>dxguid.lib;dwmapi.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

       <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile>

       <GenerateDebugInformation>true</GenerateDebugInformation>

       <SubSystem>Windows</SubSystem>

-      <RandomizedBaseAddress>false</RandomizedBaseAddress>

-      <DataExecutionPrevention>

-      </DataExecutionPrevention>

       <TargetMachine>MachineX86</TargetMachine>

     </Link>

     <PostBuildEvent>

@@ -114,16 +111,13 @@
       <IntrinsicFunctions>false</IntrinsicFunctions>

     </ClCompile>

     <Link>

-      <AdditionalDependencies>dxguid.lib;dwmapi.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

       <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>

       <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile>

       <GenerateDebugInformation>true</GenerateDebugInformation>

       <SubSystem>Windows</SubSystem>

       <OptimizeReferences>true</OptimizeReferences>

       <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <RandomizedBaseAddress>false</RandomizedBaseAddress>

-      <DataExecutionPrevention>

-      </DataExecutionPrevention>

       <TargetMachine>MachineX86</TargetMachine>

     </Link>

     <PostBuildEvent>

@@ -150,16 +144,13 @@
       <IntrinsicFunctions>false</IntrinsicFunctions>

     </ClCompile>

     <Link>

-      <AdditionalDependencies>dxguid.lib;dwmapi.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>

       <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>

       <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile>

       <GenerateDebugInformation>true</GenerateDebugInformation>

       <SubSystem>Windows</SubSystem>

       <OptimizeReferences>true</OptimizeReferences>

       <EnableCOMDATFolding>true</EnableCOMDATFolding>

-      <RandomizedBaseAddress>true</RandomizedBaseAddress>

-      <DataExecutionPrevention>

-      </DataExecutionPrevention>

       <TargetMachine>MachineX86</TargetMachine>

     </Link>

     <PostBuildEvent>

@@ -238,4 +229,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

   <ImportGroup Label="ExtensionTargets">

   </ImportGroup>

-</Project>

+</Project>
\ No newline at end of file
diff --git a/src/GLES2/libGLESv2/main.cpp b/src/GLES2/libGLESv2/main.cpp
index 4393ae7..9ddca97 100644
--- a/src/GLES2/libGLESv2/main.cpp
+++ b/src/GLES2/libGLESv2/main.cpp
@@ -1,6 +1,6 @@
 // SwiftShader Software Renderer

 //

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

+// 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

@@ -107,9 +107,21 @@
 

 namespace gl

 {

+static gl::Current *getCurrent(void)

+{

+	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);

+

+	if(!current)

+	{

+		glAttachThread();

+	}

+

+	return (Current*)sw::Thread::getLocalStorage(currentTLS);

+}

+

 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)

 {

-    Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);

+    Current *current = getCurrent();

 

     current->context = context;

     current->display = display;

@@ -122,14 +134,14 @@
 

 Context *getContext()

 {

-    Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);

+    Current *current = getCurrent();

 

     return current->context;

 }

 

 egl::Display *getDisplay()

 {

-    Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);

+    Current *current = getCurrent();

 

     return current->display;

 }