From f88300a613b4119664c841effa6bb10aee631054 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Tue, 23 Aug 2022 23:38:21 -0700 Subject: [PATCH] libobs: Emulate clear with draw for displays Laptops that render OBS displays on NVIDIA, and display through Intel have been seen flickering, and we think the driver is not properly handling swap chain buffers that have been cleared but not drawn to. To work around this, we use a draw to simulate a render target clear. This is not as efficient, so hopefully NVIDIA will fix this soon. --- libobs/obs-display.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libobs/obs-display.c b/libobs/obs-display.c index 60aff7378..74653f3c3 100644 --- a/libobs/obs-display.c +++ b/libobs/obs-display.c @@ -166,6 +166,9 @@ void obs_display_remove_draw_callback(obs_display_t *display, pthread_mutex_unlock(&display->draw_callbacks_mutex); } +/* NVIDIA clear can sometimes cause flickering */ +#define NVIDIA_BROKEN_CLEAR 1 + static inline bool render_display_begin(struct obs_display *display, uint32_t cx, uint32_t cy, bool update_color_space) @@ -193,8 +196,10 @@ static inline bool render_display_begin(struct obs_display *display, display->background_color); clear_color.w = 1.0f; +#if !NVIDIA_BROKEN_CLEAR gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH | GS_CLEAR_STENCIL, &clear_color, 1.0f, 0); +#endif gs_enable_depth_test(false); /* gs_enable_blending(false); */ @@ -202,6 +207,15 @@ static inline bool render_display_begin(struct obs_display *display, gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f); gs_set_viewport(0, 0, cx, cy); + +#if NVIDIA_BROKEN_CLEAR + gs_effect_t *const solid_effect = obs->video.solid_effect; + gs_effect_set_vec4(gs_effect_get_param_by_name(solid_effect, + "color"), + &clear_color); + while (gs_effect_loop(solid_effect, "Solid")) + gs_draw_sprite(NULL, 0, cx, cy); +#endif } return success;