Evas GL: Use EGL image to share between Evas GL and GL backend 43/47443/4
authormythri.venugopal <mythri.venugopal@samsung.com>
Fri, 13 Mar 2015 17:50:20 +0000 (17:50 +0000)
committerDaeKwang Ryu <dkdk.ryu@samsung.com>
Wed, 16 Sep 2015 12:05:40 +0000 (21:05 +0900)
Summary:When the context version between Evas GL and GL backend differs,
        we cannot share texture between them. So, when the driver
        has support for KHR_gl_texture_2D_image extension,
        use EGL image to share between Evas GL and GL backend

Change-Id: Ifffadb8f13e71b1f3889508ea21b83a25f85e2f3

src/lib/evas/Evas_Common.h [changed mode: 0644->0755]
src/modules/evas/engines/gl_common/evas_gl_api_ext.h
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_context.c
src/modules/evas/engines/gl_common/evas_gl_core.c
src/modules/evas/engines/gl_common/evas_gl_core.h
src/modules/evas/engines/gl_common/evas_gl_core_private.h
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/gl_x11/evas_engine.c
src/modules/evas/engines/wayland_egl/evas_engine.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index ceef545..6be6052
@@ -478,7 +478,12 @@ typedef enum _Evas_Native_Surface_Type
    EVAS_NATIVE_SURFACE_NONE, /**< No surface type */
    EVAS_NATIVE_SURFACE_X11,  /**< X Window system based type. pixmap id or visual of the pixmap */
    EVAS_NATIVE_SURFACE_OPENGL, /**< OpenGL system based type. texture or framebuffer id*/
-   EVAS_NATIVE_SURFACE_WL /**< Wayland system based type. buffer of surface */
+   EVAS_NATIVE_SURFACE_WL, /**< Wayland system based type. buffer of surface */
+   // TIZEN ONLY (20150112) : NOT FIXED
+   EVAS_NATIVE_SURFACE_TIZEN,
+   EVAS_NATIVE_SURFACE_TBM,    /**< Tizen system based type. This is used for tizen buffer manager. */
+   EVAS_NATIVE_SURFACE_EVASGL, /**< Evas GL based type. evas gl surface */
+   //
 } Evas_Native_Surface_Type;
 
 /**
@@ -529,6 +534,19 @@ struct _Evas_Native_Surface
       {
          void *legacy_buffer; /**< wayland client buffer to use */
       } wl; /**< Set this struct fields if surface data is Wayland based. */
+
+      struct
+      {
+         void *buffer; /**< tbm surface */
+         int   rot; /**< rotation (0, 90, 180, 270) */
+         float ratio; /**< width/height ratio of the source image */
+         int   flip; /**< flip (0:none, 1:horizontal, 2:vertical, 3:both) */
+      } tbm; /**< Set this struct fields if your surface data is Tizen based. */
+      struct
+      {
+         void *surface; /**< evas gl surface to use */
+      } evasgl; /**< Set this struct fields if surface data is Evas GL based. */
+      //
    } data; /**< Choose one union data according to your surface. */
 };
 
index 56d5dae..4c969ff 100644 (file)
 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
 /////////////////////////////////////////////////////////////////////////////////////////////////////
 #define EXT_FUNC(fname) gl_ext_sym_##fname
-
+#define EXT_FUNC_GLES1(fname) gles1_ext_sym_##fname
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////
 // Extension HEADER
 /////////////////////////////////////////////////////////////////////////////////////////////////////
 #define _EVASGL_EXT_CHECK_SUPPORT(name)
 #define _EVASGL_EXT_DISCARD_SUPPORT()
-#define _EVASGL_EXT_BEGIN(name) extern int _gl_ext_support_##name;
+#define _EVASGL_EXT_BEGIN(name) \
+   extern int _gl_ext_support_##name; \
+   extern int _gles1_ext_support_##name;
 #define _EVASGL_EXT_END()
 #define _EVASGL_EXT_DRVNAME(name)
 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
@@ -86,6 +88,7 @@
 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
 /////////////////////////////////////////////////////////////////////////////////////////////////////
 #define EXTENSION_SUPPORT(name) (_gl_ext_support_##name == 1)
+#define EXTENSION_SUPPORT_GLES1(name) (_gles1_ext_support_##name == 1)
 
 extern Eina_Bool evgl_api_ext_init(void *getproc, const char *glueexts);
 extern void evgl_api_ext_get(Evas_GL_API *gl_funcs);
index 95eea33..bc12efb 100644 (file)
 #ifndef GL_UNPACK_ROW_LENGTH
 # define GL_UNPACK_ROW_LENGTH 0x0cf2
 #endif
-
+#ifndef EGL_NO_DISPLAY
+# define EGL_NO_DISPLAY 0
+#endif
 #ifndef EGL_NO_CONTEXT
 # define EGL_NO_CONTEXT 0
 #endif
 #ifndef EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC
 #define EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC (1<<1)
 #endif
+#ifndef EGL_GL_TEXTURE_2D_KHR
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#endif
+#ifndef EGL_GL_TEXTURE_LEVEL_KHR
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#endif
+#ifndef EGL_IMAGE_PRESERVED_KHR
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif
 
 // Evas_3d require GL_BGR, but that's an extention and will not be necessary once we move to Evas_GL_Image
 #ifndef GL_BGR
@@ -382,6 +393,7 @@ struct _Evas_GL_Shared
    Eina_Hash          *native_pm_hash;
    Eina_Hash          *native_tex_hash;
    Eina_Hash          *native_wl_hash;
