From 60efcf99822db24e999fd82fac15fd2bd19aafb8 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 68841c5..3147d56 100644 --- 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 @@ -214,6 +215,7 @@ struct _Evas_GL_Shared 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 6ce8287..95796d2 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c @@ -389,6 +389,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) { @@ -636,31 +681,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