Port to OSX.

Change-Id: I31fdb6a1e403831feb6040ea756f2c144ac79a5b
Reviewed-on: https://swiftshader-review.googlesource.com/4383
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5131a4..0e0f152 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.0)
 
-project(SwiftShaders CXX)
+project(SwiftShader C CXX)
 
 set(CMAKE_BUILD_TYPE "Release" CACHE STRING "The type of build: Debug Release RelWithDebInfo." )
 
@@ -98,6 +98,7 @@
 set(OPENGL_COMPILER_DIR ${OPENGL_DIR}/compiler)
 set(LLVM_DIR ${SOURCE_DIR}/LLVM)
 set(TESTS_DIR ${CMAKE_SOURCE_DIR}/tests)
+set(HELLO2_DIR ${TESTS_DIR}/third_party/PowerVR/Examples/Beginner/01_HelloAPI/OGLES2)
 
 ###########################################################
 # Compile flags
@@ -170,13 +171,12 @@
 ###########################################################
 
 # We want the code for all of LLVM except the code for non-X86 targets
-file(GLOB_RECURSE LLVM_LIST ${LLVM_DIR}/lib/*.cpp)
-file(GLOB_RECURSE LLVM_ALL_TARGET_LIST ${LLVM_DIR}/lib/Target/*.cpp)
-file(GLOB_RECURSE LLVM_X86_TARGET_LIST ${LLVM_DIR}/lib/Target/X86/*.cpp)
+file(GLOB_RECURSE LLVM_LIST ${LLVM_DIR}/lib/*.cpp ${LLVM_DIR}/lib/*.c)
+file(GLOB_RECURSE LLVM_ALL_TARGET_LIST ${LLVM_DIR}/lib/Target/*.cpp ${LLVM_DIR}/lib/Target/*.c)
+file(GLOB_RECURSE LLVM_X86_TARGET_LIST ${LLVM_DIR}/lib/Target/X86/*.cpp ${LLVM_DIR}/lib/Target/X86/*.c)
 
 list(REMOVE_ITEM LLVM_LIST ${LLVM_ALL_TARGET_LIST})
 list(APPEND LLVM_LIST ${LLVM_X86_TARGET_LIST})
-list(REMOVE_ITEM LLVM_LIST "${LLVM_DIR}/lib/Target/X86/X86MCInstLower.cpp")
 list(APPEND LLVM_LIST
     ${LLVM_DIR}/lib/Target/Mangler.cpp
     ${LLVM_DIR}/lib/Target/TargetData.cpp
@@ -200,10 +200,11 @@
     ${LLVM_DIR}/include
     ${LLVM_DIR}/lib/Target/X86
 )
-add_library(llvm STATIC ${LLVM_LIST})
+add_library(llvm SHARED ${LLVM_LIST})
 set_target_properties(llvm PROPERTIES
     POSITION_INDEPENDENT_CODE 1
     INCLUDE_DIRECTORIES "${LLVM_INCLUDE_DIR}"
+    COMPILE_DEFINITIONS "__STDC_CONSTANT_MACROS;__STDC_LIMIT_MACROS"
     FOLDER "LLVM"
 )
 
@@ -218,11 +219,11 @@
     ${SOURCE_DIR}/Reactor
     ${SOURCE_DIR}/Renderer
     ${SOURCE_DIR}/Shader
+    ${OPENGL_DIR}/include
     ${LLVM_INCLUDE_DIR}
 )
 set(OPENGL_INCLUDE_DIR
     ${OPENGL_DIR}
-    ${OPENGL_DIR}/include
     ${COMMON_INCLUDE_DIR}
 )
 
@@ -359,6 +360,10 @@
         ${SOURCE_DIR}/Main/FrameBufferOSX.mm
         ${SOURCE_DIR}/Main/FrameBufferOSX.hpp
     )
+    list(APPEND EGL_LIST
+        ${OPENGL_DIR}/libEGL/OSXUtils.mm
+        ${OPENGL_DIR}/libEGL/OSXUtils.hpp
+    )
     list(APPEND OPENGL_COMPILER_LIST
         ${OPENGL_COMPILER_DIR}/ossource_posix.cpp
     )
@@ -368,6 +373,10 @@
     set(OS_LIBS odbc32 odbccp32 WS2_32 dxguid)
 elseif(LINUX)
     set(OS_LIBS dl X11 Xext pthread)
+elseif(APPLE)
+    find_library(COCOA_FRAMEWORK Cocoa)
+    find_library(QUARTZ_FRAMEWORK Quartz)
+    set(OS_LIBS "${COCOA_FRAMEWORK}" "${QUARTZ_FRAMEWORK}")
 endif()
 
 ###########################################################
@@ -458,7 +467,21 @@
 # Extra programs
 ###########################################################
 
-if (LINUX)
-    add_executable(OGLES2HelloAPI tests/third_party/PowerVR/Examples/Beginner/01_HelloAPI/OGLES2/OGLES2HelloAPI_LinuxX11.cpp)
+if(LINUX)
+    add_executable(OGLES2HelloAPI HELLO2_DIR/OGLES2HelloAPI_LinuxX11.cpp)
     target_link_libraries(OGLES2HelloAPI dl X11 EGL GLESv2)
+elseif(APPLE)
+    add_executable(OGLES2HelloAPI MACOSX_BUNDLE
+        ${HELLO2_DIR}/OGLES2HelloAPI_OSX.mm
+        ${HELLO2_DIR}/Build/OSX/en.lproj/MainMenu.xib
+    )
+    set_target_properties(OGLES2HelloAPI PROPERTIES
+        INCLUDE_DIRECTORIES "${OPENGL_DIR}/include"
+        COMPILE_DEFINITIONS "GL_GLEXT_PROTOTYPES"
+        MACOSX_BUNDLE_INFO_PLIST "${HELLO2_DIR}/Build/OSX/Info.plist"
+    )
+    target_link_libraries(OGLES2HelloAPI libEGL libGLESv2 ${OS_LIBS})
+    set_source_files_properties(${HELLO2_DIR}/Build/OSX/en.lproj/MainMenu.xib PROPERTIES
+        MACOSX_PACKAGE_LOCATION "Resources"
+    )
 endif()
diff --git a/src/Main/FrameBufferOSX.hpp b/src/Main/FrameBufferOSX.hpp
index bbd8493..41a6348 100644
--- a/src/Main/FrameBufferOSX.hpp
+++ b/src/Main/FrameBufferOSX.hpp
@@ -3,6 +3,8 @@
 
 #include "Main/FrameBuffer.hpp"
 
+#import <Cocoa/Cocoa.h>
+
 @class CALayer;
 
 namespace sw
@@ -10,15 +12,23 @@
 	class FrameBufferOSX : public FrameBuffer
 	{
 	public:
-		FrameBufferOSX(CALayer *window, int width, int height) : FrameBuffer(width, height, false, false) {};
-
-		~FrameBufferOSX() override {};
+		FrameBufferOSX(CALayer *layer, int width, int height);
+		~FrameBufferOSX() override;
 
 		void flip(void *source, Format sourceFormat, size_t sourceStride) override;
-		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override {};
+		void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
 
-		void *lock() override {return nullptr;};
-		void unlock() override {};
+		void *lock() override;
+		void unlock() override;
+
+	private:
+		int width;
+		int height;
+		CALayer *layer;
+		uint8_t *buffer;
+		CGDataProviderRef provider;
+		CGColorSpaceRef colorspace;
+		CGImageRef currentImage;
 	};
 }
 
diff --git a/src/Main/FrameBufferOSX.mm b/src/Main/FrameBufferOSX.mm
index 0ed083c..40827cc 100644
--- a/src/Main/FrameBufferOSX.mm
+++ b/src/Main/FrameBufferOSX.mm
@@ -1,14 +1,89 @@
 #include "FrameBufferOSX.hpp"
 
-namespace sw
-{
+#include "Common/Debug.hpp"
+
+#include <EGL/egl.h>
+#import <QuartzCore/QuartzCore.h>
+
+namespace sw {
+
+	FrameBufferOSX::FrameBufferOSX(CALayer* layer, int width, int height)
+		: FrameBuffer(width, height, false, false), width(width), height(height),
+		  layer(layer), buffer(nullptr), provider(nullptr), currentImage(nullptr)
+	{
+		destFormat = sw::FORMAT_X8B8G8R8;
+		int bufferSize = width * height * 4 * sizeof(uint8_t);
+		buffer = new uint8_t[bufferSize];
+		provider = CGDataProviderCreateWithData(nullptr, buffer, bufferSize, nullptr);
+		colorspace = CGColorSpaceCreateDeviceRGB();
+	}
+
+	FrameBufferOSX::~FrameBufferOSX()
+	{
+		//[CATransaction begin];
+		//[layer setContents:nullptr];
+		//[CATransaction commit];
+
+		CGImageRelease(currentImage);
+		CGColorSpaceRelease(colorspace);
+		CGDataProviderRelease(provider);
+		
+		delete[] buffer;
+	}
+
 	void FrameBufferOSX::flip(void *source, Format sourceFormat, size_t sourceStride)
 	{
-		blit(source, 0, 0, sourceFormat, sourceStride);
+		blit(source, nullptr, nullptr, sourceFormat, sourceStride);
 	}
+
+	void FrameBufferOSX::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+	{
+		copy(source, sourceFormat, sourceStride);
+
+		int bytesPerRow = width * 4 * sizeof(uint8_t);
+		CGImageRef image = CGImageCreate(width, height, 8, 32, bytesPerRow, colorspace, kCGBitmapByteOrder32Big, provider, nullptr, false, kCGRenderingIntentDefault);
+
+		[CATransaction begin];
+		[layer setContents:(id)image];
+		[CATransaction commit];
+		[CATransaction flush];
+
+		if(currentImage)
+		{
+			CGImageRelease(currentImage);
+		}
+		currentImage = image;
+	}
+
+	void *FrameBufferOSX::lock()
+	{
+		stride = width * 4 * sizeof(uint8_t);
+		locked = buffer;
+		return locked;
+	};
+	
+	void FrameBufferOSX::unlock()
+	{
+		locked = nullptr;
+	};
 }
 
-sw::FrameBuffer *createFrameBuffer(void *display, CALayer *layer, int width, int height)
+sw::FrameBuffer *createFrameBuffer(void *display, EGLNativeWindowType nativeWindow, int width, int height)
 {
+	NSObject *window = reinterpret_cast<NSObject*>(nativeWindow);
+	CALayer *layer = nullptr;
+
+	if([window isKindOfClass:[NSView class]])
+	{
+		NSView *view = reinterpret_cast<NSView*>(window);
+		[view setWantsLayer:YES];
+		layer = [view layer];
+	}
+	else if([window isKindOfClass:[CALayer class]])
+	{
+		layer = reinterpret_cast<CALayer*>(window);
+	}
+	else ASSERT(0);
+	
 	return new sw::FrameBufferOSX(layer, width, height);
 }
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 4c1c7e2..3b2dbbc 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -32,6 +32,10 @@
 #include <fcntl.h>
 #endif
 
+#if defined(__APPLE__)
+#include "OSXUtils.hpp"
+#endif
+
 #include <algorithm>
 #include <vector>
 #include <map>
@@ -553,7 +557,7 @@
             return status == True;
         }
     #elif defined(__APPLE__)
-        return true;
+        return sw::OSX::IsValidWindow(window);
     #else
         #error "Display::isValidWindow unimplemented for this platform"
     #endif
@@ -688,7 +692,7 @@
         }
         else UNREACHABLE(platform);
     #elif defined(__APPLE__)
-        return sw::FORMAT_X8R8G8B8;
+        return sw::FORMAT_A8B8G8R8;
     #else
         #error "Display::isValidWindow unimplemented for this platform"
 	#endif
diff --git a/src/OpenGL/libEGL/OSXUtils.hpp b/src/OpenGL/libEGL/OSXUtils.hpp
new file mode 100644
index 0000000..26f703a
--- /dev/null
+++ b/src/OpenGL/libEGL/OSXUtils.hpp
@@ -0,0 +1,15 @@
+#ifndef	sw_OSXUtils_hpp
+#define	sw_OSXUtils_hpp
+
+#include <EGL/egl.h>
+
+namespace sw
+{
+namespace OSX
+{
+	bool IsValidWindow(EGLNativeWindowType window);
+	void GetNativeWindowSize(EGLNativeWindowType window, int &width, int &height);
+}
+}
+
+#endif // sw_OSXUtils_hpp
diff --git a/src/OpenGL/libEGL/OSXUtils.mm b/src/OpenGL/libEGL/OSXUtils.mm
new file mode 100644
index 0000000..93bc683
--- /dev/null
+++ b/src/OpenGL/libEGL/OSXUtils.mm
@@ -0,0 +1,36 @@
+#include "OSXUtils.hpp"
+
+#include "common/debug.h"
+
+#import <Cocoa/Cocoa.h>
+
+namespace sw
+{
+namespace OSX
+{
+	bool IsValidWindow(EGLNativeWindowType window)
+	{
+		NSObject *object = reinterpret_cast<NSObject*>(window);
+		return window && ([object isKindOfClass:[NSView class]] || [object isKindOfClass:[CALayer class]]);
+	}
+
+	void GetNativeWindowSize(EGLNativeWindowType window, int &width, int &height)
+	{
+		NSObject *object = reinterpret_cast<NSObject*>(window);
+
+		if([object isKindOfClass:[NSView class]])
+		{
+			NSView *view = reinterpret_cast<NSView*>(object);
+			width = [view bounds].size.width;
+			height = [view bounds].size.height;
+		}
+		else if([object isKindOfClass:[CALayer class]])
+		{
+			CALayer *layer = reinterpret_cast<CALayer*>(object);
+			width = CGRectGetWidth([layer frame]);
+			height = CGRectGetHeight([layer frame]);
+		}
+		else UNREACHABLE(0);
+	}
+}
+}
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index b6599da..48a28e2 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -31,6 +31,10 @@
 #include <tchar.h>

 #endif

 

+#if defined(__APPLE__)

+#include "OSXUtils.hpp"

+#endif

+

 #include <algorithm>

 

 namespace egl

@@ -250,7 +254,11 @@
 

 		return reset(windowAttributes.width, windowAttributes.height);

 	#elif defined(__APPLE__)

-		return true;

+		int width;

+		int height;

+		sw::OSX::GetNativeWindowSize(window, width, height);

+

+		return reset(width, height);

 	#else

 		#error "WindowSurface::initialize unimplemented for this platform"

 	#endif

@@ -295,8 +303,9 @@
 		int clientWidth = windowAttributes.width;

 		int clientHeight = windowAttributes.height;

 	#elif defined(__APPLE__)

-		int clientWidth = 0;

-		int clientHeight = 0;

+		int clientWidth;

+		int clientHeight;

+		sw::OSX::GetNativeWindowSize(window, clientWidth, clientHeight);

 		return true;

 	#else

 		#error "WindowSurface::checkForResize unimplemented for this platform"

diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
index 8c0d949..69b020c 100644
--- a/src/OpenGL/libEGL/libEGL.hpp
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -82,17 +82,31 @@
 		if(!libEGL)
 		{
 			#if defined(_WIN32)
-			const char *libEGL_lib[] = {"libEGL.dll", "libEGL_translator.dll"};
+				#if defined(__LP64__)
+					const char *libEGL_lib[] = {"libEGL.dll", "lib64EGL_translator.dll"};
+				#else
+					const char *libEGL_lib[] = {"libEGL.dll", "libEGL_translator.dll"};
+				#endif
 			#elif defined(__ANDROID__)
-			#if defined(__LP64__)
-			const char *libEGL_lib[] = {"/vendor/lib64/egl/libEGL_swiftshader.so"};
+				#if defined(__LP64__)
+					const char *libEGL_lib[] = {"/vendor/lib64/egl/libEGL_swiftshader.so"};
+				#else
+					const char *libEGL_lib[] = {"/vendor/lib/egl/libEGL_swiftshader.so"};
+				#endif
+			#elif defined(__linux__)
+				#if defined(__LP64__)
+					const char *libEGL_lib[] = {"lib64EGL_translator.so", "libEGL.so.1", "libEGL.so"};
+				#else
+					const char *libEGL_lib[] = {"libEGL_translator.so", "libEGL.so.1", "libEGL.so"};
+				#endif
+			#elif defined(__APPLE__)
+				#if defined(__LP64__)
+					const char *libEGL_lib[] = {"lib64EGL_translator.dylib", "libEGL.so", "libEGL.dylib"};
+				#else
+					const char *libEGL_lib[] = {"libEGL_translator.dylib", "libEGL.so", "libEGL.dylib"};
+				#endif
 			#else
-			const char *libEGL_lib[] = {"/vendor/lib/egl/libEGL_swiftshader.so"};
-			#endif
-			#elif defined(__LP64__)
-			const char *libEGL_lib[] = {"lib64EGL_translator.so", "libEGL.so.1", "libEGL.so"};
-			#else
-			const char *libEGL_lib[] = {"libEGL_translator.so", "libEGL.so.1", "libEGL.so"};
+				#error "libEGL::loadExports unimplemented for this platform"
 			#endif
 
 			libEGL = loadLibrary(libEGL_lib, "libEGL_swiftshader");
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index d4b4d75..f2718d7 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -241,17 +241,31 @@
 		if(!libGLES_CM)
 		{
 			#if defined(_WIN32)
-			const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};
+				#if defined(__LP64__)
+					const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};
+				#else
+					const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "lib64GLES_CM_translator.dll"};
+				#endif
 			#elif defined(__ANDROID__)
-			#if defined(__LP64__)
-			const char *libGLES_CM_lib[] = {"/vendor/lib64/egl/libGLESv1_CM_swiftshader.so"};
+				#if defined(__LP64__)
+					const char *libGLES_CM_lib[] = {"/vendor/lib64/egl/libGLESv1_CM_swiftshader.so"};
+				#else
+					const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};
+				#endif
+			#elif defined(__linux__)
+				#if defined(__LP64__)
+					const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
+				#else
+					const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
+				#endif
+			#elif defined(__APPLE__)
+				#if defined(__LP64__)
+					const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.dylib", "libGLES_CM.dylib"};
+				#else
+					const char *libGLES_CM_lib[] = {"libGLES_CM_translator.dylib", "libGLES_CM.dylib"};
+				#endif
 			#else
-			const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};
-			#endif
-			#elif defined(__LP64__)
-			const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
-			#else
-			const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
+				#error "libGLES_CM::loadExports unimplemented for this platform"
 			#endif
 
 			libGLES_CM = loadLibrary(libGLES_CM_lib, "libGLES_CM_swiftshader");
diff --git a/src/OpenGL/libGLESv2/libGLESv2.hpp b/src/OpenGL/libGLESv2/libGLESv2.hpp
index afb7224..a741329 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.hpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.hpp
@@ -209,20 +209,20 @@
 	void (*glFramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 	void (*glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
 	void (*glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image);
-	GLboolean (*glIsRenderbufferOES)(GLuint renderbuffer);

-	void (*glBindRenderbufferOES)(GLenum target, GLuint renderbuffer);

-	void (*glDeleteRenderbuffersOES)(GLsizei n, const GLuint* renderbuffers);

-	void (*glGenRenderbuffersOES)(GLsizei n, GLuint* renderbuffers);

-	void (*glRenderbufferStorageOES)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);

-	void (*glGetRenderbufferParameterivOES)(GLenum target, GLenum pname, GLint* params);

-	GLboolean (*glIsFramebufferOES)(GLuint framebuffer);

-	void (*glBindFramebufferOES)(GLenum target, GLuint framebuffer);

-	void (*glDeleteFramebuffersOES)(GLsizei n, const GLuint* framebuffers);

-	void (*glGenFramebuffersOES)(GLsizei n, GLuint* framebuffers);

-	GLenum (*glCheckFramebufferStatusOES)(GLenum target);

-	void (*glFramebufferRenderbufferOES)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);

-	void (*glFramebufferTexture2DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);

-	void (*glGetFramebufferAttachmentParameterivOES)(GLenum target, GLenum attachment, GLenum pname, GLint* params);

+	GLboolean (*glIsRenderbufferOES)(GLuint renderbuffer);
+	void (*glBindRenderbufferOES)(GLenum target, GLuint renderbuffer);
+	void (*glDeleteRenderbuffersOES)(GLsizei n, const GLuint* renderbuffers);
+	void (*glGenRenderbuffersOES)(GLsizei n, GLuint* renderbuffers);
+	void (*glRenderbufferStorageOES)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+	void (*glGetRenderbufferParameterivOES)(GLenum target, GLenum pname, GLint* params);
+	GLboolean (*glIsFramebufferOES)(GLuint framebuffer);
+	void (*glBindFramebufferOES)(GLenum target, GLuint framebuffer);
+	void (*glDeleteFramebuffersOES)(GLsizei n, const GLuint* framebuffers);
+	void (*glGenFramebuffersOES)(GLsizei n, GLuint* framebuffers);
+	GLenum (*glCheckFramebufferStatusOES)(GLenum target);
+	void (*glFramebufferRenderbufferOES)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+	void (*glFramebufferTexture2DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+	void (*glGetFramebufferAttachmentParameterivOES)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
 	void (*glGenerateMipmapOES)(GLenum target);
 
 	egl::Context *(*es2CreateContext)(const egl::Config *config, const egl::Context *shareContext, int clientVersion);
@@ -262,17 +262,31 @@
 		if(!libGLESv2)
 		{
 			#if defined(_WIN32)
-			const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};
+				#if defined(__LP64__)
+					const char *libGLESv2_lib[] = {"libGLESv2.dll", "lib64GLES_V2_translator.dll"};
+				#else
+					const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};
+				#endif
 			#elif defined(__ANDROID__)
-			#if defined(__LP64__)
-			const char *libGLESv2_lib[] = {"/vendor/lib64/egl/libGLESv2_swiftshader.so"};
+				#if defined(__LP64__)
+					const char *libGLESv2_lib[] = {"/vendor/lib64/egl/libGLESv2_swiftshader.so"};
+				#else
+					const char *libGLESv2_lib[] = {"/vendor/lib/egl/libGLESv2_swiftshader.so"};
+				#endif
+			#elif defined(__linux__)
+				#if defined(__LP64__)
+					const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
+				#else
+					const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
+				#endif
+			#elif defined(__APPLE__)
+				#if defined(__LP64__)
+					const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.dylib", "libGLESv2.dylib"};
+				#else
+					const char *libGLESv2_lib[] = {"libGLES_V2_translator.dylib", "libGLESv2.dylib"};
+				#endif
 			#else
-			const char *libGLESv2_lib[] = {"/vendor/lib/egl/libGLESv2_swiftshader.so"};
-			#endif
-			#elif defined(__LP64__)
-			const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
-			#else
-			const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
+				#error "libGLESv2::loadExports unimplemented for this platform"
 			#endif
 
 			libGLESv2 = loadLibrary(libGLESv2_lib, "libGLESv2_swiftshader");