Browse Source

libobs: Add gs_begin_frame for duplicators

We really shouldn't be resetting duplicator state as part of gs_flush.
gs_begin_scene is not ideal because it is called twice per frame, and
only after duplicators have been ticked. Even though it makes no
user-facing difference, it makes more logical sense to reset at the top
of the frame than the bottom.
jpark37 6 years ago
parent
commit
ade65df2aa

+ 10 - 3
libobs-d3d11/d3d11-subsystem.cpp

@@ -1631,6 +1631,16 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst,
 	}
 }
 
+extern "C" void reset_duplicators(void);
+
+void device_begin_frame(gs_device_t *device)
+{
+	/* does nothing in D3D11 */
+	UNUSED_PARAMETER(device);
+
+	reset_duplicators();
+}
+
 void device_begin_scene(gs_device_t *device)
 {
 	clear_textures(device);
@@ -1761,12 +1771,9 @@ void device_present(gs_device_t *device)
 	}
 }
 
-extern "C" void reset_duplicators(void);
-
 void device_flush(gs_device_t *device)
 {
 	device->context->Flush();
-	reset_duplicators();
 }
 
 void device_set_cull_mode(gs_device_t *device, enum gs_cull_mode mode)

+ 6 - 0
libobs-opengl/gl-subsystem.c

@@ -929,6 +929,12 @@ void device_copy_texture(gs_device_t *device, gs_texture_t *dst,
 	device_copy_texture_region(device, dst, 0, 0, src, 0, 0, 0, 0);
 }
 
+void device_begin_frame(gs_device_t *device)
+{
+	/* does nothing */
+	UNUSED_PARAMETER(device);
+}
+
 void device_begin_scene(gs_device_t *device)
 {
 	clear_textures(device);

+ 1 - 0
libobs/graphics/device-exports.h

@@ -113,6 +113,7 @@ EXPORT void device_copy_texture_region(gs_device_t *device, gs_texture_t *dst,
 				       uint32_t src_h);
 EXPORT void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst,
 				 gs_texture_t *src);
+EXPORT void device_begin_frame(gs_device_t *device);
 EXPORT void device_begin_scene(gs_device_t *device);
 EXPORT void device_draw(gs_device_t *device, enum gs_draw_mode draw_mode,
 			uint32_t start_vert, uint32_t num_verts);

+ 1 - 0
libobs/graphics/graphics-imports.c

@@ -85,6 +85,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
 	GRAPHICS_IMPORT(device_copy_texture_region);
 	GRAPHICS_IMPORT(device_copy_texture);
 	GRAPHICS_IMPORT(device_stage_texture);
+	GRAPHICS_IMPORT(device_begin_frame);
 	GRAPHICS_IMPORT(device_begin_scene);
 	GRAPHICS_IMPORT(device_draw);
 	GRAPHICS_IMPORT(device_load_swapchain);

+ 1 - 0
libobs/graphics/graphics-internal.h

@@ -115,6 +115,7 @@ struct gs_exports {
 					   uint32_t src_w, uint32_t src_h);
 	void (*device_stage_texture)(gs_device_t *device, gs_stagesurf_t *dst,
 				     gs_texture_t *src);
+	void (*device_begin_frame)(gs_device_t *device);
 	void (*device_begin_scene)(gs_device_t *device);
 	void (*device_draw)(gs_device_t *device, enum gs_draw_mode draw_mode,
 			    uint32_t start_vert, uint32_t num_verts);

+ 10 - 0
libobs/graphics/graphics.c

@@ -1737,6 +1737,16 @@ void gs_stage_texture(gs_stagesurf_t *dst, gs_texture_t *src)
 	graphics->exports.device_stage_texture(graphics->device, dst, src);
 }
 
+void gs_begin_frame(void)
+{
+	graphics_t *graphics = thread_graphics;
+
+	if (!gs_valid("gs_begin_frame"))
+		return;
+
+	graphics->exports.device_begin_frame(graphics->device);
+}
+
 void gs_begin_scene(void)
 {
 	graphics_t *graphics = thread_graphics;

+ 1 - 0
libobs/graphics/graphics.h

@@ -668,6 +668,7 @@ EXPORT void gs_copy_texture_region(gs_texture_t *dst, uint32_t dst_x,
 				   uint32_t src_w, uint32_t src_h);
 EXPORT void gs_stage_texture(gs_stagesurf_t *dst, gs_texture_t *src);
 
+EXPORT void gs_begin_frame(void);
 EXPORT void gs_begin_scene(void);
 EXPORT void gs_draw(enum gs_draw_mode draw_mode, uint32_t start_vert,
 		    uint32_t num_verts);

+ 4 - 0
libobs/obs-video.c

@@ -866,6 +866,10 @@ void *obs_graphics_thread(void *param)
 
 		profile_start(video_thread_name);
 
+		gs_enter_context(obs->video.graphics);
+		gs_begin_frame();
+		gs_leave_context();
+
 		profile_start(tick_sources_name);
 		last_time = tick_sources(obs->video.video_time, last_time);
 		profile_end(tick_sources_name);