rarch_softfilter_t *rarch_softfilter_new(const char *filter_config, unsigned threads, enum retro_pixel_format in_pixel_format, unsigned max_width, unsigned max_height) { softfilter_simd_mask_t cpu_features = retro_get_cpu_features(); char basedir[PATH_MAX_LENGTH] = {0}; struct string_list *plugs = NULL; rarch_softfilter_t *filt = NULL; (void)basedir; filt = (rarch_softfilter_t*)calloc(1, sizeof(*filt)); if (!filt) return NULL; filt->conf = config_file_new(filter_config); if (!filt->conf) { RARCH_ERR("[SoftFilter]: Did not find config: %s\n", filter_config); goto error; } #if defined(HAVE_DYLIB) fill_pathname_basedir(basedir, filter_config, sizeof(basedir)); plugs = dir_list_new(basedir, EXT_EXECUTABLES, false, false); if (!plugs) { RARCH_ERR("[SoftFilter]: Could not build up string list...\n"); goto error; } #endif if (!append_softfilter_plugs(filt, plugs)) { RARCH_ERR("[SoftFitler]: Failed to append softfilter plugins...\n"); goto error; } if (plugs) string_list_free(plugs); plugs = NULL; if (!create_softfilter_graph(filt, in_pixel_format, max_width, max_height, cpu_features, threads)) { RARCH_ERR("[SoftFitler]: Failed to create softfilter graph...\n"); goto error; } return filt; error: if (plugs) string_list_free(plugs); plugs = NULL; rarch_softfilter_free(filt); return NULL; }
static void deinit_video_filter(void) { rarch_softfilter_free(video_state.filter.filter); #ifdef _3DS linearFree(video_state.filter.buffer); #else free(video_state.filter.buffer); #endif memset(&video_state.filter, 0, sizeof(video_state.filter)); }
static void deinit_video_filter(void) { rarch_softfilter_free(video_state.filter.filter); free(video_state.filter.buffer); memset(&video_state.filter, 0, sizeof(video_state.filter)); }
rarch_softfilter_t *rarch_softfilter_new(const char *filter_path, unsigned threads, enum retro_pixel_format in_pixel_format, unsigned max_width, unsigned max_height) { unsigned i, cpu_features, output_fmts, input_fmts, input_fmt; softfilter_get_implementation_t cb; i = 0; (void)i; (void)filter_path; rarch_softfilter_t *filt = (rarch_softfilter_t*)calloc(1, sizeof(*filt)); if (!filt) return NULL; cb = NULL; #if defined(HAVE_FILTERS_BUILTIN) cb = (softfilter_get_implementation_t)softfilter_get_implementation_from_idx(g_settings.video.filter_idx); #elif defined(HAVE_DYLIB) filt->lib = dylib_load(filter_path); if (!filt->lib) goto error; cb = (softfilter_get_implementation_t)dylib_proc(filt->lib, "softfilter_get_implementation"); #endif if (!cb) { RARCH_ERR("Couldn't find softfilter symbol.\n"); goto error; } cpu_features = rarch_get_cpu_features(); filt->impl = cb(cpu_features); if (!filt->impl) goto error; RARCH_LOG("Loaded softfilter \"%s\".\n", filt->impl->ident); if (filt->impl->api_version != SOFTFILTER_API_VERSION) { RARCH_ERR("Softfilter ABI mismatch.\n"); goto error; } // Simple assumptions. filt->pix_fmt = in_pixel_format; input_fmts = filt->impl->query_input_formats(); switch (in_pixel_format) { case RETRO_PIXEL_FORMAT_XRGB8888: input_fmt = SOFTFILTER_FMT_XRGB8888; break; case RETRO_PIXEL_FORMAT_RGB565: input_fmt = SOFTFILTER_FMT_RGB565; break; default: goto error; } if (!(input_fmt & input_fmts)) { RARCH_ERR("Softfilter does not support input format.\n"); goto error; } output_fmts = filt->impl->query_output_formats(input_fmt); if (output_fmts & input_fmt) // If we have a match of input/output formats, use that. filt->out_pix_fmt = in_pixel_format; else if (output_fmts & SOFTFILTER_FMT_XRGB8888) filt->out_pix_fmt = RETRO_PIXEL_FORMAT_XRGB8888; else if (output_fmts & SOFTFILTER_FMT_RGB565) filt->out_pix_fmt = RETRO_PIXEL_FORMAT_RGB565; else { RARCH_ERR("Did not find suitable output format for softfilter.\n"); goto error; } filt->max_width = max_width; filt->max_height = max_height; filt->impl_data = filt->impl->create(input_fmt, input_fmt, max_width, max_height, threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : rarch_get_cpu_cores(), cpu_features); if (!filt->impl_data) { RARCH_ERR("Failed to create softfilter state.\n"); goto error; } threads = filt->impl->query_num_threads(filt->impl_data); if (!threads) { RARCH_ERR("Invalid number of threads.\n"); goto error; } RARCH_LOG("Using %u threads for softfilter.\n", threads); filt->packets = (struct softfilter_work_packet*)calloc(threads, sizeof(*filt->packets)); if (!filt->packets) { RARCH_ERR("Failed to allocate softfilter packets.\n"); goto error; } #ifdef HAVE_THREADS filt->thread_data = (struct filter_thread_data*)calloc(threads, sizeof(*filt->thread_data)); if (!filt->thread_data) goto error; filt->threads = threads; for (i = 0; i < threads; i++) { filt->thread_data[i].userdata = filt->impl_data; filt->thread_data[i].done = true; filt->thread_data[i].lock = slock_new(); if (!filt->thread_data[i].lock) goto error; filt->thread_data[i].cond = scond_new(); if (!filt->thread_data[i].cond) goto error; filt->thread_data[i].thread = sthread_create(filter_thread_loop, &filt->thread_data[i]); if (!filt->thread_data[i].thread) goto error; } #endif return filt; error: rarch_softfilter_free(filt); return NULL; }
void rarch_deinit_filter(void) { rarch_softfilter_free(g_extern.filter.filter); free(g_extern.filter.buffer); memset(&g_extern.filter, 0, sizeof(g_extern.filter)); }