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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-04-27 21:33:58 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-04-27 21:54:04 +0300
commita680bcd13bc306dbc97fd3889718238117a8f992 (patch)
tree4c3bbbc537d71b2bbe081e3730cfeee14dc44ca7 /source
parente4d856e31b2719c8ab9796495c1ac7aa48870246 (diff)
Draw Manager: basic text overlay support
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/DRW_engine.h1
-rw-r--r--source/blender/draw/intern/DRW_render.h7
-rw-r--r--source/blender/draw/intern/draw_armature.c39
-rw-r--r--source/blender/draw/intern/draw_manager.c67
-rw-r--r--source/blender/draw/intern/draw_manager_text.c199
-rw-r--r--source/blender/draw/intern/draw_manager_text.h54
-rw-r--r--source/blender/draw/modes/object_mode.c27
-rw-r--r--source/blender/gpu/GPU_viewport.h3
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c7
10 files changed, 400 insertions, 6 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 805971ebeae..20298e064f1 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -61,6 +61,7 @@ set(SRC
intern/draw_cache_impl_mesh.c
intern/draw_common.c
intern/draw_manager.c
+ intern/draw_manager_text.c
intern/draw_view.c
modes/edit_armature_mode.c
modes/edit_curve_mode.c
@@ -87,6 +88,7 @@ set(SRC
intern/draw_cache.h
intern/draw_cache_impl.h
intern/draw_common.h
+ intern/draw_manager_text.h
intern/draw_view.h
modes/draw_mode_engines.h
engines/basic/basic_engine.h
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 187ea6c1a11..dbb25796050 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -38,6 +38,7 @@ struct bContext;
struct Object;
struct SceneLayer;
struct ViewContext;
+struct ViewportEngineData;
struct View3D;
struct rcti;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index a5b193483ce..39b8e23db80 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -62,6 +62,7 @@ struct Object;
struct Batch;
struct DefaultFramebufferList;
struct DefaultTextureList;
+struct DRWTextStore;
struct LampEngineData;
struct RenderEngineType;
struct ViewportEngineData;
@@ -310,6 +311,8 @@ bool DRW_is_object_renderable(struct Object *ob);
/* Draw commands */
void DRW_draw_pass(DRWPass *pass);
+void DRW_draw_text_cache_queue(struct DRWTextStore *dt);
+
void DRW_draw_callbacks_pre_scene(void);
void DRW_draw_callbacks_post_scene(void);
@@ -322,6 +325,10 @@ void DRW_select_load_id(unsigned int id);
void DRW_state_dfdy_factors_get(float dfdyfac[2]);
bool DRW_state_is_fbo(void);
bool DRW_state_is_select(void);
+bool DRW_state_is_depth(void);
+bool DRW_state_show_text(void);
+
+struct DRWTextStore *DRW_state_text_cache_get(void);
/* Avoid too many lookups while drawing */
typedef struct DRWContextState {
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index 676170de64e..64568d92efc 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -60,6 +60,7 @@
#include "UI_resources.h"
#include "draw_common.h"
+#include "draw_manager_text.h"
#define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var))
#define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag))
@@ -485,6 +486,8 @@ static void draw_armature_edit(Object *ob)
update_color(NULL);
+ const bool show_text = DRW_state_show_text();
+
for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
@@ -508,6 +511,21 @@ static void draw_armature_edit(Object *ob)
draw_bone_octahedral(eBone, NULL, arm, select_id);
}
+ /* Draw names of bone */
+ if (show_text && (arm->flag & ARM_DRAWNAMES)) {
+ unsigned char color[4];
+ UI_GetThemeColor4ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, color);
+
+ float vec[3];
+ mid_v3_v3v3(vec, eBone->head, eBone->tail);
+ mul_m4_v3(ob->obmat, vec);
+
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRW_text_cache_add(
+ dt, vec, eBone->name, strlen(eBone->name),
+ 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
+ }
+
/* Draw additional axes */
if (arm->flag & ARM_DRAWAXES) {
draw_axes(eBone, NULL);
@@ -543,7 +561,8 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
}
}
- bool is_pose_select = (arm->flag & ARM_POSEMODE) && DRW_state_is_select();
+ const bool is_pose_select = (arm->flag & ARM_POSEMODE) && DRW_state_is_select();
+ const bool show_text = DRW_state_show_text();
/* being set below */
arm->layer_used = 0;
@@ -578,9 +597,25 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
draw_bone_octahedral(NULL, pchan, arm, select_id);
}
+ /* Draw names of bone */
+ if (show_text && (arm->flag & ARM_DRAWNAMES)) {
+ unsigned char color[4];
+ UI_GetThemeColor4ubv((arm->flag & ARM_POSEMODE) &&
+ (pchan->bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, color);
+ float vec[3];
+ mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail);
+ mul_m4_v3(ob->obmat, vec);
+
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ DRW_text_cache_add(
+ dt, vec, pchan->name, strlen(pchan->name),
+ 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
+ }
+
/* Draw additional axes */
- if (arm->flag & ARM_DRAWAXES)
+ if (arm->flag & ARM_DRAWAXES) {
draw_axes(NULL, pchan);
+ }
if (is_pose_select) {
index += 0x10000;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 6c85a2c83ee..0748d37b6ea 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -64,6 +64,8 @@
#include "UI_resources.h"
+#include "draw_manager_text.h"
+
/* only for callbacks */
#include "draw_cache_impl.h"
@@ -227,9 +229,17 @@ static struct DRWGlobalState {
float screenvecs[2][3];
float pixsize;
+ struct {
+ unsigned int is_select : 1;
+ unsigned int is_depth : 1;
+ } options;
+
/* Current rendering context */
DRWContextState draw_ctx;
+ /* Convenience pointer to text_store owned by the viewport */
+ struct DRWTextStore **text_store_p;
+
ListBase enabled_engines; /* RenderEngineType */
} DST = {NULL};
@@ -1351,6 +1361,16 @@ void DRW_state_reset(void) {}
/** \} */
+struct DRWTextStore *DRW_text_cache_ensure(void)
+{
+ BLI_assert(DST.text_store_p);
+ if (*DST.text_store_p == NULL) {
+ *DST.text_store_p = DRW_text_cache_create();
+ }
+ return *DST.text_store_p;
+}
+
+
/* -------------------------------------------------------------------- */
/** \name Settings
@@ -1699,6 +1719,15 @@ static void DRW_engines_cache_init(void)
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *engine = link->data;
ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+
+ if (data->text_draw_cache) {
+ DRW_text_cache_destroy(data->text_draw_cache);
+ data->text_draw_cache = NULL;
+ }
+ if (DST.text_store_p == NULL) {
+ DST.text_store_p = &data->text_draw_cache;
+ }
+
double stime = PIL_check_seconds_timer();
data->cache_time = 0.0;
@@ -1776,6 +1805,22 @@ static void DRW_engines_draw_scene(void)
}
}
+static void DRW_engines_draw_text(void)
+{
+ for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+ DrawEngineType *engine = link->data;
+ ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
+ double stime = PIL_check_seconds_timer();
+
+ if (data->text_draw_cache) {
+ DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.v3d, DST.draw_ctx.ar, false);
+ }
+
+ double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
+ data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
+ }
+}
+
static void use_drw_engine(DrawEngineType *engine)
{
LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
@@ -2081,6 +2126,8 @@ void DRW_draw_view(const bContext *C)
DRW_draw_callbacks_post_scene();
ED_region_draw_cb_draw(C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
+ DRW_engines_draw_text();
+
/* needed so manipulator isn't obscured */
glClear(GL_DEPTH_BUFFER_BIT);
@@ -2139,6 +2186,8 @@ void DRW_draw_select_loop(
DST.viewport = viewport;
v3d->zbuf = true;
+ DST.options.is_select = true;
+
/* Get list of enabled engines */
if (use_obedit) {
DRW_engines_enable_from_mode(obedit_mode);
@@ -2228,6 +2277,8 @@ void DRW_draw_depth_loop(
DST.viewport = viewport;
v3d->zbuf = true;
+ DST.options.is_depth = true;
+
/* Get list of enabled engines */
{
DRW_engines_enable_basic();
@@ -2312,7 +2363,21 @@ bool DRW_state_is_fbo(void)
*/
bool DRW_state_is_select(void)
{
- return (G.f & G_PICKSEL) != 0;
+ return DST.options.is_select;
+}
+
+bool DRW_state_is_depth(void)
+{
+ return DST.options.is_depth;
+}
+
+/**
+ * Should text draw in this mode?
+ */
+bool DRW_state_show_text(void)
+{
+ return (DST.options.is_select) == 0 &&
+ (DST.options.is_depth) == 0;
}
/** \} */
diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c
new file mode 100644
index 00000000000..56255af98ce
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager_text.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/** \file blender/draw/intern/draw_manager_text.c
+ * \ingroup draw
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_math.h"
+
+#include "BIF_gl.h"
+
+#include "GPU_matrix.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "UI_resources.h"
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "BLF_api.h"
+
+#include "draw_manager_text.h"
+
+typedef struct ViewCachedString {
+ struct ViewCachedString *next, *prev;
+ float vec[3];
+ union {
+ unsigned char ub[4];
+ int pack;
+ } col;
+ short sco[2];
+ short xoffs;
+ short flag;
+ int str_len;
+
+ /* str is allocated past the end */
+ char str[0];
+} ViewCachedString;
+
+typedef struct DRWTextStore {
+ ListBase list;
+} DRWTextStore;
+
+DRWTextStore *DRW_text_cache_create(void)
+{
+ DRWTextStore *dt = MEM_callocN(sizeof(*dt), __func__);
+ return dt;
+}
+
+void DRW_text_cache_destroy(struct DRWTextStore *dt)
+{
+ BLI_freelistN(&dt->list);
+ MEM_freeN(dt);
+}
+
+void DRW_text_cache_add(
+ DRWTextStore *dt,
+ const float co[3],
+ const char *str, const int str_len,
+ short xoffs, short flag,
+ const unsigned char col[4])
+{
+ int alloc_len;
+ ViewCachedString *vos;
+
+ if (flag & DRW_TEXT_CACHE_STRING_PTR) {
+ BLI_assert(str_len == strlen(str));
+ alloc_len = sizeof(void *);
+ }
+ else {
+ alloc_len = str_len + 1;
+ }
+
+ vos = MEM_mallocN(sizeof(ViewCachedString) + alloc_len, __func__);
+
+ BLI_addtail(&dt->list, vos);
+
+ copy_v3_v3(vos->vec, co);
+ copy_v4_v4_uchar(vos->col.ub, col);
+ vos->xoffs = xoffs;
+ vos->flag = flag;
+ vos->str_len = str_len;
+
+ /* allocate past the end */
+ if (flag & DRW_TEXT_CACHE_STRING_PTR) {
+ memcpy(vos->str, &str, alloc_len);
+ }
+ else {
+ memcpy(vos->str, str, alloc_len);
+ }
+}
+
+void DRW_text_cache_draw(
+ DRWTextStore *dt,
+ View3D *v3d, ARegion *ar, bool depth_write)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ ViewCachedString *vos;
+ int tot = 0;
+
+ /* project first and test */
+ for (vos = dt->list.first; vos; vos = vos->next) {
+ if (ED_view3d_project_short_ex(
+ ar,
+ (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
+ (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0,
+ vos->vec, vos->sco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
+ tot++;
+ }
+ else {
+ vos->sco[0] = IS_CLIPPED;
+ }
+ }
+
+ if (tot) {
+ int col_pack_prev = 0;
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+
+ float original_proj[4][4];
+ gpuGetProjectionMatrix(original_proj);
+ wmOrtho2_region_pixelspace(ar);
+
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ if (depth_write) {
+ if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
+ }
+ else {
+ glDepthMask(GL_FALSE);
+ }
+
+ const int font_id = BLF_default();
+
+ const uiStyle *style = UI_style_get();
+
+ BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
+
+ for (vos = dt->list.first; vos; vos = vos->next) {
+ if (vos->sco[0] != IS_CLIPPED) {
+ if (col_pack_prev != vos->col.pack) {
+ BLF_color4ubv(font_id, vos->col.ub);
+ col_pack_prev = vos->col.pack;
+ }
+
+ BLF_position(
+ font_id,
+ (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1]), (depth_write) ? 0.0f : 2.0f);
+
+ ((vos->flag & DRW_TEXT_CACHE_ASCII) ?
+ BLF_draw_ascii :
+ BLF_draw
+ )(font_id,
+ (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str,
+ vos->str_len);
+ }
+ }
+
+ if (depth_write) {
+ if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
+ }
+ else {
+ glDepthMask(GL_TRUE);
+ }
+
+ gpuPopMatrix();
+ gpuLoadProjectionMatrix(original_proj);
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_enable();
+ }
+ }
+}
diff --git a/source/blender/draw/intern/draw_manager_text.h b/source/blender/draw/intern/draw_manager_text.h
new file mode 100644
index 00000000000..a58e167be0d
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager_text.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/** \file blender/draw/intern/draw_manager_text.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_MANAGER_TEXT_H__
+#define __DRAW_MANAGER_TEXT_H__
+
+struct DRWTextStore;
+
+struct DRWTextStore *DRW_text_cache_create(void);
+void DRW_text_cache_destroy(struct DRWTextStore *dt);
+
+void DRW_text_cache_add(
+ struct DRWTextStore *dt,
+ const float co[3],
+ const char *str, const int str_len,
+ short xoffs, short flag,
+ const unsigned char col[4]);
+
+void DRW_text_cache_draw(
+ struct DRWTextStore *dt,
+ struct View3D *v3d, struct ARegion *ar, bool depth_write);
+
+enum {
+ DRW_TEXT_CACHE_ASCII = (1 << 0),
+ DRW_TEXT_CACHE_GLOBALSPACE = (1 << 1),
+ DRW_TEXT_CACHE_LOCALCLIP = (1 << 2),
+ /* reference the string by pointer */
+ DRW_TEXT_CACHE_STRING_PTR = (1 << 3),
+};
+
+/* draw_manager.c */
+struct DRWTextStore *DRW_text_cache_ensure(void);
+
+#endif /* __DRAW_MANAGER_TEXT_H__ */
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index efff11ce1ce..e626060a8b5 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -47,6 +47,7 @@
#include "UI_resources.h"
#include "draw_mode_engines.h"
+#include "draw_manager_text.h"
#include "draw_common.h"
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
@@ -1179,6 +1180,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
SceneLayer *sl = draw_ctx->sl;
+ int theme_id = TH_UNDEFINED;
//CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
@@ -1190,7 +1192,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
if (ob != obedit) {
struct Batch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
- int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or(stl, theme_id, NULL);
if (shgroup != NULL) {
DRW_shgroup_call_add(shgroup, geom, ob->obmat);
@@ -1208,7 +1210,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
Object *obedit = scene->obedit;
if (ob != obedit) {
struct Batch *geom = DRW_cache_lattice_wire_get(ob);
- int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
DRW_shgroup_call_add(shgroup, geom, ob->obmat);
@@ -1221,7 +1225,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
Object *obedit = scene->obedit;
if (ob != obedit) {
struct Batch *geom = DRW_cache_curve_edge_wire_get(ob);
- int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
DRW_shgroup_call_add(shgroup, geom, ob->obmat);
}
@@ -1266,6 +1272,21 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
DRW_shgroup_object_center(stl, ob);
DRW_shgroup_relationship_lines(stl, ob);
+
+ if ((ob->dtx & OB_DRAWNAME) && DRW_state_show_text()) {
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ if (theme_id == TH_UNDEFINED) {
+ theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+ }
+
+ unsigned char color[4];
+ UI_GetThemeColor4ubv(theme_id, color);
+
+ DRW_text_cache_add(
+ dt, ob->obmat[3],
+ ob->id.name + 2, strlen(ob->id.name + 2),
+ 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
+ }
}
static void OBJECT_draw_scene(void *vedata)
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index f1a4e0bbcdb..93bf96a5830 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -66,6 +66,9 @@ typedef struct ViewportEngineData {
PassList *psl;
StorageList *stl;
+ /* we may want to put this elsewhere */
+ struct DRWTextStore *text_draw_cache;
+
/* Profiling data */
double init_time;
double cache_time;
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 3781a9c8be0..94c2b022e86 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -123,6 +123,13 @@ static void gpu_viewport_engines_data_free(GPUViewport *viewport)
MEM_freeN(data->psl);
MEM_freeN(data->stl);
+ /* We could handle this in the DRW module */
+ if (data->text_draw_cache) {
+ extern void DRW_text_cache_destroy(struct DRWTextStore *dt);
+ DRW_text_cache_destroy(data->text_draw_cache);
+ data->text_draw_cache = NULL;
+ }
+
MEM_freeN(data);
BLI_remlink(&viewport->data, link);