libobs: Reuse matching mix's render texture if possible

Avoids re-rendering a view if a previous mix with identical settings
has already rendered it
This commit is contained in:
derrod
2023-11-28 14:42:06 +01:00
committed by Lain
parent 21a906d7d9
commit f5b7c98d2d
+44 -1
View File
@@ -129,6 +129,44 @@ static inline void unmap_last_surface(struct obs_core_video_mix *video)
}
}
static inline bool can_reuse_mix_texture(const struct obs_core_video_mix *mix,
size_t *idx)
{
for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) {
const struct obs_core_video_mix *other =
obs->video.mixes.array[i];
if (other == mix)
break;
if (other->view != mix->view)
continue;
if (other->render_space != mix->render_space)
continue;
if (other->ovi.base_width != mix->ovi.base_width ||
other->ovi.base_height != mix->ovi.base_height)
continue;
if (!other->texture_rendered)
continue;
*idx = i;
return true;
}
return false;
}
static inline void draw_mix_texture(const size_t mix_idx)
{
gs_texture_t *tex = obs->video.mixes.array[mix_idx]->render_texture;
gs_effect_t *effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
gs_eparam_t *param = gs_effect_get_param_by_name(effect, "image");
gs_effect_set_texture_srgb(param, tex);
gs_enable_framebuffer_srgb(true);
while (gs_effect_loop(effect, "Draw"))
gs_draw_sprite(tex, 0, 0, 0);
gs_enable_framebuffer_srgb(false);
}
static const char *render_main_texture_name = "render_main_texture";
static inline void render_main_texture(struct obs_core_video_mix *video)
{
@@ -158,7 +196,12 @@ static inline void render_main_texture(struct obs_core_video_mix *video)
pthread_mutex_unlock(&obs->data.draw_callbacks_mutex);
obs_view_render(video->view);
/* In some cases we can reuse a previous mix's texture and save re-rendering everything */
size_t reuse_idx;
if (can_reuse_mix_texture(video, &reuse_idx))
draw_mix_texture(reuse_idx);
else
obs_view_render(video->view);
video->texture_rendered = true;