Evas GL: Add pixmap surface fallback for gles 1.x indirect rendering 42/47442/4
authormythri.venugopal <mythri.venugopal@samsung.com>
Wed, 11 Mar 2015 15:56:12 +0000 (15:56 +0000)
committerDaeKwang Ryu <dkdk.ryu@samsung.com>
Wed, 16 Sep 2015 12:05:28 +0000 (21:05 +0900)
Merge from upstream patch
https://phab.enlightenment.org/rEFLa14492ef73c9267042c5bf505080d0e90af394de

Automatically fallback to indirect rendering on FBO or X11 Pixmap
if the Evas Object Image is not marked as dirty. This should
improve the performance and/or power consumption in those
rare cases where this area of the canvas needs to be redrawn
but the GL content has not changed.

and

- when dirty set is not called but has direct rendering,
   evas gl should render to a fallback surface and use that as texture
 - for gles 1.x, this fallback surface should be a pixmap surface,
   so it uses EVAS_NATIVE_SURFACE_X11 type
 - from now, both EVAS_NATIVE_SURFACE_OPENGL and EVAS_NATIVE_SURFACE_X11
   can be passed for direct rendering

Change-Id: I8aefb55c2b42dc90d4440bfaaa59f3824828b1cd

src/lib/evas/canvas/evas_object_image.c
src/lib/evas/include/evas_private.h
src/modules/evas/engines/gl_common/evas_gl_api_gles1.c
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_core.c
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/software_generic/evas_engine.c

index 8d1630e..d0af8eb 100755 (executable)
@@ -2819,10 +2819,7 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
                {
                   Evas_Native_Surface *ns;
                   ns = ENFN->image_native_get(ENDT, o->engine_data);
-                  if ( (ns) &&
-                       (ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
-                       (ns->data.opengl.texture_id) &&
-                       (!ns->data.opengl.framebuffer_id) )
+                  if (ns)
                     {
                        Eina_Bool direct_renderable = EINA_FALSE;
 
@@ -2845,6 +2842,8 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
                          {
                             if ((ENFN->gl_get_pixels_set) && (o->pixels->func.get_pixels))
                               ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
+                            if (ENFN->gl_image_direct_set)
+                              ENFN->gl_image_direct_set(output, o->engine_data, EINA_TRUE);
                             o->direct_render = EINA_TRUE;
                          }
                        else
@@ -2885,9 +2884,31 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
    else
      {
         // Check if the it's not dirty but it has direct rendering
-        if (o->direct_render)
+        if (o->direct_render && ENFN->image_native_get)
           {
-             ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
+             Evas_Native_Surface *ns;
+             ns = ENFN->image_native_get(output, o->engine_data);
+             if (ENFN->gl_direct_override_get)
+               ENFN->gl_direct_override_get(output, &direct_override, &direct_force_off);
+             if (ENFN->gl_surface_direct_renderable_get)
+               ENFN->gl_surface_direct_renderable_get(output, ns, &direct_override);
+
+             if (direct_override && !direct_force_off)
+               {
+                  // always use direct rendering
+                  if (ENFN->gl_get_pixels_set)
+                    ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
+                  if (ENFN->gl_image_direct_set)
+                    ENFN->gl_image_direct_set(output, o->engine_data, EINA_TRUE);
+               }
+             else
+               {
+                  // Auto-fallback to FBO rendering (for perf & power consumption)
+                  o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, obj->object);
+                  //if (ENFN->get_pixels_render_post)
+                    //ENFN->get_pixels_render_post(output);
+                  o->direct_render = EINA_FALSE;
+               }
           }
      }
 
@@ -2984,10 +3005,10 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
    ENFN->context_render_op_set(output, context, obj->cur->render_op);
 
    // Clear out the pixel get stuff..
-   if ((ENFN->gl_get_pixels_set) && (o->pixels->func.get_pixels))
-     {
-        ENFN->gl_get_pixels_set(output, NULL, NULL, NULL);
-     }
+   if (ENFN->gl_get_pixels_set)
+     ENFN->gl_get_pixels_set(output, NULL, NULL, NULL);
+   if (ENFN->gl_image_direct_set)
+     ENFN->gl_image_direct_set(output, o->engine_data, EINA_FALSE);
 
    Evas_Object_Protected_Data *source =
       (o->cur->source ?
index f06980e..fb96e10 100755 (executable)
@@ -1294,7 +1294,9 @@ struct _Evas_Func
    void *(*gl_current_surface_get)       (void *data);
    int  (*gl_rotation_angle_get)         (void *data);
    Eina_Bool (*gl_surface_query)         (void *data, void *surface, int attr, void *value);
-Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns, Eina_Bool *direct_override);
+   Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns, Eina_Bool *direct_override);
+   void (*gl_image_direct_set)           (void *data, void *image, Eina_Bool direct);
+   int  (*gl_image_direct_get)           (void *data, void *image);
 
    int  (*image_load_error_get)          (void *data, void *image);
    int  (*font_run_end_get)              (void *data, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);
index 99f793b..c3448aa 100644 (file)
@@ -1692,6 +1692,11 @@ _evgl_gles1_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
                   _gles1_api.glViewport(nc[0], nc[1], nc[2], nc[3]);
                }
 
+             ctx->viewport_direct[0] = nc[0];
+             ctx->viewport_direct[1] = nc[1];
+             ctx->viewport_direct[2] = nc[2];
+             ctx->viewport_direct[3] = nc[3];
+
              // Keep a copy of the original coordinates
              ctx->viewport_coord[0] = x;
              ctx->viewport_coord[1] = y;
index 9857569..95eea33 100644 (file)
@@ -609,6 +609,7 @@ struct _Evas_GL_Image
    unsigned char    alpha : 1;
    unsigned char    tex_only : 1;
    unsigned char    locked : 1; // gl_surface_lock/unlock
+   unsigned char    direct : 1; // evas gl direct renderable
 };
 
 struct _Evas_GL_Font_Texture
index cbb9998..b363fb4 100755 (executable)
@@ -1718,8 +1718,16 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
 
    if (sfc->direct_fb_opt)
      {
-        eina_hash_add(evgl_engine->direct_surfaces, &sfc->color_buf, sfc);
-        DBG("Added tex %d as direct surface: %p", sfc->color_buf, sfc);
+        if (!sfc->gles1_indirect)
+          {
+             eina_hash_add(evgl_engine->direct_surfaces, &sfc->color_buf, sfc);
+             DBG("Added tex %d as direct surface: %p", sfc->color_buf, sfc);
+          }
+        else
+          {
+             eina_hash_add(evgl_engine->direct_surfaces, &sfc->gles1_sfc_native, sfc);
+             DBG("Added tex %d as direct surface: %p", sfc->gles1_sfc_native, sfc);
+          }
      }
 
    if (sfc->direct_fb_opt &&
@@ -2267,19 +2275,28 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
           }
      }
 
+   // 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;
+     }
+
    if (ctx->version == EVAS_GL_GLES_1_X)
      {
         if (dbg) DBG("ctx %p is GLES 1", ctx);
         if (_evgl_direct_renderable(rsc, sfc))
           {
-             if (dbg) DBG("sfc %p is direct renderable.", sfc);
-             // Do a make current
-             if (!_internal_resource_make_current(eng_data, ctx))
+             // Transition from pixmap surface rendering to direct rendering
+             if (!rsc->direct.rendered)
                {
-                  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;
+                  // Restore viewport and scissor test to direct rendering mode
+                  glViewport(ctx->viewport_direct[0], ctx->viewport_direct[1], ctx->viewport_direct[2], ctx->viewport_direct[3]);
+                  if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+                    glEnable(GL_SCISSOR_TEST);
                }
+             if (dbg) DBG("sfc %p is direct renderable.", sfc);
              rsc->direct.rendered = 1;
           }
         else
@@ -2296,126 +2313,120 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
                   ERR("Failed to make current with GLES1 indirect surface.");
                   return 0;
                }
-          }
-
-        ctx->current_sfc = sfc;
-        rsc->current_ctx = ctx;
-        rsc->current_eng = eng_data;
-
-        // Update extensions after GLESv1 context is bound
-        //evgl_api_gles1_ext_get(gles1_funcs);
-
-        _surface_context_list_print();
 
-        return 1;
-     }
+             // Transition from direct rendering to pixmap surface rendering
+             if (rsc->direct.rendered)
+               {
+                  glViewport(ctx->viewport_coord[0], ctx->viewport_coord[1], ctx->viewport_coord[2], ctx->viewport_coord[3]);
+                  if ((ctx->direct_scissor) && (!ctx->scissor_enabled))
+                    glDisable(GL_SCISSOR_TEST);
+             }
 
-   // 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;
+             ctx->current_fbo = 0;
+             rsc->direct.rendered = 0;
+          }
      }
