From 3456ed0644e4f17b3da8b0a82e78467e846d15f1 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Thu, 18 Jul 2019 08:44:09 -0700 Subject: [PATCH] libobs: UI: Remove DrawBackdrop() to save fullscreen pass It's a waste of GPU time to do two fullscreen passes to render final mix previews. Use blend states to simulate the black background of DrawBackdrop() for the following situations: - Main preview window (Studio Mode off) - Studio Mode: Program This does not effect: - Studio Mode: Preview (still uses DrawBackdrop) - Fullscreen Projector (uses GPU clear to black) - Windowed Projector (uses GPU clear to black) intel GPA, SetStablePowerState, Intel HD Graphics 530, 1920x1080 Before: DrawBackdrop: ~529 us main texture: ~367 us (Cheaper than drawing a black quad?) After: [DrawBackdrop optimized away] main texture: ~383 us --- UI/window-basic-main-transitions.cpp | 4 +--- UI/window-basic-main.cpp | 7 ++++--- libobs/obs.c | 19 +++++++++++++++++-- libobs/obs.h | 3 +++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/UI/window-basic-main-transitions.cpp b/UI/window-basic-main-transitions.cpp index ec4b01177..a3ca9be42 100644 --- a/UI/window-basic-main-transitions.cpp +++ b/UI/window-basic-main-transitions.cpp @@ -1330,9 +1330,7 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy) gs_set_viewport(window->programX, window->programY, window->programCX, window->programCY); - window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height)); - - obs_render_main_texture(); + obs_render_main_texture_src_color_only(); gs_load_vertexbuffer(nullptr); /* --------------------------------------- */ diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 1f02f6f10..194635141 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -3341,15 +3341,16 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) gs_set_viewport(window->previewX, window->previewY, window->previewCX, window->previewCY); - window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height)); - if (window->IsPreviewProgramMode()) { + window->DrawBackdrop(float(ovi.base_width), + float(ovi.base_height)); + OBSScene scene = window->GetCurrentScene(); obs_source_t *source = obs_scene_get_source(scene); if (source) obs_source_video_render(source); } else { - obs_render_main_texture(); + obs_render_main_texture_src_color_only(); } gs_load_vertexbuffer(nullptr); diff --git a/libobs/obs.c b/libobs/obs.c index 6fe1a33c1..e3d084798 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -1645,7 +1645,10 @@ void obs_render_main_view(void) obs_view_render(&obs->data.main_view); } -void obs_render_main_texture(void) +static void obs_render_main_texture_internal(enum gs_blend_type src_c, + enum gs_blend_type dest_c, + enum gs_blend_type src_a, + enum gs_blend_type dest_a) { struct obs_core_video *video; gs_texture_t *tex; @@ -1665,7 +1668,7 @@ void obs_render_main_texture(void) gs_effect_set_texture(param, tex); gs_blend_state_push(); - gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + gs_blend_function_separate(src_c, dest_c, src_a, dest_a); while (gs_effect_loop(effect, "Draw")) gs_draw_sprite(tex, 0, 0, 0); @@ -1673,6 +1676,18 @@ void obs_render_main_texture(void) gs_blend_state_pop(); } +void obs_render_main_texture(void) +{ + obs_render_main_texture_internal(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); +} + +void obs_render_main_texture_src_color_only(void) +{ + obs_render_main_texture_internal(GS_BLEND_ONE, GS_BLEND_ZERO, + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); +} + gs_texture_t *obs_get_main_texture(void) { struct obs_core_video *video; diff --git a/libobs/obs.h b/libobs/obs.h index 58e862a0d..f2a065635 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -649,6 +649,9 @@ EXPORT void obs_render_main_view(void); /** Renders the last main output texture */ EXPORT void obs_render_main_texture(void); +/** Renders the last main output texture ignoring background color */ +EXPORT void obs_render_main_texture_src_color_only(void); + /** Returns the last main output texture. This can return NULL if the texture * is unavailable. */ EXPORT gs_texture_t *obs_get_main_texture(void);