summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaegeun Park <haegeun.park@samsung.com>2016-10-04 17:42:06 +0900
committerHaegeun Park <haegeun.park@samsung.com>2017-01-11 18:20:37 +0900
commit44c69a22710501bbb2cc3592395da5fd9aa8aa0d (patch)
tree3385ef291ab8b9de71b63d762db0c7d6dff23923
parentf33c43c01601304824c5e58d69a2fe546fc3aa7b (diff)
downloadefl-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.h7
-rw-r--r--src/lib/evas/canvas/evas_object_image.c10
-rw-r--r--src/lib/evas/include/evas_private.h2
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core.c2
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core_private.h2
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c69
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);