Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenfont/BLF_api.h1
-rw-r--r--source/blender/blenfont/intern/blf.c47
-rw-r--r--source/blender/blenfont/intern/blf_font.c126
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c15
-rw-r--r--source/blender/blenfont/intern/blf_internal.h7
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h18
-rw-r--r--source/blender/gpu/GPU_batch.h1
-rw-r--r--source/blender/windowmanager/intern/wm_window.c3
8 files changed, 154 insertions, 64 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index cd3a15f1c88..fd0c0362300 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -47,6 +47,7 @@ void BLF_exit(void);
void BLF_default_dpi(int dpi);
void BLF_default_set(int fontid);
int BLF_default(void); /* get default font ID so we can pass it to other functions */
+void BLF_batch_reset(void); /* call when changing opengl context. */
void BLF_antialias_set(bool enabled);
bool BLF_antialias_get(void);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 30919f1acda..5b51ecbc047 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -132,6 +132,11 @@ void BLF_exit(void)
blf_font_exit();
}
+void BLF_batch_reset(void)
+{
+ blf_batching_vao_clear();
+}
+
void BLF_cache_clear(void)
{
FontBLF *font;
@@ -561,8 +566,11 @@ static void blf_draw_gl__start(FontBLF *font)
* in BLF_position (old ui_rasterpos_safe).
*/
- glEnable(GL_BLEND);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ /* always bind the texture for the first glyph */
+ font->tex_bind_state = 0;
+
+ if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0)
+ return; /* glyphs will be translated individually and batched. */
gpuPushMatrix();
@@ -576,35 +584,12 @@ static void blf_draw_gl__start(FontBLF *font)
if (font->flags & BLF_ROTATION)
gpuRotate2D(RAD2DEG(font->angle));
-
-#ifndef BLF_STANDALONE
- Gwn_VertFormat *format = immVertexFormat();
- unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
- unsigned int texCoord = GWN_vertformat_attr_add(format, "tex", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
- unsigned int color = GWN_vertformat_attr_add(format, "col", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
-
- BLI_assert(pos == BLF_POS_ID);
- BLI_assert(texCoord == BLF_COORD_ID);
- BLI_assert(color == BLF_COLOR_ID);
-
- UNUSED_VARS_NDEBUG(pos, texCoord, color);
-
- immBindBuiltinProgram(GPU_SHADER_TEXT);
-#endif
-
- /* always bind the texture for the first glyph */
- font->tex_bind_state = -1;
}
-static void blf_draw_gl__end(void)
+static void blf_draw_gl__end(FontBLF *font)
{
- gpuPopMatrix();
-
-#ifndef BLF_STANDALONE
- immUnbindProgram();
-#endif
-
- glDisable(GL_BLEND);
+ if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) != 0)
+ gpuPopMatrix();
}
void BLF_draw_ex(
@@ -623,7 +608,7 @@ void BLF_draw_ex(
else {
blf_font_draw(font, str, len, r_info);
}
- blf_draw_gl__end();
+ blf_draw_gl__end(font);
}
}
void BLF_draw(int fontid, const char *str, size_t len)
@@ -652,7 +637,7 @@ void BLF_draw_ascii_ex(
else {
blf_font_draw_ascii(font, str, len, r_info);
}
- blf_draw_gl__end();
+ blf_draw_gl__end(font);
}
}
void BLF_draw_ascii(int fontid, const char *str, size_t len)
@@ -676,7 +661,7 @@ int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
if (font && font->glyph_cache) {
blf_draw_gl__start(font);
columns = blf_font_draw_mono(font, str, len, cwidth);
- blf_draw_gl__end();
+ blf_draw_gl__end(font);
}
return columns;
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 1f304d208e6..868d8eb775e 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -59,6 +59,8 @@
#include "BLF_api.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "GPU_batch.h"
#include "blf_internal_types.h"
#include "blf_internal.h"
@@ -69,12 +71,104 @@
# define FT_New_Face FT_New_Face__win32_compat
#endif
+/* Batching buffer for drawing. */
+BatchBLF g_batch;
+
/* freetype2 handle ONLY for this file!. */
static FT_Library ft_lib;
static SpinLock ft_lib_mutex;
+/* -------------------------------------------------------------------- */
+/** \name Glyph Batching
+ * \{ */
+/**
+ * Drawcalls are precious! make them count!
+ * Since most of the Text elems are not covered by other UI elements, we can
+ * group some strings together and render them in one drawcall. This behaviour
+ * is on demand only, between BLF_batch_start() and BLF_batch_end().
+ **/
+static void blf_batching_init(void)
+{
+ Gwn_VertFormat format = {0};
+ g_batch.pos_loc = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ g_batch.tex_loc = GWN_vertformat_attr_add(&format, "tex", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ g_batch.col_loc = GWN_vertformat_attr_add(&format, "col", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+
+ g_batch.verts = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STREAM);
+ GWN_vertbuf_data_alloc(g_batch.verts, BLF_BATCHING_SIZE);
+
+ g_batch.batch = GWN_batch_create_ex(GWN_PRIM_POINTS, g_batch.verts, NULL, GWN_BATCH_OWNS_VBO);
+}
+
+static void blf_batching_exit(void)
+{
+ GWN_BATCH_DISCARD_SAFE(g_batch.batch);
+}
+
+void blf_batching_vao_clear(void)
+{
+ if (g_batch.batch) {
+ gwn_batch_vao_cache_clear(g_batch.batch);
+ }
+}
+
+void blf_batching_start(FontBLF *font)
+{
+ if (g_batch.batch == NULL) {
+ blf_batching_init();
+ }
+
+ zero_v2(g_batch.ofs);
+ if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0) {
+ copy_v2_v2(g_batch.ofs, font->pos);
+ }
+
+ /* 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;
+}
+
+void blf_batching_draw(void)
+{
+ if (g_batch.glyph_ct == 0)
+ return;
+
+ glEnable(GL_BLEND);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ BLI_assert(g_batch.font->tex_bind_state != 0); /* must still be valid */
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, g_batch.font->tex_bind_state);
+
+ GWN_vertbuf_vertex_count_set(g_batch.verts, g_batch.glyph_ct);
+ GWN_vertbuf_use(g_batch.verts); /* send data */
+
+ GWN_batch_program_set_builtin(g_batch.batch, GPU_SHADER_TEXT);
+ GWN_batch_uniform_1i(g_batch.batch, "glyph", 0);
+ GWN_batch_draw(g_batch.batch);
+
+ glDisable(GL_BLEND);
+
+ g_batch.glyph_ct = 0;
+}
+
+static void blf_batching_end(void)
+{
+ if (!g_batch.enabled) {
+ blf_batching_draw();
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
int blf_font_init(void)
{
+ memset(&g_batch, 0, sizeof(g_batch));
BLI_spin_init(&ft_lib_mutex);
return FT_Init_FreeType(&ft_lib);
}
@@ -83,6 +177,7 @@ void blf_font_exit(void)
{
FT_Done_FreeType(ft_lib);
BLI_spin_end(&ft_lib_mutex);
+ blf_batching_exit();
}
void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
@@ -174,24 +269,6 @@ static void blf_font_ensure_ascii_table(FontBLF *font)
} \
} (void)0
-static unsigned int verts_needed(const FontBLF *font, const char *str, size_t len)
-{
- size_t str_len = (len > 50) ? strlen(str) : INT_MAX; /* Arbitrary. */
- unsigned int length = (unsigned int)MIN2(str_len, len);
- unsigned int quad_ct = 1;
-
- if (font->flags & BLF_SHADOW) {
- if (font->shadow == 0)
- quad_ct += 1;
- if (font->shadow <= 4)
- quad_ct += 9; /* 3x3 kernel */
- else
- quad_ct += 25; /* 5x5 kernel */
- }
-
- return length * quad_ct; /* Only one vert per quad */
-}
-
static void blf_font_draw_ex(
FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info,
int pen_y)
@@ -212,8 +289,7 @@ static void blf_font_draw_ex(
blf_font_ensure_ascii_table(font);
- immBeginAtMost(GWN_PRIM_POINTS, verts_needed(font, str, len));
- /* at most because some glyphs might be clipped & not drawn */
+ blf_batching_start(font);
while ((i < len) && str[i]) {
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
@@ -232,7 +308,7 @@ static void blf_font_draw_ex(
g_prev = g;
}
- immEnd();
+ blf_batching_end();
if (r_info) {
r_info->lines = 1;
@@ -259,7 +335,7 @@ static void blf_font_draw_ascii_ex(
blf_font_ensure_ascii_table(font);
- immBeginAtMost(GWN_PRIM_POINTS, verts_needed(font, str, len));
+ blf_batching_start(font);
while ((c = *(str++)) && len--) {
BLI_assert(c < 128);
@@ -275,7 +351,7 @@ static void blf_font_draw_ascii_ex(
g_prev = g;
}
- immEnd();
+ blf_batching_end();
if (r_info) {
r_info->lines = 1;
@@ -299,7 +375,7 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
blf_font_ensure_ascii_table(font);
- immBeginAtMost(GWN_PRIM_POINTS, verts_needed(font, str, len));
+ blf_batching_start(font);
while ((i < len) && str[i]) {
BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
@@ -320,7 +396,7 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
pen_x += cwidth * col;
}
- immEnd();
+ blf_batching_end();
return columns;
}
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 5e1debf1501..b91eceac817 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -63,6 +63,7 @@
#include "blf_internal.h"
#include "BLI_strict_flags.h"
+#include "BLI_math_vector.h"
GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned int dpi)
{
@@ -316,13 +317,19 @@ void blf_glyph_free(GlyphBLF *g)
MEM_freeN(g);
}
-static void blf_texture_draw(const unsigned char color[4], float uv[2][2], float dx, float y1, float dx1, float y2)
+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 */
- immAttrib4ubv(BLF_COLOR_ID, color);
- immAttrib4fv(BLF_COORD_ID, (float *)uv);
- immVertex4f(BLF_POS_ID, dx, y1, dx1, y2);
+ 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);
}
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.h b/source/blender/blenfont/intern/blf_internal.h
index ba17e050399..c9ea8c3323b 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -37,10 +37,9 @@ struct GlyphBLF;
struct GlyphCacheBLF;
struct rctf;
-/* vertex attribute IDs (fixed IDs so we don't have to pass them around) */
-#define BLF_POS_ID 0
-#define BLF_COORD_ID 1
-#define BLF_COLOR_ID 2
+void blf_batching_vao_clear(void);
+void blf_batching_start(struct FontBLF *font);
+void blf_batching_draw(void);
unsigned int blf_next_p2(unsigned int x);
unsigned int blf_hash(unsigned int val);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 9164a02b2cc..360aae47dd0 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -31,6 +31,24 @@
#ifndef __BLF_INTERNAL_TYPES_H__
#define __BLF_INTERNAL_TYPES_H__
+#include "../../../intern/gawain/gawain/gwn_vertex_buffer.h"
+
+#define BLF_BATCHING_SIZE 2048 /* in glyph */
+
+typedef struct BatchBLF{
+ struct FontBLF *font; /* can only batch glyph from the same font */
+ struct Gwn_Batch *batch;
+ struct Gwn_VertBuf *verts;
+ struct Gwn_VertBufRaw pos_step, tex_step, col_step;
+ 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;
+} BatchBLF;
+
+extern BatchBLF g_batch;
+
typedef struct GlyphCacheBLF {
struct GlyphCacheBLF *next;
struct GlyphCacheBLF *prev;
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index fda24018150..52cf37a7457 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -40,6 +40,7 @@ struct rctf;
// #include "gawain/batch.h"
#include "BLI_compiler_attrs.h"
+#include "BLI_sys_types.h"
#include "GPU_shader.h"
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 2ed16dd20db..14376b1bbb1 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -519,6 +519,7 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
}
if (tmpwin) {
+ BLF_batch_reset();
gpu_batch_presets_reset();
immDeactivate();
}
@@ -1168,6 +1169,7 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
printf("%s: set drawable %d\n", __func__, win->winid);
}
+ BLF_batch_reset();
gpu_batch_presets_reset();
immDeactivate();
GHOST_ActivateWindowDrawingContext(win->ghostwin);
@@ -1192,6 +1194,7 @@ void wm_window_reset_drawable(void)
wmWindow *win = wm->windrawable;
if (win && win->ghostwin) {
+ BLF_batch_reset();
gpu_batch_presets_reset();
immDeactivate();
GHOST_ActivateWindowDrawingContext(win->ghostwin);