소스 검색

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.
Kurt Kartaltepe 1 년 전
부모
커밋
cfb10ece79

+ 2 - 1
plugins/text-freetype2/data/text_default.effect

@@ -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
plugins/text-freetype2/obs-convenience.c

@@ -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
plugins/text-freetype2/obs-convenience.h

@@ -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
plugins/text-freetype2/text-freetype2.c

@@ -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);
 }

+ 0 - 1
plugins/text-freetype2/text-freetype2.h

@@ -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
plugins/text-freetype2/text-functionality.c

@@ -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')