Implemented the EGL_KHR_create_context extension

Implemented EGL_KHR_create_context as described here:
www.khronos.org/registry/egl/extensions/KHR/EGL_KHR_create_context.txt

A small part of it was already implemented, which was to add
support for the EGL_OPENGL_ES3_BIT bit in the EGL_RENDERABLE_TYPE
bitfield. Note that the EGL_OPENGL_ES3_BIT is explicitly disabled
on Android right now.

Change-Id: I10e6222511b29f2d91bd55bfeb0f39bc5b884f89
Reviewed-on: https://swiftshader-review.googlesource.com/5380
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 7a801d9..610d1c3 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -193,7 +193,8 @@
 	case EGL_CLIENT_APIS:
 		return success("OpenGL_ES");
 	case EGL_EXTENSIONS:
-		return success("EGL_KHR_gl_texture_2D_image "
+		return success("EGL_KHR_create_context "
+		               "EGL_KHR_gl_texture_2D_image "
 		               "EGL_KHR_gl_texture_cubemap_image "
 		               "EGL_KHR_gl_renderbuffer_image "
 		               "EGL_KHR_fence_sync "
@@ -644,22 +645,88 @@
 	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;
+	EGLint majorVersion = 1;
+	EGLint minorVersion = 0;
+
 	if(attrib_list)
 	{
 		for(const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
 		{
-			if(attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
+			switch(attribute[0])
 			{
-				clientVersion = attribute[1];
-			}
-			else
-			{
+			case EGL_CONTEXT_MAJOR_VERSION_KHR:   // This token is an alias for EGL_CONTEXT_CLIENT_VERSION
+				majorVersion = attribute[1];
+				break;
+			case EGL_CONTEXT_MINOR_VERSION_KHR:
+				minorVersion = attribute[1];
+				break;
+			case EGL_CONTEXT_FLAGS_KHR:
+				switch(attribute[1])
+				{
+				case EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR:
+					// According to the EGL_KHR_create_context spec:
+					// "Khronos is still defining the expected and required features of debug contexts, so
+					//  implementations are currently free to implement "debug contexts" with little or no debug
+					//  functionality. However, OpenGL and OpenGL ES implementations supporting the GL_KHR_debug
+					//  extension should enable it when this bit is set."
+					break;
+				case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR:
+				case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR:
+					// These bits are for OpenGL contexts only, not OpenGL ES contexts
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+				default:
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+				}
+				break;
+			case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
+				switch(attribute[1])
+				{
+				case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR:
+				case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR:
+					// These bits are for OpenGL contexts only, not OpenGL ES contexts
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+				default:
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+				}
+				break;
+			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
+				switch(attribute[1])
+				{
+				case EGL_NO_RESET_NOTIFICATION_KHR:
+				case EGL_LOSE_CONTEXT_ON_RESET_KHR:
+					// These bits are for OpenGL contexts only, not OpenGL ES contexts
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+				default:
+					return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+				}
+				break;
+			default:
 				return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
 			}
 		}
 	}
 
+	switch(majorVersion)
+	{
+	case 1:
+		if(minorVersion != 0 && minorVersion != 1)
+		{
+			// 1.X: Only OpenGL ES 1.0 and 1.1 contexts are supported
+			return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+		}
+		break;
+	case 2:
+	case 3:
+		if(minorVersion != 0)
+		{
+			// 2.X and 3.X: Only OpenGL ES 2.0 and 3.0 contexts are currently supported
+			return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+		}
+		break;
+	default:
+		return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+	}
+
 	egl::Display *display = egl::Display::get(dpy);
 	egl::Context *shareContext = static_cast<egl::Context*>(share_context);
 
@@ -668,12 +735,12 @@
 		return EGL_NO_CONTEXT;
 	}
 
-	if(shareContext && shareContext->getClientVersion() != clientVersion)
+	if(shareContext && shareContext->getClientVersion() != majorVersion)
 	{
 		return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
 	}
 
-	return display->createContext(config, shareContext, clientVersion);
+	return display->createContext(config, shareContext, majorVersion);
 }
 
 EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx)