diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index b626562..7a801d9 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -1,1187 +1,1190 @@
-// 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.
-//
-
-// libEGL.cpp: Implements the exported EGL functions.
-
-#include "main.h"
-#include "Display.h"
-#include "Surface.h"
-#include "Texture.hpp"
-#include "Context.hpp"
-#include "common/Image.hpp"
-#include "common/debug.h"
-#include "Common/Version.h"
-
-#if defined(__ANDROID__)
-#include <system/window.h>
-#elif defined(__linux__)
-#include "Main/libX11.hpp"
-#endif
-
-#include <string.h>
-
-using namespace egl;
-
-static bool validateDisplay(egl::Display *display)
-{
-	if(display == EGL_NO_DISPLAY)
-	{
-		return error(EGL_BAD_DISPLAY, false);
-	}
-
-	if(!display->isInitialized())
-	{
-		return error(EGL_NOT_INITIALIZED, false);
-	}
-
-	return true;
-}
-
-static bool validateConfig(egl::Display *display, EGLConfig config)
-{
-	if(!validateDisplay(display))
-	{
-		return false;
-	}
-
-	if(!display->isValidConfig(config))
-	{
-		return error(EGL_BAD_CONFIG, false);
-	}
-
-	return true;
-}
-
-static bool validateContext(egl::Display *display, egl::Context *context)
-{
-	if(!validateDisplay(display))
-	{
-		return false;
-	}
-
-	if(!display->isValidContext(context))
-	{
-		return error(EGL_BAD_CONTEXT, false);
-	}
-
-	return true;
-}
-
-static bool validateSurface(egl::Display *display, egl::Surface *surface)
-{
-	if(!validateDisplay(display))
-	{
-		return false;
-	}
-
-	if(!display->isValidSurface(surface))
-	{
-		return error(EGL_BAD_SURFACE, false);
-	}
-
-	return true;
-}
-
-namespace egl
-{
-EGLint GetError(void)
-{
-	TRACE("()");
-
-	EGLint error = egl::getCurrentError();
-
-	if(error != EGL_SUCCESS)
-	{
-		egl::setCurrentError(EGL_SUCCESS);
-	}
-
-	return error;
-}
-
-EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
-{
-	TRACE("(EGLNativeDisplayType display_id = %p)", display_id);
-
-	if(display_id != EGL_DEFAULT_DISPLAY)
-	{
-		// FIXME: Check if display_id is the default display
-	}
-
-	#if defined(__linux__) && !defined(__ANDROID__)
-		if(!libX11)
-		{
-			return success(HEADLESS_DISPLAY);
-		}
-	#endif
-
-	return success(PRIMARY_DISPLAY);   // We only support the default display
-}
-
-EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",
-		  dpy, major, minor);
-
-	if(dpy == EGL_NO_DISPLAY)
-	{
-		return error(EGL_BAD_DISPLAY, EGL_FALSE);
-	}
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!display->initialize())
-	{
-		return error(EGL_NOT_INITIALIZED, EGL_FALSE);
-	}
-
-	if(major) *major = 1;
-	if(minor) *minor = 4;
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean Terminate(EGLDisplay dpy)
-{
-	TRACE("(EGLDisplay dpy = %p)", dpy);
-
-	if(dpy == EGL_NO_DISPLAY)
-	{
-		return error(EGL_BAD_DISPLAY, EGL_FALSE);
-	}
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	display->terminate();
-
-	return success(EGL_TRUE);
-}
-
-const char *QueryString(EGLDisplay dpy, EGLint name)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);
-
-	#if defined(__linux__) && !defined(__ANDROID__)
-		if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
-		{
-			return success("EGL_KHR_platform_gbm "
-			               "EGL_KHR_platform_x11 "
-			               "EGL_EXT_client_extensions "
-			               "EGL_EXT_platform_base");
-		}
-	#endif
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateDisplay(display))
-	{
-		return NULL;
-	}
-
-	switch(name)
-	{
-	case EGL_CLIENT_APIS:
-		return success("OpenGL_ES");
-	case EGL_EXTENSIONS:
-		return success("EGL_KHR_gl_texture_2D_image "
-		               "EGL_KHR_gl_texture_cubemap_image "
-		               "EGL_KHR_gl_renderbuffer_image "
-		               "EGL_KHR_fence_sync "
-		               "EGL_KHR_image_base "
-		               "EGL_ANDROID_framebuffer_target "
-		               "EGL_ANDROID_recordable");
-	case EGL_VENDOR:
-		return success("TransGaming Inc.");
-	case EGL_VERSION:
-		return success("1.4 SwiftShader " VERSION_STRING);
-	}
-
-	return error(EGL_BAD_PARAMETER, (const char*)NULL);
-}
-
-EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "
-		  "EGLint config_size = %d, EGLint *num_config = %p)",
-		  dpy, configs, config_size, num_config);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateDisplay(display))
-	{
-		return EGL_FALSE;
-	}
-
-	if(!num_config)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	const EGLint attribList[] = {EGL_NONE};
-
-	if(!display->getConfigs(configs, attribList, config_size, num_config))
-	{
-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
-{
-	TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "
-		  "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",
-		  dpy, attrib_list, configs, config_size, num_config);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateDisplay(display))
-	{
-		return EGL_FALSE;
-	}
-
-	if(!num_config)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	const EGLint attribList[] = {EGL_NONE};
-
-	if(!attrib_list)
-	{
-		attrib_list = attribList;
-	}
-
-	if(!display->getConfigs(configs, attrib_list, config_size, num_config))
-	{
-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",
-		  dpy, config, attribute, value);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateConfig(display, config))
-	{
-		return EGL_FALSE;
-	}
-
-	if(!display->getConfigAttrib(config, attribute, value))
-	{
-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
-		  "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateConfig(display, config))
-	{
-		return EGL_NO_SURFACE;
-	}
-
-	if(!display->isValidWindow(window))
-	{
-		return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
-	}
-
-	return display->createWindowSurface(window, config, attrib_list);
-}
-
-EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",
-		  dpy, config, attrib_list);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateConfig(display, config))
-	{
-		return EGL_NO_SURFACE;
-	}
-
-	return display->createPBufferSurface(config, attrib_list);
-}
-
-EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
-		  "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateConfig(display, config))
-	{
-		return EGL_NO_SURFACE;
-	}
-
-	UNIMPLEMENTED();   // FIXME
-
-	return success(EGL_NO_SURFACE);
-}
-
-EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	if(surface == EGL_NO_SURFACE)
-	{
-		return error(EGL_BAD_SURFACE, EGL_FALSE);
-	}
-
-	display->destroySurface((egl::Surface*)surface);
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",
-		  dpy, surface, attribute, value);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = (egl::Surface*)surface;
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	if(surface == EGL_NO_SURFACE)
-	{
-		return error(EGL_BAD_SURFACE, EGL_FALSE);
-	}
-
-	switch(attribute)
-	{
-	case EGL_VG_ALPHA_FORMAT:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_VG_COLORSPACE:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_CONFIG_ID:
-		*value = eglSurface->getConfigID();
-		break;
-	case EGL_HEIGHT:
-		*value = eglSurface->getHeight();
-		break;
-	case EGL_HORIZONTAL_RESOLUTION:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_LARGEST_PBUFFER:
-		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
-		{
-			*value = eglSurface->getLargestPBuffer();
-		}
-		break;
-	case EGL_MIPMAP_TEXTURE:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_MIPMAP_LEVEL:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_MULTISAMPLE_RESOLVE:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_PIXEL_ASPECT_RATIO:
-		*value = eglSurface->getPixelAspectRatio();
-		break;
-	case EGL_RENDER_BUFFER:
-		*value = eglSurface->getRenderBuffer();
-		break;
-	case EGL_SWAP_BEHAVIOR:
-		*value = eglSurface->getSwapBehavior();
-		break;
-	case EGL_TEXTURE_FORMAT:
-		*value = eglSurface->getTextureFormat();
-		break;
-	case EGL_TEXTURE_TARGET:
-		*value = eglSurface->getTextureTarget();
-		break;
-	case EGL_VERTICAL_RESOLUTION:
-		UNIMPLEMENTED();   // FIXME
-		break;
-	case EGL_WIDTH:
-		*value = eglSurface->getWidth();
-		break;
-	default:
-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean BindAPI(EGLenum api)
-{
-	TRACE("(EGLenum api = 0x%X)", api);
-
-	switch(api)
-	{
-	case EGL_OPENGL_API:
-	case EGL_OPENVG_API:
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
-	case EGL_OPENGL_ES_API:
-		break;
-	default:
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	egl::setCurrentAPI(api);
-
-	return success(EGL_TRUE);
-}
-
-EGLenum QueryAPI(void)
-{
-	TRACE("()");
-
-	EGLenum API = egl::getCurrentAPI();
-
-	return success(API);
-}
-
-EGLBoolean WaitClient(void)
-{
-	TRACE("()");
-
-	UNIMPLEMENTED();   // FIXME
-
-	return success(EGL_FALSE);
-}
-
-EGLBoolean ReleaseThread(void)
-{
-	TRACE("()");
-
-	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
-
-	return success(EGL_TRUE);
-}
-
-EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "
-		  "EGLConfig config = %p, const EGLint *attrib_list = %p)",
-		  dpy, buftype, buffer, config, attrib_list);
-
-	UNIMPLEMENTED();
-
-	return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
-}
-
-EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",
-		  dpy, surface, attribute, value);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	switch(attribute)
-	{
-	case EGL_SWAP_BEHAVIOR:
-		if(value == EGL_BUFFER_PRESERVED)
-		{
-			if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
-			{
-				return error(EGL_BAD_MATCH, EGL_FALSE);
-			}
-		}
-		else if(value != EGL_BUFFER_DESTROYED)
-		{
-			return error(EGL_BAD_PARAMETER, EGL_FALSE);
-		}
-		eglSurface->setSwapBehavior(value);
-		break;
-	default:
-		UNIMPLEMENTED();   // FIXME
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	if(buffer != EGL_BACK_BUFFER)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
-	{
-		return error(EGL_BAD_SURFACE, EGL_FALSE);
-	}
-
-	if(eglSurface->getBoundTexture())
-	{
-		return error(EGL_BAD_ACCESS, EGL_FALSE);
-	}
-
-	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
-	{
-		return error(EGL_BAD_MATCH, EGL_FALSE);
-	}
-
-	egl::Context *context = egl::getCurrentContext();
-
-	if(context)
-	{
-		context->bindTexImage(eglSurface);
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	if(buffer != EGL_BACK_BUFFER)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
-	{
-		return error(EGL_BAD_SURFACE, EGL_FALSE);
-	}
-
-	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
-	{
-		return error(EGL_BAD_MATCH, EGL_FALSE);
-	}
-
-	egl::Texture *texture = eglSurface->getBoundTexture();
-
-	if(texture)
-	{
-		texture->releaseTexImage();
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Context *context = egl::getCurrentContext();
-
-	if(!validateContext(display, context))
-	{
-		return EGL_FALSE;
-	}
-
-	egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
-
-	if(!draw_surface)
-	{
-		return error(EGL_BAD_SURFACE, EGL_FALSE);
-	}
-
-	draw_surface->setSwapInterval(interval);
-
-	return success(EGL_TRUE);
-}
-
-EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "
-		  "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);
-
-	EGLint clientVersion = 1;
-	if(attrib_list)
-	{
-		for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
-		{
-			if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
-			{
-				clientVersion = attribute[1];
-			}
-			else
-			{
-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
-			}
-		}
-	}
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Context *shareContext = static_cast<egl::Context*>(share_context);
-
-	if(!validateConfig(display, config))
-	{
-		return EGL_NO_CONTEXT;
-	}
-
-	if(shareContext && shareContext->getClientVersion() != clientVersion)
-	{
-		return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
-	}
-
-	return display->createContext(config, shareContext, clientVersion);
-}
-
-EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Context *context = static_cast<egl::Context*>(ctx);
-
-	if(!validateContext(display, context))
-	{
-		return EGL_FALSE;
-	}
-
-	if(ctx == EGL_NO_CONTEXT)
-	{
-		return error(EGL_BAD_CONTEXT, EGL_FALSE);
-	}
-
-	display->destroyContext(context);
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",
-		  dpy, draw, read, ctx);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Context *context = static_cast<egl::Context*>(ctx);
-	egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);
-	egl::Surface *readSurface = static_cast<egl::Surface*>(read);
-
-	if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)
-	{
-		if(!validateDisplay(display))
-		{
-			return EGL_FALSE;
-		}
-	}
-
-	if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
-	{
-		return error(EGL_BAD_MATCH, EGL_FALSE);
-	}
-
-	if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
-	{
-		return EGL_FALSE;
-	}
-
-	if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||
-	   (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))
-	{
-		return EGL_FALSE;
-	}
-
-	if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))
-	{
-		return error(EGL_BAD_MATCH, EGL_FALSE);
-	}
-
-	if(draw != read)
-	{
-		UNIMPLEMENTED();   // FIXME
-	}
-
-	egl::setCurrentDisplay(dpy);
-	egl::setCurrentDrawSurface(drawSurface);
-	egl::setCurrentReadSurface(readSurface);
-	egl::setCurrentContext(context);
-
-	if(context)
-	{
-		context->makeCurrent(drawSurface);
-	}
-
-	return success(EGL_TRUE);
-}
-
-EGLContext GetCurrentContext(void)
-{
-	TRACE("()");
-
-	EGLContext context = egl::getCurrentContext();
-
-	return success(context);
-}
-
-EGLSurface GetCurrentSurface(EGLint readdraw)
-{
-	TRACE("(EGLint readdraw = %d)", readdraw);
-
-	if(readdraw == EGL_READ)
-	{
-		EGLSurface read = egl::getCurrentReadSurface();
-		return success(read);
-	}
-	else if(readdraw == EGL_DRAW)
-	{
-		EGLSurface draw = egl::getCurrentDrawSurface();
-		return success(draw);
-	}
-	else
-	{
-		return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
-	}
-}
-
-EGLDisplay GetCurrentDisplay(void)
-{
-	TRACE("()");
-
-	return success(egl::getCurrentDisplay());
-}
-
-EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",
-		  dpy, ctx, attribute, value);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Context *context = static_cast<egl::Context*>(ctx);
-
-	if(!validateContext(display, context))
-	{
-		return EGL_FALSE;
-	}
-
-	UNIMPLEMENTED();   // FIXME
-
-	return success(0);
-}
-
-EGLBoolean WaitGL(void)
-{
-	TRACE("()");
-
-	UNIMPLEMENTED();   // FIXME
-
-	return success(EGL_FALSE);
-}
-
-EGLBoolean WaitNative(EGLint engine)
-{
-	TRACE("(EGLint engine = %d)", engine);
-
-	UNIMPLEMENTED();   // FIXME
-
-	return success(EGL_FALSE);
-}
-
-EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = (egl::Surface*)surface;
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	if(surface == EGL_NO_SURFACE)
-	{
-		return error(EGL_BAD_SURFACE, EGL_FALSE);
-	}
-
-	eglSurface->swap();
-
-	return success(EGL_TRUE);
-}
-
-EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
-	if(!validateSurface(display, eglSurface))
-	{
-		return EGL_FALSE;
-	}
-
-	UNIMPLEMENTED();   // FIXME
-
-	return success(EGL_FALSE);
-}
-
-EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);
-
-	egl::Display *display = egl::Display::get(dpy);
-	egl::Context *context = static_cast<egl::Context*>(ctx);
-
-	if(!validateDisplay(display))
-	{
-		return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
-	}
-
-	if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
-	{
-		return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
-	}
-
-	EGLenum imagePreserved = EGL_FALSE;
-	GLuint textureLevel = 0;
-	if(attrib_list)
-	{
-		for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
-		{
-			if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
-			{
-				imagePreserved = attribute[1];
-			}
-			else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
-			{
-				textureLevel = attribute[1];
-			}
-			else
-			{
-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
-			}
-		}
-	}
-
-	#if defined(__ANDROID__)
-		if(target == EGL_NATIVE_BUFFER_ANDROID)
-		{
-			ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(buffer);
-
-			if(!nativeBuffer || GLPixelFormatFromAndroid(nativeBuffer->format) == GL_NONE)
-			{
-				ALOGW("%s badness unsupported HAL format=%x", __FUNCTION__, nativeBuffer ? nativeBuffer->format : 0);
-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
-			}
-
-			return success(new AndroidNativeImage(nativeBuffer));
-		}
-	#endif
-
-	GLuint name = reinterpret_cast<intptr_t>(buffer);
-
-	if(name == 0)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-	}
-
-	EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
-
-	if(validationResult != EGL_SUCCESS)
-	{
-		return error(validationResult, EGL_NO_IMAGE_KHR);
-	}
-
-	egl::Image *image = context->createSharedImage(target, name, textureLevel);
-
-	if(!image)
-	{
-		return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
-	}
-
-	if(image->getDepth() > 1)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-	}
-
-	return success((EGLImageKHR)image);
-}
-
-EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateDisplay(display))
-	{
-		return error(EGL_BAD_DISPLAY, EGL_FALSE);
-	}
-
-	if(!image)
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	egl::Image *glImage = static_cast<egl::Image*>(image);
-	glImage->destroyShared();
-
-	return success(EGL_TRUE);
-}
-
-EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
-{
-	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
-
-	switch(platform)
-	{
-	#if defined(__linux__) && !defined(__ANDROID__)
-	case EGL_PLATFORM_X11_EXT: break;
-	case EGL_PLATFORM_GBM_KHR: break;
-	#endif
-	default:
-		return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
-	}
-
-	#if defined(__linux__) && !defined(__ANDROID__)
-		if(platform == EGL_PLATFORM_X11_EXT)
-		{
-			if(!libX11)
-			{
-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);
-			}
-
-			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
-			{
-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
-			}
-		}
-		else if(platform == EGL_PLATFORM_GBM_KHR)
-		{
-			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
-			{
-				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
-			}
-
-			return success(HEADLESS_DISPLAY);
-		}
-	#endif
-
-	return success(PRIMARY_DISPLAY);   // We only support the default display
-}
-
-EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
-{
-	return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
-}
-
-EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
-{
-	return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
-}
-
-EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
-
-	egl::Display *display = egl::Display::get(dpy);
-
-	if(!validateDisplay(display))
-	{
-		return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
-	}
-
-	if(type != EGL_SYNC_FENCE_KHR)
-	{
-		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
-	}
-
-	if(attrib_list && attrib_list[0] != EGL_NONE)
-	{
-		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
-	}
-
-	egl::Context *context = egl::getCurrentContext();
-
-	if(!validateContext(display, context))
-	{
-		return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
-	}
-
-	EGLSyncKHR sync = display->createSync(context);
-
-	return success(sync);
-}
-
-EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
-
-	egl::Display *display = egl::Display::get(dpy);
-	FenceSync *eglSync = static_cast<FenceSync*>(sync);
-
-	if(!validateDisplay(display))
-	{
-		return error(EGL_BAD_DISPLAY, EGL_FALSE);
-	}
-
-	if(!display->isValidSync(eglSync))
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	display->destroySync(eglSync);
-
-	return success(EGL_TRUE);
-}
-
-EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
-
-	egl::Display *display = egl::Display::get(dpy);
-	FenceSync *eglSync = static_cast<FenceSync*>(sync);
-
-	if(!validateDisplay(display))
-	{
-		return error(EGL_BAD_DISPLAY, EGL_FALSE);
-	}
-
-	if(!display->isValidSync(eglSync))
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	(void)flags;
-	(void)timeout;
-
-	if(!eglSync->isSignaled())
-	{
-		eglSync->wait();
-	}
-
-	return success(EGL_CONDITION_SATISFIED_KHR);
-}
-
-EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
-{
-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
-
-	egl::Display *display = egl::Display::get(dpy);
-	FenceSync *eglSync = static_cast<FenceSync*>(sync);
-
-	if(!validateDisplay(display))
-	{
-		return error(EGL_BAD_DISPLAY, EGL_FALSE);
-	}
-
-	if(!display->isValidSync(eglSync))
-	{
-		return error(EGL_BAD_PARAMETER, EGL_FALSE);
-	}
-
-	switch(attribute)
-	{
-	case EGL_SYNC_TYPE_KHR:
-		*value = EGL_SYNC_FENCE_KHR;
-		return success(EGL_TRUE);
-	case EGL_SYNC_STATUS_KHR:
-		eglSync->wait();   // TODO: Don't block. Just poll based on sw::Query.
-		*value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
-		return success(EGL_TRUE);
-	case EGL_SYNC_CONDITION_KHR:
-		*value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
-		return success(EGL_TRUE);
-	default:
-		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-	}
-}
-
-__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
-{
-	TRACE("(const char *procname = \"%s\")", procname);
-
-	struct Extension
-	{
-		const char *name;
-		__eglMustCastToProperFunctionPointerType address;
-	};
-
-	static const Extension eglExtensions[] =
-	{
-		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
-
-		EXTENSION(eglCreateImageKHR),
-		EXTENSION(eglDestroyImageKHR),
-		EXTENSION(eglGetPlatformDisplayEXT),
-		EXTENSION(eglCreatePlatformWindowSurfaceEXT),
-		EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
-		EXTENSION(eglCreateSyncKHR),
-		EXTENSION(eglDestroySyncKHR),
-		EXTENSION(eglClientWaitSyncKHR),
-		EXTENSION(eglGetSyncAttribKHR),
-
-		#undef EXTENSION
-	};
-
-	for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
-	{
-		if(strcmp(procname, eglExtensions[ext].name) == 0)
-		{
-			return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address);
-		}
-	}
-
-	if(libGLESv2)
-	{
-		__eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);
-		if(proc) return success(proc);
-	}
-
-	if(libGLES_CM)
-	{
-		__eglMustCastToProperFunctionPointerType proc =  libGLES_CM->es1GetProcAddress(procname);
-		if(proc) return success(proc);
-	}
-
-	return success((__eglMustCastToProperFunctionPointerType)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.
+
+// libEGL.cpp: Implements the exported EGL functions.
+
+#include "main.h"
+#include "Display.h"
+#include "Surface.h"
+#include "Texture.hpp"
+#include "Context.hpp"
+#include "common/Image.hpp"
+#include "common/debug.h"
+#include "Common/Version.h"
+
+#if defined(__ANDROID__)
+#include <system/window.h>
+#elif defined(__linux__)
+#include "Main/libX11.hpp"
+#endif
+
+#include <string.h>
+
+using namespace egl;
+
+static bool validateDisplay(egl::Display *display)
+{
+	if(display == EGL_NO_DISPLAY)
+	{
+		return error(EGL_BAD_DISPLAY, false);
+	}
+
+	if(!display->isInitialized())
+	{
+		return error(EGL_NOT_INITIALIZED, false);
+	}
+
+	return true;
+}
+
+static bool validateConfig(egl::Display *display, EGLConfig config)
+{
+	if(!validateDisplay(display))
+	{
+		return false;
+	}
+
+	if(!display->isValidConfig(config))
+	{
+		return error(EGL_BAD_CONFIG, false);
+	}
+
+	return true;
+}
+
+static bool validateContext(egl::Display *display, egl::Context *context)
+{
+	if(!validateDisplay(display))
+	{
+		return false;
+	}
+
+	if(!display->isValidContext(context))
+	{
+		return error(EGL_BAD_CONTEXT, false);
+	}
+
+	return true;
+}
+
+static bool validateSurface(egl::Display *display, egl::Surface *surface)
+{
+	if(!validateDisplay(display))
+	{
+		return false;
+	}
+
+	if(!display->isValidSurface(surface))
+	{
+		return error(EGL_BAD_SURFACE, false);
+	}
+
+	return true;
+}
+
+namespace egl
+{
+EGLint GetError(void)
+{
+	TRACE("()");
+
+	EGLint error = egl::getCurrentError();
+
+	if(error != EGL_SUCCESS)
+	{
+		egl::setCurrentError(EGL_SUCCESS);
+	}
+
+	return error;
+}
+
+EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
+{
+	TRACE("(EGLNativeDisplayType display_id = %p)", display_id);
+
+	if(display_id != EGL_DEFAULT_DISPLAY)
+	{
+		// FIXME: Check if display_id is the default display
+	}
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(!libX11)
+		{
+			return success(HEADLESS_DISPLAY);
+		}
+	#endif
+
+	return success(PRIMARY_DISPLAY);   // We only support the default display
+}
+
+EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLint *major = %p, EGLint *minor = %p)",
+		  dpy, major, minor);
+
+	if(dpy == EGL_NO_DISPLAY)
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!display->initialize())
+	{
+		return error(EGL_NOT_INITIALIZED, EGL_FALSE);
+	}
+
+	if(major) *major = 1;
+	if(minor) *minor = 4;
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean Terminate(EGLDisplay dpy)
+{
+	TRACE("(EGLDisplay dpy = %p)", dpy);
+
+	if(dpy == EGL_NO_DISPLAY)
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	display->terminate();
+
+	return success(EGL_TRUE);
+}
+
+const char *QueryString(EGLDisplay dpy, EGLint name)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLint name = %d)", dpy, name);
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
+		{
+			return success("EGL_KHR_platform_gbm "
+			               "EGL_KHR_platform_x11 "
+			               "EGL_EXT_client_extensions "
+			               "EGL_EXT_platform_base");
+		}
+	#endif
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return nullptr;
+	}
+
+	switch(name)
+	{
+	case EGL_CLIENT_APIS:
+		return success("OpenGL_ES");
+	case EGL_EXTENSIONS:
+		return success("EGL_KHR_gl_texture_2D_image "
+		               "EGL_KHR_gl_texture_cubemap_image "
+		               "EGL_KHR_gl_renderbuffer_image "
+		               "EGL_KHR_fence_sync "
+		               "EGL_KHR_image_base "
+		               "EGL_ANDROID_framebuffer_target "
+		               "EGL_ANDROID_recordable");
+	case EGL_VENDOR:
+		return success("Google Inc.");
+	case EGL_VERSION:
+		return success("1.4 SwiftShader " VERSION_STRING);
+	}
+
+	return error(EGL_BAD_PARAMETER, (const char*)nullptr);
+}
+
+EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig *configs = %p, "
+	      "EGLint config_size = %d, EGLint *num_config = %p)",
+	      dpy, configs, config_size, num_config);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return EGL_FALSE;
+	}
+
+	if(!num_config)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	const EGLint attribList[] = {EGL_NONE};
+
+	if(!display->getConfigs(configs, attribList, config_size, num_config))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	TRACE("(EGLDisplay dpy = %p, const EGLint *attrib_list = %p, "
+	      "EGLConfig *configs = %p, EGLint config_size = %d, EGLint *num_config = %p)",
+	      dpy, attrib_list, configs, config_size, num_config);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return EGL_FALSE;
+	}
+
+	if(!num_config)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	const EGLint attribList[] = {EGL_NONE};
+
+	if(!attrib_list)
+	{
+		attrib_list = attribList;
+	}
+
+	if(!display->getConfigs(configs, attrib_list, config_size, num_config))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLint attribute = %d, EGLint *value = %p)",
+	      dpy, config, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_FALSE;
+	}
+
+	if(!display->getConfigAttrib(config, attribute, value))
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_SURFACE;
+	}
+
+	if(!display->isValidWindow(window))
+	{
+		return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+	}
+
+	return display->createWindowSurface(window, config, attrib_list);
+}
+
+EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, const EGLint *attrib_list = %p)",
+	      dpy, config, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_SURFACE;
+	}
+
+	return display->createPBufferSurface(config, attrib_list);
+}
+
+EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_SURFACE;
+	}
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_NO_SURFACE);
+}
+
+EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	display->destroySurface((egl::Surface*)surface);
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint *value = %p)",
+	      dpy, surface, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = (egl::Surface*)surface;
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	switch(attribute)
+	{
+	case EGL_VG_ALPHA_FORMAT:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_VG_COLORSPACE:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_CONFIG_ID:
+		*value = eglSurface->getConfigID();
+		break;
+	case EGL_HEIGHT:
+		*value = eglSurface->getHeight();
+		break;
+	case EGL_HORIZONTAL_RESOLUTION:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_LARGEST_PBUFFER:
+		if(eglSurface->isPBufferSurface())   // For a window or pixmap surface, the contents of *value are not modified.
+		{
+			*value = eglSurface->getLargestPBuffer();
+		}
+		break;
+	case EGL_MIPMAP_TEXTURE:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_MIPMAP_LEVEL:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_MULTISAMPLE_RESOLVE:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_PIXEL_ASPECT_RATIO:
+		*value = eglSurface->getPixelAspectRatio();
+		break;
+	case EGL_RENDER_BUFFER:
+		*value = eglSurface->getRenderBuffer();
+		break;
+	case EGL_SWAP_BEHAVIOR:
+		*value = eglSurface->getSwapBehavior();
+		break;
+	case EGL_TEXTURE_FORMAT:
+		*value = eglSurface->getTextureFormat();
+		break;
+	case EGL_TEXTURE_TARGET:
+		*value = eglSurface->getTextureTarget();
+		break;
+	case EGL_VERTICAL_RESOLUTION:
+		UNIMPLEMENTED();   // FIXME
+		break;
+	case EGL_WIDTH:
+		*value = eglSurface->getWidth();
+		break;
+	default:
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean BindAPI(EGLenum api)
+{
+	TRACE("(EGLenum api = 0x%X)", api);
+
+	switch(api)
+	{
+	case EGL_OPENGL_API:
+	case EGL_OPENVG_API:
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
+	case EGL_OPENGL_ES_API:
+		break;
+	default:
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	egl::setCurrentAPI(api);
+
+	return success(EGL_TRUE);
+}
+
+EGLenum QueryAPI(void)
+{
+	TRACE("()");
+
+	EGLenum API = egl::getCurrentAPI();
+
+	return success(API);
+}
+
+EGLBoolean WaitClient(void)
+{
+	TRACE("()");
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLBoolean ReleaseThread(void)
+{
+	TRACE("()");
+
+	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+
+	return success(EGL_TRUE);
+}
+
+EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = %p, "
+	      "EGLConfig config = %p, const EGLint *attrib_list = %p)",
+	      dpy, buftype, buffer, config, attrib_list);
+
+	UNIMPLEMENTED();
+
+	return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+}
+
+EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint attribute = %d, EGLint value = %d)",
+	      dpy, surface, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	switch(attribute)
+	{
+	case EGL_SWAP_BEHAVIOR:
+		if(value == EGL_BUFFER_PRESERVED)
+		{
+			if(!(eglSurface->getSurfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
+			{
+				return error(EGL_BAD_MATCH, EGL_FALSE);
+			}
+		}
+		else if(value != EGL_BUFFER_DESTROYED)
+		{
+			return error(EGL_BAD_PARAMETER, EGL_FALSE);
+		}
+		eglSurface->setSwapBehavior(value);
+		break;
+	default:
+		UNIMPLEMENTED();   // FIXME
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(buffer != EGL_BACK_BUFFER)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	if(eglSurface->getBoundTexture())
+	{
+		return error(EGL_BAD_ACCESS, EGL_FALSE);
+	}
+
+	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	egl::Context *context = egl::getCurrentContext();
+
+	if(context)
+	{
+		context->bindTexImage(eglSurface);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLint buffer = %d)", dpy, surface, buffer);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(buffer != EGL_BACK_BUFFER)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	if(surface == EGL_NO_SURFACE || eglSurface->isWindowSurface())
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	if(eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	egl::Texture *texture = eglSurface->getBoundTexture();
+
+	if(texture)
+	{
+		texture->releaseTexImage();
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLint interval = %d)", dpy, interval);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = egl::getCurrentContext();
+
+	if(!validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
+
+	if(!draw_surface)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	draw_surface->setSwapInterval(interval);
+
+	return success(EGL_TRUE);
+}
+
+EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLContext share_context = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, share_context, attrib_list);
+
+	EGLint clientVersion = 1;
+	if(attrib_list)
+	{
+		for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+		{
+			if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
+			{
+				clientVersion = attribute[1];
+			}
+			else
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+			}
+		}
+	}
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *shareContext = static_cast<egl::Context*>(share_context);
+
+	if(!validateConfig(display, config))
+	{
+		return EGL_NO_CONTEXT;
+	}
+
+	if(shareContext && shareContext->getClientVersion() != clientVersion)
+	{
+		return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+	}
+
+	return display->createContext(config, shareContext, clientVersion);
+}
+
+EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p)", dpy, ctx);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+
+	if(!validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	if(ctx == EGL_NO_CONTEXT)
+	{
+		return error(EGL_BAD_CONTEXT, EGL_FALSE);
+	}
+
+	display->destroyContext(context);
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface draw = %p, EGLSurface read = %p, EGLContext ctx = %p)",
+	      dpy, draw, read, ctx);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+	egl::Surface *drawSurface = static_cast<egl::Surface*>(draw);
+	egl::Surface *readSurface = static_cast<egl::Surface*>(read);
+
+	if(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)
+	{
+		if(!validateDisplay(display))
+		{
+			return EGL_FALSE;
+		}
+	}
+
+	if(ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	if((draw != EGL_NO_SURFACE && !validateSurface(display, drawSurface)) ||
+	   (read != EGL_NO_SURFACE && !validateSurface(display, readSurface)))
+	{
+		return EGL_FALSE;
+	}
+
+	if((draw != EGL_NO_SURFACE) ^ (read != EGL_NO_SURFACE))
+	{
+		return error(EGL_BAD_MATCH, EGL_FALSE);
+	}
+
+	if(draw != read)
+	{
+		UNIMPLEMENTED();   // FIXME
+	}
+
+	egl::setCurrentDisplay(dpy);
+	egl::setCurrentDrawSurface(drawSurface);
+	egl::setCurrentReadSurface(readSurface);
+	egl::setCurrentContext(context);
+
+	if(context)
+	{
+		context->makeCurrent(drawSurface);
+	}
+
+	return success(EGL_TRUE);
+}
+
+EGLContext GetCurrentContext(void)
+{
+	TRACE("()");
+
+	EGLContext context = egl::getCurrentContext();
+
+	return success(context);
+}
+
+EGLSurface GetCurrentSurface(EGLint readdraw)
+{
+	TRACE("(EGLint readdraw = %d)", readdraw);
+
+	if(readdraw == EGL_READ)
+	{
+		EGLSurface read = egl::getCurrentReadSurface();
+		return success(read);
+	}
+	else if(readdraw == EGL_DRAW)
+	{
+		EGLSurface draw = egl::getCurrentDrawSurface();
+		return success(draw);
+	}
+	else
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+	}
+}
+
+EGLDisplay GetCurrentDisplay(void)
+{
+	TRACE("()");
+
+	return success(egl::getCurrentDisplay());
+}
+
+EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLint attribute = %d, EGLint *value = %p)",
+	      dpy, ctx, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+
+	if(!validateContext(display, context))
+	{
+		return EGL_FALSE;
+	}
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(0);
+}
+
+EGLBoolean WaitGL(void)
+{
+	TRACE("()");
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLBoolean WaitNative(EGLint engine)
+{
+	TRACE("(EGLint engine = %d)", engine);
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = (egl::Surface*)surface;
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		return error(EGL_BAD_SURFACE, EGL_FALSE);
+	}
+
+	eglSurface->swap();
+
+	return success(EGL_TRUE);
+}
+
+EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p, EGLNativePixmapType target = %p)", dpy, surface, target);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
+
+	if(!validateSurface(display, eglSurface))
+	{
+		return EGL_FALSE;
+	}
+
+	UNIMPLEMENTED();   // FIXME
+
+	return success(EGL_FALSE);
+}
+
+EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLint attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+	egl::Context *context = static_cast<egl::Context*>(ctx);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
+	}
+
+	if(context != EGL_NO_CONTEXT && !display->isValidContext(context))
+	{
+		return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+	}
+
+	EGLenum imagePreserved = EGL_FALSE;
+	GLuint textureLevel = 0;
+	if(attrib_list)
+	{
+		for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+		{
+			if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
+			{
+				imagePreserved = attribute[1];
+			}
+			else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
+			{
+				textureLevel = attribute[1];
+			}
+			else
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
+			}
+		}
+	}
+
+	#if defined(__ANDROID__)
+		if(target == EGL_NATIVE_BUFFER_ANDROID)
+		{
+			ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(buffer);
+
+			if(!nativeBuffer || GLPixelFormatFromAndroid(nativeBuffer->format) == GL_NONE)
+			{
+				ALOGW("%s badness unsupported HAL format=%x", __FUNCTION__, nativeBuffer ? nativeBuffer->format : 0);
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
+			}
+
+			return success(new AndroidNativeImage(nativeBuffer));
+		}
+	#endif
+
+	GLuint name = reinterpret_cast<intptr_t>(buffer);
+
+	if(name == 0)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+	}
+
+	EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
+
+	if(validationResult != EGL_SUCCESS)
+	{
+		return error(validationResult, EGL_NO_IMAGE_KHR);
+	}
+
+	egl::Image *image = context->createSharedImage(target, name, textureLevel);
+
+	if(!image)
+	{
+		return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
+	}
+
+	if(image->getDepth() > 1)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+	}
+
+	return success((EGLImageKHR)image);
+}
+
+EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!image)
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	egl::Image *glImage = static_cast<egl::Image*>(image);
+	glImage->destroyShared();
+
+	return success(EGL_TRUE);
+}
+
+EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
+
+	switch(platform)
+	{
+	#if defined(__linux__) && !defined(__ANDROID__)
+	case EGL_PLATFORM_X11_EXT: break;
+	case EGL_PLATFORM_GBM_KHR: break;
+	#endif
+	default:
+		return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
+	}
+
+	#if defined(__linux__) && !defined(__ANDROID__)
+		if(platform == EGL_PLATFORM_X11_EXT)
+		{
+			if(!libX11)
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);
+			}
+
+			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
+			}
+		}
+		else if(platform == EGL_PLATFORM_GBM_KHR)
+		{
+			if(native_display != (void*)EGL_DEFAULT_DISPLAY || attrib_list != NULL)
+			{
+				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
+			}
+
+			return success(HEADLESS_DISPLAY);
+		}
+	#endif
+
+	return success(PRIMARY_DISPLAY);   // We only support the default display
+}
+
+EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
+{
+	return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
+}
+
+EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
+{
+	return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
+}
+
+EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
+
+	egl::Display *display = egl::Display::get(dpy);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_NO_SYNC_KHR);
+	}
+
+	if(type != EGL_SYNC_FENCE_KHR)
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+	}
+
+	if(attrib_list && attrib_list[0] != EGL_NONE)
+	{
+		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+	}
+
+	egl::Context *context = egl::getCurrentContext();
+
+	if(!validateContext(display, context))
+	{
+		return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
+	}
+
+	EGLSyncKHR sync = display->createSync(context);
+
+	return success(sync);
+}
+
+EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
+
+	egl::Display *display = egl::Display::get(dpy);
+	FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!display->isValidSync(eglSync))
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	display->destroySync(eglSync);
+
+	return success(EGL_TRUE);
+}
+
+EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint flags = %x, EGLTimeKHR value = %llx)", dpy, sync, flags, timeout);
+
+	egl::Display *display = egl::Display::get(dpy);
+	FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!display->isValidSync(eglSync))
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	(void)flags;
+	(void)timeout;
+
+	if(!eglSync->isSignaled())
+	{
+		eglSync->wait();
+	}
+
+	return success(EGL_CONDITION_SATISFIED_KHR);
+}
+
+EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
+
+	egl::Display *display = egl::Display::get(dpy);
+	FenceSync *eglSync = static_cast<FenceSync*>(sync);
+
+	if(!validateDisplay(display))
+	{
+		return error(EGL_BAD_DISPLAY, EGL_FALSE);
+	}
+
+	if(!display->isValidSync(eglSync))
+	{
+		return error(EGL_BAD_PARAMETER, EGL_FALSE);
+	}
+
+	switch(attribute)
+	{
+	case EGL_SYNC_TYPE_KHR:
+		*value = EGL_SYNC_FENCE_KHR;
+		return success(EGL_TRUE);
+	case EGL_SYNC_STATUS_KHR:
+		eglSync->wait();   // TODO: Don't block. Just poll based on sw::Query.
+		*value = eglSync->isSignaled() ? EGL_SIGNALED_KHR : EGL_UNSIGNALED_KHR;
+		return success(EGL_TRUE);
+	case EGL_SYNC_CONDITION_KHR:
+		*value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
+		return success(EGL_TRUE);
+	default:
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
+}
+
+__eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
+{
+	TRACE("(const char *procname = \"%s\")", procname);
+
+	struct Extension
+	{
+		const char *name;
+		__eglMustCastToProperFunctionPointerType address;
+	};
+
+	static const Extension eglExtensions[] =
+	{
+		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+		EXTENSION(eglCreateImageKHR),
+		EXTENSION(eglDestroyImageKHR),
+		EXTENSION(eglGetPlatformDisplayEXT),
+		EXTENSION(eglCreatePlatformWindowSurfaceEXT),
+		EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
+		EXTENSION(eglCreateSyncKHR),
+		EXTENSION(eglDestroySyncKHR),
+		EXTENSION(eglClientWaitSyncKHR),
+		EXTENSION(eglGetSyncAttribKHR),
+
+		#undef EXTENSION
+	};
+
+	for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
+	{
+		if(strcmp(procname, eglExtensions[ext].name) == 0)
+		{
+			return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address);
+		}
+	}
+
+	if(libGLESv2)
+	{
+		__eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);
+		if(proc) return success(proc);
+	}
+
+	if(libGLES_CM)
+	{
+		__eglMustCastToProperFunctionPointerType proc =  libGLES_CM->es1GetProcAddress(procname);
+		if(proc) return success(proc);
+	}
+
+	return success((__eglMustCastToProperFunctionPointerType)NULL);
+}
+}