-
-   // Normal FBO Rendering
-   // Create FBO if it hasn't been created
-   if (!ctx->surface_fbo)
-      glGenFramebuffers(1, &ctx->surface_fbo);
-
-   // Direct Rendering
-   if (_evgl_direct_renderable(rsc, sfc))
+   else // gles 2.x and 3.x
      {
-        if (dbg) DBG("sfc %p is direct renderable.", sfc);
+        // Normal FBO Rendering
+        // Create FBO if it hasn't been created
+        if (!ctx->surface_fbo)
+           glGenFramebuffers(1, &ctx->surface_fbo);
 
-        // This is to transition from FBO rendering to direct rendering
-        glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
-        if (ctx->surface_fbo == (GLuint)curr_fbo)
-          {
-             glBindFramebuffer(GL_FRAMEBUFFER, 0);
-             ctx->current_fbo = 0;
-          }
-        else if (ctx->current_sfc && (ctx->current_sfc->pbuffer.is_pbuffer))
+        // Direct Rendering
+        if (_evgl_direct_renderable(rsc, sfc))
           {
-             // Using the same context, we were rendering on a pbuffer
-             glBindFramebuffer(GL_FRAMEBUFFER, 0);
-             ctx->current_fbo = 0;
-          }
+             if (dbg) DBG("sfc %p is direct renderable.", sfc);
 
-        if (ctx->current_fbo == 0)
-          {
-             // If master clip is set and clip is greater than 0, do partial render
-             if (rsc->direct.partial.enabled)
+             // This is to transition from FBO rendering to direct rendering
+             glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
+             if (ctx->surface_fbo == (GLuint)curr_fbo)
+               {
+                  glBindFramebuffer(GL_FRAMEBUFFER, 0);
+                  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);
+                  ctx->current_fbo = 0;
+               }
+
+             if (ctx->current_fbo == 0)
                {
-                  if (!ctx->partial_render)
+                  // If master clip is set and clip is greater than 0, do partial render
+                  if (rsc->direct.partial.enabled)
                     {
-                       evgl_direct_partial_render_start();
-                       ctx->partial_render = 1;
+                       if (!ctx->partial_render)
+                         {
+                            evgl_direct_partial_render_start();
+                            ctx->partial_render = 1;
+                         }
                     }
                }
-          }
-
-        rsc->direct.rendered = 1;
-     }
-   else if (sfc->pbuffer.native_surface)
-     {
-        if (dbg) DBG("Surface sfc %p is a pbuffer: %p", sfc, sfc->pbuffer.native_surface);
-
-        // Call end tiling
-        if (rsc->direct.partial.enabled)
-           evgl_direct_partial_render_end();
 
-        if (sfc->color_buf)
-          {
-             if (!_surface_buffers_fbo_set(sfc, sfc->color_buf))
-               ERR("Could not detach current FBO");
+             rsc->direct.rendered = 1;
           }
-
-        if (dbg) DBG("Calling make_current(%p, %p)", sfc->pbuffer.native_surface, ctx->context);
-        evgl_engine->funcs->make_current(eng_data, sfc->pbuffer.native_surface,
-                                         ctx->context, EINA_TRUE);
-
-        // Bind to the previously bound buffer (may be 0)
-        if (ctx->current_fbo)
+        else if (sfc->pbuffer.native_surface)
           {
-             glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
-             GLERRLOG();
-          }
+             if (dbg) DBG("Surface sfc %p is a pbuffer: %p", sfc, sfc->pbuffer.native_surface);
 
-        rsc->direct.rendered = 0;
-     }
-   else
-     {
-        if (dbg) DBG("Surface sfc %p is a normal surface.", sfc);
+             // Call end tiling
+             if (rsc->direct.partial.enabled)
+                evgl_direct_partial_render_end();
 
-        // Attach fbo and the buffers
-        if ((ctx->current_sfc != sfc) || (ctx != sfc->current_ctx))
-          {
-             sfc->current_ctx = ctx;
-             if ((sfc->direct_mem_opt) && (sfc->direct_fb_opt))
+             if (sfc->color_buf)
                {
-                  DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!");
+                  if (!_surface_buffers_fbo_set(sfc, sfc->color_buf))
+                    ERR("Could not detach current FBO");
                }
-             else
+
+             if (dbg) DBG("Calling make_current(%p, %p)", sfc->pbuffer.native_surface, ctx->context);
+             evgl_engine->funcs->make_current(eng_data, sfc->pbuffer.native_surface,
+                                              ctx->context, EINA_TRUE);
+
+             // Bind to the previously bound buffer (may be 0)
+             if (ctx->current_fbo)
                {
-                  // If it's transitioning from direct render to fbo render
-                  // Call end tiling
-                  if (rsc->direct.partial.enabled)
-                     evgl_direct_partial_render_end();
+                  glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
+                  GLERRLOG();
+               }
 
-                  if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo))
+             rsc->direct.rendered = 0;
+          }
+        else
+          {
+             if (dbg) DBG("Surface sfc %p is a normal surface.", sfc);
+
+             // Attach fbo and the buffers
+             if ((rsc->current_ctx != ctx) || (ctx->current_sfc != sfc) || (rsc->direct.rendered))
+               {
+                  sfc->current_ctx = ctx;
+                  if ((sfc->direct_mem_opt) && (sfc->direct_fb_opt))
                     {
-                       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);
-                       return 0;
+                       DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!");
                     }
-               }
+                  else
+                    {
+                       // If it's transitioning from direct render to fbo render
+                       // Call end tiling
+                       if (rsc->direct.partial.enabled)
+                          evgl_direct_partial_render_end();
 
-             // Bind to the previously bound buffer
-             if (ctx->current_fbo)
-                glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
+                       if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo))
+                         {
+                            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);
+                            return 0;
+                         }
+                    }
+
+                  // Bind to the previously bound buffer
+                  if (ctx->current_fbo)
+                     glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
+               }
+             rsc->direct.rendered = 0;
           }
