mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-14 04:57:54 +00:00
[client] egl: implement loading and saving of filter order
This commit is contained in:
parent
c85cc7d668
commit
dc27638025
5 changed files with 93 additions and 1 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue