OSDN Git Service

Implemented the EGL_KHR_create_context extension
authorAlexis Hetu <sugoi@google.com>
Wed, 18 May 2016 15:43:43 +0000 (11:43 -0400)
committerAlexis Hétu <sugoi@google.com>
Fri, 20 May 2016 17:31:09 +0000 (17:31 +0000)
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>
src/OpenGL/libEGL/libEGL.cpp

index 7a801d9..610d1c3 100644 (file)
@@ -193,7 +193,8 @@ const char *QueryString(EGLDisplay dpy, EGLint name)
        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 @@ EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_cont
        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)
-                       {
-                               clientVersion = attribute[1];
-                       }
-                       else
+                       switch(attribute[0])
                        {
+                       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 @@ EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_cont
                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)