-        rsc->direct.rendered = 0;
      }
 
    ctx->current_sfc = sfc;
@@ -2502,7 +2513,7 @@ evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
         return 0;
      }
 
-   if (!sfc->xpixmap || sfc->direct_fb_opt)
+   if (!sfc->gles1_indirect)
      {
         ns->type = EVAS_NATIVE_SURFACE_OPENGL;
         ns->version = EVAS_NATIVE_SURFACE_VERSION;
@@ -2514,9 +2525,6 @@ evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
         ns->data.opengl.y = 0;
         ns->data.opengl.w = sfc->w;
         ns->data.opengl.h = sfc->h;
-
-        if (sfc->direct_fb_opt)
-          ns->data.opengl.framebuffer_id = 0;
      }
    else
      {
@@ -2557,27 +2565,44 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
    if (client_side_rotation) *client_side_rotation = EINA_FALSE;
 
    if (!evgl_engine) return EINA_FALSE;
-   if (!ns || (ns->type != EVAS_NATIVE_SURFACE_OPENGL)) return EINA_FALSE;
-   if (ns->data.opengl.framebuffer_id != 0) return EINA_FALSE;
-   if (ns->data.opengl.texture_id == 0) return EINA_FALSE;
+   if (!ns) return EINA_FALSE;
 
-   sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.opengl.texture_id);
-   if (!sfc)
+   if (ns->type == EVAS_NATIVE_SURFACE_OPENGL &&
+       ns->data.opengl.texture_id)
+     {
+        sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.opengl.texture_id);
+        if (!sfc)
+          {
+             DBG("Native surface %p (color_buf %d) was not found.",
+                 ns, ns->data.opengl.texture_id);
+             return EINA_FALSE;
+          }
+     }
+   else if (ns->type == EVAS_NATIVE_SURFACE_X11 &&
+            ns->data.x11.pixmap)
+     {
+        sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.x11.pixmap);
+        if (!sfc)
+          {
+             DBG("Native surface %p (pixmap %x) was not found.",
+                 ns, ns->data.x11.pixmap);
+             return EINA_FALSE;
+          }
+     }
+   else
      {
-        DBG("Native surface %p (color_buf %d) was not found.",
-            ns, ns->data.opengl.texture_id);
+        ERR("Only EVAS_NATIVE_SURFACE_OPENGL or EVAS_NATIVE_SURFACE_X11 can be used for direct rendering");
         return EINA_FALSE;
      }
 
    if (evgl_engine->api_debug_mode)
      {
-        DBG("Found native surface: texid:%u DR:%d DORR:%d CSR:%d",
-            ns->data.opengl.texture_id, (int) sfc->direct_fb_opt,
-            (int) sfc->direct_override, (int) sfc->client_side_rotation);
+        DBG("Found native surface:  DR:%d CSR:%d",
+            (int) sfc->direct_fb_opt, (int) sfc->client_side_rotation);
      }
 
    if (direct_render) *direct_render = sfc->direct_fb_opt;
