evas/gl_x11: introduce tbm native surface type
authorDongyeon Kim <dy5.kim@samsung.com>
Mon, 19 Jan 2015 03:28:32 +0000 (12:28 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Tue, 10 Feb 2015 05:48:22 +0000 (14:48 +0900)
Summary:
This native surface type is based on the tbm surface used for the tizen platform.
EGL_TIZEN_image_native_surface EGL extension is used to map
tbm surface to an egl image
@feature

Reviewers: raster, cedric, jpeg

Subscribers: cedric, wonsik

Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
15 files changed:
src/Makefile_Evas.am
src/lib/evas/Evas_Common.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/shader/evas_gl_enum.x
src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x
src/modules/evas/engines/gl_common/shader/tex_external_afill_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_afill_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_nomul_afill_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_nomul_afill_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_nomul_frag.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_nomul_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_common/shader/tex_external_vert.shd [new file with mode: 0644]
src/modules/evas/engines/gl_x11/evas_engine.c

index 2b7eab4..faff651 100644 (file)
@@ -709,6 +709,14 @@ modules/evas/engines/gl_common/shader/map_mask_bgra_frag.shd \
 modules/evas/engines/gl_common/shader/map_mask_bgra_vert.shd \
 modules/evas/engines/gl_common/shader/map_mask_bgra_nomul_frag.shd \
 modules/evas/engines/gl_common/shader/map_mask_bgra_nomul_vert.shd \
+modules/evas/engines/gl_common/shader/tex_external_frag.shd \
+modules/evas/engines/gl_common/shader/tex_external_vert.shd \
+modules/evas/engines/gl_common/shader/tex_external_nomul_frag.shd \
+modules/evas/engines/gl_common/shader/tex_external_nomul_vert.shd \
+modules/evas/engines/gl_common/shader/tex_external_afill_frag.shd \
+modules/evas/engines/gl_common/shader/tex_external_afill_vert.shd \
+modules/evas/engines/gl_common/shader/tex_external_nomul_afill_frag.shd \
+modules/evas/engines/gl_common/shader/tex_external_nomul_afill_vert.shd \
 $(NULL)
 
 EXTRA_DIST += \
index e53a122..e1ab7d6 100644 (file)
@@ -474,7 +474,8 @@ 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 */
+   EVAS_NATIVE_SURFACE_TBM, /**< Tizen system based type. tbm surface  */
 } Evas_Native_Surface_Type;
 
 /**
@@ -487,7 +488,9 @@ typedef enum _Evas_Native_Surface_Type
  * EVAS_NATIVE_SURFACE_OPENGL, on the other hand, you need to set union data
  * with opengl.texture_id or opengl.framebuffer_id and so on.
  * If you need to set the native surface as EVAS_NATIVE_SURFACE_WL,
- * you need to set union data with wl.legacy_buffer. The version field
+ * you need to set union data with wl.legacy_buffer.
+ * If you need to set the native surface as EVAS_NATIVE_SURFACE_TBM,
+ * you need to set union data with tbm surface. The version field
  * should be set with EVAS_NATIVE_SURFACE_VERSION in order to check abi
  * break in your application on the different efl library versions.
  *
@@ -525,6 +528,10 @@ 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 buffer to use */
+      } tbm; /**< Set this struct fields if surface data is Tizen based. */
    } data; /**< Choose one union data according to your surface. */
 };
 
index 4f2a552..481a557 100644 (file)
 #ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
 # define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
 #endif
+#ifndef GL_TEXTURE_EXTERNAL_OES
+# define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
 
 #ifndef GL_UNPACK_ROW_LENGTH
 # define GL_UNPACK_ROW_LENGTH 0x0cf2
 #ifndef EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC
 # define EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC 0x320c
 #endif
+#ifndef EGL_NATIVE_SURFACE_TIZEN
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif
 #ifndef GL_PROGRAM_BINARY_LENGTH
 # define GL_PROGRAM_BINARY_LENGTH 0x8741
 #endif
@@ -378,6 +385,7 @@ struct _Evas_GL_Shared
    Eina_Hash          *native_pm_hash;
    Eina_Hash          *native_tex_hash;
    Eina_Hash          *native_wl_hash;
+   Eina_Hash          *native_tbm_hash;
 
 #ifdef GL_GLES
    // FIXME: hack.
index bd683bd..bed567c 100644 (file)
@@ -907,6 +907,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_tbm_hash = eina_hash_pointer_new(NULL);
      }
    gc->shared = shared;
    gc->shared->references++;
@@ -981,6 +982,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_tbm_hash);
         free(gc->shared);
         shared = NULL;
      }
