This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch glth-save
in repository efl.
View the commit online.
commit 203f2d09f6e7d011098ad621555c16ba1c32a433
Author: jutty.lee <jutty....@samsung.com>
AuthorDate: Fri Aug 25 17:49:06 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 | 74 +++++++++-
10 files changed, 306 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 0b9776a1d7..e660c78e27 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 fe19a7ea47..d8bbdc7a65 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 47bfd45f1a..aceb6330e5 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,77 @@ eng_window_new(Evas_Engine_Info_Wayland *einfo, int w, int h, Render_Engine_Swap
return gw;
}
-void
+typedef struct
+{
+ Outbuf *return_value;
+ Evas *evas;
+ Evas_Engine_Info_Wayland *einfo;
+ int w;
+ int h;
+ Render_Engine_Swap_Mode swap_mode;
+ int depth_bits;
+ int stencil_bits;
+ int msaa_bits;
+} Evas_Thread_Command_eng_window_new;
+
+static void
+_gl_thread_eng_window_new(void *data)
+{
+ Evas_Thread_Command_eng_window_new *thread_param =
+ (Evas_Thread_Command_eng_window_new *)data;
+
+ evas_gl_thread_begin();
+
+ thread_param->return_value = _orig_eng_window_new(thread_param->evas,
+ thread_param->einfo,
+ thread_param->w,
+ thread_param->h,
+ thread_param->swap_mode,
+ thread_param->depth_bits,
+ thread_param->stencil_bits,
+ thread_param->msaa_bits);
+
+ evas_gl_thread_end();
+}
+
+Outbuf *
+eng_window_new(Evas *evas, Evas_Engine_Info_Wayland_Egl *einfo, int w, int h, Render_Engine_Swap_Mode swap_mode,
+ int depth_bits, int stencil_bits, int msaa_bits)
+{
+ /* eng_window_new() is moved into the worker thread that minimizes driver issue with EGL use*/
+ if (!evas_gl_thread_enabled())
+ {
+ return _orig_eng_window_new(evas,
+ einfo,
+ w,
+ h,
+ swap_mode,
+ depth_bits,
+ stencil_bits,
+ msaa_bits);
+ }
+
+ Evas_Thread_Command_eng_window_new thread_param_local;
+ Evas_Thread_Command_eng_window_new *thread_param = &thread_param_local;
+ thread_param->evas = evas;
+ thread_param->einfo = einfo;
+ thread_param->w = w;
+ thread_param->h = h;
+ thread_param->swap_mode = swap_mode;
+ thread_param->depth_bits = depth_bits;
+ thread_param->stencil_bits = stencil_bits;
+ thread_param->msaa_bits = msaa_bits;
+
+ evas_gl_thread_cmd_enqueue(EVAS_GL_THREAD_TYPE_GL,
+ _gl_thread_eng_window_new,
+ thread_param,
+ EVAS_GL_THREAD_MODE_FINISH);
+
+ return thread_param->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.