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.
master
jpark37 2022-08-23 23:38:21 -07:00 committed by Jim
parent 0061d95483
commit f88300a613
1 changed files with 14 additions and 0 deletions

View File

@ -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;