libobs: Plumb texcoord hint to reduce GPU cost

In order to do linear-correct filtering cheaply when scale filtering is
disabled, we need to know whether or not texture coordinates will always
sample from texel centers. This can be computed at the scene item level
relatively easily, and passed along to sources when rendering. Scene
items will use obs_source_set_texcoords_centered to set hint status, and
sources will use obs_source_get_texcoords_centered to retrieve it.
master
jpark37 2021-07-06 22:03:45 -07:00
parent da3375d5a4
commit 7c72fd1d4c
5 changed files with 48 additions and 0 deletions

View File

@ -847,6 +847,14 @@ General Source Functions
---------------------
.. function:: bool obs_source_get_texcoords_centered(obs_source_t *source)
Hints whether or not the source will blend texels.
:return: Whether or not the source will blend texels
---------------------
.. function:: obs_data_t *obs_source_get_settings(const obs_source_t *source)
:return: The settings string for a source. The reference counter of the

View File

@ -630,6 +630,9 @@ struct obs_source {
/* used to temporarily disable sources if needed */
bool enabled;
/* hint to allow sources to render more quickly */
bool texcoords_centered;
/* timing (if video is present, is based upon video) */
volatile bool timing_set;
volatile uint64_t timing_adjust;
@ -847,6 +850,8 @@ convert_video_format(enum video_format format)
}
}
extern void obs_source_set_texcoords_centered(obs_source_t *source,
bool centered);
extern void obs_source_activate(obs_source_t *source, enum view_type type);
extern void obs_source_deactivate(obs_source_t *source, enum view_type type);
extern void obs_source_video_tick(obs_source_t *source, float seconds);

View File

@ -561,6 +561,20 @@ static void render_item_texture(struct obs_scene_item *item)
GS_DEBUG_MARKER_END();
}
static bool are_texcoords_centered(struct matrix4 *m)
{
static const struct matrix4 identity = {
{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f},
};
struct matrix4 copy = identity;
copy.t.x = floorf(m->t.x);
copy.t.y = floorf(m->t.y);
return memcmp(m, &copy, sizeof(*m)) == 0;
}
static inline void render_item(struct obs_scene_item *item)
{
GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_ITEM, "Item: %s",
@ -610,7 +624,11 @@ static inline void render_item(struct obs_scene_item *item)
cx, cy);
obs_source_video_render(item->hide_transition);
} else {
obs_source_set_texcoords_centered(item->source,
true);
obs_source_video_render(item->source);
obs_source_set_texcoords_centered(item->source,
false);
}
gs_texrender_end(item->item_render);
@ -635,7 +653,11 @@ static inline void render_item(struct obs_scene_item *item)
obs_transition_set_size(item->hide_transition, cx, cy);
obs_source_video_render(item->hide_transition);
} else {
const bool centered =
are_texcoords_centered(&item->draw_transform);
obs_source_set_texcoords_centered(item->source, centered);
obs_source_video_render(item->source);
obs_source_set_texcoords_centered(item->source, false);
}
gs_matrix_pop();
gs_set_linear_srgb(previous);

View File

@ -1030,6 +1030,16 @@ void obs_source_send_key_click(obs_source_t *source,
}
}
bool obs_source_get_texcoords_centered(obs_source_t *source)
{
return source->texcoords_centered;
}
void obs_source_set_texcoords_centered(obs_source_t *source, bool centered)
{
source->texcoords_centered = centered;
}
static void activate_source(obs_source_t *source)
{
if (source->context.data && source->info.activate)

View File

@ -962,6 +962,9 @@ EXPORT uint32_t obs_source_get_width(obs_source_t *source);
/** Gets the height of a source (if it has video) */
EXPORT uint32_t obs_source_get_height(obs_source_t *source);
/** Hints whether or not the source will blend texels */
EXPORT bool obs_source_get_texcoords_centered(obs_source_t *source);
/**
* If the source is a filter, returns the parent source of the filter. Only
* guaranteed to be valid inside of the video_render, filter_audio,