Add EGL 1.5 entry points.

This enables running dEQP on Linux when it was built against an EGL 1.5
capable driver. Note that this is not a complete EGL 1.5 implementation.

Change-Id: Ie29d9ec61e7e3694eb8862aad7432b77fe7c7bae
Reviewed-on: https://swiftshader-review.googlesource.com/15909
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 952fb88..c76f52b 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -30,11 +30,14 @@
 #endif
 
 #include <algorithm>
+#include <vector>
 #include <string.h>
 
-using namespace egl;
-
-static bool validateDisplay(egl::Display *display)
+namespace egl
+{
+namespace
+{
+bool validateDisplay(egl::Display *display)
 {
 	if(display == EGL_NO_DISPLAY)
 	{
@@ -49,7 +52,7 @@
 	return true;
 }
 
-static bool validateConfig(egl::Display *display, EGLConfig config)
+bool validateConfig(egl::Display *display, EGLConfig config)
 {
 	if(!validateDisplay(display))
 	{
@@ -64,7 +67,7 @@
 	return true;
 }
 
-static bool validateContext(egl::Display *display, egl::Context *context)
+bool validateContext(egl::Display *display, egl::Context *context)
 {
 	if(!validateDisplay(display))
 	{
@@ -79,7 +82,7 @@
 	return true;
 }
 
-static bool validateSurface(egl::Display *display, egl::Surface *surface)
+bool validateSurface(egl::Display *display, egl::Surface *surface)
 {
 	if(!validateDisplay(display))
 	{
@@ -94,8 +97,34 @@
 	return true;
 }
 
-namespace egl
+// Class to facilitate conversion from EGLint to EGLAttrib lists.
+class EGLAttribs
 {
+public:
+	explicit EGLAttribs(const EGLint *attrib_list)
+	{
+		if(attrib_list)
+		{
+			while(*attrib_list != EGL_NONE)
+			{
+				attrib.push_back(static_cast<EGLAttrib>(*attrib_list));
+				attrib_list++;
+			}
+		}
+
+		attrib.push_back(EGL_NONE);
+	}
+
+	operator const EGLAttrib*() const
+	{
+		return &attrib[0];
+	}
+
+private:
+	std::vector<EGLAttrib> attrib;
+};
+}
+
 EGLint GetError(void)
 {
 	TRACE("()");
@@ -301,10 +330,10 @@
 	return success(EGL_TRUE);
 }
 
-EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+EGLSurface CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
 {
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType win = %p, "
-	      "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, void *native_window = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, native_window, attrib_list);
 
 	egl::Display *display = egl::Display::get(dpy);
 
@@ -313,12 +342,30 @@
 		return EGL_NO_SURFACE;
 	}
 
-	if(!display->isValidWindow(window))
+	if(!display->isValidWindow((EGLNativeWindowType)native_window))
 	{
 		return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
 	}
 
-	return display->createWindowSurface(window, config, attrib_list);
+	return display->createWindowSurface((EGLNativeWindowType)native_window, config, attrib_list);
+}
+
+EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, void *native_window = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, native_window, attrib_list);
+
+	EGLAttribs attribs(attrib_list);
+	return CreatePlatformWindowSurface(dpy, config, native_window, attribs);
+}
+
+EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativeWindowType window = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, window, attrib_list);
+
+	EGLAttribs attribs(attrib_list);
+	return CreatePlatformWindowSurface(dpy, config, (void*)window, attribs);
 }
 
 EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
@@ -336,10 +383,10 @@
 	return display->createPBufferSurface(config, attrib_list);
 }
 
-EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+EGLSurface CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
 {
-	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, EGLNativePixmapType pixmap = %p, "
-	      "const EGLint *attrib_list = %p)", dpy, config, pixmap, attrib_list);
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, void *native_pixmap = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, native_pixmap, attrib_list);
 
 	egl::Display *display = egl::Display::get(dpy);
 
