<div dir="ltr">Hi Brian,<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 23, 2016 at 9:51 PM, Brian Paul <span dir="ltr"><<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Plamena,<br>
<br>
Some style nitpicks below.  Feel free to take 'em or leave 'em.<br>
I'm not too involved in EGL.<div><div class="h5"><br>
<br>
<br>
On 05/23/2016 10:27 AM, Plamena Manolova wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
According to the EGL specifications before binding an API<br>
we must check whether it's supported first. If not eglBindAPI<br>
should return EGL_FALSE and generate a EGL_BAD_PARAMETER error.<br>
<br>
Signed-off-by: Plamena Manolova <<a href="mailto:plamena.manolova@intel.com" target="_blank">plamena.manolova@intel.com</a>><br>
---<br>
  src/egl/main/eglapi.c     | 70 +++++++++++++++++++++++++++++++++++++++++++++++<br>
  src/egl/main/eglcurrent.h | 11 +-------<br>
  src/egl/main/egldisplay.c |  5 ++++<br>
  src/egl/main/egldisplay.h |  1 +<br>
  4 files changed, 77 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c<br>
index be2c90f..9dcee79 100644<br>
--- a/src/egl/main/eglapi.c<br>
+++ b/src/egl/main/eglapi.c<br>
@@ -1196,6 +1196,66 @@ eglGetError(void)<br>
  }<br>
<br>
<br>
+static bool<br>
+_eglDisplaySupportsApi(_EGLDisplay *dpy, EGLenum api)<br>
+{<br>
+   if (!dpy->Initialized) {<br>
+      return false;<br>
+   }<br>
+<br>
+   switch (api) {<br>
+      case EGL_OPENGL_API:<br>
+         if (dpy->ClientAPIs & EGL_OPENGL_BIT)<br>
+            return true;<br>
</blockquote>
> +         break;<br>
<br></div></div>
I'd probably do:<br>
  return !!(dpy->ClientAPIs & EGL_OPENGL_BIT);<br>
<br>
and similar for these cases to make it a little more concise.<span class=""><br>
<br></span></blockquote><div><br></div><div>This would make the switch much tidier, I'll go ahead and make that change.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+      case EGL_OPENGL_ES_API:<br>
+         if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||<br>
+             dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||<br>
+             dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {<br>
+               return true;<br>
+         }<br>
+         break;<br>
+      case EGL_OPENVG_API:<br>
+         if (dpy->ClientAPIs & EGL_OPENVG_BIT)<br>
+            return true;<br>
+         break;<br>
+      default:<br>
+         return false;<br>
+         break;<br>
</blockquote>
<br></span>
break not needed.  Should the default case raise an invalid enum error or something?  I don't recall what the EGL spec says about that stuff.</blockquote><div><br></div><div>Yes a EGL_BAD_PARAMETER error is generated if for whatever reason this function returns false </div><div>for all displays associated with the current thread. Actually it would make more sense for the </div><div>default case to be evaluated in the caller. I'll go ahead and move it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Whitespace note: we normally indent 'case' the same amount as the 'switch'.<div class=""><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+   }<br>
+<br>
+   return false;<br>
+}<br>
+<br>
+<br>
+/**<br>
+ * Return true if a client API enum is recognized.<br>
+ */<br>
+static bool<br>
+_eglIsApiValid(EGLenum api)<br>
+{<br>
+   _EGLDisplay *dpy = _eglGlobal.DisplayList;<br>
+   _EGLThreadInfo *current_thread = _eglGetCurrentThread();<br>
+<br>
+   while (dpy) {<br>
+      _EGLThreadInfo *thread = dpy->ThreadList;<br>
+<br>
+      while (thread) {<br>
+         if (thread == current_thread) {<br>
+            if (_eglDisplaySupportsApi(dpy, api))<br>
+               return true;<br>
+         }<br>
+<br>
+         thread = thread->Next;<br>
+      }<br>
+<br>
+      dpy = dpy->Next;<br>
+   }<br>
+<br>
+   return false;<br>
+}<br>
+<br>
+<br>
  /**<br>
   ** EGL 1.2<br>
   **/<br>
