libobs: obs-filters: Area upscale shader
Add a separate shader for area upscaling to take advantage of bilinear filtering. Iterating over texels is unnecessary in the upscale case because a target pixel can only overlap 1 or 2 texels in X and Y directions. When only overlapping one texel, adjust UVs to sample texel center to avoid filtering. Also add "base_dimension" uniform to avoid unnecessary division. Intel HD Graphics 530, 644x478 -> 1323x1080: ~836 us -> ~232 us
This commit is contained in:
@@ -470,6 +470,7 @@ static void render_item_texture(struct obs_scene_item *item)
|
||||
enum obs_scale_type type = item->scale_filter;
|
||||
uint32_t cx = gs_texture_get_width(tex);
|
||||
uint32_t cy = gs_texture_get_height(tex);
|
||||
const char *tech = "Draw";
|
||||
|
||||
if (type != OBS_SCALE_DISABLE) {
|
||||
if (type == OBS_SCALE_POINT) {
|
||||
@@ -481,6 +482,7 @@ static void render_item_texture(struct obs_scene_item *item)
|
||||
} else if (!close_float(item->output_scale.x, 1.0f, EPSILON) ||
|
||||
!close_float(item->output_scale.y, 1.0f, EPSILON)) {
|
||||
gs_eparam_t *scale_param;
|
||||
gs_eparam_t *scale_i_param;
|
||||
|
||||
if (item->output_scale.x < 0.5f ||
|
||||
item->output_scale.y < 0.5f) {
|
||||
@@ -491,15 +493,26 @@ static void render_item_texture(struct obs_scene_item *item)
|
||||
effect = obs->video.lanczos_effect;
|
||||
} else if (type == OBS_SCALE_AREA) {
|
||||
effect = obs->video.area_effect;
|
||||
if ((item->output_scale.x >= 1.0f) &&
|
||||
(item->output_scale.y >= 1.0f))
|
||||
tech = "DrawUpscale";
|
||||
}
|
||||
|
||||
scale_param = gs_effect_get_param_by_name(
|
||||
effect, "base_dimension_i");
|
||||
effect, "base_dimension");
|
||||
if (scale_param) {
|
||||
struct vec2 base_res_i = {(float)cx, (float)cy};
|
||||
|
||||
gs_effect_set_vec2(scale_param, &base_res_i);
|
||||
}
|
||||
|
||||
scale_i_param = gs_effect_get_param_by_name(
|
||||
effect, "base_dimension_i");
|
||||
if (scale_i_param) {
|
||||
struct vec2 base_res_i = {1.0f / (float)cx,
|
||||
1.0f / (float)cy};
|
||||
|
||||
gs_effect_set_vec2(scale_param, &base_res_i);
|
||||
gs_effect_set_vec2(scale_i_param, &base_res_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -507,7 +520,7 @@ static void render_item_texture(struct obs_scene_item *item)
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
while (gs_effect_loop(effect, "Draw"))
|
||||
while (gs_effect_loop(effect, tech))
|
||||
obs_source_draw(tex, 0, 0, 0, 0, 0);
|
||||
|
||||
gs_blend_state_pop();
|
||||
|
Reference in New Issue
Block a user