+   Eina_Hash          *native_evasgl_hash;
 
 #ifdef GL_GLES
    // FIXME: hack.
index 63816ee..ba984ee 100644 (file)
@@ -909,6 +909,7 @@ evas_gl_common_context_new(void)
         shared->native_pm_hash  = eina_hash_int32_new(NULL);
         shared->native_tex_hash = eina_hash_int32_new(NULL);
         shared->native_wl_hash = eina_hash_pointer_new(NULL);
+        shared->native_evasgl_hash = eina_hash_pointer_new(NULL);
      }
    gc->shared = shared;
    gc->shared->references++;
@@ -983,6 +984,7 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
         eina_hash_free(gc->shared->native_pm_hash);
         eina_hash_free(gc->shared->native_tex_hash);
         eina_hash_free(gc->shared->native_wl_hash);
+        eina_hash_free(gc->shared->native_evasgl_hash);
         free(gc->shared);
         shared = NULL;
      }
index b363fb4..56603f0 100755 (executable)
@@ -56,6 +56,14 @@ _internal_resources_create(void *eng_data)
         return NULL;
      }
 
+   // Get display
+   rsc->display = evgl_engine->funcs->display_get(eng_data);
+   if (!rsc->display)
+     {
+        ERR("Error getting display");
+        goto error;
+     }
+
    // Create resource surface
    rsc->window = evgl_engine->funcs->native_window_create(eng_data);
    if (!rsc->window)
@@ -75,7 +83,7 @@ _internal_resources_create(void *eng_data)
    rsc->context = evgl_engine->funcs->context_create(eng_data, NULL, EVAS_GL_GLES_2_X);
    if (!rsc->context)
      {
-        ERR("Internal resource context creations failed.");
+        ERR("Internal resource context creation failed.");
         goto error;
      }
 
@@ -156,14 +164,14 @@ _internal_resource_make_current(void *eng_data, EVGL_Context *ctx)
 //  - Internal config choose function
 //---------------------------------------------------------------//
 // Gen Texture
-void
+static void
 _texture_create(GLuint *tex)
 {
    glGenTextures(1, tex);
 }
 
 // Create and allocate 2D texture
-void
+static void
 _texture_allocate_2d(GLuint tex, GLint ifmt, GLenum fmt, GLenum type, int w, int h)
 {
    //if (!(*tex))
@@ -178,7 +186,7 @@ _texture_allocate_2d(GLuint tex, GLint ifmt, GLenum fmt, GLenum type, int w, int
 }
 
 // Destroy Texture
-void
+static void
 _texture_destroy(GLuint *tex)
 {
    if (*tex)
@@ -190,8 +198,8 @@ _texture_destroy(GLuint *tex)
 
 // Attach 2D texture with the given format to already bound FBO
 // *NOTE: attach2 here is used for depth_stencil attachment in GLES env.
-void
-_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples)
+static void
+_texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples, Eina_Bool use_extension)
 {
    if (samples)
      {
@@ -211,6 +219,15 @@ _texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples)
         ERR("MSAA not supported.  Should not have come in here...!");
 #endif
      }
+   else if (use_extension)
+     {
+        if (gles1_funcs->glFramebufferTexture2DOES)
+          gles1_funcs->glFramebufferTexture2DOES(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0);
+
+        if (attach2)
+          if (gles1_funcs->glFramebufferTexture2DOES)
+            gles1_funcs->glFramebufferTexture2DOES(GL_FRAMEBUFFER, attach2, GL_TEXTURE_2D, tex, 0);
+     }
    else
      {
         glFramebufferTexture2D(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, tex, 0);
@@ -221,8 +238,83 @@ _texture_attach_2d(GLuint tex, GLenum attach, GLenum attach2, int samples)
      }
 }
 
+static void *
+_egl_image_create(EVGL_Context *context, GLuint tex)
+{
+#ifdef GL_GLES
+   EGLDisplay dpy = EGL_NO_DISPLAY;
+   EGLContext ctx = EGL_NO_CONTEXT;
+   EVGL_Resource *rsc = NULL;
+
+   int attribs[] = {
+      EGL_GL_TEXTURE_LEVEL_KHR, 0,
+      EGL_IMAGE_PRESERVED_KHR, 0,
+      EGL_NONE
+   };
+
+   // Retrieve the resource object
+   if (!(rsc = _evgl_tls_resource_get()))
+     {
+        ERR("Error creating resources in tls.");
+        return NULL;
+     }
+
+   dpy = (EGLDisplay)rsc->display;
+   ctx = (EGLContext)context->context;
+
+   return EXT_FUNC(eglCreateImage)(dpy, ctx, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)tex, attribs);
+#else
+   (void) context; (void) tex;
+   return NULL;
+#endif
+}
+
+static void
+_framebuffer_create(GLuint *buf, Eina_Bool use_extension)
+{
+   if (use_extension)
+     {
+        if (gles1_funcs && gles1_funcs->glGenFramebuffersOES)
+          gles1_funcs->glGenFramebuffersOES(1, buf);
+     }
+   else
+     {
+        glGenFramebuffers(1, buf);
+     }
+}
+
+static void
+_framebuffer_bind(GLuint buf, Eina_Bool use_extension)
+{
+   if (use_extension)
+     {
+        if (gles1_funcs && gles1_funcs->glBindFramebufferOES)
+          gles1_funcs->glBindFramebufferOES(GL_FRAMEBUFFER, buf);
+     }
+   else
+     {
+        glBindFramebuffer(GL_FRAMEBUFFER, buf);
+     }
+}
+
+static GLenum
+_framebuffer_check(Eina_Bool use_extension)
+{
+   GLenum ret = 0;
+   if (use_extension)
+     {
+        if (gles1_funcs && gles1_funcs->glCheckFramebufferStatusOES)
+          ret = gles1_funcs->glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
+     }
+   else
+     {
+        ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+     }
+   return ret;
+}
+
 // Gen Renderbuffer
