Implement eglQueryContext.

Bug b/37991302

Change-Id: I8a1c28d4a9c8968be3a04da64a19ddd3f5274dd6
Reviewed-on: https://swiftshader-review.googlesource.com/9768
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/Context.hpp b/src/OpenGL/libEGL/Context.hpp
index da3246c..70a47a6 100644
--- a/src/OpenGL/libEGL/Context.hpp
+++ b/src/OpenGL/libEGL/Context.hpp
@@ -35,7 +35,8 @@
 	virtual void bindTexImage(Surface *surface) = 0;
 	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
 	virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
-	virtual int getClientVersion() const = 0;
+	virtual EGLint getClientVersion() const = 0;
+	virtual EGLint getConfigID() const = 0;
 	virtual void finish() = 0;
 
 protected:
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index ff30812..b5097ac 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -441,7 +441,7 @@
 	{
 		if(libGLES_CM)
 		{
-			context = libGLES_CM->es1CreateContext(this, shareContext);
+			context = libGLES_CM->es1CreateContext(this, shareContext, config);
 		}
 	}
 	else if((clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT) ||
@@ -449,7 +449,7 @@
 	{
 		if(libGLESv2)
 		{
-			context = libGLESv2->es2CreateContext(this, shareContext, clientVersion);
+			context = libGLESv2->es2CreateContext(this, shareContext, clientVersion, config);
 		}
 	}
 	else
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 4a1998f..3103abf 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -871,9 +871,25 @@
 		return EGL_FALSE;
 	}
 
-	UNIMPLEMENTED();   // FIXME
+	switch(attribute)
+	{
+	case EGL_CONFIG_ID:

+		*value = context->getConfigID();

+		break;

+	case EGL_CONTEXT_CLIENT_TYPE:

+		*value = egl::getCurrentAPI();

+		break;

+	case EGL_CONTEXT_CLIENT_VERSION:
+		*value = context->getClientVersion();
+		break;
+	case EGL_RENDER_BUFFER:
+		*value = EGL_BACK_BUFFER;

+		break;
+	default:
+		return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+	}
 
-	return success(0);
+	return success(EGL_TRUE);
 }
 
 EGLBoolean WaitGL(void)
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 1a4ed35..78fcec5 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -37,8 +37,8 @@
 
 namespace es1
 {
-Context::Context(egl::Display *const display, const Context *shareContext)
-	: egl::Context(display),
+Context::Context(egl::Display *const display, const Context *shareContext, const egl::Config *config)
+	: egl::Context(display), config(config),
 	  modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
 	  projectionStack(MAX_PROJECTION_STACK_DEPTH),
 	  textureStack0(MAX_TEXTURE_STACK_DEPTH),
@@ -321,11 +321,16 @@
 	markAllStateDirty();
 }
 
-int Context::getClientVersion() const
+EGLint Context::getClientVersion() const
 {
 	return 1;
 }
 
+EGLint Context::getConfigID() const
+{
+	return config->mConfigID;
+}
+
 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
 void Context::markAllStateDirty()
 {
@@ -3470,8 +3475,8 @@
 
 }
 
-egl::Context *es1CreateContext(egl::Display *display, const egl::Context *shareContext)
+egl::Context *es1CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
 {
 	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext
-	return new es1::Context(display, static_cast<const es1::Context*>(shareContext));
+	return new es1::Context(display, static_cast<const es1::Context*>(shareContext), config);
 }
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index 24e5a08..63efb74 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -291,14 +291,16 @@
 	TextureUnit textureUnit[MAX_TEXTURE_UNITS];
 };
 