@@ -1885,6 +1887,19 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
                                                         SHADER_IMG_MASK_BGRA_NOMUL, SHADER_IMG_MASK_BGRA);
                }
           }
+#ifdef GL_GLES
+        else if (tex->im && tex->im->native.target == GL_TEXTURE_EXTERNAL_OES)
+          {
+             if ((!tex->alpha) && (tex->pt->native))
+               shader = evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                     SHADER_TEX_EXTERNAL_NOMUL_AFILL, SHADER_TEX_EXTERNAL_AFILL,
+                                                     SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK);
+             else
+               shader = evas_gl_common_shader_choice(0, NULL, r, g, b, a, !!mtex,
+                                                     SHADER_TEX_EXTERNAL_NOMUL, SHADER_TEX_EXTERNAL,
+                                                     SHADER_IMG_MASK_NOMUL, SHADER_IMG_MASK);
+          }
+#endif
         else
           {
              if ((smooth) && ((sw >= (w * 2)) && (sh >= (h * 2))))
index 6a543bb..3da8ac2 100644 (file)
@@ -58,5 +58,9 @@ typedef enum {
    SHADER_MAP_MASK_NOMUL,
    SHADER_MAP_MASK_BGRA,
    SHADER_MAP_MASK_BGRA_NOMUL,
+   SHADER_TEX_EXTERNAL,
+   SHADER_TEX_EXTERNAL_NOMUL,
+   SHADER_TEX_EXTERNAL_AFILL,
+   SHADER_TEX_EXTERNAL_NOMUL_AFILL,
    SHADER_LAST
 } Evas_GL_Shader;
index 1aa4b27..712a849 100644 (file)
@@ -2899,6 +2899,192 @@ Evas_GL_Program_Source shader_map_mask_bgra_nomul_vert_src =
    NULL, 0
 };
 
