diff options
author | Haegeun Park <haegeun.park@samsung.com> | 2016-10-04 17:42:06 +0900 |
---|---|---|
committer | Haegeun Park <haegeun.park@samsung.com> | 2017-01-11 18:20:37 +0900 |
commit | 44c69a22710501bbb2cc3592395da5fd9aa8aa0d (patch) | |
tree | 3385ef291ab8b9de71b63d762db0c7d6dff23923 | |
parent | f33c43c01601304824c5e58d69a2fe546fc3aa7b (diff) | |
download | efl-44c69a22710501bbb2cc3592395da5fd9aa8aa0d.tar.gz |
Evas GL: (GL thread) Added the EvasGL pixel callback threading
EvasGL pixel callback function will be moved to thread when application set a special flag.
Two major modifications are included in this patch:
- Added an option bit to enable thread rendering for pixel callback function (spec is changed)
- Redirected the get_pixel callback to threadable function
How to enable the option in application code:
Evas_GL_Config config = evas_gl_config_new();
config->options_bits |= EVAS_GL_OPTIONS_THREAD;
Change-Id: I33281c9b23b1e1f1023c112f8bb4ded8b2b714b0
-rw-r--r-- | src/lib/evas/Evas_GL.h | 7 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_image.c | 10 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 2 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_core.c | 2 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_common/evas_gl_core_private.h | 2 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_generic/evas_engine.c | 69 |
6 files changed, 88 insertions, 4 deletions
diff --git a/src/lib/evas/Evas_GL.h b/src/lib/evas/Evas_GL.h index 8669c92172..26e7dd0147 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 08fdb1f163..bbed6c699d 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -1652,7 +1652,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); } @@ -1696,7 +1699,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(output); - 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(output); o->direct_render = EINA_FALSE; diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index b75ef49613..210f54b2bb 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1560,6 +1560,8 @@ struct _Evas_Func void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async); void* (*ector_new) (void *data, void *context, Ector_Surface *ector, void *surface); void (*ector_free) (void *engine_data); + + 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_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c index 593130b3dd..77faf26dba 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -1482,6 +1482,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 3b7540f67d..7ae1c1748c 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 @@ -126,6 +126,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_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 92daa03af5..da0638d431 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -1781,6 +1781,74 @@ eng_gl_get_pixels_pre(void *data) evgl_get_pixels_pre(); } +typedef struct +{ + Evas_Object_Image_Pixels_Get_Cb cb; + void *get_pixels_data; + Evas_Object *o; +} Evas_GL_Thread_Command_get_pixels; + +static void +_evgl_thread_get_pixels(void *data) +{ + Evas_GL_Thread_Command_get_pixels *thread_param = + (Evas_GL_Thread_Command_get_pixels *)data; + + evas_evgl_thread_begin(); + thread_param->cb(thread_param->get_pixels_data, thread_param->o); + evas_evgl_thread_end(); + + eina_mempool_free(_mp_command, thread_param); +} + +static void +get_pixels_evgl_thread_cmd(Evas_Object_Image_Pixels_Get_Cb cb, void *get_pixels_data, Evas_Object *o) +{ + if (!evas_gl_thread_enabled()) /* XXX */ + { + cb(get_pixels_data, o); + return; + } + + Evas_GL_Thread_Command_get_pixels *thread_param; + thread_param = eina_mempool_malloc(_mp_command, + sizeof(Evas_GL_Thread_Command_get_pixels)); + thread_param->cb = cb; + thread_param->get_pixels_data = get_pixels_data; + thread_param->o = o; + evas_gl_thread_cmd_enqueue(EVAS_GL_THREAD_TYPE_EVGL, + _evgl_thread_get_pixels, + thread_param, + 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) + { + get_pixels_evgl_thread_cmd(cb, get_pixels_data, o); + return; + } + } + } + } + + cb(get_pixels_data, o); +} + static void eng_gl_get_pixels_post(void *data EINA_UNUSED) { @@ -3260,6 +3328,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); |