forked from enlightenment/efl
Pulled out evas gl backend binary shader file caching code from
evas_gl_shader.c file and made an internal generic caching api in evas_gl_common.h for use in other places ie. evas_gl. Then implemented evas_gl surface cap. caching code in gl backend to accelerate the engine creation. SVN revision: 82321
This commit is contained in:
parent
fb1225caa7
commit
edcb4cf295
|
@ -1,3 +1,12 @@
|
||||||
|
2013-01-07 Sung W. Park (sung_)
|
||||||
|
|
||||||
|
* Pulled out evas gl backend binary shader file caching code from
|
||||||
|
evas_gl_shader.c file and made an internal generic caching api in
|
||||||
|
evas_gl_common.h for use in evas_gl code.
|
||||||
|
* Implemented evas_gl surface cap. caching code in gl backend to
|
||||||
|
accelerate the engine creation.
|
||||||
|
|
||||||
|
|
||||||
2013-01-07 Thomas Petazzoni
|
2013-01-07 Thomas Petazzoni
|
||||||
|
|
||||||
* Fix build of Evas XCB backend.
|
* Fix build of Evas XCB backend.
|
||||||
|
|
|
@ -448,6 +448,7 @@ GL_COMMON_SOURCES = \
|
||||||
modules/evas/engines/gl_common/evas_gl_private.h \
|
modules/evas/engines/gl_common/evas_gl_private.h \
|
||||||
modules/evas/engines/gl_common/evas_gl_common.h \
|
modules/evas/engines/gl_common/evas_gl_common.h \
|
||||||
modules/evas/engines/gl_common/evas_gl_context.c \
|
modules/evas/engines/gl_common/evas_gl_context.c \
|
||||||
|
modules/evas/engines/gl_common/evas_gl_file_cache.c \
|
||||||
modules/evas/engines/gl_common/evas_gl_shader.c \
|
modules/evas/engines/gl_common/evas_gl_shader.c \
|
||||||
modules/evas/engines/gl_common/evas_gl_rectangle.c \
|
modules/evas/engines/gl_common/evas_gl_rectangle.c \
|
||||||
modules/evas/engines/gl_common/evas_gl_texture.c \
|
modules/evas/engines/gl_common/evas_gl_texture.c \
|
||||||
|
|
|
@ -555,6 +555,15 @@ int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
|
||||||
void evas_gl_common_shader_program_init_done(void);
|
void evas_gl_common_shader_program_init_done(void);
|
||||||
void evas_gl_common_shader_program_shutdown(Evas_GL_Program *p);
|
void evas_gl_common_shader_program_shutdown(Evas_GL_Program *p);
|
||||||
|
|
||||||
|
Eina_Bool evas_gl_common_file_cache_is_dir(const char *file);
|
||||||
|
Eina_Bool evas_gl_common_file_cache_mkdir(const char *dir);
|
||||||
|
Eina_Bool evas_gl_common_file_cache_file_exists(const char *file);
|
||||||
|
Eina_Bool evas_gl_common_file_cache_mkpath_if_not_exists(const char *path);
|
||||||
|
Eina_Bool evas_gl_common_file_cache_mkpath(const char *path);
|
||||||
|
int evas_gl_common_file_cache_dir_check(char *cache_dir, int num);
|
||||||
|
int evas_gl_common_file_cache_file_check(const char *cache_dir, const char *cache_name, char *cache_file, int dir_num);
|
||||||
|
int evas_gl_common_file_cache_save(Evas_GL_Shared *shared);
|
||||||
|
|
||||||
void evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h);
|
void evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h);
|
||||||
|
|
||||||
void evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt);
|
void evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt);
|
||||||
|
|
|
@ -16,7 +16,7 @@ int _evas_gl_log_dom = -1;
|
||||||
static void _surface_cap_print(EVGL_Engine *ee, int error);
|
static void _surface_cap_print(EVGL_Engine *ee, int error);
|
||||||
|
|
||||||
//---------------------------------------------------------------//
|
//---------------------------------------------------------------//
|
||||||
// Internal Resources:
|
// Internal Resources:
|
||||||
// - Surface and Context used for internal buffer creation
|
// - Surface and Context used for internal buffer creation
|
||||||
//---------------------------------------------------------------//
|
//---------------------------------------------------------------//
|
||||||
static int
|
static int
|
||||||
|
@ -262,7 +262,7 @@ _internal_resource_make_current(EVGL_Engine *ee, EVGL_Context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------//
|
//---------------------------------------------------------------//
|
||||||
// Surface Related Functions
|
// Surface Related Functions
|
||||||
// - Texture/ Renderbuffer Creation/ Attachment to FBO
|
// - Texture/ Renderbuffer Creation/ Attachment to FBO
|
||||||
// - Surface capability check
|
// - Surface capability check
|
||||||
// - Internal config choose function
|
// - Internal config choose function
|
||||||
|
@ -364,7 +364,7 @@ _renderbuffer_attach(GLuint buf, GLenum attach)
|
||||||
|
|
||||||
// Check whether the given FBO surface config is supported by the driver
|
// Check whether the given FBO surface config is supported by the driver
|
||||||
static int
|
static int
|
||||||
_fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
_fbo_surface_cap_test(GLint color_ifmt, GLenum color_fmt,
|
||||||
GLenum depth_fmt, GLenum stencil_fmt, int mult_samples)
|
GLenum depth_fmt, GLenum stencil_fmt, int mult_samples)
|
||||||
{
|
{
|
||||||
GLuint fbo = 0;
|
GLuint fbo = 0;
|
||||||
|
@ -456,10 +456,10 @@ _surface_cap_test(EVGL_Surface_Format *fmt, GL_Format *color,
|
||||||
if ( (depth->bit == DEPTH_STENCIL) && (stencil->bit != STENCIL_BIT_8))
|
if ( (depth->bit == DEPTH_STENCIL) && (stencil->bit != STENCIL_BIT_8))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = _fbo_surface_cap_test((GLint)color->fmt,
|
ret = _fbo_surface_cap_test((GLint)color->fmt,
|
||||||
color->fmt,
|
color->fmt,
|
||||||
depth->fmt,
|
depth->fmt,
|
||||||
stencil->fmt, samples);
|
stencil->fmt, samples);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
fmt->color_bit = color->bit;
|
fmt->color_bit = color->bit;
|
||||||
|
@ -478,7 +478,7 @@ _surface_cap_test(EVGL_Surface_Format *fmt, GL_Format *color,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fmt->depth_stencil_fmt = 0;
|
fmt->depth_stencil_fmt = 0;
|
||||||
fmt->depth_bit = depth->bit;
|
fmt->depth_bit = depth->bit;
|
||||||
fmt->depth_fmt = depth->fmt;
|
fmt->depth_fmt = depth->fmt;
|
||||||
fmt->stencil_bit = stencil->bit;
|
fmt->stencil_bit = stencil->bit;
|
||||||
|
@ -503,16 +503,16 @@ _surface_cap_check(EVGL_Engine *ee)
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GL_GLES
|
#ifdef GL_GLES
|
||||||
GL_Format depth[] = {
|
GL_Format depth[] = {
|
||||||
{ DEPTH_NONE, 0 },
|
{ DEPTH_NONE, 0 },
|
||||||
{ DEPTH_STENCIL, GL_DEPTH_STENCIL_OES },
|
{ DEPTH_STENCIL, GL_DEPTH_STENCIL_OES },
|
||||||
{ DEPTH_BIT_8, GL_DEPTH_COMPONENT },
|
{ DEPTH_BIT_8, GL_DEPTH_COMPONENT },
|
||||||
{ DEPTH_BIT_16, GL_DEPTH_COMPONENT16 },
|
{ DEPTH_BIT_16, GL_DEPTH_COMPONENT16 },
|
||||||
{ DEPTH_BIT_24, GL_DEPTH_COMPONENT24_OES },
|
{ DEPTH_BIT_24, GL_DEPTH_COMPONENT24_OES },
|
||||||
{ DEPTH_BIT_32, GL_DEPTH_COMPONENT32_OES },
|
{ DEPTH_BIT_32, GL_DEPTH_COMPONENT32_OES },
|
||||||
{ -1, -1 },
|
{ -1, -1 },
|
||||||
};
|
};
|
||||||
GL_Format stencil[] = {
|
GL_Format stencil[] = {
|
||||||
{ STENCIL_NONE, 0 },
|
{ STENCIL_NONE, 0 },
|
||||||
{ STENCIL_BIT_1, GL_STENCIL_INDEX1_OES },
|
{ STENCIL_BIT_1, GL_STENCIL_INDEX1_OES },
|
||||||
{ STENCIL_BIT_4, GL_STENCIL_INDEX4_OES },
|
{ STENCIL_BIT_4, GL_STENCIL_INDEX4_OES },
|
||||||
|
@ -520,7 +520,7 @@ _surface_cap_check(EVGL_Engine *ee)
|
||||||
{ -1, -1 },
|
{ -1, -1 },
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
GL_Format depth[] = {
|
GL_Format depth[] = {
|
||||||
{ DEPTH_NONE, 0 },
|
{ DEPTH_NONE, 0 },
|
||||||
{ DEPTH_STENCIL, GL_DEPTH24_STENCIL8 },
|
{ DEPTH_STENCIL, GL_DEPTH24_STENCIL8 },
|
||||||
{ DEPTH_BIT_8, GL_DEPTH_COMPONENT },
|
{ DEPTH_BIT_8, GL_DEPTH_COMPONENT },
|
||||||
|
@ -528,7 +528,7 @@ _surface_cap_check(EVGL_Engine *ee)
|
||||||
{ DEPTH_BIT_24, GL_DEPTH_COMPONENT24 },
|
{ DEPTH_BIT_24, GL_DEPTH_COMPONENT24 },
|
||||||
{ DEPTH_BIT_32, GL_DEPTH_COMPONENT32 },
|
{ DEPTH_BIT_32, GL_DEPTH_COMPONENT32 },
|
||||||
{ -1, -1 },
|
{ -1, -1 },
|
||||||
};
|
};
|
||||||
GL_Format stencil[] = {
|
GL_Format stencil[] = {
|
||||||
{ STENCIL_NONE, 0 },
|
{ STENCIL_NONE, 0 },
|
||||||
{ STENCIL_BIT_1, GL_STENCIL_INDEX1 },
|
{ STENCIL_BIT_1, GL_STENCIL_INDEX1 },
|
||||||
|
@ -563,10 +563,10 @@ _surface_cap_check(EVGL_Engine *ee)
|
||||||
// Color Formats
|
// Color Formats
|
||||||
i = 0;
|
i = 0;
|
||||||
while ( color[i].bit >= 0 )
|
while ( color[i].bit >= 0 )
|
||||||
{
|
{
|
||||||
j = 0;
|
j = 0;
|
||||||
// Depth Formats
|
// Depth Formats
|
||||||
while ( depth[j].bit >= 0 )
|
while ( depth[j].bit >= 0 )
|
||||||
{
|
{
|
||||||
k = 0;
|
k = 0;
|
||||||
// Stencil Formats
|
// Stencil Formats
|
||||||
|
@ -586,6 +586,156 @@ _surface_cap_check(EVGL_Engine *ee)
|
||||||
return num_fmts;
|
return num_fmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_surface_cap_load(EVGL_Engine *ee, Eet_File *ef)
|
||||||
|
{
|
||||||
|
int res = 0, i = 0, length = 0;
|
||||||
|
char tag[80];
|
||||||
|
void *data = 0;
|
||||||
|
|
||||||
|
data = eet_read(ef, "num_fbo_fmts", &length);
|
||||||
|
if ((!data) || (length <= 0)) goto finish;
|
||||||
|
ee->caps.num_fbo_fmts = atoi(data);
|
||||||
|
free(data);
|
||||||
|
data = 0;
|
||||||
|
|
||||||
|
// !!!FIXME
|
||||||
|
// Should use eet functionality instead of just reading using sscanfs...
|
||||||
|
for (i = 0; i < ee->caps.num_fbo_fmts; ++i)
|
||||||
|
{
|
||||||
|
EVGL_Surface_Format *fmt = &ee->caps.fbo_fmts[i];
|
||||||
|
|
||||||
|
snprintf(tag, sizeof(tag), "fbo_%d", i);
|
||||||
|
data = eet_read(ef, tag, &length);
|
||||||
|
if ((!data) || (length <= 0)) goto finish;
|
||||||
|
sscanf(data, "%d%d%d%d%d%d%d%d%d%d",
|
||||||
|
&(fmt->index),
|
||||||
|
(int*)(&(fmt->color_bit)), &(fmt->color_ifmt), &(fmt->color_fmt),
|
||||||
|
(int*)(&(fmt->depth_bit)), &(fmt->depth_fmt),
|
||||||
|
(int*)(&(fmt->stencil_bit)), &(fmt->stencil_fmt),
|
||||||
|
&(fmt->depth_stencil_fmt),
|
||||||
|
&(fmt->samples));
|
||||||
|
free(data);
|
||||||
|
data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = 1;
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if (data) free(data);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_surface_cap_save(EVGL_Engine *ee, Eet_File *ef)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
char tag[80], data[80];;
|
||||||
|
|
||||||
|
snprintf(data, sizeof(data), "%d", ee->caps.num_fbo_fmts);
|
||||||
|
if (eet_write(ef, "num_fbo_fmts", data, sizeof(data), 1) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// !!!FIXME
|
||||||
|
// Should use eet functionality instead of just writing out using snprintfs...
|
||||||
|
for (i = 0; i < ee->caps.num_fbo_fmts; ++i)
|
||||||
|
{
|
||||||
|
EVGL_Surface_Format *fmt = &ee->caps.fbo_fmts[i];
|
||||||
|
|
||||||
|
snprintf(tag, sizeof(tag), "fbo_%d", i);
|
||||||
|
snprintf(data, sizeof(data), "%d %d %d %d %d %d %d %d %d %d",
|
||||||
|
fmt->index,
|
||||||
|
fmt->color_bit, fmt->color_ifmt, fmt->color_fmt,
|
||||||
|
fmt->depth_bit, fmt->depth_fmt,
|
||||||
|
fmt->stencil_bit, fmt->stencil_fmt,
|
||||||
|
fmt->depth_stencil_fmt,
|
||||||
|
fmt->samples);
|
||||||
|
if (eet_write(ef, tag, data, sizeof(data), 1) < 0) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_surface_cap_cache_load(EVGL_Engine *ee)
|
||||||
|
{
|
||||||
|
/* check eet */
|
||||||
|
Eet_File *et = NULL;
|
||||||
|
char cap_dir_path[PATH_MAX];
|
||||||
|
char cap_file_path[PATH_MAX];
|
||||||
|
|
||||||
|
if (!evas_gl_common_file_cache_dir_check(cap_dir_path, sizeof(cap_dir_path)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!evas_gl_common_file_cache_file_check(cap_dir_path, "surface_cap",
|
||||||
|
cap_file_path, sizeof(cap_dir_path)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* use eet */
|
||||||
|
if (!eet_init()) return 0;
|
||||||
|
et = eet_open(cap_file_path, EET_FILE_MODE_READ);
|
||||||
|
if (!et) goto error;
|
||||||
|
|
||||||
|
if (!_surface_cap_load(ee, et))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (et) eet_close(et);
|
||||||
|
eet_shutdown();
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (et) eet_close(et);
|
||||||
|
eet_shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_surface_cap_cache_save(EVGL_Engine *ee)
|
||||||
|
{
|
||||||
|
/* check eet */
|
||||||
|
Eet_File *et = NULL; //check eet file
|
||||||
|
int tmpfd;
|
||||||
|
int res = 0;
|
||||||
|
char cap_dir_path[PATH_MAX];
|
||||||
|
char cap_file_path[PATH_MAX];
|
||||||
|
char tmp_file[PATH_MAX];
|
||||||
|
|
||||||
|
if (!evas_gl_common_file_cache_dir_check(cap_dir_path, sizeof(cap_dir_path)))
|
||||||
|
{
|
||||||
|
res = evas_gl_common_file_cache_mkpath(cap_dir_path);
|
||||||
|
if (!res) return 0; /* we can't make directory */
|
||||||
|
}
|
||||||
|
|
||||||
|
evas_gl_common_file_cache_file_check(cap_dir_path, "surface_cap", cap_file_path,
|
||||||
|
sizeof(cap_dir_path));
|
||||||
|
|
||||||
|
/* use mkstemp for writing */
|
||||||
|
snprintf(tmp_file, sizeof(tmp_file), "%s.XXXXXX", cap_file_path);
|
||||||
|
tmpfd = mkstemp(tmp_file);
|
||||||
|
if (tmpfd < 0) goto error;
|
||||||
|
close(tmpfd);
|
||||||
|
|
||||||
|
/* use eet */
|
||||||
|
if (!eet_init()) goto error;
|
||||||
|
|
||||||
|
et = eet_open(tmp_file, EET_FILE_MODE_WRITE);
|
||||||
|
if (!et) goto error;
|
||||||
|
|
||||||
|
if (!_surface_cap_save(ee, et)) goto error;
|
||||||
|
|
||||||
|
if (eet_close(et) != EET_ERROR_NONE) goto error;
|
||||||
|
if (rename(tmp_file,cap_file_path) < 0) goto error;
|
||||||
|
eet_shutdown();
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (et) eet_close(et);
|
||||||
|
if (evas_gl_common_file_cache_file_exists(tmp_file)) unlink(tmp_file);
|
||||||
|
eet_shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_surface_cap_init(EVGL_Engine *ee)
|
_surface_cap_init(EVGL_Engine *ee)
|
||||||
{
|
{
|
||||||
|
@ -623,16 +773,23 @@ _surface_cap_init(EVGL_Engine *ee)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int num_fmts = 0;
|
// Load Surface Cap
|
||||||
|
if (!_surface_cap_cache_load(ee))
|
||||||
// Check Surface Cap
|
{
|
||||||
num_fmts = _surface_cap_check(ee);
|
// Check Surface Cap
|
||||||
|
ee->caps.num_fbo_fmts = _surface_cap_check(ee);
|
||||||
if (num_fmts)
|
_surface_cap_cache_save(ee);
|
||||||
|
DBG("Ran Evas GL Surface Cap and Cached the existing values.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG("Loaded cached Evas GL Surface Cap values.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ee->caps.num_fbo_fmts)
|
||||||
{
|
{
|
||||||
ee->caps.num_fbo_fmts = num_fmts;
|
|
||||||
_surface_cap_print(ee, 0);
|
_surface_cap_print(ee, 0);
|
||||||
DBG("Number of supported surface formats: %d", num_fmts);
|
DBG("Number of supported surface formats: %d", ee->caps.num_fbo_fmts);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -885,7 +1042,7 @@ _internal_config_set(EVGL_Engine *ee, EVGL_Surface *sfc, Evas_GL_Config *cfg)
|
||||||
color_bit = (1 << cfg->color_format);
|
color_bit = (1 << cfg->color_format);
|
||||||
if (cfg->depth_bits) depth_bit = (1 << (cfg->depth_bits-1));
|
if (cfg->depth_bits) depth_bit = (1 << (cfg->depth_bits-1));
|
||||||
if (cfg->stencil_bits) stencil_bit = (1 << (cfg->stencil_bits-1));
|
if (cfg->stencil_bits) stencil_bit = (1 << (cfg->stencil_bits-1));
|
||||||
if (cfg->multisample_bits)
|
if (cfg->multisample_bits)
|
||||||
msaa_samples = ee->caps.msaa_samples[cfg->multisample_bits-1];
|
msaa_samples = ee->caps.msaa_samples[cfg->multisample_bits-1];
|
||||||
|
|
||||||
// Run through all the available formats and choose the first match
|
// Run through all the available formats and choose the first match
|
||||||
|
@ -1160,7 +1317,7 @@ int evgl_engine_destroy(EVGL_Engine *ee)
|
||||||
if (_evas_gl_log_dom >= 0) return 0;
|
if (_evas_gl_log_dom >= 0) return 0;
|
||||||
eina_log_domain_unregister(_evas_gl_log_dom);
|
eina_log_domain_unregister(_evas_gl_log_dom);
|
||||||
_evas_gl_log_dom = -1;
|
_evas_gl_log_dom = -1;
|
||||||
|
|
||||||
// Destroy internal resources
|
// Destroy internal resources
|
||||||
_internal_resources_destroy(ee);
|
_internal_resources_destroy(ee);
|
||||||
|
|
||||||
|
@ -1240,7 +1397,7 @@ evgl_surface_create(EVGL_Engine *ee, Evas_GL_Config *cfg, int w, int h)
|
||||||
ERR("Unable Create Specificed Surfaces. Unsupported format!");
|
ERR("Unable Create Specificed Surfaces. Unsupported format!");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
return sfc;
|
return sfc;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1413,7 +1570,7 @@ evgl_make_current(EVGL_Engine *ee, EVGL_Surface *sfc, EVGL_Context *ctx)
|
||||||
ERR("Invalid Inputs. Engine: %p Surface: %p Context: %p!", ee, sfc, ctx);
|
ERR("Invalid Inputs. Engine: %p Surface: %p Context: %p!", ee, sfc, ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get TLS Resources
|
// Get TLS Resources
|
||||||
if (!(rsc = _evgl_tls_resource_get(ee))) return 0;
|
if (!(rsc = _evgl_tls_resource_get(ee))) return 0;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "evas_gl_private.h"
|
||||||
|
|
||||||
|
static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
evas_gl_common_file_cache_is_dir(const char *file)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(file, &st) < 0) return EINA_FALSE;
|
||||||
|
if (S_ISDIR(st.st_mode)) return EINA_TRUE;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
evas_gl_common_file_cache_mkdir(const char *dir)
|
||||||
|
{
|
||||||
|
/* evas gl only call this function when the dir is not exist */
|
||||||
|
if (mkdir(dir, default_mode) < 0) return EINA_FALSE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
evas_gl_common_file_cache_file_exists(const char *file)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (!file) return EINA_FALSE;
|
||||||
|
if (stat(file, &st) < 0) return EINA_FALSE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
evas_gl_common_file_cache_mkpath_if_not_exists(const char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(path, &st) < 0)
|
||||||
|
return evas_gl_common_file_cache_mkdir(path);
|
||||||
|
else if (!S_ISDIR(st.st_mode))
|
||||||
|
return EINA_FALSE;
|
||||||
|
else
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
evas_gl_common_file_cache_mkpath(const char *path)
|
||||||
|
{
|
||||||
|
char ss[PATH_MAX];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (evas_gl_common_file_cache_is_dir(path)) return EINA_TRUE;
|
||||||
|
|
||||||
|
for (i = 0; path[i]; ss[i] = path[i], i++)
|
||||||
|
{
|
||||||
|
if (i == sizeof(ss) - 1) return EINA_FALSE;
|
||||||
|
if ((path[i] == '/') && (i > 0))
|
||||||
|
{
|
||||||
|
ss[i] = 0;
|
||||||
|
if (!evas_gl_common_file_cache_mkpath_if_not_exists(ss))
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss[i] = 0;
|
||||||
|
return evas_gl_common_file_cache_mkpath_if_not_exists(ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
evas_gl_common_file_cache_dir_check(char *cache_dir, int num)
|
||||||
|
{
|
||||||
|
char *home = NULL;
|
||||||
|
char *subdir = ".cache/evas_gl_common_caches";
|
||||||
|
|
||||||
|
home = getenv("HOME");
|
||||||
|
if ((!home) || (!home[0])) return 0;
|
||||||
|
|
||||||
|
snprintf(cache_dir, num, "%s/%s", home, subdir);
|
||||||
|
return evas_gl_common_file_cache_file_exists(cache_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
evas_gl_common_file_cache_file_check(const char *cache_dir, const char *cache_name, char *cache_file, int dir_num)
|
||||||
|
{
|
||||||
|
char before_name[PATH_MAX];
|
||||||
|
char after_name[PATH_MAX];
|
||||||
|
int new_path_len = 0;
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
char *vendor = NULL;
|
||||||
|
char *driver = NULL;
|
||||||
|
char *version = NULL;
|
||||||
|
|
||||||
|
vendor = (char *)glGetString(GL_VENDOR);
|
||||||
|
driver = (char *)glGetString(GL_RENDERER);
|
||||||
|
version = (char *)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
new_path_len = snprintf(before_name, sizeof(before_name), "%s::%s::%s::%s::%s.eet", vendor, version, driver, MODULE_ARCH, cache_name);
|
||||||
|
|
||||||
|
/* remove '/' from file name */
|
||||||
|
for (i = 0; i < new_path_len; i++)
|
||||||
|
{
|
||||||
|
if (before_name[i] != '/')
|
||||||
|
{
|
||||||
|
after_name[j] = before_name[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
after_name[j] = 0;
|
||||||
|
|
||||||
|
snprintf(cache_file, dir_num, "%s/%s", cache_dir, after_name);
|
||||||
|
|
||||||
|
return evas_gl_common_file_cache_file_exists(cache_file);
|
||||||
|
}
|
||||||
|
|
|
@ -321,117 +321,6 @@ gl_compile_link_error(GLuint target, const char *action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_evas_gl_shader_file_is_dir(const char *file)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(file, &st) < 0) return EINA_FALSE;
|
|
||||||
if (S_ISDIR(st.st_mode)) return EINA_TRUE;
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_evas_gl_shader_file_mkdir(const char *dir)
|
|
||||||
{
|
|
||||||
/* evas gl shader only call this function when the dir is not exist */
|
|
||||||
if (mkdir(dir, default_mode) < 0) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_evas_gl_shader_file_exists(const char *file)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
if (!file) return EINA_FALSE;
|
|
||||||
if (stat(file, &st) < 0) return EINA_FALSE;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Eina_Bool
|
|
||||||
_evas_gl_shader_file_mkpath_if_not_exists(const char *path)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(path, &st) < 0)
|
|
||||||
return _evas_gl_shader_file_mkdir(path);
|
|
||||||
else if (!S_ISDIR(st.st_mode))
|
|
||||||
return EINA_FALSE;
|
|
||||||
else
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_evas_gl_shader_file_mkpath(const char *path)
|
|
||||||
{
|
|
||||||
char ss[PATH_MAX];
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (_evas_gl_shader_file_is_dir(path)) return EINA_TRUE;
|
|
||||||
|
|
||||||
for (i = 0; path[i]; ss[i] = path[i], i++)
|
|
||||||
{
|
|
||||||
if (i == sizeof(ss) - 1) return EINA_FALSE;
|
|
||||||
if ((path[i] == '/') && (i > 0))
|
|
||||||
{
|
|
||||||
ss[i] = 0;
|
|
||||||
if (!_evas_gl_shader_file_mkpath_if_not_exists(ss))
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ss[i] = 0;
|
|
||||||
return _evas_gl_shader_file_mkpath_if_not_exists(ss);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_evas_gl_shader_dir_check(char *bin_shader_dir, int num)
|
|
||||||
{
|
|
||||||
char *home = NULL;
|
|
||||||
char *subdir = ".cache/evas_gl_common_shaders";
|
|
||||||
|
|
||||||
home = getenv("HOME");
|
|
||||||
if ((!home) || (!home[0])) return 0;
|
|
||||||
|
|
||||||
snprintf(bin_shader_dir, num, "%s/%s", home, subdir);
|
|
||||||
return _evas_gl_shader_file_exists(bin_shader_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_evas_gl_shader_file_check(const char *bin_shader_dir, char *bin_shader_file, int dir_num)
|
|
||||||
{
|
|
||||||
char before_name[PATH_MAX];
|
|
||||||
char after_name[PATH_MAX];
|
|
||||||
int new_path_len = 0;
|
|
||||||
int i = 0, j = 0;
|
|
||||||
|
|
||||||
char *vendor = NULL;
|
|
||||||
char *driver = NULL;
|
|
||||||
char *version = NULL;
|
|
||||||
|
|
||||||
vendor = (char *)glGetString(GL_VENDOR);
|
|
||||||
driver = (char *)glGetString(GL_RENDERER);
|
|
||||||
version = (char *)glGetString(GL_VERSION);
|
|
||||||
|
|
||||||
new_path_len = snprintf(before_name, sizeof(before_name), "%s::%s::%s::%s::binary_shader.eet", vendor, version, driver, MODULE_ARCH);
|
|
||||||
|
|
||||||
/* remove '/' from file name */
|
|
||||||
for (i = 0; i < new_path_len; i++)
|
|
||||||
{
|
|
||||||
if (before_name[i] != '/')
|
|
||||||
{
|
|
||||||
after_name[j] = before_name[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
after_name[j] = 0;
|
|
||||||
|
|
||||||
snprintf(bin_shader_file, dir_num, "%s/%s", bin_shader_dir, after_name);
|
|
||||||
|
|
||||||
return _evas_gl_shader_file_exists(bin_shader_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
|
_evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
|
||||||
const char *pname,
|
const char *pname,
|
||||||
|
@ -459,8 +348,8 @@ _evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
|
||||||
p->prog = glCreateProgram();
|
p->prog = glCreateProgram();
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// TODO: invalid rendering error occurs when attempting to use a
|
// TODO: invalid rendering error occurs when attempting to use a
|
||||||
// glProgramBinary. in order to render correctly we should create a dummy
|
// glProgramBinary. in order to render correctly we should create a dummy
|
||||||
// vertex shader.
|
// vertex shader.
|
||||||
p->vert = glCreateShader(GL_VERTEX_SHADER);
|
p->vert = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glAttachShader(p->prog, p->vert);
|
glAttachShader(p->prog, p->vert);
|
||||||
|
@ -544,7 +433,7 @@ _evas_gl_common_shader_program_source_init(Evas_GL_Program *p,
|
||||||
|
|
||||||
p->vert = glCreateShader(GL_VERTEX_SHADER);
|
p->vert = glCreateShader(GL_VERTEX_SHADER);
|
||||||
p->frag = glCreateShader(GL_FRAGMENT_SHADER);
|
p->frag = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
glShaderSource(p->vert, 1,
|
glShaderSource(p->vert, 1,
|
||||||
(const char **)&(vert->src), NULL);
|
(const char **)&(vert->src), NULL);
|
||||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||||
|
@ -573,7 +462,7 @@ _evas_gl_common_shader_program_source_init(Evas_GL_Program *p,
|
||||||
ERR("Abort compile of shader frag (%s): %s", name, frag->src);
|
ERR("Abort compile of shader frag (%s): %s", name, frag->src);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->prog = glCreateProgram();
|
p->prog = glCreateProgram();
|
||||||
#ifdef GL_GLES
|
#ifdef GL_GLES
|
||||||
#else
|
#else
|
||||||
|
@ -667,10 +556,10 @@ _evas_gl_common_shader_binary_init(Evas_GL_Shared *shared)
|
||||||
char bin_file_path[PATH_MAX];
|
char bin_file_path[PATH_MAX];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!_evas_gl_shader_dir_check(bin_dir_path, sizeof(bin_dir_path)))
|
if (!evas_gl_common_file_cache_dir_check(bin_dir_path, sizeof(bin_dir_path)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!_evas_gl_shader_file_check(bin_dir_path, bin_file_path,
|
if (!evas_gl_common_file_cache_file_check(bin_dir_path, "binary_shader", bin_file_path,
|
||||||
sizeof(bin_dir_path)))
|
sizeof(bin_dir_path)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -707,13 +596,13 @@ _evas_gl_common_shader_binary_save(Evas_GL_Shared *shared)
|
||||||
char tmp_file[PATH_MAX];
|
char tmp_file[PATH_MAX];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!_evas_gl_shader_dir_check(bin_dir_path, sizeof(bin_dir_path)))
|
if (!evas_gl_common_file_cache_dir_check(bin_dir_path, sizeof(bin_dir_path)))
|
||||||
{
|
{
|
||||||
res = _evas_gl_shader_file_mkpath(bin_dir_path);
|
res = evas_gl_common_file_cache_mkpath(bin_dir_path);
|
||||||
if (!res) return 0; /* we can't make directory */
|
if (!res) return 0; /* we can't make directory */
|
||||||
}
|
}
|
||||||
|
|
||||||
_evas_gl_shader_file_check(bin_dir_path, bin_file_path,
|
evas_gl_common_file_cache_file_check(bin_dir_path, "binary_shader", bin_file_path,
|
||||||
sizeof(bin_dir_path));
|
sizeof(bin_dir_path));
|
||||||
|
|
||||||
/* use mkstemp for writing */
|
/* use mkstemp for writing */
|
||||||
|
@ -741,7 +630,7 @@ _evas_gl_common_shader_binary_save(Evas_GL_Shared *shared)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (et) eet_close(et);
|
if (et) eet_close(et);
|
||||||
if (_evas_gl_shader_file_exists(tmp_file)) unlink(tmp_file);
|
if (evas_gl_common_file_cache_file_exists(tmp_file)) unlink(tmp_file);
|
||||||
eet_shutdown();
|
eet_shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue