video_shader_parse.c - reduce stack usage

This commit is contained in:
twinaphex 2017-09-09 22:54:55 +02:00
parent 9aa16ddfcc
commit ba77d862a3

View File

@ -119,8 +119,6 @@ static enum gfx_wrap_type wrap_str_to_mode(const char *wrap_mode)
static bool video_shader_parse_pass(config_file_t *conf,
struct video_shader_pass *pass, unsigned i)
{
char tmp_str[PATH_MAX_LENGTH];
char tmp_path[PATH_MAX_LENGTH];
char shader_name[64];
char filter_name_buf[64];
char wrap_name_buf[64];
@ -136,6 +134,9 @@ static bool video_shader_parse_pass(config_file_t *conf,
char scale_type_x[64];
char scale_type_y[64];
char frame_count_mod[64];
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
char *tmp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
char *tmp_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
struct gfx_fbo_scale *scale = NULL;
bool tmp_bool = false;
float fattr = 0.0f;
@ -150,14 +151,14 @@ static bool video_shader_parse_pass(config_file_t *conf,
/* Source */
snprintf(shader_name, sizeof(shader_name), "shader%u", i);
if (!config_get_path(conf, shader_name, tmp_str, sizeof(tmp_str)))
if (!config_get_path(conf, shader_name, tmp_str, path_size))
{
RARCH_ERR("Couldn't parse shader source (%s).\n", shader_name);
return false;
goto error;
}
strlcpy(tmp_path, tmp_str, sizeof(tmp_path));
path_resolve_realpath(tmp_path, sizeof(tmp_path));
strlcpy(tmp_path, tmp_str, path_size);
path_resolve_realpath(tmp_path, path_size);
if (!path_file_exists(tmp_path))
strlcpy(pass->source.path, tmp_str, sizeof(pass->source.path));
@ -246,7 +247,7 @@ static bool video_shader_parse_pass(config_file_t *conf,
break;
default:
RARCH_ERR("Invalid attribute.\n");
return false;
goto error;
}
}
@ -267,7 +268,7 @@ static bool video_shader_parse_pass(config_file_t *conf,
break;
default:
RARCH_ERR("Invalid attribute.\n");
return false;
goto error;
}
}
@ -319,7 +320,14 @@ static bool video_shader_parse_pass(config_file_t *conf,
}
}
free(tmp_str);
free(tmp_path);
return true;
error:
free(tmp_str);
free(tmp_path);
return false;
}
/**
@ -334,15 +342,20 @@ static bool video_shader_parse_pass(config_file_t *conf,
static bool video_shader_parse_textures(config_file_t *conf,
struct video_shader *shader)
{
char textures[1024];
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
const char *id = NULL;
char *save = NULL;
char tmp_path[PATH_MAX_LENGTH];
char *textures = (char*)malloc(1024 * sizeof(char));
char *tmp_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
textures[0] = '\0';
if (!config_get_array(conf, "textures", textures, sizeof(textures)))
if (!config_get_array(conf, "textures", textures, 1024 * sizeof(char)))
{
free(textures);
free(tmp_path);
return true;
}
for (id = strtok_r(textures, ";", &save);
id && shader->luts < GFX_MAX_TEXTURES;
@ -361,11 +374,12 @@ static bool video_shader_parse_textures(config_file_t *conf,
sizeof(shader->lut[shader->luts].path)))
{
RARCH_ERR("Cannot find path to texture \"%s\" ...\n", id);
return false;
goto error;
}
strlcpy(tmp_path, shader->lut[shader->luts].path, sizeof(tmp_path));
path_resolve_realpath(tmp_path, sizeof(tmp_path));
strlcpy(tmp_path, shader->lut[shader->luts].path,
path_size);
path_resolve_realpath(tmp_path, path_size);
if (path_file_exists(tmp_path))
{
@ -394,7 +408,14 @@ static bool video_shader_parse_textures(config_file_t *conf,
shader->lut[shader->luts].mipmap = false;
}
free(textures);
free(tmp_path);
return true;
error:
free(textures);
free(tmp_path);
return false;
}
/**
@ -434,25 +455,34 @@ static struct video_shader_parameter *video_shader_parse_find_parameter(
bool video_shader_resolve_current_parameters(config_file_t *conf,
struct video_shader *shader)
{
char parameters[4096];
size_t param_size = 4096 * sizeof(char);
char *parameters = (char*)malloc(4096 * sizeof(char));
const char *id = NULL;
char *save = NULL;
if (!conf)
{
free(parameters);
return false;
}
parameters[0] = '\0';
/* Read in parameters which override the defaults. */
if (!config_get_array(conf, "parameters",
parameters, sizeof(parameters)))
parameters, param_size))
{
free(parameters);
return true;
}
for (id = strtok_r(parameters, ";", &save); id;
id = strtok_r(NULL, ";", &save))
{
struct video_shader_parameter *parameter = (struct video_shader_parameter*)
video_shader_parse_find_parameter(shader->parameters, shader->num_parameters, id);
struct video_shader_parameter *parameter =
(struct video_shader_parameter*)
video_shader_parse_find_parameter(
shader->parameters, shader->num_parameters, id);
if (!parameter)
{
@ -463,6 +493,8 @@ bool video_shader_resolve_current_parameters(config_file_t *conf,
if (!config_get_float(conf, id, &parameter->current))
RARCH_WARN("[CGP/GLSLP]: Parameter %s is not set in preset.\n", id);
}
free(parameters);
return true;
}
@ -487,28 +519,36 @@ bool video_shader_resolve_parameters(config_file_t *conf,
for (i = 0; i < shader->passes; i++)
{
char line[4096];
RFILE *file = NULL;
size_t line_size = 4096 * sizeof(char);
char *line = (char*)malloc(4096 * sizeof(char));
const char *path = shader->pass[i].source.path;
#ifdef HAVE_SLANG
/* First try to use the more robust slang implementation to support #includes. */
/* FIXME: The check for slang can be removed if it's sufficiently tested for
* GLSL/Cg as well, it should be the same implementation. */
if (!string_is_empty(path) && (string_is_equal_fast(path_get_extension(path), "slang", 5)) &&
slang_preprocess_parse_parameters(shader->pass[i].source.path, shader))
{
free(line);
continue;
}
/* If that doesn't work, fallback to the old path.
* Ideally, we'd get rid of this path sooner or later. */
#endif
file = filestream_open(path, RFILE_MODE_READ_TEXT, -1);
if (!file)
{
free(line);
continue;
}
line[0] = '\0';
while (shader->num_parameters < ARRAY_SIZE(shader->parameters)
&& filestream_gets(file, line, sizeof(line)))
&& filestream_gets(file, line, line_size))
{
int ret = sscanf(line,
"#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
@ -533,6 +573,7 @@ bool video_shader_resolve_parameters(config_file_t *conf,
param++;
}
free(line);
filestream_close(file);
}
@ -554,15 +595,21 @@ bool video_shader_resolve_parameters(config_file_t *conf,
static bool video_shader_parse_imports(config_file_t *conf,
struct video_shader *shader)
{
char imports[1024];
char tmp_str[PATH_MAX_LENGTH];
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
char *imports = (char*)malloc(1024 * sizeof(char));
char *tmp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
const char *id = NULL;
char *save = NULL;
imports[0] = tmp_str[0] = '\0';
if (!config_get_array(conf, "imports", imports, sizeof(imports)))
if (!config_get_array(conf, "imports", imports,
1024 * sizeof(char)))
{
free(imports);
free(tmp_str);
return true;
}
for (id = strtok_r(imports, ";", &save);
id && shader->variables < GFX_MAX_VARIABLES;
@ -595,7 +642,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
if (!config_get_array(conf, semantic_buf, semantic, sizeof(semantic)))
{
RARCH_ERR("No semantic for import variable.\n");
return false;
goto error;
}
semantic_hash = djb2_calculate(semantic);
@ -622,7 +669,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
break;
default:
RARCH_ERR("Invalid semantic.\n");
return false;
goto error;
}
@ -644,7 +691,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
default:
RARCH_ERR("Invalid input slot for import.\n");
return false;
goto error;
}
}
else if (config_get_hex(conf, wram_buf, &addr))
@ -655,7 +702,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
else
{
RARCH_ERR("No address assigned to semantic.\n");
return false;
goto error;
}
}
@ -665,12 +712,19 @@ static bool video_shader_parse_imports(config_file_t *conf,
var->equal = equal;
}
if (config_get_path(conf, "import_script", tmp_str, sizeof(tmp_str)))
if (config_get_path(conf, "import_script", tmp_str, path_size))
strlcpy(shader->script_path, tmp_str, sizeof(shader->script_path));
config_get_array(conf, "import_script_class",
shader->script_class, sizeof(shader->script_class));
free(imports);
free(tmp_str);
return true;
error:
free(imports);
free(tmp_str);
return false;
}
/**
@ -879,18 +933,21 @@ void video_shader_write_conf_cgp(config_file_t *conf,
for (i = 0; i < shader->passes; i++)
{
char key[64];
char tmp[PATH_MAX_LENGTH];
size_t tmp_size = PATH_MAX_LENGTH * sizeof(char);
char *tmp = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
const struct video_shader_pass *pass = &shader->pass[i];
key[0] = '\0';
snprintf(key, sizeof(key), "shader%u", i);
strlcpy(tmp, pass->source.path, sizeof(tmp));
strlcpy(tmp, pass->source.path, tmp_size);
if (!path_is_absolute(tmp))
path_resolve_realpath(tmp, sizeof(tmp));
path_resolve_realpath(tmp, tmp_size);
config_set_string(conf, key, tmp);
free(tmp);
if (pass->filter != RARCH_FILTER_UNSPEC)
{
snprintf(key, sizeof(key), "filter_linear%u", i);
@ -917,17 +974,18 @@ void video_shader_write_conf_cgp(config_file_t *conf,
if (shader->num_parameters)
{
char parameters[4096];
size_t param_size = 4096 * sizeof(char);
char *parameters = (char*)malloc(4096 * sizeof(char));
parameters[0] = '\0';
strlcpy(parameters, shader->parameters[0].id, sizeof(parameters));
strlcpy(parameters, shader->parameters[0].id, param_size);
for (i = 1; i < shader->num_parameters; i++)
{
/* O(n^2), but number of parameters is very limited. */
strlcat(parameters, ";", sizeof(parameters));
strlcat(parameters, shader->parameters[i].id, sizeof(parameters));
strlcat(parameters, ";", param_size);
strlcat(parameters, shader->parameters[i].id, param_size);
}
config_set_string(conf, "parameters", parameters);
@ -935,24 +993,28 @@ void video_shader_write_conf_cgp(config_file_t *conf,
for (i = 0; i < shader->num_parameters; i++)
config_set_float(conf, shader->parameters[i].id,
shader->parameters[i].current);
free(parameters);
}
if (shader->luts)
{
char textures[4096];
size_t tex_size = 4096 * sizeof(char);
char *textures = (char*)malloc(4096 * sizeof(char));
textures[0] = '\0';
strlcpy(textures, shader->lut[0].id, sizeof(textures));
strlcpy(textures, shader->lut[0].id, tex_size);
for (i = 1; i < shader->luts; i++)
{
/* O(n^2), but number of textures is very limited. */
strlcat(textures, ";", sizeof(textures));
strlcat(textures, shader->lut[i].id, sizeof(textures));
strlcat(textures, ";", tex_size);
strlcat(textures, shader->lut[i].id, tex_size);
}
config_set_string(conf, "textures", textures);
free(textures);
for (i = 0; i < shader->luts; i++)
{
char key[64];
@ -983,22 +1045,24 @@ void video_shader_write_conf_cgp(config_file_t *conf,
if (shader->variables)
{
char variables[4096];
size_t var_tmp = 4096 * sizeof(char);
char *variables = (char*)malloc(4096 * sizeof(char));
variables[0] = '\0';
strlcpy(variables, shader->variable[0].id, sizeof(variables));
strlcpy(variables, shader->variable[0].id, var_tmp);
for (i = 1; i < shader->variables; i++)
{
strlcat(variables, ";", sizeof(variables));
strlcat(variables, shader->variable[i].id, sizeof(variables));
strlcat(variables, ";", var_tmp);
strlcat(variables, shader->variable[i].id, var_tmp);
}
config_set_string(conf, "imports", variables);
for (i = 0; i < shader->variables; i++)
shader_write_variable(conf, &shader->variable[i]);
free(variables);
}
}
@ -1050,7 +1114,8 @@ void video_shader_resolve_relative(struct video_shader *shader,
const char *ref_path)
{
unsigned i;
char tmp_path[4096];
size_t tmp_path_size = 4096 * sizeof(char);
char *tmp_path = (char*)malloc(4096 * sizeof(char));
tmp_path[0] = '\0';
@ -1059,23 +1124,25 @@ void video_shader_resolve_relative(struct video_shader *shader,
if (!*shader->pass[i].source.path)
continue;
strlcpy(tmp_path, shader->pass[i].source.path, sizeof(tmp_path));
strlcpy(tmp_path, shader->pass[i].source.path, tmp_path_size);
fill_pathname_resolve_relative(shader->pass[i].source.path,
ref_path, tmp_path, sizeof(shader->pass[i].source.path));
}
for (i = 0; i < shader->luts; i++)
{
strlcpy(tmp_path, shader->lut[i].path, sizeof(tmp_path));
strlcpy(tmp_path, shader->lut[i].path, tmp_path_size);
fill_pathname_resolve_relative(shader->lut[i].path,
ref_path, tmp_path, sizeof(shader->lut[i].path));
}
if (*shader->script_path)
{
strlcpy(tmp_path, shader->script_path, sizeof(tmp_path));
strlcpy(tmp_path, shader->script_path, tmp_path_size);
fill_pathname_resolve_relative(shader->script_path,
ref_path, tmp_path, sizeof(shader->script_path));
}
free(tmp_path);
}