-void
+static void
 _renderbuffer_create(GLuint *buf)
 {
    glGenRenderbuffers(1, buf);
@@ -230,7 +322,7 @@ _renderbuffer_create(GLuint *buf)
 
 
 // Attach a renderbuffer with the given format to already bound FBO
-void
+static void
 _renderbuffer_allocate(GLuint buf, GLenum fmt, int w, int h, int samples)
 {
    glBindRenderbuffer(GL_RENDERBUFFER, buf);
@@ -248,7 +340,7 @@ _renderbuffer_allocate(GLuint buf, GLenum fmt, int w, int h, int samples)
    samples = 0;
 }
 
-void
+static void
 _renderbuffer_destroy(GLuint *buf)
 {
    if (*buf)
@@ -259,10 +351,18 @@ _renderbuffer_destroy(GLuint *buf)
 }
 
 // Attach a renderbuffer with the given format to already bound FBO
-void
-_renderbuffer_attach(GLuint buf, GLenum attach)
+static void
+_renderbuffer_attach(GLuint buf, GLenum attach, Eina_Bool use_extension)
 {
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
+   if (use_extension)
+     {
+        if (gles1_funcs->glFramebufferRenderbufferOES)
+          gles1_funcs->glFramebufferRenderbufferOES(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
+     }
+   else
+     {
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, attach, GL_RENDERBUFFER, buf);
+     }
 }
 
 // Check whether the given FBO surface config is supported by the driver
@@ -288,7 +388,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
      {
         _texture_create(&color_buf);
         _texture_allocate_2d(color_buf, color_ifmt, color_fmt, GL_UNSIGNED_BYTE, w, h);
-        _texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples);
+        _texture_attach_2d(color_buf, GL_COLOR_ATTACHMENT0, 0, mult_samples, EINA_FALSE);
      }
 
    // Check Depth_Stencil Format First
@@ -299,7 +399,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
         _texture_allocate_2d(depth_stencil_buf, depth_fmt,
                            depth_fmt, GL_UNSIGNED_INT_24_8_OES, w, h);
         _texture_attach_2d(depth_stencil_buf, GL_DEPTH_ATTACHMENT,
-                           GL_STENCIL_ATTACHMENT, mult_samples);
+                           GL_STENCIL_ATTACHMENT, mult_samples, EINA_FALSE);
         depth_stencil = 1;
      }
 #else
@@ -307,7 +407,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
      {
         _renderbuffer_create(&depth_stencil_buf);
         _renderbuffer_allocate(depth_stencil_buf, depth_fmt, w, h, mult_samples);
-        _renderbuffer_attach(depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT);
+        _renderbuffer_attach(depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, EINA_FALSE);
         depth_stencil = 1;
      }
 #endif
@@ -317,7 +417,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
      {
         _renderbuffer_create(&depth_buf);
         _renderbuffer_allocate(depth_buf, depth_fmt, w, h, mult_samples);
-        _renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT);
+        _renderbuffer_attach(depth_buf, GL_DEPTH_ATTACHMENT, EINA_FALSE);
      }
 
    // Stencil Attachment
@@ -325,7 +425,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
      {
         _renderbuffer_create(&stencil_buf);
         _renderbuffer_allocate(stencil_buf, stencil_fmt, w, h, mult_samples);
-        _renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT);
+        _renderbuffer_attach(stencil_buf, GL_STENCIL_ATTACHMENT, EINA_FALSE);
      }
 
    // Check FBO for completeness
@@ -359,7 +459,7 @@ _fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
       return 1;
 }
 
-int
+static int
 _surface_cap_test(EVGL_Surface_Format *fmt, GL_Format *color,
                   GL_Format *depth, GL_Format *stencil, int samples)
 {
@@ -402,7 +502,7 @@ _surface_cap_test(EVGL_Surface_Format *fmt, GL_Format *color,
 }
 
 
-int
+static int
 _surface_cap_check()
 {
    int num_fmts = 0;
@@ -732,6 +832,47 @@ _surface_cap_init(void *eng_data)
      }
 }
 