-   if (direct_override) *direct_override = sfc->direct_override;
+   if (direct_override) *direct_override |= sfc->direct_override;
    if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation;
    return EINA_TRUE;
 }
index 10578b2..3736656 100755 (executable)
@@ -177,6 +177,7 @@ struct _EVGL_Context
 
    int          scissor_coord[4];
    int          viewport_coord[4];
+   int          viewport_direct[4];
 
    // For GLES1 with indirect rendering
    EVGLNative_Context gles1_context;
index 99950f3..1114d2f 100755 (executable)
@@ -33,6 +33,8 @@
 
 static int _evas_engine_GL_log_dom = -1;
 
+static int eng_gl_image_direct_get(void *data EINA_UNUSED, void *image);
+
 static void
 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
 {
@@ -819,10 +821,10 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
    gl_context = re->window_gl_context_get(re->software.ob);
    re->window_use(re->software.ob);
 
-   if ((n) && (n->type == EVAS_NATIVE_SURFACE_OPENGL) &&
-       (n->data.opengl.framebuffer_id == 0) &&
-       re->func.get_pixels)
+   if (eng_gl_image_direct_get(data, image))
      {
+        unsigned int texid;
+
         gl_context->dc = context;
         if ((gl_context->master_clip.enabled) &&
             (gl_context->master_clip.w > 0) &&
@@ -832,6 +834,16 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
              evgl_direct_partial_info_set(gl_context->preserve_bit);
           }
 
+        if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
+          texid = n->data.opengl.texture_id;
+        else if (n->type == EVAS_NATIVE_SURFACE_X11)
+          texid = n->data.x11.pixmap;
+        else
+          {
+             ERR("This native surface type is not supported for direct rendering");
+             return EINA_FALSE;
+          }
+
         // Set necessary info for direct rendering
         evgl_direct_info_set(gl_context->w,
                              gl_context->h,
@@ -841,7 +853,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,
-                             n->data.opengl.texture_id);
+                             texid);
 
         // Call pixel get function
         re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
@@ -1474,6 +1486,27 @@ eng_gl_surface_query(void *data, void *surface, int attr, void *value)
 #endif
 }
 
+static int
+eng_gl_image_direct_get(void *data EINA_UNUSED, void *image)
+{
+   Evas_GL_Image *im = image;
+   if (!im) return EINA_FALSE;
+   return im->direct;
+}
+
+static void
+eng_gl_image_direct_set(void *data, void *image, Eina_Bool direct)
+{
+   Render_Engine_GL_Generic *re = data;
+   Evas_GL_Image *im = image;
+
+   if (!im) return;
+   if (im->native.data && direct && re && re->func.get_pixels)
+     im->direct = EINA_TRUE;
+   else
+     im->direct = EINA_FALSE;
+}
+
 //--------------------------------//
 
 static int
@@ -2158,6 +2191,8 @@ module_open(Evas_Module *em)
    // gl_current_context_get is in engine
    ORD(gl_current_surface_get);
    ORD(gl_rotation_angle_get);
+   ORD(gl_image_direct_get);
+   ORD(gl_image_direct_set);
 
    ORD(image_load_error_get);
 
index 823cbb4..61a3b2a 100755 (executable)
@@ -1954,7 +1954,7 @@ _native_bind_cb(void *data EINA_UNUSED, void *image)
           if (glsym_glEGLImageTargetTexture2DOES)
             {
               glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
-              if (eglGetError() != EGL_SUCCESS)
+              if (glGetError() != GL_NO_ERROR)
                 ERR("glEGLImageTargetTexture2DOES() failed.");
             }
           else
index 36e91a8..2dbd726 100644 (file)
@@ -3853,6 +3853,8 @@ static Evas_Func func =
      NULL, // need software mesa for gl rendering <- gl_rotation_angle_get
      NULL, // need software mesa for gl rendering <- gl_surface_query
      NULL, // need software mesa for gl rendering <- gl_surface_direct_renderable_get
+     NULL, // need software mesa for gl rendering <- gl_image_direct_set
+     NULL, // need software mesa for gl rendering <- gl_image_direct_get
      eng_image_load_error_get,
      eng_font_run_font_end_get,
      eng_image_animated_get,