+/* Source: modules/evas/engines/gl_common/shader/tex_external_frag.shd */
+static const char const tex_external_frag_glsl[] =
+   "#ifdef GL_ES\n"
+   "#extension GL_OES_EGL_image_external : require\n"
+   "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+   "precision highp float;\n"
+   "#else\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "uniform samplerExternalOES tex;\n"
+   "#else\n"
+   "uniform sampler2D tex;\n"
+   "#endif\n"
+   "varying vec4 col;\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_FragColor = texture2D(tex, tex_c.xy) * col;\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_frag_src =
+{
+   tex_external_frag_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_vert.shd */
+static const char const tex_external_vert_glsl[] =
+   "#ifdef GL_ES\n"
+   "precision highp float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec4 color;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "varying vec4 col;\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_Position = mvp * vertex;\n"
+   "   col = color;\n"
+   "   tex_c = tex_coord;\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_vert_src =
+{
+   tex_external_vert_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_nomul_frag.shd */
+static const char const tex_external_nomul_frag_glsl[] =
+   "#ifdef GL_ES\n"
+   "#extension GL_OES_EGL_image_external : require\n"
+   "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+   "precision highp float;\n"
+   "#else\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "uniform samplerExternalOES tex;\n"
+   "#else\n"
+   "uniform sampler2D tex;\n"
+   "#endif\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_FragColor = texture2D(tex, tex_c.xy);\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_nomul_frag_src =
+{
+   tex_external_nomul_frag_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_nomul_vert.shd */
+static const char const tex_external_nomul_vert_glsl[] =
+   "#ifdef GL_ES\n"
+   "precision highp float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_Position = mvp * vertex;\n"
+   "   tex_c = tex_coord;\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_nomul_vert_src =
+{
+   tex_external_nomul_vert_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_afill_frag.shd */
+static const char const tex_external_afill_frag_glsl[] =
+   "#ifdef GL_ES\n"
+   "#extension GL_OES_EGL_image_external : require\n"
+   "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+   "precision highp float;\n"
+   "#else\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "uniform samplerExternalOES tex;\n"
+   "#else\n"
+   "uniform sampler2D tex;\n"
+   "#endif\n"
+   "varying vec4 col;\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   vec4 c = texture2D(tex, tex_c.xy);\n"
+   "   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_afill_frag_src =
+{
+   tex_external_afill_frag_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_afill_vert.shd */
+static const char const tex_external_afill_vert_glsl[] =
+   "#ifdef GL_ES\n"
+   "precision highp float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec4 color;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "varying vec4 col;\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_Position = mvp * vertex;\n"
+   "   col = color;\n"
+   "   tex_c = tex_coord;\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_afill_vert_src =
+{
+   tex_external_afill_vert_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_nomul_afill_frag.shd */
+static const char const tex_external_nomul_afill_frag_glsl[] =
+   "#ifdef GL_ES\n"
+   "#extension GL_OES_EGL_image_external : require\n"
+   "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+   "precision highp float;\n"
+   "#else\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "uniform samplerExternalOES tex;\n"
+   "#else\n"
+   "uniform sampler2D tex;\n"
+   "#endif\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   vec4 c = texture2D(tex, tex_c.xy);\n"
+   "   gl_FragColor = vec4(c.r, c.g, c.b, 1);\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_nomul_afill_frag_src =
+{
+   tex_external_nomul_afill_frag_glsl,
+   NULL, 0
+};
+
+/* Source: modules/evas/engines/gl_common/shader/tex_external_nomul_afill_vert.shd */
+static const char const tex_external_nomul_afill_vert_glsl[] =
+   "#ifdef GL_ES\n"
+   "precision highp float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "varying vec2 tex_c;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_Position = mvp * vertex;\n"
+   "   tex_c = tex_coord;\n"
+   "}\n";
+Evas_GL_Program_Source shader_tex_external_nomul_afill_vert_src =
+{
+   tex_external_nomul_afill_vert_glsl,
+   NULL, 0
+};
+
 static const struct {
    Evas_GL_Shader id;
    Evas_GL_Program_Source *vert;
@@ -2961,5 +3147,9 @@ static const struct {
    { SHADER_MAP_MASK_NOMUL, &(shader_map_mask_nomul_vert_src), &(shader_map_mask_nomul_frag_src), "map_mask_nomul" },
    { SHADER_MAP_MASK_BGRA, &(shader_map_mask_bgra_vert_src), &(shader_map_mask_bgra_frag_src), "map_mask_bgra" },
    { SHADER_MAP_MASK_BGRA_NOMUL, &(shader_map_mask_bgra_nomul_vert_src), &(shader_map_mask_bgra_nomul_frag_src), "map_mask_bgra_nomul" },
+   { SHADER_TEX_EXTERNAL, &(shader_tex_external_vert_src), &(shader_tex_external_frag_src), "tex_external" },
+   { SHADER_TEX_EXTERNAL_NOMUL, &(shader_tex_external_nomul_vert_src), &(shader_tex_external_nomul_frag_src), "tex_external_nomul" },
+   { SHADER_TEX_EXTERNAL_AFILL, &(shader_tex_external_afill_vert_src), &(shader_tex_external_afill_frag_src), "tex_external_afill" },
+   { SHADER_TEX_EXTERNAL_NOMUL_AFILL, &(shader_tex_external_nomul_afill_vert_src), &(shader_tex_external_nomul_afill_frag_src), "tex_external_nomul_afill" },
 };
 
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_afill_frag.shd b/src/modules/evas/engines/gl_common/shader/tex_external_afill_frag.shd
new file mode 100644 (file)
index 0000000..790911e
--- /dev/null
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#extension GL_OES_EGL_image_external : require
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+#else
+uniform sampler2D tex;
+#endif
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy);
+   gl_FragColor = vec4(c.r, c.g, c.b, 1) * col;
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_afill_vert.shd b/src/modules/evas/engines/gl_common/shader/tex_external_afill_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_frag.shd b/src/modules/evas/engines/gl_common/shader/tex_external_frag.shd
new file mode 100644 (file)
index 0000000..48a6626
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#extension GL_OES_EGL_image_external : require
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+#else
+uniform sampler2D tex;
+#endif
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c.xy) * col;
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_nomul_afill_frag.shd b/src/modules/evas/engines/gl_common/shader/tex_external_nomul_afill_frag.shd
new file mode 100644 (file)
index 0000000..93e8aa0
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef GL_ES
+#extension GL_OES_EGL_image_external : require
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+#else
+uniform sampler2D tex;
+#endif
+varying vec2 tex_c;
+void main()
+{
+   vec4 c = texture2D(tex, tex_c.xy);
+   gl_FragColor = vec4(c.r, c.g, c.b, 1);
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_nomul_afill_vert.shd b/src/modules/evas/engines/gl_common/shader/tex_external_nomul_afill_vert.shd
new file mode 100644 (file)
index 0000000..74f3207
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_nomul_frag.shd b/src/modules/evas/engines/gl_common/shader/tex_external_nomul_frag.shd
new file mode 100644 (file)
index 0000000..f852d17
--- /dev/null
@@ -0,0 +1,16 @@
+#ifdef GL_ES
+#extension GL_OES_EGL_image_external : require
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+uniform samplerExternalOES tex;
+#else
+uniform sampler2D tex;
+#endif
+varying vec2 tex_c;
+void main()
+{
+   gl_FragColor = texture2D(tex, tex_c.xy);
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_nomul_vert.shd b/src/modules/evas/engines/gl_common/shader/tex_external_nomul_vert.shd
new file mode 100644 (file)
index 0000000..74f3207
--- /dev/null
@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   tex_c = tex_coord;
+}
diff --git a/src/modules/evas/engines/gl_common/shader/tex_external_vert.shd b/src/modules/evas/engines/gl_common/shader/tex_external_vert.shd
new file mode 100644 (file)
index 0000000..606c297
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+attribute vec4 vertex;
+attribute vec4 color;
+attribute vec2 tex_coord;
+uniform mat4 mvp;
+varying vec4 col;
+varying vec2 tex_c;
+void main()
+{
+   gl_Position = mvp * vertex;
+   col = color;
+   tex_c = tex_coord;
+}
index 3721d31..cdbe5d2 100644 (file)
@@ -1841,6 +1841,7 @@ struct _Native
    Evas_Native_Surface ns;
    Pixmap     pixmap;
    Visual    *visual;
+   void      *buffer;
 
 #ifdef GL_GLES
    void      *egl_surface;
@@ -1899,6 +1900,22 @@ _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_TBM)
+    {
+#ifdef GL_GLES
+      if (n->egl_surface)
+        {
+           if (glsym_glEGLImageTargetTexture2DOES)
+              {
+                glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, n->egl_surface);
+                if (eglGetError() != EGL_SUCCESS)
+                  ERR("glEGLImageTargetTexture2DOES() failed.");
+              }
+            else
+              ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
+        }
+#endif
+    }
 }
 
 static void
@@ -1931,6 +1948,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_TBM)
+    {
+      // nothing
+    }
 }
 
 static void
@@ -1994,6 +2015,28 @@ _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_TBM)
+    {
+      eina_hash_del(eng_get_ob(re)->gl_context->shared->native_tbm_hash, &n->buffer, im);
+#ifdef GL_GLES
+      if (n->egl_surface)
+        {
+           int err;
+           if (glsym_eglDestroyImage)
+             {
+                glsym_eglDestroyImage(eng_get_ob(re)->egl_disp,
+                                      n->egl_surface);
+                if ((err = eglGetError()) != EGL_SUCCESS)
+                  {
+                     ERR("eglDestroyImage() failed.");
+                     glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
+                  }
+             }
+           else
+              ERR("Try eglDestroyImage on EGL with no support");
+        }
+#endif
+    }
   im->native.data        = NULL;
   im->native.func.data   = NULL;
   im->native.func.bind   = NULL;