+static int
+_context_ext_check(EVGL_Context *ctx)
+{
+   int fbo_supported = 0;
+   int egl_image_supported = 0;
+
+   if (!ctx)
+      return 0;
+
+   if (ctx->extension_checked)
+      return 1;
+
+#ifdef GL_GLES
+   switch (ctx->version)
+     {
+      case EVAS_GL_GLES_1_X:
+         if (EXTENSION_SUPPORT_GLES1(framebuffer_object))
+           fbo_supported = 1;
+         break;
+      case EVAS_GL_GLES_2_X:
+      case EVAS_GL_GLES_3_X:
+      default:
+         fbo_supported = 1;
+     }
+
+   if (EXTENSION_SUPPORT(EGL_KHR_image_base)
+       && EXTENSION_SUPPORT(EGL_KHR_gl_texture_2D_image))
+     egl_image_supported = 1;
+#else
+   fbo_supported = 1;
+   egl_image_supported = 0;
+#endif
+
+   if (fbo_supported && egl_image_supported)
+     ctx->fbo_image_supported = 1;
+
+   ctx->extension_checked = 1;
+
+   return 1;
+}
+
 static const char *
 _glenum_string_get(GLenum e)
 {
@@ -911,48 +1052,47 @@ _surface_context_list_print()
 // Start from here.....
 //--------------------------------------------------------//
 static int
-_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo)
+_surface_buffers_fbo_set(EVGL_Surface *sfc, GLuint fbo, Eina_Bool use_extension)
 {
    int status;
 
-   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+   _framebuffer_bind(fbo, use_extension);
 
    // Detach any previously attached buffers
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, 0, 0);
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+   _texture_attach_2d(0, GL_COLOR_ATTACHMENT0, 0, 0, use_extension);
+   _renderbuffer_attach(0, GL_DEPTH_ATTACHMENT, use_extension);
+   _renderbuffer_attach(0, GL_STENCIL_ATTACHMENT, use_extension);
 #ifdef GL_GLES
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
-   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+   _texture_attach_2d(0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, 0, use_extension);
 #else
-   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+    _renderbuffer_attach(0, GL_DEPTH_STENCIL_ATTACHMENT, use_extension);
 #endif
 
    // Render Target Texture
    if (sfc->color_buf)
-     _texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples);
+     _texture_attach_2d(sfc->color_buf, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, use_extension);
 
    // Depth Stencil RenderBuffer - Attach it to FBO
    if (sfc->depth_stencil_buf)
      {
 #ifdef GL_GLES
         _texture_attach_2d(sfc->depth_stencil_buf, GL_DEPTH_ATTACHMENT,
-                           GL_STENCIL_ATTACHMENT, sfc->msaa_samples);
+                           GL_STENCIL_ATTACHMENT, sfc->msaa_samples, use_extension);
 #else
-        _renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT);
+        _renderbuffer_attach(sfc->depth_stencil_buf, GL_DEPTH_STENCIL_ATTACHMENT, use_extension);
 #endif
      }
 
    // Depth RenderBuffer - Attach it to FBO
    if (sfc->depth_buf)
-     _renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT);
+     _renderbuffer_attach(sfc->depth_buf, GL_DEPTH_ATTACHMENT, use_extension);
 
    // Stencil RenderBuffer - Attach it to FBO
    if (sfc->stencil_buf)
-     _renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT);
+     _renderbuffer_attach(sfc->stencil_buf, GL_STENCIL_ATTACHMENT, use_extension);
 
    // Check FBO for completeness
-   status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+   status = _framebuffer_check(use_extension);
    if (status != GL_FRAMEBUFFER_COMPLETE)
      {
         ERR("FBO not complete. Error Code: %x!", status);
@@ -1013,6 +1153,8 @@ _surface_buffers_allocate(void *eng_data, EVGL_Surface *sfc, int w, int h, int m
      {
         _texture_allocate_2d(sfc->color_buf, sfc->color_ifmt, sfc->color_fmt,
                              GL_UNSIGNED_BYTE, w, h);
+        if ((sfc->current_ctx) && (sfc->current_ctx->fbo_image_supported))
+          sfc->egl_image = _egl_image_create(sfc->current_ctx, sfc->color_buf);
         sfc->buffer_mem[0] = w * h * 4;
      }
 
@@ -1663,55 +1805,6 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
           sfc->direct_override = EINA_TRUE;
      }
 
-   // Set the context current with resource context/surface
-   if (!_internal_resource_make_current(eng_data, NULL))
-     {
-        ERR("Error doing an internal resource make current");
-        evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
-        goto error;
-     }
-
-   // Allocate a special surface for 1.1
-   if (cfg->gles_version == EVAS_GL_GLES_1_X)
-     {
-        if (!evgl_engine->funcs->gles1_surface_create)
-          {
-             ERR("Can't create GLES 1.1 surfaces");
-             evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
-             goto error;
-          }
-
-        INF("Creating special surface for GLES 1.x rendering");
-        evgl_engine->funcs->gles1_surface_create(eng_data, sfc, cfg, w, h);
-     }
-
-   // Create internal buffers
-   if (!_surface_buffers_create(sfc))
-     {
-        ERR("Unable Create Specificed Surfaces.");
-        evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
-        goto error;
-     };
-
-   // Allocate resources for fallback unless the flag is on
-   if (!sfc->direct_mem_opt)
-     {
-        if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
-          {
-             ERR("Unable Create Allocate Memory for Surface.");
-             evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
-             goto error;
-          }
-     }
-
-   if (dbg) DBG("Calling make_current(NULL, NULL)");
-   if (!evgl_engine->funcs->make_current(eng_data, NULL, NULL, 0))
-     {
-        ERR("Error doing make_current(NULL, NULL).");
-        evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
-        goto error;
-     }
-
    // Keep track of all the created surfaces
    LKL(evgl_engine->resource_lock);
    evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc);
@@ -1890,7 +1983,6 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
    EVGL_Resource *rsc;
    Eina_Bool need_reconfigure = EINA_FALSE;
    Eina_Bool dbg;
-   GLuint texid;
 
    // FIXME: This does some make_current(0,0) which may have side effects
 
@@ -1960,7 +2052,6 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
 
 
    // Destroy created buffers
