Avoid allocation for each string, improves redraw speed for text heavy views. A contrived test showed FPS ~18.5% speedup but this doesn't represent typical usage.
181 lines
4.2 KiB
C
181 lines
4.2 KiB
C
/*
|
|
* 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.
|
|
*
|
|
* Copyright 2016, Blender Foundation.
|
|
*/
|
|
|
|
/** \file
|
|
* \ingroup draw
|
|
*/
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BLI_memiter.h"
|
|
#include "BLI_math.h"
|
|
|
|
#include "GPU_matrix.h"
|
|
|
|
#include "ED_screen.h"
|
|
#include "ED_view3d.h"
|
|
|
|
#include "UI_interface.h"
|
|
|
|
#include "WM_api.h"
|
|
#include "BLF_api.h"
|
|
|
|
#include "draw_manager_text.h"
|
|
|
|
typedef struct ViewCachedString {
|
|
float vec[3];
|
|
union {
|
|
uchar ub[4];
|
|
int pack;
|
|
} col;
|
|
short sco[2];
|
|
short xoffs, yoffs;
|
|
short flag;
|
|
int str_len;
|
|
|
|
/* str is allocated past the end */
|
|
char str[0];
|
|
} ViewCachedString;
|
|
|
|
typedef struct DRWTextStore {
|
|
BLI_memiter *cache_strings;
|
|
} DRWTextStore;
|
|
|
|
DRWTextStore *DRW_text_cache_create(void)
|
|
{
|
|
DRWTextStore *dt = MEM_callocN(sizeof(*dt), __func__);
|
|
dt->cache_strings = BLI_memiter_create(1 << 14); /* 16kb */
|
|
return dt;
|
|
}
|
|
|
|
void DRW_text_cache_destroy(struct DRWTextStore *dt)
|
|
{
|
|
BLI_memiter_destroy(dt->cache_strings);
|
|
MEM_freeN(dt);
|
|
}
|
|
|
|
void DRW_text_cache_add(
|
|
DRWTextStore *dt,
|
|
const float co[3],
|
|
const char *str, const int str_len,
|
|
short xoffs, short yoffs, short flag,
|
|
const uchar 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 = BLI_memiter_alloc(dt->cache_strings, sizeof(ViewCachedString) + alloc_len);
|
|
|
|
copy_v3_v3(vos->vec, co);
|
|
copy_v4_v4_uchar(vos->col.ub, col);
|
|
vos->xoffs = xoffs;
|
|
vos->yoffs = yoffs;
|
|
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, ARegion *ar)
|
|
{
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
ViewCachedString *vos;
|
|
int tot = 0;
|
|
|
|
/* project first and test */
|
|
BLI_memiter_handle it;
|
|
BLI_memiter_iter_init(dt->cache_strings, &it);
|
|
while ((vos = BLI_memiter_iter_step(&it))) {
|
|
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];
|
|
GPU_matrix_projection_get(original_proj);
|
|
wmOrtho2_region_pixelspace(ar);
|
|
|
|
GPU_matrix_push();
|
|
GPU_matrix_identity_set();
|
|
|
|
const int font_id = BLF_default();
|
|
|
|
const uiStyle *style = UI_style_get();
|
|
|
|
BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
|
|
|
|
BLI_memiter_iter_init(dt->cache_strings, &it);
|
|
while ((vos = BLI_memiter_iter_step(&it))) {
|
|
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] + vos->yoffs), 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);
|
|
}
|
|
}
|
|
|
|
GPU_matrix_pop();
|
|
GPU_matrix_projection_set(original_proj);
|
|
|
|
if (rv3d->rflag & RV3D_CLIPPING) {
|
|
ED_view3d_clipping_enable();
|
|
}
|
|
}
|
|
}
|