-class Context : public egl::Context
+class [[clang::lto_visibility_public]] Context : public egl::Context
 {
 public:
-	Context(egl::Display *display, const Context *shareContext);
+	Context(egl::Display *display, const Context *shareContext, const egl::Config *config);
 
-	virtual void makeCurrent(egl::Surface *surface);
-	virtual int getClientVersion() const;
-	virtual void finish();
+	void makeCurrent(egl::Surface *surface) override;
+	EGLint getClientVersion() const override;
+	EGLint getConfigID() const override;
+
+	void finish() override;
 
 	void markAllStateDirty();
 
@@ -594,6 +596,8 @@
 	bool cullSkipsDraw(GLenum drawMode);
 	bool isTriangleMode(GLenum drawMode);
 
+	const egl::Config *const config;
+
 	State mState;
 
 	gl::BindingPointer<Texture2D> mTexture2DZero;
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index 08644c6..1c66f18 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -219,7 +219,7 @@
 	void (*glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
 	void (*glDrawTexfvOES)(const GLfloat *coords);
 
-	egl::Context *(*es1CreateContext)(egl::Display *display, const egl::Context *shareContext);
+	egl::Context *(*es1CreateContext)(egl::Display *display, const egl::Context *shareContext, const egl::Config *config);
 	__eglMustCastToProperFunctionPointerType (*es1GetProcAddress)(const char *procname);
 	egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
 	egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index 4840522..036147f 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -330,7 +330,7 @@
 void DrawTexfvOES(const GLfloat *coords);
 }
 
-egl::Context *es1CreateContext(egl::Display *display, const egl::Context *shareContext);
+egl::Context *es1CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config);
 extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname);
 egl::Image *createBackBuffer(int width, int height, const egl::Config *config);
 egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 0504a31..00ad92c 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -45,8 +45,8 @@
 
 namespace es2
 {
-Context::Context(egl::Display *display, const Context *shareContext, EGLint clientVersion)
-	: egl::Context(display), clientVersion(clientVersion)
+Context::Context(egl::Display *display, const Context *shareContext, EGLint clientVersion, const egl::Config *config)
+	: egl::Context(display), clientVersion(clientVersion), config(config)
 {
 	sw::Context *context = new sw::Context();
 	device = new es2::Device(context);
@@ -313,6 +313,11 @@
 	return clientVersion;
 }
 
+EGLint Context::getConfigID() const
+{
+	return config->mConfigID;
+}
+
 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
 void Context::markAllStateDirty()
 {
@@ -4358,8 +4363,8 @@
 
 }
 
-egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion)
+egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion, const egl::Config *config)
 {
 	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext
-	return new es2::Context(display, static_cast<const es2::Context*>(shareContext), clientVersion);
+	return new es2::Context(display, static_cast<const es2::Context*>(shareContext), clientVersion, config);
 }
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index a6c6e71..a8e450a 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -429,10 +429,11 @@
 class [[clang::lto_visibility_public]] Context : public egl::Context
 {
 public:
-	Context(egl::Display *display, const Context *shareContext, EGLint clientVersion);
+	Context(egl::Display *display, const Context *shareContext, EGLint clientVersion, const egl::Config *config);
 
 	void makeCurrent(egl::Surface *surface) override;
-	virtual EGLint getClientVersion() const;
+	EGLint getClientVersion() const override;
+	EGLint getConfigID() const override;
 
 	void markAllStateDirty();
 
@@ -725,6 +726,7 @@
 	Query *createQuery(GLuint handle, GLenum type);
 
 	const EGLint clientVersion;
+	const egl::Config *const config;
 
 	State mState;
 
diff --git a/src/OpenGL/libGLESv2/libGLESv2.hpp b/src/OpenGL/libGLESv2/libGLESv2.hpp
index 89811c3..0b9e135 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.hpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.hpp
@@ -242,7 +242,7 @@
 	void (*glGenerateMipmapOES)(GLenum target);
 	void (*glDrawBuffersEXT)(GLsizei n, const GLenum *bufs);
 
-	egl::Context *(*es2CreateContext)(egl::Display *display, const egl::Context *shareContext, int clientVersion);
+	egl::Context *(*es2CreateContext)(egl::Display *display, const egl::Context *shareContext, int clientVersion, const egl::Config *config);
 	__eglMustCastToProperFunctionPointerType (*es2GetProcAddress)(const char *procname);
 	egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
 	egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
diff --git a/src/OpenGL/libGLESv2/main.cpp b/src/OpenGL/libGLESv2/main.cpp
index 28efe8c..de3e7e1 100644
--- a/src/OpenGL/libGLESv2/main.cpp
+++ b/src/OpenGL/libGLESv2/main.cpp
@@ -1338,7 +1338,7 @@
 }
 }
 
-egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion);
+egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion, const egl::Config *config);
 extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname);
 egl::Image *createBackBuffer(int width, int height, const egl::Config *config);
 egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);