-   texid = sfc->color_buf;
    if (!_surface_buffers_destroy(sfc))
      {
         ERR("Error deleting surface resources.");
@@ -1996,8 +2087,16 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc)
 
    if (sfc->direct_fb_opt)
      {
-        eina_hash_del(evgl_engine->direct_surfaces, &texid, sfc);
-        DBG("Removed tex %d from the direct surface: %p", texid, sfc);
+        if (!sfc->gles1_indirect)
+          {
+             eina_hash_del(evgl_engine->direct_surfaces, &sfc->color_buf, sfc);
+             DBG("Removed tex %d as direct surface: %p", sfc->color_buf, sfc);
+          }
+        else
+          {
+             eina_hash_del(evgl_engine->direct_surfaces, &sfc->gles1_sfc_native, sfc);
+             DBG("Removed native %p as direct surface: %p", sfc->gles1_sfc_native, sfc);
+          }
      }
 
    if (sfc->direct_fb_opt &&
@@ -2031,6 +2130,7 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
                     Evas_GL_Context_Version version)
 {
    EVGL_Context *ctx   = NULL;
+   EVGL_Resource *rsc  = NULL;
 
    // Check the input
    if (!evgl_engine)
@@ -2050,6 +2150,12 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx,
    if (evgl_engine->api_debug_mode)
      DBG("Creating context GLESv%d (eng = %p, shctx = %p)", version, eng_data, share_ctx);
 
+   if (!(rsc = _evgl_tls_resource_get()))
+     {
+        ERR("Error creating resources in tls.");
+        return NULL;
+     }
+
    // Allocate context object
    ctx = calloc(1, sizeof(EVGL_Context));
    if (!ctx)
@@ -2231,6 +2337,43 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
         rsc->current_ctx->partial_render = 0;
      }
 
+   // Do a make current
+   if (!_internal_resource_make_current(eng_data, ctx))
+     {
+        ERR("Error doing a make current with internal surface. Context: %p", ctx);
+        evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
+        return 0;
+     }
+   sfc->current_ctx = ctx;
+   rsc->current_ctx = ctx;
+   rsc->current_eng = eng_data;
+
+   // Check whether extensions are supported for the current context version
+   // to use fbo & egl image passing to evas
+   if (!ctx->extension_checked)
+     {
+        if (!evgl_api_get(ctx->version))
+          {
+             ERR("Unable to get the list of GL APIs for version %d", ctx->version);
+             evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
+             return 0;
+          }
+
+        if (!_context_ext_check(ctx))
+          {
+             ERR("Unable to check required extension for the current context");
+             evas_gl_common_error_set(eng_data, EVAS_GL_NOT_INITIALIZED);
+             return 0;
+          }
+     }
+
+   if (!sfc->color_buf && !_surface_buffers_create(sfc))
+     {
+        ERR("Unable to create specified surfaces.");
+        evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
+        return 0;
+     };
+
    // Allocate or free resources depending on what mode (direct of fbo) it's
    // running only if the env var EVAS_GL_DIRECT_MEM_OPT is set.
    if (sfc->direct_mem_opt)
@@ -2274,21 +2417,26 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
                }
           }
      }
-
-   // Do a make current
-   if (!_internal_resource_make_current(eng_data, ctx))
+   else
      {
-        ERR("Error doing a make current with internal surface. Context: %p", ctx);
-        evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
+        if (!sfc->buffers_allocated)
+          {
+             if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0))
+     {
+                  ERR("Unable Create Allocate Memory for Surface.");
+                  evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC);
         return 0;
      }
+             sfc->buffers_allocated = 1;
+          }
+     }
 
-   if (ctx->version == EVAS_GL_GLES_1_X)
+   if (!ctx->fbo_image_supported)
      {
         if (dbg) DBG("ctx %p is GLES 1", ctx);
         if (_evgl_direct_renderable(rsc, sfc))
           {
-             // Transition from pixmap surface rendering to direct rendering
+             // Transition from indirect rendering to direct rendering
              if (!rsc->direct.rendered)
                {
                   // Restore viewport and scissor test to direct rendering mode
@@ -2328,10 +2476,14 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
      }
    else // gles 2.x and 3.x
      {
+        Eina_Bool use_extension = EINA_FALSE;
+        if ((ctx->version == EVAS_GL_GLES_1_X) && (gles1_funcs))
+          use_extension = EINA_TRUE;
+
         // Normal FBO Rendering
         // Create FBO if it hasn't been created
         if (!ctx->surface_fbo)
-           glGenFramebuffers(1, &ctx->surface_fbo);
+          _framebuffer_create(&ctx->surface_fbo, use_extension);
 
         // Direct Rendering
         if (_evgl_direct_renderable(rsc, sfc))
@@ -2342,13 +2494,13 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
              glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
              if (ctx->surface_fbo == (GLuint)curr_fbo)
                {
-                  glBindFramebuffer(GL_FRAMEBUFFER, 0);
+                  _framebuffer_bind(0, use_extension);
                   ctx->current_fbo = 0;
                }
              else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
                {
                   // Using the same context, we were rendering on a pbuffer
-                  glBindFramebuffer(GL_FRAMEBUFFER, 0);
+                  _framebuffer_bind(0, use_extension);
                   ctx->current_fbo = 0;
                }
 
@@ -2377,7 +2529,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
 
              if (sfc->color_buf)
                {
-                  if (!_surface_buffers_fbo_set(sfc, sfc->color_buf))
+                  if (!_surface_buffers_fbo_set(sfc, sfc->color_buf, use_extension))
                     ERR("Could not detach current FBO");
                }
 
@@ -2388,7 +2540,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
              // Bind to the previously bound buffer (may be 0)
              if (ctx->current_fbo)
                {
-                  glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
+                  _framebuffer_bind(ctx->current_fbo, use_extension);
                   GLERRLOG();
                }
 
@@ -2413,7 +2565,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
                        if (rsc->direct.partial.enabled)
                           evgl_direct_partial_render_end();
 
-                       if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo))
+                       if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, use_extension))
                          {
                             ERR("Attaching buffers to context fbo failed. Engine: %p  Surface: %p Context FBO: %u", evgl_engine, sfc, ctx->surface_fbo);
                             evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT);
