From ade65df2aa4bb176f2613584b3d3c77b51dbdf26 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Thu, 10 Oct 2019 21:06:01 -0700 Subject: [PATCH] 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. --- libobs-d3d11/d3d11-subsystem.cpp | 13 ++++++++++--- libobs-opengl/gl-subsystem.c | 6 ++++++ libobs/graphics/device-exports.h | 1 + libobs/graphics/graphics-imports.c | 1 + libobs/graphics/graphics-internal.h | 1 + libobs/graphics/graphics.c | 10 ++++++++++ libobs/graphics/graphics.h | 1 + libobs/obs-video.c | 4 ++++ 8 files changed, 34 insertions(+), 3 deletions(-) diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index 5ff3d5fac..17756ab32 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/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) diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index e9c986fb0..cc2bc1722 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/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); diff --git a/libobs/graphics/device-exports.h b/libobs/graphics/device-exports.h index 1f03a5da6..566774e47 100644 --- a/libobs/graphics/device-exports.h +++ b/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); diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index 10a42b566..424c06c90 100644 --- a/libobs/graphics/graphics-imports.c +++ b/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); diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index e527e1e61..bc3fd0182 100644 --- a/libobs/graphics/graphics-internal.h +++ b/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); diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 9e77cc393..e36129f12 100644 --- a/libobs/graphics/graphics.c +++ b/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; diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 14245dd4e..51b2bd28d 100644 --- a/libobs/graphics/graphics.h +++ b/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); diff --git a/libobs/obs-video.c b/libobs/obs-video.c index 0bd84fc34..4b82aa366 100644 --- a/libobs/obs-video.c +++ b/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);