jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=90b96b07d9d39bb98f7d362fbfdd386deceefa84

commit 90b96b07d9d39bb98f7d362fbfdd386deceefa84
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Fri Oct 2 15:15:40 2015 +0900

    Evas GL: Add new API to get current Evas GL
    
    While this seems to go against the rest of the API (because we
    always pass in the Evas GL object), there is no way right now
    fully restore a context if there are multiple Evas GL objects.
    
    For instance, an app can use Evas GL from an Elm GLView, and also
    use Cairo with another Evas GL at the same time. In that case Cairo
    needs to restore the previous Evas GL but the library had no way
    of getting the current Evas GL. This is the equivalent of
    eglGetCurrentDisplay().
    
    @feature
---
 src/lib/evas/Evas_GL.h        | 19 ++++++++++++++++++-
 src/lib/evas/canvas/evas_gl.c | 44 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/src/lib/evas/Evas_GL.h b/src/lib/evas/Evas_GL.h
index a032eaf..0a4aa70 100644
--- a/src/lib/evas/Evas_GL.h
+++ b/src/lib/evas/Evas_GL.h
@@ -847,7 +847,7 @@ EAPI Evas_GL_Context         *evas_gl_current_context_get 
(Evas_GL *evas_gl) EIN
 /**
  * @brief Returns the Evas GL surface object in use or set by @ref 
evas_gl_make_current
  *
- * @param evas_gl The given Evas_GL object
+ * @param[in] evas_gl The given Evas_GL object
  *
  * @return The current surface for the calling thread, or @c NULL in case of
  *         failure and when there is no current surface in this thread.
@@ -862,6 +862,23 @@ EAPI Evas_GL_Context         *evas_gl_current_context_get 
(Evas_GL *evas_gl) EIN
  */
 EAPI Evas_GL_Surface         *evas_gl_current_surface_get (Evas_GL *evas_gl) 
EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
 
+/**
+ * @brief Get current Evas GL
+ *
+ * @param[out] context  Optional return value for the current context
+ * @param[out] surface  Optional return value for the current surface
+ *
+ * @return The current Evas GL, ie. the last Evas GL passed to 
evas_gl_make_current
+ *
+ * @see evas_gl_make_current
+ *
+ * @note This can be used to restore a previous context, for instance if you
+ *       are writing a library that needs to work transparently with Evas GL,
+ *       and may not have control over the other Evas GL objects.
+ *
+ * @since 1.16
+ */
+EAPI Evas_GL                 *evas_gl_current_evas_gl_get (Evas_GL_Context 
**context, Evas_GL_Surface **surface) EINA_WARN_UNUSED_RESULT;
 
 
 /*-------------------------------------------------------------------------
diff --git a/src/lib/evas/canvas/evas_gl.c b/src/lib/evas/canvas/evas_gl.c
index 5b539e4..7e9c4e7 100644
--- a/src/lib/evas/canvas/evas_gl.c
+++ b/src/lib/evas/canvas/evas_gl.c
@@ -5,6 +5,9 @@
 
 typedef struct _Evas_GL_TLS_data Evas_GL_TLS_data;
 
+/* since 1.16: store current evas gl - this TLS is never destroyed */
+static Eina_TLS _current_evas_gl_key = 0;
+
 struct _Evas_GL
 {
    DATA32      magic;
@@ -126,6 +129,16 @@ evas_gl_new(Evas *e)
    return NULL;
    MAGIC_CHECK_END();
 
+   if (!_current_evas_gl_key)
+     {
+        if (!eina_tls_new(&_current_evas_gl_key))
+          {
+             ERR("Error creating tls key for current Evas GL");
+             return NULL;
+          }
+        eina_tls_set(_current_evas_gl_key, NULL);
+     }
+
    evas_gl = calloc(1, sizeof(Evas_GL));
    if (!evas_gl) return NULL;
 
@@ -136,6 +149,7 @@ evas_gl_new(Evas *e)
    if (!evas_gl->evas->engine.func->gl_context_create)
      {
         ERR("Evas GL engine not available.");
+        eo_data_unref(e, evas_gl->evas);
         free(evas_gl);
         return NULL;
      }
@@ -144,6 +158,7 @@ evas_gl_new(Evas *e)
    if (eina_tls_new(&(evas_gl->resource_key)) == EINA_FALSE)
      {
         ERR("Error creating tls key");
+        eo_data_unref(e, evas_gl->evas);
         free(evas_gl);
         return NULL;
      }
@@ -167,9 +182,13 @@ evas_gl_free(Evas_GL *evas_gl)
    while (evas_gl->contexts)
      evas_gl_context_destroy(evas_gl, evas_gl->contexts->data);
 
-   // Destroy tls
+   // Destroy private tls
    _evas_gl_internal_tls_destroy(evas_gl);
 
+   // Reset current evas gl tls
+   if (_current_evas_gl_key && (evas_gl == eina_tls_get(_current_evas_gl_key)))
+     eina_tls_set(_current_evas_gl_key, NULL);
+
    eo_data_unref(evas_gl->evas->evas, evas_gl->evas);
    evas_gl->magic = 0;
    LKD(evas_gl->lck);
@@ -452,6 +471,9 @@ evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface 
*surf, Evas_GL_Context *c
         return EINA_FALSE;
      }
 
+   if (_current_evas_gl_key)
+     eina_tls_set(_current_evas_gl_key, evas_gl);
+
    return ret;
 }
 
@@ -531,6 +553,26 @@ evas_gl_current_surface_get(Evas_GL *evas_gl)
    return NULL;
 }
 
+EAPI Evas_GL *
+evas_gl_current_evas_gl_get(Evas_GL_Context **context, Evas_GL_Surface 
**surface)
+{
+   Evas_GL *evasgl = NULL;
+
+   if (_current_evas_gl_key)
+     evasgl = eina_tls_get(_current_evas_gl_key);
+
+   if (!evasgl)
+     {
+        if (context) *context = NULL;
+        if (surface) *surface = NULL;
+        return NULL;
+     }
+
+   if (context) *context = evas_gl_current_context_get(evasgl);
+   if (surface) *surface = evas_gl_current_surface_get(evasgl);
+   return evasgl;
+}
+
 EAPI const char *
 evas_gl_string_query(Evas_GL *evas_gl, int name)
 {

-- 


Reply via email to