Merge pull request #11342 from Ophidon/master

Variable BFI
This commit is contained in:
Autechre 2020-09-19 22:24:47 +02:00 committed by GitHub
commit 7b600d46ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 126 additions and 88 deletions

View File

@ -259,12 +259,13 @@
*/
#define DEFAULT_FRAME_DELAY 0
/* Inserts a black frame inbetween frames.
* Useful for 120 Hz monitors who want to play 60 Hz material with eliminated
* ghosting. video_refresh_rate should still be configured as if it
* is a 60 Hz monitor (divide refresh rate by 2).
/* Inserts black frame(s) inbetween frames.
* Useful for Higher Hz monitors (set to multiples of 60 Hz) who want to play 60 Hz
* material with eliminated ghosting. video_refresh_rate should still be configured
* as if it is a 60 Hz monitor (divide refresh rate by multiple of 60 Hz).
*/
#define DEFAULT_BLACK_FRAME_INSERTION false
#define DEFAULT_BLACK_FRAME_INSERTION 0
/* Uses a custom swap interval for VSync.
* Set this to effectively halve monitor refresh rate.

View File

@ -1466,7 +1466,6 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("video_vsync", &settings->bools.video_vsync, true, DEFAULT_VSYNC, false);
SETTING_BOOL("video_adaptive_vsync", &settings->bools.video_adaptive_vsync, true, DEFAULT_ADAPTIVE_VSYNC, false);
SETTING_BOOL("video_hard_sync", &settings->bools.video_hard_sync, true, DEFAULT_HARD_SYNC, false);
SETTING_BOOL("video_black_frame_insertion", &settings->bools.video_black_frame_insertion, true, DEFAULT_BLACK_FRAME_INSERTION, false);
SETTING_BOOL("video_disable_composition", &settings->bools.video_disable_composition, true, DEFAULT_DISABLE_COMPOSITION, false);
SETTING_BOOL("pause_nonactive", &settings->bools.pause_nonactive, true, DEFAULT_PAUSE_NONACTIVE, false);
SETTING_BOOL("video_gpu_screenshot", &settings->bools.video_gpu_screenshot, true, DEFAULT_GPU_SCREENSHOT, false);
@ -2008,6 +2007,7 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("core_updater_auto_backup_history_size", &settings->uints.core_updater_auto_backup_history_size, true, DEFAULT_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE, false);
SETTING_UINT("video_black_frame_insertion", &settings->uints.video_black_frame_insertion, true, DEFAULT_BLACK_FRAME_INSERTION, false);
*size = count;
return tmp;

View File

@ -269,6 +269,7 @@ typedef struct settings
unsigned ai_service_source_lang;
unsigned core_updater_auto_backup_history_size;
unsigned video_black_frame_insertion;
} uints;
struct
@ -447,7 +448,6 @@ typedef struct settings
bool video_vsync;
bool video_adaptive_vsync;
bool video_hard_sync;
bool video_black_frame_insertion;
bool video_vfilter;
bool video_smooth;
bool video_ctx_scaling;

View File

@ -1600,7 +1600,7 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use,
bool video_window_save_positions = settings->bools.video_window_save_positions;
float video_refresh = settings->floats.video_refresh_rate;
unsigned swap_interval = settings->uints.video_swap_interval;
bool bfi = settings->bools.video_black_frame_insertion;
unsigned bfi = settings->uints.video_black_frame_insertion;
unsigned window_position_x = settings->uints.window_position_x;
unsigned window_position_y = settings->uints.window_position_y;
unsigned window_position_width = settings->uints.window_position_width;
@ -1610,9 +1610,9 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use,
{
/* Windows only reports the refresh rates for modelines as
* an integer, so video_refresh_rate needs to be rounded. Also, account
* for black frame insertion using video_refresh_rate set to half
* for black frame insertion using video_refresh_rate set to a portion
* of the display refresh rate, as well as higher vsync swap intervals. */
float refresh_mod = bfi ? 2.0f : 1.0f;
float refresh_mod = bfi + 1.0f;
unsigned refresh = roundf(video_refresh * refresh_mod
* swap_interval);

View File

