[client] egl: implement loading and saving of filter order

This commit is contained in:
Quantum 2021-08-28 18:08:46 -04:00 committed by Geoffrey McRae
parent c85cc7d668
commit dc27638025
5 changed files with 93 additions and 1 deletions

View File

@ -31,6 +31,9 @@ typedef struct EGL_Filter EGL_Filter;
typedef struct EGL_FilterOps
{
/* the identifier of this filter */
const char * id;
/* the friendly name of this filter */
const char * name;

View File

@ -417,6 +417,7 @@ static GLuint egl_filterDownscaleRun(EGL_Filter * filter, EGL_Model * model,
EGL_FilterOps egl_filterDownscaleOps =
{
.id = "downscale",
.name = "Downscaler",
.type = EGL_FILTER_TYPE_DOWNSCALE,
.earlyInit = egl_filterDownscaleEarlyInit,

View File

@ -279,6 +279,7 @@ static GLuint egl_filterFFXCASRun(EGL_Filter * filter, EGL_Model * model,
EGL_FilterOps egl_filterFFXCASOps =
{
.id = "ffxCAS",
.name = "AMD FidelityFX CAS",
.type = EGL_FILTER_TYPE_EFFECT,
.earlyInit = egl_filterFFXCASEarlyInit,

View File

@ -414,6 +414,7 @@ static GLuint egl_filterFFXFSR1Run(EGL_Filter * filter, EGL_Model * model,
EGL_FilterOps egl_filterFFXFSR1Ops =
{
.id = "ffxFSR1",
.name = "AMD FidelityFX FSR",
.type = EGL_FILTER_TYPE_UPSCALE,
.earlyInit = egl_filterFFXFSR1EarlyInit,

View File

@ -18,6 +18,7 @@
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _GNU_SOURCE
#include "postprocess.h"
#include "filters.h"
#include "app.h"
@ -25,6 +26,7 @@
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <stdatomic.h>
#include <sys/stat.h>
@ -62,7 +64,20 @@ struct EGL_PostProcess
void egl_postProcessEarlyInit(void)
{
for(int i = 0; i < ARRAY_LENGTH(EGL_Filters); ++i)
static struct Option options[] =
{
{
.module = "eglFilter",
.name = "order",
.description = "The order of filters to use",
.type = OPTION_TYPE_STRING,
.value.x_string = ""
},
{ 0 }
};
option_register(options);
for (int i = 0; i < ARRAY_LENGTH(EGL_Filters); ++i)
EGL_Filters[i]->earlyInit();
}
@ -138,6 +153,22 @@ static bool savePreset(struct EGL_PostProcess * this, const char * name)
vector_forEach(filter, &this->filters)
egl_filterSaveState(filter);
size_t orderLen = 0;
vector_forEach(filter, &this->filters)
orderLen += strlen(filter->ops.id) + 1;
char order[orderLen];
char * p = order;
vector_forEach(filter, &this->filters)
{
strcpy(p, filter->ops.id);
p += strlen(filter->ops.id);
*p++ = ';';
}
if (p > order)
p[-1] = '\0';
option_set_string("eglFilter", "order", order);
char * path;
alloc_sprintf(&path, "%s/%s", this->presetDir, name);
if (!path)
@ -167,6 +198,59 @@ static bool savePreset(struct EGL_PostProcess * this, const char * name)
return true;
}
static int stringListIndex(StringList list, const char * str)
{
unsigned int count = stringlist_count(list);
for (unsigned int i = 0; i < count; ++i)
if (strcmp(stringlist_at(list, i), str) == 0)
return i;
return INT_MAX;
}
static int compareFilterOrder(const void * a_, const void * b_, void * opaque)
{
const EGL_Filter * a = *(const EGL_Filter **)a_;
const EGL_Filter * b = *(const EGL_Filter **)b_;
StringList order = opaque;
return stringListIndex(order, a->ops.id) - stringListIndex(order, b->ops.id);
}
static void reorderFilters(struct EGL_PostProcess * this)
{
StringList order = stringlist_new(false);
if (!order)
{
DEBUG_ERROR("Failed to allocate memory");
return;
}
char * orderStr = strdup(option_get_string("eglFilter", "order"));
if (!orderStr)
{
DEBUG_ERROR("Failed to allocate memory");
stringlist_free(&order);
return;
}
char * p = orderStr;
while (*p)
{
stringlist_push(order, p);
char * end = strchr(p, ';');
if (!end)
break;
*end = '\0';
p = end + 1;
}
qsort_r(vector_data(&this->filters), vector_size(&this->filters),
sizeof(EGL_Filter *), compareFilterOrder, order);
stringlist_free(&order);
free(orderStr);
}
static void loadPreset(struct EGL_PostProcess * this, const char * name)
{
char * path;
@ -194,6 +278,7 @@ static void loadPreset(struct EGL_PostProcess * this, const char * name)
EGL_Filter * filter;
vector_forEach(filter, &this->filters)
egl_filterLoadState(filter);
reorderFilters(this);
}
static void createPreset(struct EGL_PostProcess * this)
@ -408,6 +493,7 @@ bool egl_postProcessInit(EGL_PostProcess ** pp)
egl_modelSetDefault(this->model, false);
loadPresetList(this);
reorderFilters(this);
app_overlayConfigRegisterTab("EGL Filters", configUI, this);
*pp = this;