diff --git a/gfx/filter.c b/gfx/filter.c index 1995edbe95..69e55c4034 100644 --- a/gfx/filter.c +++ b/gfx/filter.c @@ -27,8 +27,10 @@ struct rarch_softfilter void *impl_data; unsigned max_width, max_height; - unsigned threads; enum retro_pixel_format pix_fmt, out_pix_fmt; + + struct softfilter_work_packet *packets; + unsigned threads; }; rarch_softfilter_t *rarch_softfilter_new(const char *filter_path, @@ -56,13 +58,33 @@ rarch_softfilter_t *rarch_softfilter_new(const char *filter_path, if (!filt->impl) goto error; + // Simple assumptions. + unsigned input_fmt = in_pixel_format == RETRO_PIXEL_FORMAT_XRGB8888 ? + SOFTFILTER_FMT_XRGB8888 : SOFTFILTER_FMT_RGB565; + unsigned input_fmts = filt->impl->query_input_formats(); + if (!(input_fmt & input_fmts)) + goto error; + + unsigned output_fmts = filt->impl->query_output_formats(input_fmt); + if (!(output_fmts & input_fmt)) + goto error; + filt->max_width = max_width; filt->max_height = max_height; filt->pix_fmt = in_pixel_format; - filt->threads = threads; - filt->out_pix_fmt = in_pixel_format; + filt->impl_data = filt->impl->create(input_fmt, input_fmt, max_width, max_height, + threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : 1, cpu_features); + if (!filt->impl_data) + goto error; + + threads = filt->impl->query_num_threads(filt->impl_data); + filt->packets = (struct softfilter_work_packet*)calloc(threads, sizeof(*filt->packets)); + if (!filt->packets) + goto error; + filt->threads = threads; + return filt; error: @@ -75,6 +97,7 @@ void rarch_softfilter_free(rarch_softfilter_t *filt) if (!filt) return; + free(filt->packets); if (filt->impl && filt->impl_data) filt->impl->destroy(filt->impl_data); if (filt->lib) @@ -104,5 +127,12 @@ void rarch_softfilter_process(rarch_softfilter_t *filt, void *output, size_t output_stride, const void *input, unsigned width, unsigned height, size_t input_stride) { + unsigned i; + filt->impl->process(filt->impl_data, filt->packets, + output, output_stride, input, width, height, input_stride); + + // TODO: Move to worker threads. + for (i = 0; i < filt->threads; i++) + filt->packets[i].work(filt->impl_data, filt->packets[i].thread_data); } diff --git a/gfx/filter.h b/gfx/filter.h index 65fc0fdf86..0aa5cec486 100644 --- a/gfx/filter.h +++ b/gfx/filter.h @@ -21,7 +21,7 @@ #include "softfilter.h" -#define RARCH_CPU_FILTER_THREADS_AUTO 0 +#define RARCH_SOFTFILTER_THREADS_AUTO 0 typedef struct rarch_softfilter rarch_softfilter_t; rarch_softfilter_t *rarch_softfilter_new(const char *filter_path, diff --git a/gfx/softfilter.h b/gfx/softfilter.h index 983fbc350a..6d7cb84356 100644 --- a/gfx/softfilter.h +++ b/gfx/softfilter.h @@ -62,11 +62,10 @@ typedef unsigned (*softfilter_query_input_formats_t)(void); typedef unsigned (*softfilter_query_output_formats_t)(unsigned input_format); // In softfilter_process_t, the softfilter implementation submits work units to a worker thread pool. -typedef void (*softfilter_work_t)(void *userdata, void *thread_data); +typedef void (*softfilter_work_t)(void *data, void *thread_data); struct softfilter_work_packet { softfilter_work_t work; - void *userdata; void *thread_data; }; @@ -100,7 +99,7 @@ typedef unsigned (*softfilter_query_num_threads_t)(void *data); struct softfilter_implementation { softfilter_query_input_formats_t query_input_formats; - softfilter_query_output_formats_t query_output_format; + softfilter_query_output_formats_t query_output_formats; softfilter_create_t create; softfilter_destroy_t destroy;