This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch glthx
in repository efl.

View the commit online.

commit 350f1c401075454604d42d4f597db355e0f39da4
Author: jutty.lee <jutty....@samsung.com>
AuthorDate: Mon Sep 18 18:53:01 2017 +0900

    (GL thread R 4/5) Stabilized patches (basic functional threading)
    
    Summary:
    Depends on D5089
    
    - Pixel call threading
    - eng_window_new
    - Texturing logics
    - shader_array_flush
    
    Reviewers: raster, sung, jpeg
    
    Differential Revision: https://phab.enlightenment.org/D5090
---
 src/lib/evas/Evas_GL.h                             |   7 +-
 src/lib/evas/canvas/evas_object_image.c            |  10 +-
 src/lib/evas/include/evas_private.h                |   2 +
 .../evas/engines/gl_common/evas_gl_context.c       |  44 +++++-
 src/modules/evas/engines/gl_common/evas_gl_core.c  |   2 +
 .../evas/engines/gl_common/evas_gl_core_private.h  |   2 +
 .../evas/engines/gl_common/evas_gl_shader.c        |   1 +
 .../evas/engines/gl_common/evas_gl_texture.c       | 151 +++++++++++++++------
 src/modules/evas/engines/gl_generic/evas_engine.c  |  67 +++++++++
 .../evas/engines/wayland_egl/evas_wl_main.c        |  51 ++++++-
 10 files changed, 283 insertions(+), 54 deletions(-)

diff --git a/src/lib/evas/Evas_GL.h b/src/lib/evas/Evas_GL.h
index abc03ef267..d05fb9121a 100644
--- a/src/lib/evas/Evas_GL.h
+++ b/src/lib/evas/Evas_GL.h
@@ -512,9 +512,12 @@ typedef enum _Evas_GL_Options_Bits
 {
    EVAS_GL_OPTIONS_NONE    = 0,     /**< No extra options */
    EVAS_GL_OPTIONS_DIRECT  = (1<<0),/**< Optional hint to allow rendering directly to the Evas window if possible */
-   EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION = (1<<1) /**< Force direct rendering even if the canvas is rotated.
+   EVAS_GL_OPTIONS_CLIENT_SIDE_ROTATION = (1<<1),/**< Force direct rendering even if the canvas is rotated.
                                                   *   In that case, it is the application's role to rotate the contents of
-                                                  *   the Evas_GL view. @see evas_gl_rotation_get. @since 1.12 */
+                                                  *   the Evas_GL view. @see evas_gl_rotation_get */
+   EVAS_GL_OPTIONS_THREAD  = (1<<2) /**< If enabled, Evas GL pixel callback will be called by another thread instead of main thread.
+                                     * This option can enhance performance because Evas GL is worked with aynchronized call,
+                                     * but user must guarantee synchronization with pixel callback and main loop when using this flag. */
 } Evas_GL_Options_Bits;
 
 /**
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index 47128cb2bd..8cefe10fc3 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -1661,7 +1661,10 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
                {
                   if (ENFN->gl_get_pixels_pre)
                     ENFN->gl_get_pixels_pre(output);
-                  o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, eo_obj);
+                  if (ENFN->gl_get_pixels)
+                    ENFN->gl_get_pixels(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj, o->engine_data);
+                  else
+                    o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, eo_obj);
                   if (ENFN->gl_get_pixels_post)
                     ENFN->gl_get_pixels_post(output);
                }
@@ -1705,7 +1708,10 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
                   // Auto-fallback to FBO rendering (for perf & power consumption)
                   if (ENFN->gl_get_pixels_pre)
                     ENFN->gl_get_pixels_pre(engine);
-                  o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, obj->object);
+                  if (ENFN->gl_get_pixels)
+                    ENFN->gl_get_pixels(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj, o->engine_data);
+                  else
+                    o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, eo_obj);
                   if (ENFN->gl_get_pixels_post)
                     ENFN->gl_get_pixels_post(engine);
                   o->direct_render = EINA_FALSE;
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index af5a08318f..96961ce267 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1617,6 +1617,8 @@ struct _Evas_Func
 
    Evas_Filter_Support (*gfx_filter_supports) (void *engine, Evas_Filter_Command *cmd);
    Eina_Bool (*gfx_filter_process)       (void *engine, Evas_Filter_Command *cmd);
+
+   void (*gl_get_pixels)                 (void *data, Evas_Object_Image_Pixels_Get_Cb cb, void *get_pixels_data, Evas_Object *o, void *image);
 };
 
 struct _Evas_Image_Save_Func
diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c
index eafde5af5f..f18c79459f 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -829,7 +829,7 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
         prog = gc->state.current.prog;
         GL_TH(glUseProgram, prog->prog);
         GL_TH(glUniform1i, prog->uniform.rotation_id, gc->rot / 90);
-        GL_TH(glUniformMatrix4fv, prog->uniform.mvp, 1, GL_FALSE, gc->shared->proj);
+        GL_TH(glUniformMatrix4fv, gc->state.current.prog->uniform.mvp, 1, GL_FALSE, gc->shared->proj);
      }
 }
 
@@ -3717,14 +3717,13 @@ start_tiling(Evas_Engine_GL_Context *gc EINA_UNUSED,
 }
 
 static void
-shader_array_flush(Evas_Engine_GL_Context *gc)
+_orig_shader_array_flush(Evas_Engine_GL_Context *gc)
 {
    int i, gw, gh, offx = 0, offy = 0;
    unsigned int pipe_done = 0;  //count pipe iteration for debugging
    Eina_Bool setclip;
    Eina_Bool fbo = EINA_FALSE;
 
-   if (!gc->havestuff) return;
    gw = gc->w;
    gh = gc->h;
    if (!((gc->pipe[0].shader.surface == gc->def_surface) ||
@@ -4441,6 +4440,45 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
    gc->havestuff = EINA_FALSE;
 }
 
+typedef struct
+{
+   Evas_Engine_GL_Context *gc;
+} GL_TH_ST(shader_array_flush);
+
+static void
+GL_TH_CB(shader_array_flush)(void *data)
+{
+   GL_TH_ST(shader_array_flush) *thread_param = *(void **)data;
+
+   _orig_shader_array_flush(thread_param->gc);
+}
+
+static void
+shader_array_flush(Evas_Engine_GL_Context *gc)
+{
+   GL_TH_ST(shader_array_flush) thread_data_local, *thread_data = &thread_data_local, **thread_data_ptr;
+   void *thcmd_ref;
+
+   if (!gc->havestuff) return;
+
+   if (!evas_gl_thread_enabled(EVAS_GL_THREAD_TYPE_GL))
+     {
+        _orig_shader_array_flush(gc);
+        return;
+     }
+
+   thread_data_ptr =
+      evas_gl_thread_cmd_create(EVAS_GL_THREAD_TYPE_GL, sizeof(GL_TH_ST(shader_array_flush) *), &thcmd_ref);
+   *thread_data_ptr = thread_data;
+
+   thread_data->gc = gc;
+
+   evas_gl_thread_cmd_enqueue(thcmd_ref,
+                              GL_TH_CB(shader_array_flush),
+                              EVAS_GL_THREAD_MODE_FINISH);
+
+}
+
 EAPI int
 evas_gl_common_buffer_dump(Evas_Engine_GL_Context *gc, const char* dname, const char* buf_name, int frame, const char *suffix)
 {
diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c
index c811356f34..bc4687aa7c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_core.c
@@ -1528,6 +1528,8 @@ try_again:
                     }
                }
 
+             sfc->thread_rendering = !!(cfg->options_bits & EVAS_GL_OPTIONS_THREAD);
+
              cfg_index = i;
              break;
           }
diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h b/src/modules/evas/engines/gl_common/evas_gl_core_private.h
index f56e74edc4..00d76e2e8a 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h
@@ -277,6 +277,8 @@ struct _EVGL_Surface
    unsigned buffers_skip_allocate : 1;
    unsigned buffers_allocated : 1;
 
+   unsigned thread_rendering : 1;
+
    void   *cfg;
    int     cfg_index;
 
diff --git a/src/modules/evas/engines/gl_common/evas_gl_shader.c b/src/modules/evas/engines/gl_common/evas_gl_shader.c
index cccedb6357..3ef66b463b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_shader.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c
@@ -176,6 +176,7 @@ _evas_gl_common_shader_program_binary_load(Eet_File *ef, unsigned int flags)
    p->prog = prg;
    p->reset = EINA_TRUE;
    p->bin_saved = EINA_TRUE;
+   GL_TH(glUseProgram, prg);
    p->uniform.mvp = GL_TH(glGetUniformLocation, prg, "mvp");
    p->uniform.rotation_id = GL_TH(glGetUniformLocation, prg, "rotation_id");
    evas_gl_common_shader_textures_bind(p);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c
index 8575566fd1..95381de80c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_texture.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c
@@ -103,7 +103,15 @@ _tex_sub_2d(Evas_Engine_GL_Context *gc, int x, int y, int w, int h, int fmt, int
 {
    if ((w > gc->shared->info.max_texture_size) ||
        (h > gc->shared->info.max_texture_size)) return;
-   GL_TH(glTexSubImage2D, GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
+   GL_TH_FN(glTexSubImage2DEVAS)(0, GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
+}
+
+static void
+_tex_sub_2d_push(Evas_Engine_GL_Context *gc, int x, int y, int w, int h, int fmt, int type, const void *pix)
+{
+   if ((w > gc->shared->info.max_texture_size) ||
+       (h > gc->shared->info.max_texture_size)) return;
+   GL_TH_FN(glTexSubImage2DEVAS)(1, GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
 }
 
 static void
@@ -1776,7 +1784,7 @@ evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
              if (comp)
                GL_TH(glCompressedTexImage2D, GL_TEXTURE_2D, 0, tex->pt->intformat, w, h, 0, sz, data1);
              else
-               _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
+               _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
           }
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->pta->texture);
         if (!_tex_2d(tex->gc, tex->pta->intformat, w, h, tex->pta->format, tex->pta->dataformat))
@@ -1786,7 +1794,7 @@ evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
              if (comp)
                GL_TH(glCompressedTexImage2D, GL_TEXTURE_2D, 0, tex->pta->intformat, w, h, 0, sz, data2);
              else
-               _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pta->format, tex->pta->dataformat, data2);
+               _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pta->format, tex->pta->dataformat, data2);
           }
      }
    else
@@ -1805,7 +1813,7 @@ evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
                   if (comp)
                     _comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data1);
                   else
-                    _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
+                    _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, data1);
                }
              else
                {
@@ -1814,7 +1822,7 @@ evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
                        if (comp)
                          _comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, sz, data1);
                        else
-                         _tex_sub_2d(tex->gc, 0, y, w, ystep, tex->pt->format,
+                         _tex_sub_2d_push(tex->gc, 0, y, w, ystep, tex->pt->format,
                                      tex->pt->dataformat, data1 + rowlen * y / ystep);
                     }
                }
@@ -1831,7 +1839,7 @@ evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
                   if (comp)
                     _comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pta->format, sz, data2);
                   else
-                    _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pta->format, tex->pta->dataformat, data2);
+                    _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pta->format, tex->pta->dataformat, data2);
                }
              else
                {
@@ -1840,14 +1848,15 @@ evas_gl_common_texture_rgb_a_pair_update(Evas_GL_Texture *tex,
                        if (comp)
                          _comp_tex_sub_2d(tex->gc, 0, 0, w, h, tex->pta->format, sz, data2);
                        else
-                         _tex_sub_2d(tex->gc, 0, y, w, ystep, tex->pta->format,
-                                     tex->pta->dataformat, data2 + rowlen * y / ystep);
+                         _tex_sub_2d_push(tex->gc, 0, y, w, ystep, tex->pta->format,
+                                          tex->pta->dataformat, data2 + rowlen * y / ystep);
                     }
                }
           }
      }
 on_error:
    GL_TH(glBindTexture, tex->gc->state.current.tex_target, tex->gc->state.current.cur_tex);
+   evas_gl_thread_finish();
 }
 
 Evas_GL_Texture *
@@ -1955,7 +1964,7 @@ evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigne
 }
 
 void
-evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
+_orig_evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
 {
    Evas_GL_Texture_Pool *pt, *ptu, *ptv;
 
@@ -1978,18 +1987,18 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
         GL_TH(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->pt->texture);
         if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
-          return;
-        _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+          goto finish;
+        _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptu->texture);
         GL_TH(glPixelStorei, GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
         if (!_tex_2d(tex->gc, tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat))
-          return;
-        _tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
+          goto finish;
+        _tex_sub_2d_push(tex->gc, 0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptv->texture);
         GL_TH(glPixelStorei, GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
         if (!_tex_2d(tex->gc, tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat))
-          return;
-        _tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
+          goto finish;
+        _tex_sub_2d_push(tex->gc, 0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
      }
    else if (rows[0] && rows[h])
      {
@@ -1998,39 +2007,85 @@ evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned i
         GL_TH(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->pt->texture);
         if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
-          return;
+          goto finish;
         if ((rows[1] - rows[0]) == (int)w)
-          _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+          _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
         else
           {
              for (y = 0; y < h; y++)
-               _tex_sub_2d(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+               _tex_sub_2d_push(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
           }
 
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptu->texture);
         if (!_tex_2d(tex->gc, tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat))
           return;
         if ((rows[h + 1] - rows[h]) == (int)(w / 2))
-          _tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
+          _tex_sub_2d_push(tex->gc, 0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
         else
           {
              for (y = 0; y < (h / 2); y++)
-               _tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
+               _tex_sub_2d_push(tex->gc, 0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
           }
 
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptv->texture);
         if (!_tex_2d(tex->gc, tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat))
-          return;
+          goto finish;
         if ((rows[h + (h / 2) + 1] - rows[h + (h / 2)]) == (int)(w / 2))
-          _tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
+          _tex_sub_2d_push(tex->gc, 0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
         else
           {
              for (y = 0; y < (h / 2); y++)
-               _tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
+               _tex_sub_2d_push(tex->gc, 0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
           }
      }
    if (tex->pt->texture != tex->gc->state.current.cur_tex)
      GL_TH(glBindTexture, tex->gc->state.current.tex_target, tex->gc->state.current.cur_tex);
+
+finish:
+   evas_gl_thread_finish();
+}
+
+typedef struct
+{
+   Evas_GL_Texture *tex;
+   DATA8 **rows;
+   unsigned int w;
+   unsigned int h;
+} GL_TH_ST(evas_gl_common_texture_yuv_update);
+
+static void
+GL_TH_CB(evas_gl_common_texture_yuv_update)(void *data)
+{
+   GL_TH_ST(evas_gl_common_texture_yuv_update) *thread_data = *(void**)data;
+
+   _orig_evas_gl_common_texture_yuv_update(thread_data->tex, thread_data->rows, thread_data->w, thread_data->h);
+}
+
+void
+evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
+{
+   GL_TH_ST(evas_gl_common_texture_yuv_update) thread_data_local, *thread_data = &thread_data_local, **thread_data_ptr;
+   void *thcmd_ref;
+
+   if (!evas_gl_thread_enabled(EVAS_GL_THREAD_TYPE_GL))
+     {
+        _orig_evas_gl_common_texture_yuv_update(tex, rows, w, h);
+        return;
+     }
+
+   thread_data_ptr =
+      evas_gl_thread_cmd_create(EVAS_GL_THREAD_TYPE_GL, sizeof(GL_TH_ST(evas_gl_common_texture_yuv_update) *), &thcmd_ref);
+   *thread_data_ptr = thread_data;
+
+   thread_data->tex = tex;
+   thread_data->rows = rows;
+   thread_data->w = w;
+   thread_data->h = h;
+
+   evas_gl_thread_cmd_enqueue(thcmd_ref,
+                              GL_TH_CB(evas_gl_common_texture_yuv_update),
+                              EVAS_GL_THREAD_MODE_FINISH);
+
 }
 
 static Evas_GL_Texture *
@@ -2174,16 +2229,16 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
    if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
      return;
    if ((rows[1] - rows[0]) == (int)w * 4)
-     _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+     _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
    else
      {
         for (y = 0; y < h; y++)
-          _tex_sub_2d(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+          _tex_sub_2d_push(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
      }
 
    GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptuv->texture);
    if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat))
-     return;
+     goto finish;
 #if 0
    /*
      FIXME: this piece of code doesn't work anymore since texture width
@@ -2195,11 +2250,13 @@ evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
 #endif
      {
         for (y = 0; y < h; y++)
-          _tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
+          _tex_sub_2d_push(tex->gc, 0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
      }
 
    if (tex->pt->texture != tex->gc->state.current.cur_tex)
      GL_TH(glBindTexture, tex->gc->state.current.tex_target, tex->gc->state.current.cur_tex);
+finish:
+   evas_gl_thread_finish();
 }
 
 void
@@ -2218,13 +2275,13 @@ evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
         GL_TH(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->pt->texture);
         if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
-          return;
-        _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+          goto finish;
+        _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptuv->texture);
         GL_TH(glPixelStorei, GL_UNPACK_ROW_LENGTH, (rows[h + 1] - rows[h]) / 2);
         if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat))
-          return;
-        _tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
+          goto finish;
+        _tex_sub_2d_push(tex->gc, 0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
      }
    else
      {
@@ -2233,28 +2290,30 @@ evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned
         GL_TH(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->pt->texture);
         if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
-          return;
+          goto finish;
         if ((rows[1] - rows[0]) == (int)w)
-          _tex_sub_2d(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
+          _tex_sub_2d_push(tex->gc, 0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
         else
           {
              for (y = 0; y < h; y++)
-               _tex_sub_2d(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
+               _tex_sub_2d_push(tex->gc, 0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
           }
 
         GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptuv->texture);
         if (!_tex_2d(tex->gc, tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat))
-          return;
+          goto finish;
         if ((rows[h + 1] - rows[h]) == (int)(w / 2))
-          _tex_sub_2d(tex->gc, 0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
+          _tex_sub_2d_push(tex->gc, 0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
         else
           {
              for (y = 0; y < (h / 2); y++)
-               _tex_sub_2d(tex->gc, 0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
+               _tex_sub_2d_push(tex->gc, 0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
           }
      }
    if (tex->pt->texture != tex->gc->state.current.cur_tex)
      GL_TH(glBindTexture, tex->gc->state.current.tex_target, tex->gc->state.current.cur_tex);
+finish:
+   evas_gl_thread_finish();
 }
 
 void
@@ -2416,7 +2475,7 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
 
    // We are telling the driver to not swizzle back the buffer as we are going to replace all pixel
    if (!_tex_2d(tex->gc, tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat))
-     return;
+     goto finish;
 
    /* Iterate each Y macroblock like we do in evas_convert_yuv.c */
    for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
