eglCreateContext passes the client version to the context. gl::Context stores the client version to validate gl function parameters.

TRAC #22694

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2067 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index ce42990..250803e 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -373,7 +373,7 @@
     return success(surface);
 }
 
-EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
+EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
 {
     if (!mRenderer)
     {
@@ -385,7 +385,7 @@
             return NULL;
     }
 
-    gl::Context *context = glCreateContext(shareContext, mRenderer, notifyResets, robustAccess);
+    gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
     mContextSet.insert(context);
 
     return context;
diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h
index 131a7e8..87f3306 100644
--- a/src/libEGL/Display.h
+++ b/src/libEGL/Display.h
@@ -42,7 +42,7 @@
 
     EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
     EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
-    EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+    EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
 
     void destroySurface(egl::Surface *surface);
     void destroyContext(gl::Context *context);
diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp
index 7fca456..f362d28 100644
--- a/src/libEGL/libEGL.cpp
+++ b/src/libEGL/libEGL.cpp
@@ -814,14 +814,22 @@
             }
         }
 
-        if (client_version != 2)
+        if (client_version != 2 && client_version != 3)
         {
             return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
         }
 
-        if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification)
+        if (share_context)
         {
-            return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+            gl::Context* glContext = static_cast<gl::Context*>(share_context);
+            if (glContext->isResetNotificationEnabled() != reset_notification)
+            {
+                return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+            }
+            if (glContext->getClientVersion() != client_version)
+            {
+                return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+            }
         }
 
         egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -831,7 +839,7 @@
             return EGL_NO_CONTEXT;
         }
 
-        EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
+        EGLContext context = display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
 
         if (context)
             return egl::success(context);
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index c274091..1a4cedc 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -42,7 +42,7 @@
     return strings.insert(str).first->c_str();
 }
 
-Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
+Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
 {
     ASSERT(robustAccess == false);   // Unimplemented
 
@@ -50,6 +50,8 @@
 
     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
+    mClientVersion = clientVersion;
+
     mState.depthClearValue = 1.0f;
     mState.stencilClearValue = 0;
 
@@ -2123,6 +2125,11 @@
     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
 }
 
+int Context::getClientVersion() const
+{
+    return mClientVersion;
+}
+
 int Context::getMajorShaderModel() const
 {
     return mMajorShaderModel;
@@ -2884,9 +2891,9 @@
 
 extern "C"
 {
-gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
+gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
 {
-    return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
+    return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
 }
 
 void glDestroyContext(gl::Context *context)
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index 9c222be..b1b312c 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -169,7 +169,7 @@
 class Context
 {
   public:
-    Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
+    Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
 
     ~Context();
 
@@ -359,6 +359,8 @@
     GLenum getResetStatus();
     virtual bool isResetNotificationEnabled();
 
+    virtual int getClientVersion() const;
+
     int getMajorShaderModel() const;
     float getMaximumPointSize() const;
     unsigned int getMaximumCombinedTextureImageUnits() const;
@@ -421,6 +423,8 @@
 
     rx::Renderer *const mRenderer;
 
+    int mClientVersion;
+
     State mState;
 
     BindingPointer<Texture2D> mTexture2DZero;
diff --git a/src/libGLESv2/main.h b/src/libGLESv2/main.h
index 9168a22..85cbdf3 100644
--- a/src/libGLESv2/main.h
+++ b/src/libGLESv2/main.h
@@ -54,7 +54,7 @@
 extern "C"
 {
 // Exported functions for use by EGL
-gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
+gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
 void glDestroyContext(gl::Context *context);
 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
 gl::Context *glGetCurrentContext();