@@ -353,6 +400,24 @@
 	return success(EGL_NO_SURFACE);
 }
 
+EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
+{
+	TRACE("(EGLDisplay dpy = %p, EGLConfig config = %p, void *native_pixmap = %p, "
+	      "const EGLint *attrib_list = %p)", dpy, config, native_pixmap, attrib_list);
+
+	EGLAttribs attribs(attrib_list);
+	return CreatePlatformPixmapSurface(dpy, config, native_pixmap, attribs);
+}
+
+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);
+
+	EGLAttribs attribs(attrib_list);
+	return CreatePlatformPixmapSurface(dpy, config, (void*)pixmap, attribs);
+}
+
 EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
 	TRACE("(EGLDisplay dpy = %p, EGLSurface surface = %p)", dpy, surface);
@@ -1062,9 +1127,9 @@
 	return success(EGL_FALSE);
 }
 
-EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+EGLImage CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *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);
+	TRACE("(EGLDisplay dpy = %p, EGLContext ctx = %p, EGLenum target = 0x%X, buffer = %p, const EGLAttrib *attrib_list = %p)", dpy, ctx, target, buffer, attrib_list);
 
 	egl::Display *display = egl::Display::get(dpy);
 	egl::Context *context = static_cast<egl::Context*>(ctx);
@@ -1083,15 +1148,15 @@
 	GLuint textureLevel = 0;
 	if(attrib_list)
 	{
-		for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+		for(const EGLAttrib *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
 		{
 			if(attribute[0] == EGL_IMAGE_PRESERVED_KHR)
 			{
-				imagePreserved = attribute[1];
+				imagePreserved = static_cast<EGLenum>(attribute[1]);
 			}
 			else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
 			{
-				textureLevel = attribute[1];
+				textureLevel = static_cast<GLuint>(attribute[1]);
 			}
 			else
 			{
@@ -1144,11 +1209,19 @@
 		return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 	}
 
-	EGLImageKHR eglImage = display->createSharedImage(image);
+	EGLImage eglImage = display->createSharedImage(image);
 
 	return success(eglImage);
 }
 
+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);
+
+	EGLAttribs attribs(attrib_list);
+	return CreateImage(dpy, ctx, target, buffer, attribs);
+}
+
 EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 {
 	TRACE("(EGLDisplay dpy = %p, EGLImageKHR image = %p)", dpy, image);
@@ -1168,32 +1241,21 @@
 	return success(EGL_TRUE);
 }
 
-EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+EGLDisplay GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
 {
-	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
+	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLAttrib *attrib_list = %p)", platform, native_display, attrib_list);
 
 	#if defined(__linux__) && !defined(__ANDROID__)
 		switch(platform)
 		{
-		#if defined(USE_X11)
-		case EGL_PLATFORM_X11_EXT: break;
-		#endif
-		case EGL_PLATFORM_GBM_KHR: break;
+		case EGL_PLATFORM_X11_EXT:
+		case EGL_PLATFORM_GBM_KHR:
+			break;
 		default:
 			return error(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
 		}
 
-		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);
-		}
-		#if defined(USE_X11)
-		else if(platform == EGL_PLATFORM_X11_EXT)
+		if(platform == EGL_PLATFORM_X11_EXT)
 		{
 			if(!libX11)
 			{
@@ -1205,7 +1267,15 @@
 				return error(EGL_BAD_ATTRIBUTE, EGL_NO_DISPLAY);   // Unimplemented
 			}
 		}
-		#endif
+		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);
+		}
 
 		return success(PRIMARY_DISPLAY);   // We only support the default display
 	#else
@@ -1213,19 +1283,17 @@
 	#endif
 }
 
-EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
+EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
 {
-	return CreateWindowSurface(dpy, config, (EGLNativeWindowType)native_window, attrib_list);
+	TRACE("(EGLenum platform = 0x%X, void *native_display = %p, const EGLint *attrib_list = %p)", platform, native_display, attrib_list);
+
+	EGLAttribs attribs(attrib_list);
+	return GetPlatformDisplay(platform, native_display, attribs);
 }
 
-EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
+EGLSync CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *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);
+	TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLAttrib *attrib_list=%p)", dpy, type, attrib_list);
 
 	egl::Display *display = egl::Display::get(dpy);
 
@@ -1256,6 +1324,14 @@
 	return success(sync);
 }
 
+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);
+
+	EGLAttribs attribs(attrib_list);
+	return CreateSync(dpy, type, attribs);
+}
+
 EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
 {
 	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p)", dpy, sync);
@@ -1306,9 +1382,9 @@
 	return success(EGL_CONDITION_SATISFIED_KHR);
 }
 
-EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+EGLBoolean GetSyncAttrib(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLAttrib *value)
 {
-	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
+	TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLAttrib *value = %p)", dpy, sync, attribute, value);
 
 	egl::Display *display = egl::Display::get(dpy);
 	FenceSync *eglSync = static_cast<FenceSync*>(sync);
@@ -1340,6 +1416,14 @@
 	}
 }
 
+EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+	EGLAttrib attrib_value;
+	EGLBoolean result = GetSyncAttrib(dpy, sync, attribute, &attrib_value);
+	*value = static_cast<EGLint>(attrib_value);
+	return result;
+}
+
 __eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname)
 {
 	TRACE("(const char *procname = \"%s\")", procname);
@@ -1367,20 +1451,27 @@
 		FUNCTION(eglBindAPI),
 		FUNCTION(eglBindTexImage),
 		FUNCTION(eglChooseConfig),
+		FUNCTION(eglClientWaitSync),
 		FUNCTION(eglClientWaitSyncKHR),
 		FUNCTION(eglCopyBuffers),
 		FUNCTION(eglCreateContext),
+		FUNCTION(eglCreateImage),
 		FUNCTION(eglCreateImageKHR),
 		FUNCTION(eglCreatePbufferFromClientBuffer),
 		FUNCTION(eglCreatePbufferSurface),
 		FUNCTION(eglCreatePixmapSurface),
+		FUNCTION(eglCreatePlatformPixmapSurface),
 		FUNCTION(eglCreatePlatformPixmapSurfaceEXT),
+		FUNCTION(eglCreatePlatformWindowSurface),
 		FUNCTION(eglCreatePlatformWindowSurfaceEXT),
+		FUNCTION(eglCreateSync),
 		FUNCTION(eglCreateSyncKHR),
 		FUNCTION(eglCreateWindowSurface),
 		FUNCTION(eglDestroyContext),
+		FUNCTION(eglDestroyImage),
 		FUNCTION(eglDestroyImageKHR),
 		FUNCTION(eglDestroySurface),
+		FUNCTION(eglDestroySync),
 		FUNCTION(eglDestroySyncKHR),
 		FUNCTION(eglGetConfigAttrib),
 		FUNCTION(eglGetConfigs),
@@ -1389,8 +1480,10 @@
 		FUNCTION(eglGetCurrentSurface),
 		FUNCTION(eglGetDisplay),
 		FUNCTION(eglGetError),
+		FUNCTION(eglGetPlatformDisplay),
 		FUNCTION(eglGetPlatformDisplayEXT),
 		FUNCTION(eglGetProcAddress),
+		FUNCTION(eglGetSyncAttrib),
 		FUNCTION(eglGetSyncAttribKHR),
 		FUNCTION(eglInitialize),
 		FUNCTION(eglMakeCurrent),
@@ -1407,6 +1500,8 @@
 		FUNCTION(eglWaitClient),
 		FUNCTION(eglWaitGL),
 		FUNCTION(eglWaitNative),
+		FUNCTION(eglWaitSync),
+		FUNCTION(eglWaitSyncKHR),
 
 		#undef FUNCTION
 	};