[Bf-blender-cvs] [963e48e1dfb] blender2.8: BLF: Add Batching capabilities.

Clément Foucault noreply at git.blender.org
Fri Mar 30 23:34:06 CEST 2018


Commit: 963e48e1dfb09520369b9a3a31b4f57663651c21
Author: Clément Foucault
Date:   Fri Mar 30 20:59:45 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB963e48e1dfb09520369b9a3a31b4f57663651c21

BLF: Add Batching capabilities.

You can now use BLF_batching_start and BLF_batching_end to batch every
drawcall to BLF together minimizing the overhead introduced by BLF and the
opengl driver.

These calls cannot be nested (for now).

If the modelview matrix changes, previously batched calls are issued and a
the process resume with the new matrix.

However the projection matrix MUST not change and gl scissors as well.

===================================================================

M	source/blender/blenfont/BLF_api.h
M	source/blender/blenfont/intern/blf.c
M	source/blender/blenfont/intern/blf_font.c
M	source/blender/blenfont/intern/blf_glyph.c
M	source/blender/blenfont/intern/blf_internal_types.h

===================================================================

diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index fd0c0362300..f9841c83163 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -95,6 +95,11 @@ void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha);
  */
 void BLF_matrix(int fontid, const float m[16]);
 
+/* Batch drawcalls together as long as
+ * the modelview matrix and the font remain unchanged. */
+void BLF_batching_start(void);
+void BLF_batching_end(void);
+
 /* Draw the string using the default font, size and dpi. */
 void BLF_draw_default(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL();
 void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL();
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 5b51ecbc047..2407abdaf28 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -540,6 +540,19 @@ void BLF_color3f(int fontid, float r, float g, float b)
 	BLF_color4fv(fontid, rgba);
 }
 
+void BLF_batching_start(void)
+{
+	BLI_assert(g_batch.enabled == false);
+	g_batch.enabled = true;
+}
+
+void BLF_batching_end(void)
+{
+	BLI_assert(g_batch.enabled == true);
+	blf_batching_draw(); /* Draw remaining glyphs */
+	g_batch.enabled = false;
+}
+
 void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
 {
 	ASSERT_DEFAULT_SET;
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 868d8eb775e..1df1dc5706c 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -97,6 +97,11 @@ static void blf_batching_init(void)
 	g_batch.verts = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STREAM);
 	GWN_vertbuf_data_alloc(g_batch.verts, BLF_BATCHING_SIZE);
 
+	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
+	g_batch.glyph_ct = 0;
+
 	g_batch.batch = GWN_batch_create_ex(GWN_PRIM_POINTS, g_batch.verts, NULL, GWN_BATCH_OWNS_VBO);
 }
 
@@ -118,17 +123,53 @@ void blf_batching_start(FontBLF *font)
 		blf_batching_init();
 	}
 
-	zero_v2(g_batch.ofs);
-	if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0) {
+	const bool font_changed = (g_batch.font != font);
+	g_batch.font = font;
+
+	const bool manual_ofs_active = ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0);
+	g_batch.active = g_batch.enabled && manual_ofs_active;
+
+	if (manual_ofs_active) {
+		/* Offset is applied to each glyph. */
 		copy_v2_v2(g_batch.ofs, font->pos);
 	}
+	else {
+		/* Offset is baked in modelview mat. */
+		zero_v2(g_batch.ofs);
+	}
 
-	/* restart to 1st vertex data pointers */
-	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
-	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
-	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
-	g_batch.glyph_ct = 0;
-	g_batch.font = font;
+	if (g_batch.active) {
+		float gpumat[4][4];
+		gpuGetModelViewMatrix(gpumat);
+
+		bool mat_changed = (memcmp(gpumat, g_batch.mat, sizeof(g_batch.mat)) != 0);
+		/* Save for next memcmp. */
+		memcpy(g_batch.mat, gpumat, sizeof(g_batch.mat));
+
+		if (mat_changed) {
+			/* Modelviewmat is no longer the same.
+			 * Flush cache but with the previous mat. */
+			gpuPushMatrix();
+			gpuLoadMatrix(g_batch.mat);
+		}
+
+		/* flush cache if config is not the same. */
+		if (mat_changed || font_changed) {
+			blf_batching_draw();
+		}
+		else {
+			/* Nothing changed continue batching. */
+			return;
+		}
+
+		if (mat_changed) {
+			gpuPopMatrix();
+		}
+	}
+	else {
+		/* flush cache */
+		blf_batching_draw();
+	}
 }
 
 void blf_batching_draw(void)
@@ -152,12 +193,16 @@ void blf_batching_draw(void)
 
 	glDisable(GL_BLEND);
 
+	/* restart to 1st vertex data pointers */
+	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
+	GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
 	g_batch.glyph_ct = 0;
 }
 
 static void blf_batching_end(void)
 {
-	if (!g_batch.enabled) {
+	if (!g_batch.active) {
 		blf_batching_draw();
 	}
 }
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index b91eceac817..b05cabcd830 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -319,17 +319,17 @@ void blf_glyph_free(GlyphBLF *g)
 
 static void blf_texture_draw(const unsigned char color[4], float uv[2][2], float x1, float y1, float x2, float y2)
 {
-	if (g_batch.glyph_ct == BLF_BATCHING_SIZE) {
-		blf_batching_draw();
-		blf_batching_start(g_batch.font);
-	}
-	g_batch.glyph_ct++;
 	/* Only one vertex per glyph, geometry shader expand it into a quad. */
 	/* TODO Get rid of Geom Shader because it's not optimal AT ALL for the GPU */
 	copy_v4_fl4(GWN_vertbuf_raw_step(&g_batch.pos_step), x1 + g_batch.ofs[0], y1 + g_batch.ofs[1],
 	                                                     x2 + g_batch.ofs[0], y2 + g_batch.ofs[1]);
 	copy_v4_v4(GWN_vertbuf_raw_step(&g_batch.tex_step), (float *)uv);
 	copy_v4_v4_uchar(GWN_vertbuf_raw_step(&g_batch.col_step), color);
+	g_batch.glyph_ct++;
+	/* Flush cache if it's full. */
+	if (g_batch.glyph_ct == BLF_BATCHING_SIZE) {
+		blf_batching_draw();
+	}
 }
 
 static void blf_texture5_draw(const unsigned char color_in[4], float uv[2][2], float x1, float y1, float x2, float y2)
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 360aae47dd0..91d7917b0b5 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -43,8 +43,8 @@ typedef struct BatchBLF{
 	unsigned int pos_loc, tex_loc, col_loc;
 	unsigned int glyph_ct;
 	float ofs[2];    /* copy of font->pos */
-	float mat[4][4]; /* to catch bad usage */
-	bool enabled;
+	float mat[4][4]; /* previous call modelmatrix. */
+	bool enabled, active;
 } BatchBLF;
 
 extern BatchBLF g_batch;



More information about the Bf-blender-cvs mailing list