@@ -1211,6 +1271,16 @@ eglGetError(void)<br>
   *  eglWaitNative()<br>
   * See section 3.7 "Rendering Context" in the EGL specification for details.<br>
   */<br>
+<br>
+ /**<br>
+  * Section 3.7 (Rendering Contexts) of the EGL 1.5 spec says:<br>
+  *<br>
+  * "api must specify one of the supported client APIs, either<br>
+  * EGL_OPENGL_API, EGL_OPENGL_ES_API, or EGL_OPENVG_API... If api<br>
+  * is not one of the values specified above, or if the client API<br>
+  * specified by api is not supported by the implementation, an<br>
+  * EGL_BAD_PARAMETER error is generated."<br>
+  */<br>
  EGLBoolean EGLAPIENTRY<br>
  eglBindAPI(EGLenum api)<br>
  {<br>
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h<br>
index 1e386ac..6c203be 100644<br>
--- a/src/egl/main/eglcurrent.h<br>
+++ b/src/egl/main/eglcurrent.h<br>
@@ -56,6 +56,7 @@ extern "C" {<br>
   */<br>
  struct _egl_thread_info<br>
  {<br>
+   _EGLThreadInfo *Next; /* used to link threads */<br>
     EGLint LastError;<br>
     _EGLContext *CurrentContexts[_EGL_API_NUM_APIS];<br>
     /* use index for fast access to current context */<br>
@@ -64,16 +65,6 @@ struct _egl_thread_info<br>
<br>
<br>
  /**<br>
- * Return true if a client API enum is recognized.<br>
- */<br>
-static inline EGLBoolean<br>
-_eglIsApiValid(EGLenum api)<br>
-{<br>
-   return (api >= _EGL_API_FIRST_API && api <= _EGL_API_LAST_API);<br>
-}<br>
-<br>
-<br>
-/**<br>
   * Convert a client API enum to an index, for use by thread info.<br>
   * The client API enum is assumed to be valid.<br>
   */<br>
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c<br>
index f6db03a..907a607 100644<br>
--- a/src/egl/main/egldisplay.c<br>
+++ b/src/egl/main/egldisplay.c<br>
@@ -240,6 +240,7 @@ _EGLDisplay *<br>
  _eglFindDisplay(_EGLPlatformType plat, void *plat_dpy)<br>
  {<br>
     _EGLDisplay *dpy;<br>
+   _EGLThreadInfo *thread = _eglGetCurrentThread();<br>
<br>
     if (plat == _EGL_INVALID_PLATFORM)<br>
        return NULL;<br>
@@ -265,9 +266,13 @@ _eglFindDisplay(_EGLPlatformType plat, void *plat_dpy)<br>
           /* add to the display list */<br>
           dpy->Next = _eglGlobal.DisplayList;<br>
           _eglGlobal.DisplayList = dpy;<br>
+         dpy->ThreadList = NULL;<br>
        }<br>
     }<br>
<br>
+   thread->Next = dpy->ThreadList;<br>
+   dpy->ThreadList = thread;<br>
+<br>
     mtx_unlock(_eglGlobal.Mutex);<br>
<br>
     return dpy;<br>
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h<br>
index 6bfc858..8a730ed 100644<br>
--- a/src/egl/main/egldisplay.h<br>
+++ b/src/egl/main/egldisplay.h<br>
@@ -140,6 +140,7 @@ struct _egl_display<br>
     _EGLPlatformType Platform; /**< The type of the platform display */<br>
     void *PlatformDisplay;     /**< A pointer to the platform display */<br>
<br>
+   _EGLThreadInfo *ThreadList;/**< A pointer to the thread the display was created form */<br>
     _EGLDriver *Driver;        /**< Matched driver of the display */<br>
     EGLBoolean Initialized;    /**< True if the display is initialized */<br>
<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div></div>