From 4890454e8b29ddee4525c22abb4821c1ec94a718 Mon Sep 17 00:00:00 2001 From: sunghyun kim Date: Tue, 18 Jul 2017 11:57:49 +0900 Subject: [PATCH] [evas_gl] Add lock to wait compiling shader when application compile shader, shader files are created at the end. so if other proceess try creating shader before shader file is created, it also try again compile shader. so add lock to wait compiling shader Change-Id: Id9da72f226e180cc18fcaaa65d639676ccfe9114 --- .../evas/engines/gl_common/evas_gl_common.h | 2 + .../evas/engines/gl_common/evas_gl_shader.c | 94 ++++++++++++++++++---- 2 files changed, 79 insertions(+), 17 deletions(-) diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 4b2b16e..1ec1878 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -11,6 +11,7 @@ #include #include #include +#include #define GL_GLEXT_PROTOTYPES @@ -238,6 +239,7 @@ struct _Evas_GL_Shared int offx, offy; GLfloat proj[16]; Eina_Bool needs_shaders_flush : 1; + int lock_shader; }; typedef enum _Shader_Sampling Shader_Sampling; 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 698e94a..d1bde35 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c @@ -414,6 +414,51 @@ _shaders_hash_free_cb(void *data) _program_del(data); } +static void +_shader_lock(Evas_GL_Shared *shared,const char *cache_dir) +{ + char lock_path[PATH_MAX]; + snprintf(lock_path, sizeof(lock_path), "%s/shader_compile.lock", cache_dir); + shared->lock_shader = open(lock_path, O_RDWR | O_CREAT , S_IRUSR | S_IWUSR); + if(shared->lock_shader<0) + { + ERR("lock create is failed "); + return; + } + + /* lock for wait creating shader*/ + struct flock filelock; + filelock.l_type = F_WRLCK; + filelock.l_whence = SEEK_SET; + filelock.l_start = 0; + filelock.l_len = 0; + if (fcntl(shared->lock_shader, F_SETLKW, &filelock) == -1) + { + ERR("lock take fail"); + return; + } +} + +static void +_shader_unlock(Evas_GL_Shared *shared) +{ + if(shared->lock_shader < 0) return; + + /* reset lock */ + struct flock filelock; + filelock.l_type = F_UNLCK; + filelock.l_whence = SEEK_SET; + filelock.l_start = 0; + filelock.l_len = 0; + if (fcntl(shared->lock_shader, F_SETLKW, &filelock) == -1) + { + ERR("lock release fail"); + } + + /* need to close lock file */ + close(shared->lock_shader); +} + static char * evas_gl_common_shader_glsl_get(unsigned int flags, const char *base) { @@ -644,31 +689,46 @@ evas_gl_common_shader_program_init(Evas_GL_Shared *shared) }; Evas_GL_Program *p; unsigned i; + char bin_dir_path[PATH_MAX]; shared->shaders_hash = eina_hash_int32_new(_shaders_hash_free_cb); - if (_evas_gl_common_shader_binary_init(shared)) + if (!evas_gl_common_file_cache_dir_check(bin_dir_path, sizeof(bin_dir_path))) + evas_gl_common_file_cache_mkpath(bin_dir_path); + + if(_evas_gl_common_shader_binary_init(shared)) + goto Load; + + //shader lock for wait other process + _shader_lock(shared,bin_dir_path); + if(_evas_gl_common_shader_binary_init(shared)) { - for (i = 0; i < (sizeof(autoload) / sizeof(autoload[0])); i++) - { - p = _evas_gl_common_shader_program_binary_load(shared->shaders_cache, autoload[i]); - if (p) - { - evas_gl_common_shader_textures_bind(p); - eina_hash_add(shared->shaders_hash, &autoload[i], p); - } - } + _shader_unlock(shared); + goto Load; } - else + + //precompile shader + evas_gl_common_shader_precompile_all(shared); + for (i = 0; i < (sizeof(autoload) / sizeof(autoload[0])); i++) + { + p = eina_hash_find(shared->shaders_hash, &autoload[i]); + if (p) p->delete_me = 0; + } + evas_gl_common_shaders_flush(shared); + + //shader un-lock for wait other process + _shader_unlock(shared); + return 1; + +Load: + for (i = 0; i < (sizeof(autoload) / sizeof(autoload[0])); i++) { - evas_gl_common_shader_precompile_all(shared); - for (i = 0; i < (sizeof(autoload) / sizeof(autoload[0])); i++) + p = _evas_gl_common_shader_program_binary_load(shared->shaders_cache, autoload[i]); + if (p) { - p = eina_hash_find(shared->shaders_hash, &autoload[i]); - if (p) p->delete_me = 0; + evas_gl_common_shader_textures_bind(p); + eina_hash_add(shared->shaders_hash, &autoload[i], p); } - evas_gl_common_shaders_flush(shared); } - return 1; } -- 2.7.4