@@ -2423,7 +2575,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
 
                   // Bind to the previously bound buffer
                   if (ctx->current_fbo)
-                     glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
+                    _framebuffer_bind(ctx->current_fbo, use_extension);
                }
              rsc->direct.rendered = 0;
           }
@@ -2433,11 +2585,6 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
    rsc->current_ctx = ctx;
    rsc->current_eng = eng_data;
 
-   // Update GLESv1 extension functions after GLESv1 context is bound
-   if (ctx->version == EVAS_GL_GLES_1_X)
-     {
-        evgl_api_gles1_ext_get(gles1_funcs);
-     }
 
    _surface_context_list_print();
 
@@ -2503,6 +2650,18 @@ evgl_safe_extension_get(const char *name, void **pfuncptr)
    return EINA_TRUE;
 }
 
+void *
+evgl_native_surface_egl_image_get(EVGL_Surface *sfc)
+{
+   if (!evgl_engine)
+     {
+        ERR("Invalid input data.  Engine: %p", evgl_engine);
+        return NULL;
+     }
+
+   return sfc->egl_image;
+}
+
 int
 evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
 {
@@ -2515,16 +2674,9 @@ evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
 
    if (!sfc->gles1_indirect)
      {
-        ns->type = EVAS_NATIVE_SURFACE_OPENGL;
+        ns->type = EVAS_NATIVE_SURFACE_EVASGL;
         ns->version = EVAS_NATIVE_SURFACE_VERSION;
-        ns->data.opengl.texture_id = sfc->color_buf;
-        ns->data.opengl.framebuffer_id = sfc->color_buf;
-        ns->data.opengl.internal_format = sfc->color_ifmt;
-        ns->data.opengl.format = sfc->color_fmt;
-        ns->data.opengl.x = 0;
-        ns->data.opengl.y = 0;
-        ns->data.opengl.w = sfc->w;
-        ns->data.opengl.h = sfc->h;
+        ns->data.evasgl.surface = sfc;
      }
    else
      {
@@ -2589,6 +2741,11 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
              return EINA_FALSE;
           }
      }
+   else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL &&
+            ns->data.evasgl.surface)
+     {
+        sfc = ns->data.evasgl.surface;
+     }
    else
      {
         ERR("Only EVAS_NATIVE_SURFACE_OPENGL or EVAS_NATIVE_SURFACE_X11 can be used for direct rendering");
@@ -2611,10 +2768,10 @@ void
 evgl_direct_info_set(int win_w, int win_h, int rot,
                      int img_x, int img_y, int img_w, int img_h,
                      int clip_x, int clip_y, int clip_w, int clip_h,
-                     unsigned int texid)
+                     void *surface)
 {
    EVGL_Resource *rsc;
-   EVGL_Surface *sfc;
+   EVGL_Surface *sfc = surface;
 
    if (!(rsc = _evgl_tls_resource_get()))
      return;
@@ -2629,7 +2786,6 @@ evgl_direct_info_set(int win_w, int win_h, int rot,
     * If the surface is not found, we assume indirect rendering.
     */
 
-   sfc = eina_hash_find(evgl_engine->direct_surfaces, &texid);
 
    if ((rot == 0) ||
        evgl_engine->direct_override ||
@@ -2756,4 +2912,3 @@ evgl_direct_partial_render_end()
 }
 //-----------------------------------------------------//
 
-
index d1d3053..97a5aca 100644 (file)
@@ -20,7 +20,8 @@ typedef struct _EVGL_Surface_Format EVGL_Surface_Format;
 EAPI void         evgl_engine_shutdown(void *eng_data);
 
 typedef void (*EVGL_Engine_Call)(void *eng_data);
-
+EAPI void   *evgl_native_surface_egl_image_get(EVGL_Surface *sfc);
+typedef void *(*EVGL_Native_Surface_Call)(void *sfc);
 EVGL_Engine *evgl_engine_init(void *eng_data, const EVGL_Interface *efunc);
 
 void        *evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h);
@@ -41,7 +42,7 @@ void         evgl_direct_override_get(int *override, int *force_off);
 void         evgl_direct_info_set(int win_w, int win_h, int rot,
                                   int img_x, int img_y, int img_w, int img_h,
                                   int clip_x, int clip_y, int clip_w, int clip_h,
-                                  unsigned int texid);
+                                  void *surface);
 void         evgl_direct_info_clear();
 
 Eina_Bool    evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
index 3736656..db17e58 100755 (executable)
@@ -140,6 +140,7 @@ struct _EVGL_Surface
    void              *gles1_sfc_native;
    void              *gles1_sfc_visual;
    void              *gles1_sfc_config;