@@ -2014,6 +2057,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)
     {
@@ -2055,6 +2099,16 @@ eng_image_native_set(void *data, void *image, void *native)
                 return im;
             }
         }
+      else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+        {
+           buffer = ns->data.tbm.buffer;
+           if (im->native.data)
+             {
+                Evas_Native_Surface *ens = im->native.data;
+                if (ens->data.tbm.buffer == buffer)
+                  return im;
+             }
+        }
     }
   if ((!ns) && (!im->native.data)) return im;
 
@@ -2102,6 +2156,21 @@ eng_image_native_set(void *data, void *image, void *native)
          }
 
     }
+  else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+    {
+       im2 = eina_hash_find(eng_get_ob(re)->gl_context->shared->native_tbm_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);
@@ -2432,6 +2501,42 @@ eng_image_native_set(void *data, void *image, void *native)
         }
 
     }
+  else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
+    {
+#ifdef GL_GLES
+       if (native)
+         {
+           n = calloc(1, sizeof(Native));
+           if (n)
+             {
+               eina_hash_add(eng_get_ob(re)->gl_context->shared->native_tbm_hash, &buffer, im);
+
+               memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
+               n->buffer = buffer;
+               if (glsym_eglCreateImage)
+                 n->egl_surface = glsym_eglCreateImage(eng_get_ob(re)->egl_disp,
+                                                       EGL_NO_CONTEXT,
+                                                       EGL_NATIVE_SURFACE_TIZEN,
+                                                       (void *)buffer,
+                                                       NULL);
+               else
+                 ERR("Try eglCreateImage on EGL with no support");
+               if (!n->egl_surface)
+                 ERR("eglCreateImage() for %p failed", buffer);
+               im->native.yinvert     = 1;
+               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_EXTERNAL_OES;
+               im->native.mipmap      = 0;
+               glsym_evas_gl_common_image_native_enable(im);
+             }
+         }
+#endif
+    }
    return im;
 }