@ -268,7 +268,7 @@ static bool get_video_mode(
float minimum_fps_diff = 0.0f;
XF86VidModeModeInfo **modes = NULL;
settings_t *settings = config_get_ptr();
bool black_frame_insertion = settings->bools.video_black_frame_insertion;
unsigned black_frame_insertion = settings->uints.video_black_frame_insertion;
float video_refresh_rate = settings->floats.video_refresh_rate;
XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &num_modes, &modes);
@ -283,7 +283,7 @@ static bool get_video_mode(
/* If we use black frame insertion, we fake a 60 Hz monitor
* for 120 Hz one, etc, so try to match that. */
refresh_mod = black_frame_insertion ? 0.5f : 1.0f;
refresh_mod = 1.0f / (black_frame_insertion + 1.0f);
for (i = 0; i < num_modes; i++)
{

View File

@ -1497,7 +1497,7 @@ static bool d3d8_frame(void *data, const void *frame,
&video_info->osd_stat_params;
const char *stat_text = video_info->stat_text;
bool statistics_show = video_info->statistics_show;
bool black_frame_insertion = video_info->black_frame_insertion;
unsigned black_frame_insertion = video_info->black_frame_insertion;
#ifdef HAVE_MENU
bool menu_is_alive = video_info->menu_is_alive;
#endif
@ -1538,14 +1538,6 @@ static bool d3d8_frame(void *data, const void *frame,
d3d8_set_viewports(d3d->dev, &screen_vp);
d3d8_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0);
/* Insert black frame first, so we
* can screenshot, etc. */
if (black_frame_insertion)
{
if (!d3d8_swap(d3d, d3d->dev) || d3d->needs_restore)
return true;
d3d8_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0);
}
if (!d3d8_renderchain_render(
d3d,
@ -1556,6 +1548,17 @@ static bool d3d8_frame(void *data, const void *frame,
return false;
}
if (black_frame_insertion && !d3d->menu->enabled)
{
unsigned n;
for (n = 0; n < video_info->black_frame_insertion; ++n)
{
if (!d3d8_swap(d3d, d3d->dev) || d3d->needs_restore)
return true;
d3d8_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0);
}
}
#ifdef HAVE_MENU
if (d3d->menu && d3d->menu->enabled)
{

View File

@ -1532,7 +1532,7 @@ static bool d3d9_frame(void *data, const void *frame,
unsigned width = video_info->width;
unsigned height = video_info->height;
bool statistics_show = video_info->statistics_show;
bool black_frame_insertion = video_info->black_frame_insertion;
unsigned black_frame_insertion = video_info->black_frame_insertion;
struct font_params *osd_params = (struct font_params*)
&video_info->osd_stat_params;
const char *stat_text = video_info->stat_text;
@ -1581,15 +1581,6 @@ static bool d3d9_frame(void *data, const void *frame,
d3d9_set_viewports(d3d->dev, &screen_vp);
d3d9_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0);
/* Insert black frame first, so we
* can screenshot, etc. */
if (black_frame_insertion)
{
if (!d3d9_swap(d3d, d3d->dev) || d3d->needs_restore)
return true;
d3d9_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0);
}
if (!d3d->renderchain_driver->render(
d3d, frame, frame_width, frame_height,
pitch, d3d->dev_rotation))
@ -1597,6 +1588,17 @@ static bool d3d9_frame(void *data, const void *frame,
RARCH_ERR("[D3D9]: Failed to render scene.\n");
return false;
}
if (black_frame_insertion && !d3d->menu->enabled)
{
unsigned n;
for (n = 0; n < video_info->black_frame_insertion; ++n)
{
if (!d3d9_swap(d3d, d3d->dev) || d3d->needs_restore)
return true;
d3d9_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0);
}
}
#ifdef HAVE_MENU
if (d3d->menu && d3d->menu->enabled)

View File

@ -2808,6 +2808,7 @@ static bool gl2_frame(void *data, const void *frame,
bool use_rgba = video_info->use_rgba;
bool statistics_show = video_info->statistics_show;
bool msg_bgcolor_enable = video_info->msg_bgcolor_enable;
unsigned black_frame_insertion = video_info->black_frame_insertion;
bool input_driver_nonblock_state = video_info->input_driver_nonblock_state;
bool hard_sync = video_info->hard_sync;
unsigned hard_sync_frames = video_info->hard_sync_frames;
@ -2823,7 +2824,6 @@ static bool gl2_frame(void *data, const void *frame,
#ifndef EMSCRIPTEN
bool runloop_is_slowmotion = video_info->runloop_is_slowmotion;
bool runloop_is_paused = video_info->runloop_is_paused;
bool black_frame_insertion = video_info->black_frame_insertion;
#endif
if (!gl)
@ -3088,24 +3088,31 @@ static bool gl2_frame(void *data, const void *frame,
#endif
gl2_pbo_async_readback(gl);
/* Emscripten has to do black frame insertion in its main loop */
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
/* Emscripten has to do black frame insertion in its main loop */
#ifndef EMSCRIPTEN
/* Disable BFI during fast forward, slow-motion,
* and pause to prevent flicker. */
if (
if (
black_frame_insertion
&& !input_driver_nonblock_state
&& !runloop_is_slowmotion
&& !runloop_is_paused)
{
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
glClear(GL_COLOR_BUFFER_BIT);
}
#endif
&& !runloop_is_paused
&& !gl->menu_texture_enable)
{
unsigned n;
for (n = 0; n < black_frame_insertion; ++n)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
}
}
#endif
/* check if we are fast forwarding or in menu,
* if we are ignore hard sync */

View File

@ -899,7 +899,11 @@ static bool gl1_gfx_frame(void *data, const void *frame,
4, GL_RGBA, GL_UNSIGNED_BYTE,
gl1->readback_buffer_screenshot);
/* Emscripten has to do black frame insertion in its main loop */
if (gl1->ctx_driver->swap_buffers)
gl1->ctx_driver->swap_buffers(gl1->ctx_data);
/* Emscripten has to do black frame insertion in its main loop */
#ifndef EMSCRIPTEN
/* Disable BFI during fast forward, slow-motion,
* and pause to prevent flicker. */
@ -907,16 +911,21 @@ static bool gl1_gfx_frame(void *data, const void *frame,
video_info->black_frame_insertion
&& !video_info->input_driver_nonblock_state
&& !video_info->runloop_is_slowmotion
&& !video_info->runloop_is_paused)
&& !video_info->runloop_is_paused
&& !gl1->menu_texture_enable)
{
if (gl1->ctx_driver->swap_buffers)
gl1->ctx_driver->swap_buffers(gl1->ctx_data);
glClear(GL_COLOR_BUFFER_BIT);
}
#endif
if (gl1->ctx_driver->swap_buffers)
gl1->ctx_driver->swap_buffers(gl1->ctx_data);
unsigned n;
for (n = 0; n < video_info->black_frame_insertion; ++n)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (gl1->ctx_driver->swap_buffers)
gl1->ctx_driver->swap_buffers(gl1->ctx_data);
}
}
#endif
/* check if we are fast forwarding or in menu, if we are ignore hard sync */
if (hard_sync

View File

@ -1853,7 +1853,8 @@ static bool gl_core_frame(void *data, const void *frame,
const char *stat_text = video_info->stat_text;
bool statistics_show = video_info->statistics_show;
bool msg_bgcolor_enable = video_info->msg_bgcolor_enable;
bool black_frame_insertion = video_info->black_frame_insertion;
unsigned black_frame_insertion = video_info->black_frame_insertion;
unsigned hard_sync_frames = video_info->hard_sync_frames;
bool runloop_is_paused = video_info->runloop_is_paused;
bool runloop_is_slowmotion = video_info->runloop_is_slowmotion;
@ -1989,22 +1990,33 @@ static bool gl_core_frame(void *data, const void *frame,
gl_core_pbo_async_readback(gl);
}
/* Disable BFI during fast forward, slow-motion,
* and pause to prevent flicker. */
if (
black_frame_insertion
&& !input_driver_nonblock_state
&& !runloop_is_slowmotion
&& !runloop_is_paused)
{
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
glClear(GL_COLOR_BUFFER_BIT);
}
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
/* Emscripten has to do black frame insertion in its main loop */
#ifndef EMSCRIPTEN
/* Disable BFI during fast forward, slow-motion,
* and pause to prevent flicker. */
if (
black_frame_insertion
&& !input_driver_nonblock_state
&& !runloop_is_slowmotion
&& !runloop_is_paused
&& !gl->menu_texture_enable)
{
unsigned n;
for (n = 0; n < black_frame_insertion; ++n)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (gl->ctx_driver->swap_buffers)
gl->ctx_driver->swap_buffers(gl->ctx_data);
}
}
#endif
if (hard_sync &&
!input_driver_nonblock_state &&
!gl->menu_texture_enable)

View File

@ -1724,7 +1724,7 @@ static bool vulkan_frame(void *data, const void *frame,
unsigned height = video_info->height;
bool statistics_show = video_info->statistics_show;
const char *stat_text = video_info->stat_text;
bool black_frame_insertion = video_info->black_frame_insertion;
unsigned black_frame_insertion = video_info->black_frame_insertion;
bool input_driver_nonblock_state = video_info->input_driver_nonblock_state;
bool runloop_is_slowmotion = video_info->runloop_is_slowmotion;
bool runloop_is_paused = video_info->runloop_is_paused;
@ -2258,18 +2258,25 @@ static bool vulkan_frame(void *data, const void *frame,
vk->should_resize = false;
}
vulkan_check_swapchain(vk);
vulkan_check_swapchain(vk);
/* Disable BFI during fast forward, slow-motion,
* and pause to prevent flicker. */
if (
backbuffer->image != VK_NULL_HANDLE
backbuffer->image != VK_NULL_HANDLE
&& vk->context->has_acquired_swapchain
&& black_frame_insertion
&& !input_driver_nonblock_state
&& !runloop_is_slowmotion
&& !runloop_is_paused)
vulkan_inject_black_frame(vk, video_info, vk->ctx_data);
&& !runloop_is_paused
&& !vk->menu.enable)
{
unsigned n;
for (n = 0; n < black_frame_insertion; ++n)
{
vulkan_inject_black_frame(vk, video_info, vk->ctx_data);
}
}
/* Vulkan doesn't directly support swap_interval > 1,
* so we fake it by duping out more frames. */

View File

@ -620,7 +620,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data,
struct drm_fb *fb = NULL;
gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data;
settings_t *settings = config_get_ptr();
bool black_frame_insertion = settings->bools.video_black_frame_insertion;
unsigned black_frame_insertion = settings->uints.video_black_frame_insertion;
float video_refresh_rate = settings->floats.video_refresh_rate;
if (!drm)
@ -631,8 +631,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data,
/* If we use black frame insertion,
* we fake a 60 Hz monitor for 120 Hz one,
* etc, so try to match that. */
refresh_mod = black_frame_insertion
? 0.5f : 1.0f;
refresh_mod = 1.0f / (black_frame_insertion + 1.0f);
/* Find desired video mode, and use that.
* If not fullscreen, we get desired windowed size,

View File

@ -5673,7 +5673,7 @@ unsigned menu_displaylist_build_list(
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION,
PARSE_ONLY_BOOL, false) == 0)
PARSE_ONLY_UINT, false) == 0)
count++;
#ifdef HAVE_SCREENSHOTS
if (video_driver_supports_viewport_read())

View File

@ -10835,23 +10835,21 @@ static bool setting_append_list(
#if !defined(RARCH_MOBILE)
if (video_driver_test_all_flags(GFX_CTX_FLAGS_BLACK_FRAME_INSERTION))
{
CONFIG_BOOL(
CONFIG_UINT(
list, list_info,
&settings->bools.video_black_frame_insertion,
&settings->uints.video_black_frame_insertion,
MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION,
MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION,
DEFAULT_BLACK_FRAME_INSERTION,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE
);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_LAKKA_ADVANCED);
}
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
menu_settings_list_current_add_range(list, list_info, 0, 5, 1, true, true);
}
#endif
END_SUB_GROUP(list, list_info, parent_group);
START_SUB_GROUP(

View File

@ -17842,7 +17842,7 @@ void emscripten_mainloop(void)
static unsigned emscripten_frame_count = 0;
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
bool black_frame_insertion = settings->bools.video_black_frame_insertion;
bool black_frame_insertion = settings->uints.video_black_frame_insertion;
bool input_driver_nonblock_state = p_rarch->input_driver_nonblock_state;
bool runloop_is_slowmotion = p_rarch->runloop_slowmotion;
bool runloop_is_paused = p_rarch->runloop_paused;
@ -17859,7 +17859,7 @@ void emscripten_mainloop(void)
&& !runloop_is_slowmotion
&& !runloop_is_paused)
{
if ((emscripten_frame_count & 1) == 0)
if ((emscripten_frame_count % (black_frame_insertion+1)) != 0)
{
glClear(GL_COLOR_BUFFER_BIT);
if (p_rarch->current_video_context.swap_buffers)
@ -33869,7 +33869,7 @@ void video_driver_build_info(video_frame_info_t *video_info)
video_info->crt_switch_resolution_super = settings->uints.crt_switch_resolution_super;
video_info->crt_switch_center_adjust = settings->ints.crt_switch_center_adjust;
video_info->crt_switch_porch_adjust = settings->ints.crt_switch_porch_adjust;
video_info->black_frame_insertion = settings->bools.video_black_frame_insertion;
video_info->black_frame_insertion = settings->uints.video_black_frame_insertion;
video_info->hard_sync = settings->bools.video_hard_sync;
video_info->hard_sync_frames = settings->uints.video_hard_sync_frames;
video_info->fps_show = settings->bools.video_fps_show;
@ -39740,7 +39740,7 @@ static enum runloop_state runloop_check_state(
if (p_rarch->runloop_slowmotion)
{
if (settings->bools.video_black_frame_insertion)
if (settings->uints.video_black_frame_insertion)
if (!p_rarch->runloop_idle)
video_driver_cached_frame();

View File

@ -1137,6 +1137,7 @@ typedef struct video_frame_info
unsigned custom_vp_height;
unsigned custom_vp_full_width;
unsigned custom_vp_full_height;
unsigned black_frame_insertion;
float menu_wallpaper_opacity;
float menu_framebuffer_opacity;
@ -1178,7 +1179,6 @@ typedef struct video_frame_info
bool widgets_is_rewinding;
bool input_menu_swap_ok_cancel_buttons;
bool input_driver_nonblock_state;
bool black_frame_insertion;
bool hard_sync;
bool fps_show;
bool memory_show;