Procházet zdrojové kódy

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.
jpark37 před 3 roky
rodič
revize
f88300a613
1 změnil soubory, kde provedl 14 přidání a 0 odebrání
  1. 14 0
      libobs/obs-display.c

+ 14 - 0
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;