+   void              *egl_image;
 
    //-------------------------//
    // Related to PBuffer Surface
@@ -170,10 +171,12 @@ struct _EVGL_Context
    GLuint       current_fbo;
 
    // Direct Rendering Related
-   int          scissor_enabled : 1;
-   int          scissor_updated : 1;
-   int          direct_scissor : 1;
-   int          viewport_updated : 1;
+   unsigned     scissor_enabled : 1;
+   unsigned     scissor_updated : 1;
+   unsigned     direct_scissor : 1;
+   unsigned     viewport_updated : 1;
+   unsigned     extension_checked : 1;
+   unsigned     fbo_image_supported : 1;
 
    int          scissor_coord[4];
    int          viewport_coord[4];
index 1114d2f..929eb06 100755 (executable)
@@ -823,7 +823,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
 
    if (eng_gl_image_direct_get(data, image))
      {
-        unsigned int texid;
+        void *direct_surface = NULL;
 
         gl_context->dc = context;
         if ((gl_context->master_clip.enabled) &&
@@ -835,9 +835,11 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
           }
 
         if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
-          texid = n->data.opengl.texture_id;
+          direct_surface = eina_hash_find(evgl_engine->direct_surfaces, &n->data.opengl.texture_id);
         else if (n->type == EVAS_NATIVE_SURFACE_X11)
-          texid = n->data.x11.pixmap;
+          direct_surface = eina_hash_find(evgl_engine->direct_surfaces, &n->data.x11.pixmap);
+        else if (n->type == EVAS_NATIVE_SURFACE_EVASGL)
+          direct_surface = n->data.evasgl.surface;
         else
           {
              ERR("This native surface type is not supported for direct rendering");
@@ -853,7 +855,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
                              gl_context->dc->clip.y,
                              gl_context->dc->clip.w,
                              gl_context->dc->clip.h,
-                             texid);
+                             direct_surface);
 
         // Call pixel get function
         re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
index 61a3b2a..164d59a 100755 (executable)
@@ -59,6 +59,7 @@ Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
 Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
 Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
 EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
+EVGL_Native_Surface_Call glsym_evgl_native_surface_egl_image_get = NULL;
 Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
 
 Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
@@ -1247,6 +1248,7 @@ gl_symbols(void)
    LINK2GENERIC(evas_gl_preload_init);
    LINK2GENERIC(evas_gl_preload_shutdown);
    LINK2GENERIC(evgl_engine_shutdown);
+   LINK2GENERIC(evgl_native_surface_egl_image_get);
    LINK2GENERIC(evas_gl_symbols);
    LINK2GENERIC(evas_gl_common_error_get);
    LINK2GENERIC(evas_gl_common_error_set);
@@ -1980,6 +1982,25 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
       glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
     }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+#ifdef GL_GLES
+      if (n->egl_surface)
+        {
+          void *surface = glsym_evgl_native_surface_egl_image_get(n->egl_surface);
+          if (glsym_glEGLImageTargetTexture2DOES)
+            {
+              glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, surface);
+              if (eglGetError() != EGL_SUCCESS)
+                ERR("glEGLImageTargetTexture2DOES() failed.");
+            }
+          else
+            ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+        }
+#else
+// TODO
+#endif
+    }
 }
 
 static void
@@ -2012,6 +2033,10 @@ _native_unbind_cb(void *data EINA_UNUSED, void *image)
       glBindTexture(GL_TEXTURE_2D, 0);
       GLERR(__FUNCTION__, __FILE__, __LINE__, "");
     }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      // nothing
+    }
 }
 
 static void
@@ -2075,6 +2100,10 @@ _native_free_cb(void *data, void *image)
       texid = n->ns.data.opengl.texture_id;
       eina_hash_del(eng_get_ob(re)->gl_context->shared->native_tex_hash, &texid, im);
     }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      eina_hash_del(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &n->ns.data.evasgl.surface, im);
+    }
   im->native.data        = NULL;
   im->native.func.data   = NULL;
   im->native.func.bind   = NULL;
@@ -2095,6 +2124,7 @@ eng_image_native_set(void *data, void *image, void *native)
   uint32_t pmid, texid;
   unsigned int tex = 0;
   unsigned int fbo = 0;
+  void *buffer = NULL;
 
   if (!im)
     {
@@ -2136,6 +2166,16 @@ eng_image_native_set(void *data, void *image, void *native)
                 return im;
             }
         }
+      else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+        {
+           buffer = ns->data.evasgl.surface;
+           if (im->native.data)
+             {
+                Evas_Native_Surface *ens = im->native.data;
+                if (ens->data.evasgl.surface == buffer)
+                  return im;
+             }
+        }
     }
   if ((!ns) && (!im->native.data)) return im;
 
@@ -2183,6 +2223,21 @@ eng_image_native_set(void *data, void *image, void *native)
          }
 
     }
+  else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+       im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer);
+       if (im2 == im) return im;
+       if (im2)
+         {
+            n = im2->native.data;
+            if (n)
+             {
+                glsym_evas_gl_common_image_ref(im2);
+                glsym_evas_gl_common_image_free(im);
+                return im2;
+             }
+        }
+    }
   im2 = glsym_evas_gl_common_image_new_from_data(eng_get_ob(re)->gl_context,
                                            im->w, im->h, NULL, im->alpha,
                                            EVAS_COLORSPACE_ARGB8888);
@@ -2519,6 +2574,44 @@ eng_image_native_set(void *data, void *image, void *native)
         }
 
     }
