text-freetype2: Use a shader uniform instead of vertex attributes

We used to swap in a buffer with (0,0,0,1) for all vertex colors for
drop shadows and outlines. However, this vertex buffer couldn't be
uploaded separately from the vertex data in OBS, so we were reuploading
the text vertices every frame.

Instead, let's use a uniform for this uniform data and save 500us (or
more when handles are visible), a significant portion of my test scenes
render time.
This commit is contained in:
Kurt Kartaltepe
2024-04-14 20:13:56 -07:00
committed by Lain
parent a3a8f6dbfb
commit cfb10ece79
6 changed files with 12 additions and 40 deletions
@@ -1,5 +1,6 @@
uniform float4x4 ViewProj;
uniform texture2d image;
uniform bool use_color;
sampler_state def_sampler {
Filter = Linear;
@@ -18,7 +19,7 @@ VertInOut VSDefault(VertInOut vert_in)
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
vert_out.col = vert_in.col;
vert_out.col = use_color ? vert_in.col : float4(0.0, 0.0, 0.0, 1.0);
return vert_out;
}
+5 -2
View File
@@ -57,7 +57,7 @@ gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color)
}
void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex,
gs_effect_t *effect, uint32_t num_verts)
gs_effect_t *effect, uint32_t num_verts, bool use_color)
{
gs_texture_t *texture = tex;
gs_technique_t *tech = gs_effect_get_technique(effect, "Draw");
@@ -72,7 +72,6 @@ void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex,
const bool previous = gs_framebuffer_srgb_enabled();
gs_enable_framebuffer_srgb(linear_srgb);
gs_vertexbuffer_flush(vbuf);
gs_load_vertexbuffer(vbuf);
gs_load_indexbuffer(NULL);
@@ -85,6 +84,10 @@ void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex,
else
gs_effect_set_texture(image, texture);
gs_effect_set_bool(gs_effect_get_param_by_name(
effect, "use_color"),
use_color);
gs_draw(GS_TRIS, 0, num_verts);
gs_technique_end_pass(tech);
+1 -1
View File
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color);
void draw_uv_vbuffer(gs_vertbuffer_t *vbuf, gs_texture_t *tex,
gs_effect_t *effect, uint32_t num_verts);
gs_effect_t *effect, uint32_t num_verts, bool use_color);
#define set_v3_rect(a, x, y, w, h) \
vec3_set(a, x, y, 0.0f); \
+1 -3
View File
@@ -240,8 +240,6 @@ static void ft2_source_destroy(void *data)
bfree(srcdata->text);
if (srcdata->texbuf != NULL)
bfree(srcdata->texbuf);
if (srcdata->colorbuf != NULL)
bfree(srcdata->colorbuf);
if (srcdata->text_file != NULL)
bfree(srcdata->text_file);
@@ -283,7 +281,7 @@ static void ft2_source_render(void *data, gs_effect_t *effect)
draw_drop_shadow(srcdata);
draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect,
(uint32_t)wcslen(srcdata->text) * 6);
(uint32_t)wcslen(srcdata->text) * 6, true);
UNUSED_PARAMETER(effect);
}
-1
View File
@@ -48,7 +48,6 @@ struct ft2_source {
uint32_t outline_width;
uint32_t texbuf_x, texbuf_y;
uint32_t color[2];
uint32_t *colorbuf;
int32_t cur_scroll, scroll_speed;
+3 -32
View File
@@ -30,52 +30,32 @@ extern uint32_t texbuf_w, texbuf_h;
void draw_outlines(struct ft2_source *srcdata)
{
// Horrible (hopefully temporary) solution for outlines.
uint32_t *tmp;
struct gs_vb_data *vdata = gs_vertexbuffer_get_data(srcdata->vbuf);
if (!srcdata->text)
return;
tmp = vdata->colors;
vdata->colors = srcdata->colorbuf;
gs_matrix_push();
for (int32_t i = 0; i < 8; i++) {
gs_matrix_translate3f(offsets[i * 2], offsets[(i * 2) + 1],
0.0f);
draw_uv_vbuffer(srcdata->vbuf, srcdata->tex,
srcdata->draw_effect,
(uint32_t)wcslen(srcdata->text) * 6);
(uint32_t)wcslen(srcdata->text) * 6, false);
}
gs_matrix_identity();
gs_matrix_pop();
vdata->colors = tmp;
}
void draw_drop_shadow(struct ft2_source *srcdata)
{
// Horrible (hopefully temporary) solution for drop shadow.
uint32_t *tmp;
struct gs_vb_data *vdata = gs_vertexbuffer_get_data(srcdata->vbuf);
if (!srcdata->text)
return;
tmp = vdata->colors;
vdata->colors = srcdata->colorbuf;
gs_matrix_push();
gs_matrix_translate3f(4.0f, 4.0f, 0.0f);
draw_uv_vbuffer(srcdata->vbuf, srcdata->tex, srcdata->draw_effect,
(uint32_t)wcslen(srcdata->text) * 6);
(uint32_t)wcslen(srcdata->text) * 6, false);
gs_matrix_identity();
gs_matrix_pop();
vdata->colors = tmp;
}
void set_up_vertex_buffer(struct ft2_source *srcdata)
@@ -147,6 +127,7 @@ void set_up_vertex_buffer(struct ft2_source *srcdata)
skip_word_wrap:;
fill_vertex_buffer(srcdata);
gs_vertexbuffer_flush(srcdata->vbuf);
obs_leave_graphics();
}
@@ -171,16 +152,6 @@ void fill_vertex_buffer(struct ft2_source *srcdata)
dx = offset;
}
if (srcdata->colorbuf != NULL) {
bfree(srcdata->colorbuf);
srcdata->colorbuf = NULL;
}
srcdata->colorbuf =
bzalloc(sizeof(uint32_t) * wcslen(srcdata->text) * 6);
for (size_t i = 0; i < len * 6; i++) {
srcdata->colorbuf[i] = 0xFF000000;
}
for (size_t i = 0; i < len; i++) {
add_linebreak:;
if (srcdata->text[i] != L'\n')