@@ -2432,7 +2491,7 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
 
         for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
           {
-             _tex_sub_2d(tex->gc, x, ry[offset], 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
+             _tex_sub_2d_push(tex->gc, x, ry[offset], 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
 
              step++;
              if ((step & 0x3) == 0)
@@ -2456,13 +2515,13 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
         ry = mb_y * 2 * 32;
 
         for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32)
-          _tex_sub_2d(tex->gc, x, ry, 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
+          _tex_sub_2d_push(tex->gc, x, ry, 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
      }
 
    GL_TH(glBindTexture, GL_TEXTURE_2D, tex->ptuv->texture);
 
    if (!_tex_2d(tex->gc, tex->ptuv->intformat, w, h, tex->ptuv->format, tex->ptuv->dataformat))
-     return;
+     goto finish;
 
    /* Iterate each UV macroblock like we do in evas_convert_yuv.c */
    base_h = (mb_h >> 1) + (mb_h & 0x1);
@@ -2487,9 +2546,9 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
 
         for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
           {
-             _tex_sub_2d(tex->gc, x, ry[offset], 32, 32,
-                         tex->ptuv->format, tex->ptuv->dataformat,
-                         rows[mb_y + base_h] + rmb_x);
+             _tex_sub_2d_push(tex->gc, x, ry[offset], 32, 32,
+                              tex->ptuv->format, tex->ptuv->dataformat,
+                              rows[mb_y + base_h] + rmb_x);
              step++;
              if ((step & 0x3) == 0)
                {
@@ -2512,6 +2571,8 @@ evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsi
         ry = mb_y * 2 * 32;
 
         for (mb_x = 0; mb_x < mb_w; mb_x++, x += 32, rmb_x += 64 * 32)
-          _tex_sub_2d(tex->gc, x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x);
+          _tex_sub_2d_push(tex->gc, x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x);
      }
+finish:
+   evas_gl_thread_finish();
 }
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index 7bc6ba8bbc..d87e56a007 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -1709,6 +1709,72 @@ eng_gl_get_pixels_pre(void *engine)
    evgl_get_pixels_pre();
 }
 
+typedef struct
+{
+   Evas_Object_Image_Pixels_Get_Cb cb;
+   void *get_pixels_data;
+   Evas_Object *o;
+} GL_TH_ST(eng_gl_get_pixels);
+
+static void
+GL_TH_CB(eng_gl_get_pixels)(void *data)
+{
+   GL_TH_ST(eng_gl_get_pixels) *thread_data = *(void **)data;
+
+  thread_data->cb(thread_data->get_pixels_data, thread_data->o);
+}
+
+static void
+GL_TH_FN(eng_gl_get_pixels)(Evas_Object_Image_Pixels_Get_Cb cb, void *get_pixels_data, Evas_Object *o)
+{
+   GL_TH_ST(eng_gl_get_pixels) thread_data_local, *thread_data = &thread_data_local, **thread_data_ptr;
+   void *thcmd_ref;
+
+   if (!evas_gl_thread_enabled(EVAS_GL_THREAD_TYPE_EVGL)) /* XXX */
+     {
+        cb(get_pixels_data, o);
+        return;
+     }
+
+   thread_data_ptr =
+      evas_gl_thread_cmd_create(EVAS_GL_THREAD_TYPE_GL, sizeof(GL_TH_ST(eng_gl_get_pixels) *) + sizeof(GL_TH_ST(eng_gl_get_pixels)), &thcmd_ref);
+   *thread_data_ptr = (void *)(thread_data_ptr + sizeof(GL_TH_ST(eng_gl_get_pixels) *));
+
+   thread_data->cb = cb;
+   thread_data->get_pixels_data = get_pixels_data;
+   thread_data->o = o;
+   evas_gl_thread_cmd_enqueue(thcmd_ref,
+                              GL_TH_CB(eng_gl_get_pixels),
+                              EVAS_GL_THREAD_MODE_FLUSH);
+}
+
+static void
+eng_gl_get_pixels(void *data EINA_UNUSED, Evas_Object_Image_Pixels_Get_Cb cb, void *get_pixels_data, Evas_Object *o, void *image)
+{
+   Evas_GL_Image *im = image;
+   Evas_Native_Surface *n;
+   EVGL_Surface *sfc;
+
+   if (im)
+     {
+        n = im->native.data;
+        if (n)
+          {
+             sfc = n->data.evasgl.surface;
+             if (sfc)
+               {
+                  if (sfc->thread_rendering)
+                    {
+                       GL_TH_FN(eng_gl_get_pixels)(cb, get_pixels_data, o);
+                       return;
+                    }
+               }
+          }
+     }
+
+   cb(get_pixels_data, o);
+}
+
 static void
 eng_gl_get_pixels_post(void *engine EINA_UNUSED)
 {
@@ -3209,6 +3275,7 @@ module_open(Evas_Module *em)
    ORD(gl_surface_direct_renderable_get);
    ORD(gl_get_pixels_set);
    ORD(gl_get_pixels_pre);
+   ORD(gl_get_pixels);
    ORD(gl_get_pixels_post);
    ORD(gl_surface_lock);
    ORD(gl_surface_read_pixels);
diff --git a/src/modules/evas/engines/wayland_egl/evas_wl_main.c b/src/modules/evas/engines/wayland_egl/evas_wl_main.c
index 9136736955..0405e18f10 100644
--- a/src/modules/evas/engines/wayland_egl/evas_wl_main.c
+++ b/src/modules/evas/engines/wayland_egl/evas_wl_main.c
@@ -9,7 +9,7 @@ static struct wl_display *display = NULL;
 static int win_count = 0;
 
 Outbuf *
-eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Engine_Swap_Mode swap_mode)
+_orig_eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Engine_Swap_Mode swap_mode)
 {
    Outbuf *gw;
    int context_attrs[3];
@@ -168,7 +168,54 @@ eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Engine_Swap
    return gw;
 }
 
-void
+typedef struct
+{
+   Outbuf *return_value;
+   Evas_Engine_Info_Wayland *einfo;
+   int w;
+   int h;
+   Render_Engine_Swap_Mode swap_mode;
+} GL_TH_ST(eng_window_new);
+
+static void
+GL_TH_CB(eng_window_new)(void *data)
+{
+   GL_TH_ST(eng_window_new) *thread_data = *(void **)data;
+
+   thread_data->return_value = _orig_eng_window_new(thread_data->einfo,
+                                                    thread_data->w,
+                                                    thread_data->h,
+                                                    thread_data->swap_mode);
+}
+
+Outbuf *
+eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Engine_Swap_Mode swap_mode)
+{
+   GL_TH_ST(eng_window_new) thread_data_local, *thread_data = &thread_data_local, **thread_data_ptr;
+   void *thcmd_ref;
+
+   /* eng_window_new() is moved into the worker thread that minimizes driver issue with EGL use*/
+   if (!evas_gl_thread_enabled(EVAS_GL_THREAD_TYPE_GL))
+     return _orig_eng_window_new(einfo, w, h, swap_mode);
+
+   thread_data_ptr =
+      evas_gl_thread_cmd_create(EVAS_GL_THREAD_TYPE_GL, sizeof(GL_TH_ST(eng_window_new) *), &thcmd_ref);
+   *thread_data_ptr = thread_data;
+
+   thread_data->einfo = einfo;
+   thread_data->w = w;
+   thread_data->h = h;
+   thread_data->swap_mode = swap_mode;
+
+   evas_gl_thread_cmd_enqueue(thcmd_ref,
+                              GL_TH_CB(eng_window_new),
+                              EVAS_GL_THREAD_MODE_FINISH);
+
+   return thread_data->return_value;
+
+}
+
+void 
 eng_window_free(Outbuf *gw)
 {
    int ref = 0;

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to