+  else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      if (native)
+        {
+          n = calloc(1, sizeof(Native));
+          if (n)
+            {
+              memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+
+              eina_hash_add(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer, im);
+
+              n->pixmap = 0;
+              n->visual = 0;
+#ifdef GL_GLES
+              n->egl_surface = ns->data.evasgl.surface;
+#else
+              n->fbc = 0;
+              n->glx_pixmap = 0;
+#endif
+
+              im->native.yinvert     = 0;
+              im->native.loose       = 0;
+              im->native.data        = n;
+              im->native.func.data   = re;
+              im->native.func.bind   = _native_bind_cb;
+              im->native.func.unbind = _native_unbind_cb;
+              im->native.func.free   = _native_free_cb;
+              im->native.target      = GL_TEXTURE_2D;
+              im->native.mipmap      = 0;
+
+              // FIXME: need to implement mapping sub texture regions
+              // x, y, w, h for possible texture atlasing
+
+              glsym_evas_gl_common_image_native_enable(im);
+            }
+        }
+
+    }
    return im;
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index aef9a11..7a957b1
@@ -63,6 +63,7 @@ Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
 Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
 Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
 EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
+EVGL_Native_Surface_Call glsym_evgl_native_surface_egl_image_get = NULL;
 Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
 
 Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
@@ -143,6 +144,7 @@ gl_symbols(void)
    LINK2GENERIC(evas_gl_preload_render_relax);
    LINK2GENERIC(evas_gl_preload_init);
    LINK2GENERIC(evas_gl_preload_shutdown);
+   LINK2GENERIC(evgl_native_surface_egl_image_get);
    LINK2GENERIC(evgl_engine_shutdown);
    LINK2GENERIC(evas_gl_symbols);
    LINK2GENERIC(evas_gl_common_error_get);
@@ -1015,6 +1017,21 @@ _native_cb_bind(void *data EINA_UNUSED, void *image)
         glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
      }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+        if (n->egl_surface)
+          {
+            void *surface = glsym_evgl_native_surface_egl_image_get(n->egl_surface);
+            if (glsym_glEGLImageTargetTexture2DOES)
+              {
+                glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, surface);
+                if (eglGetError() != EGL_SUCCESS)
+                  ERR("glEGLImageTargetTexture2DOES() failed.");
+              }
+            else
+              ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+          }
+    }
 }
 
 static void
@@ -1031,6 +1048,10 @@ _native_cb_unbind(void *data EINA_UNUSED, void *image)
         glBindTexture(GL_TEXTURE_2D, 0);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
      }
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      // nothing
+    }
 }
 
 static void
@@ -1052,7 +1073,10 @@ _native_cb_free(void *data, void *image)
         texid = n->ns.data.opengl.texture_id;
         eina_hash_del(ob->gl_context->shared->native_tex_hash, &texid, img);
      }
-
+  else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
+    {
+      eina_hash_del(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &n->ns.data.evasgl.surface, img);
+    }
    img->native.data = NULL;
    img->native.func.data = NULL;
    img->native.func.bind = NULL;
@@ -1072,6 +1096,7 @@ eng_image_native_set(void *data, void *image, void *native)
    Evas_GL_Image *img, *img2;
    unsigned int tex = 0, fbo = 0;
    uint32_t texid;
+   void *buffer = NULL;
 
    if (!(re = (Render_Engine *)data)) return NULL;
    if (!(ob = eng_get_ob(re))) return NULL;
@@ -1107,6 +1132,16 @@ eng_image_native_set(void *data, void *image, void *native)
                return img;
           }
      }
+   else if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_EVASGL))
+     {
+        buffer = ns->data.evasgl.surface;
+        if (img->native.data)
+          {
+             Evas_Native_Surface *ens = img->native.data;
+             if (ens->data.evasgl.surface == buffer)
+               return img;
+          }
+     }
 
    if ((!ns) && (!img->native.data)) return img;
 
@@ -1136,6 +1171,21 @@ eng_image_native_set(void *data, void *image, void *native)
                }
           }
      }
+   else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+     {
+         img2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer);
+        if (img2 == img) return img;
+        if (img2)
+          {
+             n = img2->native.data;
+             if (n)
+              {
+                 glsym_evas_gl_common_image_ref(img2);
+                 glsym_evas_gl_common_image_free(img);
+                 return img2;
+              }
+         }
+     }
 
    img2 = glsym_evas_gl_common_image_new_from_data(ob->gl_context, img->w,
                                                    img->h, NULL, img->alpha,
@@ -1169,6 +1219,32 @@ eng_image_native_set(void *data, void *image, void *native)
                }
           }
      }
+   else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
+     {
+       if (native)
+         {
+           n = calloc(1, sizeof(Native));
+           if (n)
+             {
+               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+
+               eina_hash_add(eng_get_ob(re)->gl_context->shared->native_evasgl_hash, &buffer, img);
+
+               n->egl_surface = ns->data.evasgl.surface;
+               img->native.yinvert     = 0;
+               img->native.loose       = 0;
+               img->native.data        = n;
+               img->native.func.data   = re;
+               img->native.func.bind   = _native_cb_bind;
+               img->native.func.unbind = _native_cb_unbind;
+               img->native.func.free   = _native_cb_free;
+               img->native.target      = GL_TEXTURE_2D;
+               img->native.mipmap      = 0;
+
+               glsym_evas_gl_common_image_native_enable(img);
+             }
+         }
+     }
 
    return img;
 }