static void _surface_cap_print(EVGL_Engine *ee, int error);
//---------------------------------------------------------------//
-// Internal Resources:
+// Internal Resources:
// - Surface and Context used for internal buffer creation
//---------------------------------------------------------------//
static int
}
//---------------------------------------------------------------//
-// Surface Related Functions
+// Surface Related Functions
// - Texture/ Renderbuffer Creation/ Attachment to FBO
// - Surface capability check
// - Internal config choose function
// Check whether the given FBO surface config is supported by the driver
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)
{
GLuint fbo = 0;
if ( (depth->bit == DEPTH_STENCIL) && (stencil->bit != STENCIL_BIT_8))
return 0;
- ret = _fbo_surface_cap_test((GLint)color->fmt,
+ ret = _fbo_surface_cap_test((GLint)color->fmt,
color->fmt,
- depth->fmt,
- stencil->fmt, samples);
+ depth->fmt,
+ stencil->fmt, samples);
if (ret)
{
fmt->color_bit = color->bit;
}
else
{
- fmt->depth_stencil_fmt = 0;
+ fmt->depth_stencil_fmt = 0;
fmt->depth_bit = depth->bit;
fmt->depth_fmt = depth->fmt;
fmt->stencil_bit = stencil->bit;
};
#ifdef GL_GLES
- GL_Format depth[] = {
+ GL_Format depth[] = {
{ DEPTH_NONE, 0 },
- { DEPTH_STENCIL, GL_DEPTH_STENCIL_OES },
+ { DEPTH_STENCIL, GL_DEPTH_STENCIL_OES },
{ DEPTH_BIT_8, GL_DEPTH_COMPONENT },
{ DEPTH_BIT_16, GL_DEPTH_COMPONENT16 },
{ DEPTH_BIT_24, GL_DEPTH_COMPONENT24_OES },
{ DEPTH_BIT_32, GL_DEPTH_COMPONENT32_OES },
{ -1, -1 },
- };
- GL_Format stencil[] = {
+ };
+ GL_Format stencil[] = {
{ STENCIL_NONE, 0 },
{ STENCIL_BIT_1, GL_STENCIL_INDEX1_OES },
{ STENCIL_BIT_4, GL_STENCIL_INDEX4_OES },
{ -1, -1 },
};
#else
- GL_Format depth[] = {
+ GL_Format depth[] = {
{ DEPTH_NONE, 0 },
{ DEPTH_STENCIL, GL_DEPTH24_STENCIL8 },
{ DEPTH_BIT_8, GL_DEPTH_COMPONENT },
{ DEPTH_BIT_24, GL_DEPTH_COMPONENT24 },
{ DEPTH_BIT_32, GL_DEPTH_COMPONENT32 },
{ -1, -1 },
- };
+ };
GL_Format stencil[] = {
{ STENCIL_NONE, 0 },
{ STENCIL_BIT_1, GL_STENCIL_INDEX1 },
// Color Formats
i = 0;
while ( color[i].bit >= 0 )
- {
+ {
j = 0;
// Depth Formats
- while ( depth[j].bit >= 0 )
+ while ( depth[j].bit >= 0 )
{
k = 0;
// Stencil Formats
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
_surface_cap_init(EVGL_Engine *ee)
{
}
#endif
- int num_fmts = 0;
-
- // Check Surface Cap
- num_fmts = _surface_cap_check(ee);
+ // Load Surface Cap
+ if (!_surface_cap_cache_load(ee))
+ {
+ // Check Surface Cap
+ ee->caps.num_fbo_fmts = _surface_cap_check(ee);
+ _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 (num_fmts)
+ if (ee->caps.num_fbo_fmts)
{
- ee->caps.num_fbo_fmts = num_fmts;
_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;
}
else
color_bit = (1 << cfg->color_format);
if (cfg->depth_bits) depth_bit = (1 << (cfg->depth_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];
// Run through all the available formats and choose the first match
if (_evas_gl_log_dom >= 0) return 0;
eina_log_domain_unregister(_evas_gl_log_dom);
_evas_gl_log_dom = -1;
-
+
// Destroy internal resources
_internal_resources_destroy(ee);
ERR("Unable Create Specificed Surfaces. Unsupported format!");
goto error;
};
-
+
return sfc;
error:
ERR("Invalid Inputs. Engine: %p Surface: %p Context: %p!", ee, sfc, ctx);
return 0;
}
-
+
// Get TLS Resources
if (!(rsc = _evgl_tls_resource_get(ee))) return 0;
--- /dev/null
+#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);
+}
+
}
}
-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
_evas_gl_common_shader_program_binary_init(Evas_GL_Program *p,
const char *pname,
p->prog = glCreateProgram();
#if 1
- // TODO: invalid rendering error occurs when attempting to use a
- // glProgramBinary. in order to render correctly we should create a dummy
+ // TODO: invalid rendering error occurs when attempting to use a
+ // glProgramBinary. in order to render correctly we should create a dummy
// vertex shader.
p->vert = glCreateShader(GL_VERTEX_SHADER);
glAttachShader(p->prog, p->vert);
p->vert = glCreateShader(GL_VERTEX_SHADER);
p->frag = glCreateShader(GL_FRAGMENT_SHADER);
-
+
glShaderSource(p->vert, 1,
(const char **)&(vert->src), NULL);
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
ERR("Abort compile of shader frag (%s): %s", name, frag->src);
return 0;
}
-
+
p->prog = glCreateProgram();
#ifdef GL_GLES
#else
char bin_file_path[PATH_MAX];
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;
- 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)))
return 0;
char tmp_file[PATH_MAX];
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 */
}
- _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));
/* use mkstemp for writing */
error:
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();
return 0;
}