mirror of
https://github.com/libretro/RetroArch.git
synced 2024-10-08 07:03:30 +00:00
Reimplement driver.*_data_own variables so that they actually
work for a usecase now - on Xbox, full teardown/re-initing of D3D context seems to be error-prone - so by flagging driver.video_data_own to true inside of the video_init function, we signal later on to the uninit_drivers function that we DO NOT want to call the free function of this driver and clean up the handle. Instead, this driver should properly retain the handle by returning the pre-existing handle when (for example) driver.video_data is not NULL. You can see an example of this in xdk/xdk_d3d.cpp. Overall still a quite clean solution and we will only use this in extraordinary conditions (like this Xbox one I suppose) - full teardown/setup will be the goal for all other platforms where we can be certain that the state can be brought down and up entirely during runtime without any problems.
This commit is contained in:
parent
346701fce8
commit
a97b53f9f1
172
driver.c
172
driver.c
@ -503,17 +503,17 @@ bool driver_update_system_av_info(const struct retro_system_av_info *info)
|
||||
|
||||
void init_drivers(void)
|
||||
{
|
||||
driver.video_data_own = !driver.video_data;
|
||||
driver.audio_data_own = !driver.audio_data;
|
||||
driver.input_data_own = !driver.input_data;
|
||||
driver.video_data_own = false;
|
||||
driver.audio_data_own = false;
|
||||
driver.input_data_own = false;
|
||||
#ifdef HAVE_CAMERA
|
||||
driver.camera_data_own = !driver.camera_data;
|
||||
driver.camera_data_own = false;
|
||||
#endif
|
||||
#ifdef HAVE_LOCATION
|
||||
driver.location_data_own = !driver.location_data;
|
||||
driver.location_data_own = false;
|
||||
#endif
|
||||
#ifdef HAVE_OSK
|
||||
driver.osk_data_own = !driver.osk_data;
|
||||
driver.osk_data_own = false;
|
||||
#endif
|
||||
|
||||
adjust_system_rates();
|
||||
@ -550,6 +550,64 @@ void init_drivers(void)
|
||||
g_extern.system.frame_time_last = 0;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
static void deinit_pixel_converter(void)
|
||||
{
|
||||
scaler_ctx_gen_reset(&driver.scaler);
|
||||
memset(&driver.scaler, 0, sizeof(driver.scaler));
|
||||
free(driver.scaler_out);
|
||||
driver.scaler_out = NULL;
|
||||
}
|
||||
|
||||
static void deinit_shader_dir(void)
|
||||
{
|
||||
// It handles NULL, no worries :D
|
||||
dir_list_free(g_extern.shader_dir.list);
|
||||
g_extern.shader_dir.list = NULL;
|
||||
g_extern.shader_dir.ptr = 0;
|
||||
}
|
||||
|
||||
static void compute_monitor_fps_statistics(void)
|
||||
{
|
||||
if (g_settings.video.threaded)
|
||||
{
|
||||
RARCH_LOG("Monitor FPS estimation is disabled for threaded video.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_extern.measure_data.frame_time_samples_count < 2 * MEASURE_FRAME_TIME_SAMPLES_COUNT)
|
||||
{
|
||||
RARCH_LOG("Does not have enough samples for monitor refresh rate estimation. Requires to run for at least %u frames.\n",
|
||||
2 * MEASURE_FRAME_TIME_SAMPLES_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
double avg_fps = 0.0;
|
||||
double stddev = 0.0;
|
||||
unsigned samples = 0;
|
||||
if (driver_monitor_fps_statistics(&avg_fps, &stddev, &samples))
|
||||
{
|
||||
RARCH_LOG("Average monitor Hz: %.6f Hz. (%.3f %% frame time deviation, based on %u last samples).\n",
|
||||
avg_fps, 100.0 * stddev, samples);
|
||||
}
|
||||
}
|
||||
|
||||
static void uninit_video_misc(void)
|
||||
{
|
||||
deinit_pixel_converter();
|
||||
|
||||
rarch_deinit_filter();
|
||||
|
||||
deinit_shader_dir();
|
||||
compute_monitor_fps_statistics();
|
||||
}
|
||||
|
||||
void uninit_drivers(void)
|
||||
{
|
||||
uninit_audio();
|
||||
@ -557,44 +615,41 @@ void uninit_drivers(void)
|
||||
if (g_extern.system.hw_render_callback.context_destroy && !driver.video_cache_context)
|
||||
g_extern.system.hw_render_callback.context_destroy();
|
||||
|
||||
#ifndef _XBOX
|
||||
uninit_video_input();
|
||||
#endif
|
||||
uninit_video_misc();
|
||||
|
||||
if (!driver.video_data_own)
|
||||
driver.video_data = NULL;
|
||||
|
||||
#ifdef HAVE_CAMERA
|
||||
uninit_camera();
|
||||
|
||||
if (driver.camera_data_own)
|
||||
if (!driver.camera_data_own)
|
||||
{
|
||||
uninit_camera();
|
||||
driver.camera_data = NULL;
|
||||
driver.camera_data_own = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOCATION
|
||||
uninit_location();
|
||||
|
||||
if (driver.location_data_own)
|
||||
if (!driver.location_data_own)
|
||||
{
|
||||
uninit_location();
|
||||
driver.location_data = NULL;
|
||||
driver.location_data_own = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OSK
|
||||
uninit_osk();
|
||||
|
||||
if (driver.osk_data_own)
|
||||
if (!driver.osk_data_own)
|
||||
{
|
||||
uninit_osk();
|
||||
driver.osk_data = NULL;
|
||||
driver.osk_data_own = false;
|
||||
}
|
||||
#endif
|
||||
#ifndef _XBOX
|
||||
if (driver.video_data_own)
|
||||
driver.video_data = NULL;
|
||||
driver.video_data_own = false;
|
||||
if (driver.input_data_own)
|
||||
|
||||
if (!driver.input_data_own)
|
||||
driver.input_data = NULL;
|
||||
driver.input_data_own = false;
|
||||
#endif
|
||||
if (driver.audio_data_own)
|
||||
|
||||
if (!driver.audio_data_own)
|
||||
driver.audio_data = NULL;
|
||||
driver.audio_data_own = false;
|
||||
}
|
||||
|
||||
void rarch_init_dsp_filter(void)
|
||||
@ -803,31 +858,6 @@ bool driver_monitor_fps_statistics(double *refresh_rate, double *deviation, unsi
|
||||
return true;
|
||||
}
|
||||
|
||||
static void compute_monitor_fps_statistics(void)
|
||||
{
|
||||
if (g_settings.video.threaded)
|
||||
{
|
||||
RARCH_LOG("Monitor FPS estimation is disabled for threaded video.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_extern.measure_data.frame_time_samples_count < 2 * MEASURE_FRAME_TIME_SAMPLES_COUNT)
|
||||
{
|
||||
RARCH_LOG("Does not have enough samples for monitor refresh rate estimation. Requires to run for at least %u frames.\n",
|
||||
2 * MEASURE_FRAME_TIME_SAMPLES_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
double avg_fps = 0.0;
|
||||
double stddev = 0.0;
|
||||
unsigned samples = 0;
|
||||
if (driver_monitor_fps_statistics(&avg_fps, &stddev, &samples))
|
||||
{
|
||||
RARCH_LOG("Average monitor Hz: %.6f Hz. (%.3f %% frame time deviation, based on %u last samples).\n",
|
||||
avg_fps, 100.0 * stddev, samples);
|
||||
}
|
||||
}
|
||||
|
||||
void uninit_audio(void)
|
||||
{
|
||||
if (driver.audio_data && driver.audio)
|
||||
@ -859,13 +889,6 @@ void uninit_audio(void)
|
||||
compute_audio_buffer_statistics();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void rarch_init_filter(enum retro_pixel_format colfmt)
|
||||
{
|
||||
rarch_deinit_filter();
|
||||
@ -932,14 +955,6 @@ error:
|
||||
rarch_deinit_filter();
|
||||
}
|
||||
|
||||
static void deinit_shader_dir(void)
|
||||
{
|
||||
// It handles NULL, no worries :D
|
||||
dir_list_free(g_extern.shader_dir.list);
|
||||
g_extern.shader_dir.list = NULL;
|
||||
g_extern.shader_dir.ptr = 0;
|
||||
}
|
||||
|
||||
static void init_shader_dir(void)
|
||||
{
|
||||
unsigned i;
|
||||
@ -960,14 +975,6 @@ static void init_shader_dir(void)
|
||||
RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.list->elems[i].data);
|
||||
}
|
||||
|
||||
static void deinit_pixel_converter(void)
|
||||
{
|
||||
scaler_ctx_gen_reset(&driver.scaler);
|
||||
memset(&driver.scaler, 0, sizeof(driver.scaler));
|
||||
free(driver.scaler_out);
|
||||
driver.scaler_out = NULL;
|
||||
}
|
||||
|
||||
static bool init_video_pixel_converter(unsigned size)
|
||||
{
|
||||
// This function can be called multiple times without deiniting first on consoles.
|
||||
@ -1168,18 +1175,11 @@ void uninit_video_input(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (driver.input_data != driver.video_data && driver.input && driver.input->free)
|
||||
if (!driver.input_data_own && driver.input_data != driver.video_data && driver.input && driver.input->free)
|
||||
input_free_func();
|
||||
|
||||
if (driver.video_data && driver.video && driver.video->free)
|
||||
if (!driver.video_data_own && driver.video_data && driver.video && driver.video->free)
|
||||
video_free_func();
|
||||
|
||||
deinit_pixel_converter();
|
||||
|
||||
rarch_deinit_filter();
|
||||
|
||||
deinit_shader_dir();
|
||||
compute_monitor_fps_statistics();
|
||||
}
|
||||
|
||||
driver_t driver;
|
||||
|
16
driver.h
16
driver.h
@ -484,13 +484,15 @@ typedef struct driver
|
||||
bool video_cache_context;
|
||||
bool video_cache_context_ack; // Set to true by driver if context caching succeeded.
|
||||
|
||||
// Set if the respective handles are owned by RetroArch driver core.
|
||||
// Consoles upper logic will generally intialize the drivers before
|
||||
// the driver core initializes. It will then be up to upper logic
|
||||
// to finally free() up the driver handles.
|
||||
// Driver core will still call init() and free(), but in this case
|
||||
// these calls should be seen as "reinit() + ref_count++" and "ref_count--"
|
||||
// respectively.
|
||||
// Set this to true if the platform in question needs to 'own' the respective
|
||||
// handle and therefore skip regular RetroArch driver teardown/reiniting procedure.
|
||||
// If set to true, the 'free' function will get skipped. It is then up to the
|
||||
// driver implementation to properly handle 'reiniting' inside the 'init' function
|
||||
// and make sure it returns the existing handle instead of allocating and returning
|
||||
// a pointer to a new handle.
|
||||
//
|
||||
// Typically, if a driver intends to make use of this, it should set this to true
|
||||
// at the end of its 'init' function.
|
||||
bool video_data_own;
|
||||
bool audio_data_own;
|
||||
bool input_data_own;
|
||||
|
@ -461,6 +461,14 @@ static void *d3d_init(const video_info_t *vid, const input_driver_t **input, voi
|
||||
d3d_video_t *d3d = (d3d_video_t*)driver.video_data;
|
||||
// Reinitialize textures as we might have changed pixel formats.
|
||||
d3d_reinit_textures(d3d, vid);
|
||||
if (input && input_data)
|
||||
{
|
||||
*input = driver.input;
|
||||
*input_data = driver.input_data;
|
||||
}
|
||||
|
||||
driver.video_data_own = true;
|
||||
driver.input_data_own = true;
|
||||
return driver.video_data;
|
||||
}
|
||||
|
||||
@ -491,6 +499,11 @@ static void *d3d_init(const video_info_t *vid, const input_driver_t **input, voi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
driver.video_data_own = true;
|
||||
driver.input_data_own = true;
|
||||
#endif
|
||||
|
||||
return d3d;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user