Viewport Text Drawing: replace single allocs with a memarena
- pass label strlen since in many cases its already known. - use single linked list for cached text drawing. - add BLI_link_utils.h for single linked list macros. own tests give approx 22% overall speedup.
This commit is contained in:
parent
1b9db9911d
commit
3e3efae7e9
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BLI_LINK_UTILS_H__
|
||||
#define __BLI_LINK_UTILS_H__
|
||||
|
||||
/** \file BLI_link_utils.h
|
||||
* \ingroup bli
|
||||
* \brief Single link-list utility macros. (header only api).
|
||||
*
|
||||
* Use this api when the structure defines its own ``next`` pointer
|
||||
* and a double linked list such as #ListBase isnt needed.
|
||||
*/
|
||||
|
||||
#define BLI_LINKS_PREPEND(list, link) { \
|
||||
CHECK_TYPE_PAIR(list, link); \
|
||||
(link)->next = list; \
|
||||
list = link; \
|
||||
} (void)0
|
||||
|
||||
#define BLI_LINKS_FREE(list) { \
|
||||
while (list) { \
|
||||
void *next = list->next; \
|
||||
MEM_freeN(list); \
|
||||
list = next; \
|
||||
} \
|
||||
} (void)0
|
||||
|
||||
#endif /* __BLI_LINK_UTILS_H__ */
|
|
@ -210,8 +210,8 @@ void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac);
|
|||
short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, int x, int y);
|
||||
|
||||
/* cached text drawing in v2d, to allow pixel-aligned draw as post process */
|
||||
void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y, const char *str, const char col[4]);
|
||||
void UI_view2d_text_cache_rectf(struct View2D *v2d, const struct rctf *rect, const char *str, const char col[4]);
|
||||
void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y, const char *str, size_t str_len, const char col[4]);
|
||||
void UI_view2d_text_cache_rectf(struct View2D *v2d, const struct rctf *rect, const char *str, size_t str_len, const char col[4]);
|
||||
void UI_view2d_text_cache_draw(struct ARegion *ar);
|
||||
|
||||
/* operators */
|
||||
|
|
|
@ -38,9 +38,13 @@
|
|||
#include "DNA_scene_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_link_utils.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_timecode.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
@ -2175,56 +2179,76 @@ short UI_view2d_mouse_in_scrollers(const bContext *C, View2D *v2d, int x, int y)
|
|||
|
||||
/* ******************* view2d text drawing cache ******************** */
|
||||
|
||||
/* assumes caches are used correctly, so for time being no local storage in v2d */
|
||||
static ListBase strings = {NULL, NULL};
|
||||
|
||||
typedef struct View2DString {
|
||||
struct View2DString *next, *prev;
|
||||
struct View2DString *next;
|
||||
union {
|
||||
unsigned char ub[4];
|
||||
int pack;
|
||||
} col;
|
||||
int mval[2];
|
||||
rcti rect;
|
||||
int mval[2];
|
||||
} View2DString;
|
||||
|
||||
/* assumes caches are used correctly, so for time being no local storage in v2d */
|
||||
static MemArena *g_v2d_strings_arena = NULL;
|
||||
static View2DString *g_v2d_strings = NULL;
|
||||
|
||||
void UI_view2d_text_cache_add(View2D *v2d, float x, float y, const char *str, const char col[4])
|
||||
void UI_view2d_text_cache_add(View2D *v2d, float x, float y, const char *str, size_t str_len, const char col[4])
|
||||
{
|
||||
int mval[2];
|
||||
|
||||
BLI_assert(str_len == strlen(str));
|
||||
|
||||
UI_view2d_view_to_region(v2d, x, y, mval, mval + 1);
|
||||
|
||||
if (mval[0] != V2D_IS_CLIPPED && mval[1] != V2D_IS_CLIPPED) {
|
||||
int len = strlen(str) + 1;
|
||||
/* use calloc, rect has to be zeroe'd */
|
||||
View2DString *v2s = MEM_callocN(sizeof(View2DString) + len, "View2DString");
|
||||
char *v2s_str = (char *)(v2s + 1);
|
||||
memcpy(v2s_str, str, len);
|
||||
int alloc_len = str_len + 1;
|
||||
View2DString *v2s;
|
||||
|
||||
if (g_v2d_strings_arena == NULL) {
|
||||
g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
|
||||
}
|
||||
|
||||
v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
|
||||
|
||||
BLI_LINKS_PREPEND(g_v2d_strings, v2s);
|
||||
|
||||
BLI_addtail(&strings, v2s);
|
||||
v2s->col.pack = *((int *)col);
|
||||
|
||||
memset(&v2s->rect, 0, sizeof(v2s->rect));
|
||||
|
||||
v2s->mval[0] = mval[0];
|
||||
v2s->mval[1] = mval[1];
|
||||
|
||||
memcpy(v2s + 1, str, alloc_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* no clip (yet) */
|
||||
void UI_view2d_text_cache_rectf(View2D *v2d, const rctf *rect, const char *str, const char col[4])
|
||||
void UI_view2d_text_cache_rectf(View2D *v2d, const rctf *rect, const char *str, size_t str_len, const char col[4])
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
View2DString *v2s = MEM_callocN(sizeof(View2DString) + len, "View2DString");
|
||||
char *v2s_str = (char *)(v2s + 1);
|
||||
memcpy(v2s_str, str, len);
|
||||
int alloc_len = str_len;
|
||||
View2DString *v2s;
|
||||
|
||||
BLI_assert(str_len == strlen(str));
|
||||
|
||||
if (g_v2d_strings_arena == NULL) {
|
||||
g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
|
||||
}
|
||||
|
||||
v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
|
||||
|
||||
BLI_LINKS_PREPEND(g_v2d_strings, v2s);
|
||||
|
||||
v2s->col.pack = *((int *)col);
|
||||
|
||||
UI_view2d_to_region_no_clip(v2d, rect->xmin, rect->ymin, &v2s->rect.xmin, &v2s->rect.ymin);
|
||||
UI_view2d_to_region_no_clip(v2d, rect->xmax, rect->ymax, &v2s->rect.xmax, &v2s->rect.ymax);
|
||||
|
||||
v2s->col.pack = *((int *)col);
|
||||
v2s->mval[0] = v2s->rect.xmin;
|
||||
v2s->mval[1] = v2s->rect.ymin;
|
||||
|
||||
BLI_addtail(&strings, v2s);
|
||||
memcpy(v2s + 1, str, alloc_len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2234,7 +2258,7 @@ void UI_view2d_text_cache_draw(ARegion *ar)
|
|||
int col_pack_prev = 0;
|
||||
|
||||
/* investigate using BLF_ascender() */
|
||||
const float default_height = strings.first ? BLF_height_default("28", 3) : 0.0f;
|
||||
const float default_height = g_v2d_strings ? BLF_height_default("28", 3) : 0.0f;
|
||||
|
||||
// glMatrixMode(GL_PROJECTION);
|
||||
// glPushMatrix();
|
||||
|
@ -2242,7 +2266,7 @@ void UI_view2d_text_cache_draw(ARegion *ar)
|
|||
// glPushMatrix();
|
||||
ED_region_pixelspace(ar);
|
||||
|
||||
for (v2s = strings.first; v2s; v2s = v2s->next) {
|
||||
for (v2s = g_v2d_strings; v2s; v2s = v2s->next) {
|
||||
const char *str = (const char *)(v2s + 1);
|
||||
int xofs = 0, yofs;
|
||||
|
||||
|
@ -2263,14 +2287,17 @@ void UI_view2d_text_cache_draw(ARegion *ar)
|
|||
BLF_disable_default(BLF_CLIPPING);
|
||||
}
|
||||
}
|
||||
|
||||
g_v2d_strings = NULL;
|
||||
|
||||
if (g_v2d_strings_arena) {
|
||||
BLI_memarena_free(g_v2d_strings_arena);
|
||||
g_v2d_strings_arena = NULL;
|
||||
}
|
||||
|
||||
// glMatrixMode(GL_PROJECTION);
|
||||
// glPopMatrix();
|
||||
// glMatrixMode(GL_MODELVIEW);
|
||||
// glPopMatrix();
|
||||
|
||||
if (strings.first)
|
||||
BLI_freelistN(&strings);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -428,16 +428,17 @@ static void nla_draw_strip_text(AnimData *adt, NlaTrack *nlt, NlaStrip *strip, i
|
|||
{
|
||||
short notSolo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) && (nlt->flag & NLATRACK_SOLO) == 0);
|
||||
char str[256];
|
||||
size_t str_len;
|
||||
char col[4];
|
||||
float xofs;
|
||||
rctf rect;
|
||||
|
||||
/* just print the name and the range */
|
||||
if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
|
||||
BLI_snprintf(str, sizeof(str), "%d) Temp-Meta", index);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%d) Temp-Meta", index);
|
||||
}
|
||||
else {
|
||||
BLI_strncpy(str, strip->name, sizeof(str));
|
||||
str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str));
|
||||
}
|
||||
|
||||
/* set text color - if colors (see above) are light, draw black text, otherwise draw white */
|
||||
|
@ -470,7 +471,7 @@ static void nla_draw_strip_text(AnimData *adt, NlaTrack *nlt, NlaStrip *strip, i
|
|||
rect.ymax = ymaxc;
|
||||
|
||||
/* add this string to the cache of texts to draw */
|
||||
UI_view2d_text_cache_rectf(v2d, &rect, str, col);
|
||||
UI_view2d_text_cache_rectf(v2d, &rect, str, str_len, col);
|
||||
}
|
||||
|
||||
/* add frame extents to cache of text-strings to draw in pixelspace
|
||||
|
@ -480,7 +481,8 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
|
|||
{
|
||||
const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */
|
||||
const char col[4] = {220, 220, 220, 255}; /* light gray */
|
||||
char numstr[32] = "";
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
|
||||
|
||||
/* Always draw times above the strip, whereas sequencer drew below + above.
|
||||
|
@ -490,12 +492,12 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
|
|||
* while also preserving some accuracy, since we do use floats
|
||||
*/
|
||||
/* start frame */
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->start);
|
||||
UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, col);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->start);
|
||||
UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col);
|
||||
|
||||
/* end frame */
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->end);
|
||||
UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, col);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.1f", strip->end);
|
||||
UI_view2d_text_cache_add(v2d, strip->end, ymaxc + ytol, numstr, numstr_len, col);
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
|
|
|
@ -342,7 +342,6 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
|
|||
{
|
||||
float v1[2], v2[2], v3[2], rx1 = 0, rx2 = 0; //for triangles and rect
|
||||
float x1, x2, y1, y2;
|
||||
char numstr[32];
|
||||
unsigned int whichsel = 0;
|
||||
|
||||
x1 = seq->startdisp;
|
||||
|
@ -401,17 +400,20 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
|
|||
|
||||
if ((G.moving & G_TRANSFORM_SEQ) || (seq->flag & whichsel)) {
|
||||
const char col[4] = {255, 255, 255, 255};
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
|
||||
if (direction == SEQ_LEFTHANDLE) {
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", seq->startdisp);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", seq->startdisp);
|
||||
x1 = rx1;
|
||||
y1 -= 0.45f;
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
|
||||
x1 = x2 - handsize_clamped * 0.75f;
|
||||
y1 = y2 + 0.05f;
|
||||
}
|
||||
UI_view2d_text_cache_add(v2d, x1, y1, numstr, col);
|
||||
UI_view2d_text_cache_add(v2d, x1, y1, numstr, numstr_len, col);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,6 +528,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
|
|||
{
|
||||
rctf rect;
|
||||
char str[32 + FILE_MAX];
|
||||
size_t str_len;
|
||||
const char *name = seq->name + 2;
|
||||
char col[4];
|
||||
|
||||
|
@ -534,67 +537,76 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
|
|||
name = BKE_sequence_give_name(seq);
|
||||
|
||||
if (seq->type == SEQ_TYPE_META || seq->type == SEQ_TYPE_ADJUSTMENT) {
|
||||
BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len);
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_SCENE) {
|
||||
if (seq->scene) {
|
||||
if (seq->scene_camera) {
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s (%s) | %d",
|
||||
name, seq->scene->id.name + 2, ((ID *)seq->scene_camera)->name + 2, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s (%s) | %d",
|
||||
name, seq->scene->id.name + 2, ((ID *)seq->scene_camera)->name + 2, seq->len);
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->scene->id.name + 2, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->scene->id.name + 2, seq->len);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
}
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
|
||||
if (seq->clip && strcmp(name, seq->clip->id.name + 2) != 0) {
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->clip->id.name + 2, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->clip->id.name + 2, seq->len);
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
}
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_MASK) {
|
||||
if (seq->mask && strcmp(name, seq->mask->id.name + 2) != 0) {
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->mask->id.name + 2, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->mask->id.name + 2, seq->len);
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
}
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_MULTICAM) {
|
||||
BLI_snprintf(str, sizeof(str), "Cam %s: %d",
|
||||
name, seq->multicam_source);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "Cam %s: %d",
|
||||
name, seq->multicam_source);
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_IMAGE) {
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
|
||||
name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
|
||||
name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
|
||||
}
|
||||
else if (seq->type & SEQ_TYPE_EFFECT) {
|
||||
BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
|
||||
if (seq->sound)
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->sound->name, seq->len);
|
||||
else
|
||||
BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
if (seq->sound) {
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
|
||||
name, seq->sound->name, seq->len);
|
||||
}
|
||||
else {
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
}
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_MOVIE) {
|
||||
BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
|
||||
name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s: %s%s | %d",
|
||||
name, seq->strip->dir, seq->strip->stripdata->name, seq->len);
|
||||
}
|
||||
else {
|
||||
/* should never get here!, but might with files from future */
|
||||
BLI_assert(0);
|
||||
|
||||
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
|
||||
name, seq->len);
|
||||
}
|
||||
|
||||
if (seq->flag & SELECT) {
|
||||
|
@ -612,7 +624,8 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
|
|||
rect.ymin = y1;
|
||||
rect.xmax = x2;
|
||||
rect.ymax = y2;
|
||||
UI_view2d_text_cache_rectf(v2d, &rect, str, col);
|
||||
|
||||
UI_view2d_text_cache_rectf(v2d, &rect, str, str_len, col);
|
||||
}
|
||||
|
||||
/* draws a shaded strip, made from gradient + flat color + gradient */
|
||||
|
|
|
@ -238,22 +238,25 @@ void draw_motion_path_instance(Scene *scene,
|
|||
for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) {
|
||||
int frame = sfra + i;
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
float co[3];
|
||||
|
||||
/* only draw framenum if several consecutive highlighted points don't occur on same point */
|
||||
if (i == 0) {
|
||||
sprintf(numstr, " %d", frame);
|
||||
numstr_len = sprintf(numstr, " %d", frame);
|
||||
mul_v3_m4v3(co, ob->imat, mpv->co);
|
||||
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
|
||||
view3d_cached_text_draw_add(co, numstr, numstr_len,
|
||||
0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
|
||||
}
|
||||
else if ((i >= stepsize) && (i < len - stepsize)) {
|
||||
bMotionPathVert *mpvP = (mpv - stepsize);
|
||||
bMotionPathVert *mpvN = (mpv + stepsize);
|
||||
|
||||
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
|
||||
sprintf(numstr, " %d", frame);
|
||||
numstr_len = sprintf(numstr, " %d", frame);
|
||||
mul_v3_m4v3(co, ob->imat, mpv->co);
|
||||
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
|
||||
view3d_cached_text_draw_add(co, numstr, numstr_len,
|
||||
0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,10 +317,12 @@ void draw_motion_path_instance(Scene *scene,
|
|||
|
||||
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) {
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
|
||||
sprintf(numstr, " %d", (sfra + i));
|
||||
numstr_len = sprintf(numstr, " %d", (sfra + i));
|
||||
mul_v3_m4v3(co, ob->imat, mpv->co);
|
||||
view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
|
||||
view3d_cached_text_draw_add(co, numstr, numstr_len,
|
||||
0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2065,7 +2065,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
|
|||
/* Draw names of bone */
|
||||
if (arm->flag & ARM_DRAWNAMES) {
|
||||
mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail);
|
||||
view3d_cached_text_draw_add(vec, pchan->name, 10, 0, col);
|
||||
view3d_cached_text_draw_add(vec, pchan->name, strlen(pchan->name), 10, 0, col);
|
||||
}
|
||||
|
||||
/* Draw additional axes on the bone tail */
|
||||
|
@ -2270,7 +2270,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
|
|||
if (arm->flag & ARM_DRAWNAMES) {
|
||||
mid_v3_v3v3(vec, eBone->head, eBone->tail);
|
||||
glRasterPos3fv(vec);
|
||||
view3d_cached_text_draw_add(vec, eBone->name, 10, 0, col);
|
||||
view3d_cached_text_draw_add(vec, eBone->name, strlen(eBone->name), 10, 0, col);
|
||||
}
|
||||
/* Draw additional axes */
|
||||
if (arm->flag & ARM_DRAWAXES) {
|
||||
|
|
|
@ -43,8 +43,12 @@
|
|||
#include "DNA_world_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_link_utils.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
|
||||
#include "BKE_anim.h" /* for the where_on_path function */
|
||||
#include "BKE_armature.h"
|
||||
|
@ -742,11 +746,9 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3],
|
|||
}
|
||||
|
||||
/* *********** text drawing for object/particles/armature ************* */
|
||||
static ListBase CachedText[3];
|
||||
static int CachedTextLevel = 0;
|
||||
|
||||
typedef struct ViewCachedString {
|
||||
struct ViewCachedString *next, *prev;
|
||||
struct ViewCachedString *next;
|
||||
float vec[3];
|
||||
union {
|
||||
unsigned char ub[4];
|
||||
|
@ -759,43 +761,61 @@ typedef struct ViewCachedString {
|
|||
/* str is allocated past the end */
|
||||
} ViewCachedString;
|
||||
|
||||
/* one arena for all 3 string lists */
|
||||
static MemArena *g_v3d_strings_arena = NULL;
|
||||
static ViewCachedString *g_v3d_strings[3] = {NULL, NULL, NULL};
|
||||
static int g_v3d_string_level = -1;
|
||||
|
||||
void view3d_cached_text_draw_begin(void)
|
||||
{
|
||||
ListBase *strings = &CachedText[CachedTextLevel];
|
||||
BLI_listbase_clear(strings);
|
||||
CachedTextLevel++;
|
||||
g_v3d_string_level++;
|
||||
|
||||
BLI_assert(g_v3d_string_level >= 0);
|
||||
|
||||
if (g_v3d_string_level == 0) {
|
||||
BLI_assert(g_v3d_strings_arena == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void view3d_cached_text_draw_add(const float co[3],
|
||||
const char *str,
|
||||
const char *str, const size_t str_len,
|
||||
short xoffs, short flag,
|
||||
const unsigned char col[4])
|
||||
{
|
||||
int alloc_len = strlen(str) + 1;
|
||||
ListBase *strings = &CachedText[CachedTextLevel - 1];
|
||||
int alloc_len = str_len + 1;
|
||||
/* TODO, replace with more efficient malloc, perhaps memarena per draw? */
|
||||
ViewCachedString *vos = MEM_callocN(sizeof(ViewCachedString) + alloc_len, "ViewCachedString");
|
||||
ViewCachedString *vos;
|
||||
|
||||
BLI_assert(str_len == strlen(str));
|
||||
|
||||
if (g_v3d_strings_arena == NULL) {
|
||||
g_v3d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
|
||||
}
|
||||
|
||||
vos = BLI_memarena_alloc(g_v3d_strings_arena, sizeof(ViewCachedString) + alloc_len);
|
||||
|
||||
BLI_LINKS_PREPEND(g_v3d_strings[g_v3d_string_level], vos);
|
||||
|
||||
BLI_addtail(strings, vos);
|
||||
copy_v3_v3(vos->vec, co);
|
||||
copy_v4_v4_char((char *)vos->col.ub, (const char *)col);
|
||||
vos->xoffs = xoffs;
|
||||
vos->flag = flag;
|
||||
vos->str_len = alloc_len - 1;
|
||||
vos->str_len = str_len;
|
||||
|
||||
/* allocate past the end */
|
||||
memcpy(++vos, str, alloc_len);
|
||||
memcpy(vos + 1, str, alloc_len);
|
||||
}
|
||||
|
||||
void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, float mat[4][4])
|
||||
{
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
ListBase *strings = &CachedText[CachedTextLevel - 1];
|
||||
ViewCachedString *vos;
|
||||
int tot = 0;
|
||||
|
||||
BLI_assert(g_v3d_string_level >= 0 && g_v3d_string_level <= 2);
|
||||
|
||||
/* project first and test */
|
||||
for (vos = strings->first; vos; vos = vos->next) {
|
||||
for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
|
||||
if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
|
||||
mul_m4_v3(mat, vos->vec);
|
||||
|
||||
|
@ -840,7 +860,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
|
|||
glDepthMask(0);
|
||||
}
|
||||
|
||||
for (vos = strings->first; vos; vos = vos->next) {
|
||||
for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
|
||||
if (vos->sco[0] != IS_CLIPPED) {
|
||||
const char *str = (char *)(vos + 1);
|
||||
|
||||
|
@ -859,7 +879,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
|
|||
vos->str_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (depth_write) {
|
||||
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
@ -876,11 +896,17 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
|
|||
ED_view3d_clipping_enable();
|
||||
}
|
||||
}
|
||||
|
||||
if (strings->first)
|
||||
BLI_freelistN(strings);
|
||||
|
||||
CachedTextLevel--;
|
||||
|
||||
g_v3d_strings[g_v3d_string_level] = NULL;
|
||||
|
||||
if (g_v3d_string_level == 0) {
|
||||
if (g_v3d_strings_arena) {
|
||||
BLI_memarena_free(g_v3d_strings_arena);
|
||||
g_v3d_strings_arena = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_v3d_string_level--;
|
||||
}
|
||||
|
||||
/* ******************** primitive drawing ******************* */
|
||||
|
@ -1605,7 +1631,10 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D
|
|||
float pos[3];
|
||||
|
||||
mul_v3_m4v3(pos, mat, track->bundle_pos);
|
||||
view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, selected ? col_sel : col_unsel);
|
||||
view3d_cached_text_draw_add(pos,
|
||||
track->name, strlen(track->name),
|
||||
10, V3D_CACHE_TEXT_GLOBALSPACE,
|
||||
selected ? col_sel : col_unsel);
|
||||
}
|
||||
|
||||
tracknr++;
|
||||
|
@ -2780,6 +2809,7 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
|
|||
Mesh *me = ob->data;
|
||||
float v1[3], v2[3], v3[3], vmid[3], fvec[3];
|
||||
char numstr[32]; /* Stores the measurement display text here */
|
||||
size_t numstr_len;
|
||||
const char *conv_float; /* Use a float conversion matching the grid size */
|
||||
unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */
|
||||
float area; /* area of the face */
|
||||
|
@ -2857,14 +2887,14 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
|
|||
}
|
||||
|
||||
if (unit->system) {
|
||||
bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3,
|
||||
unit->system, B_UNIT_LENGTH, do_split, false);
|
||||
numstr_len = bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3,
|
||||
unit->system, B_UNIT_LENGTH, do_split, false);
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2));
|
||||
}
|
||||
|
||||
view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
|
||||
view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2940,9 +2970,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
|
|||
|
||||
angle = angle_normalized_v3v3(no_a, no_b);
|
||||
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
|
||||
|
||||
view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
|
||||
view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2959,14 +2989,15 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
|
|||
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { \
|
||||
mul_v3_fl(vmid, 1.0f / (float)n); \
|
||||
if (unit->system) { \
|
||||
bUnit_AsString(numstr, sizeof(numstr), \
|
||||
(double)(area * unit->scale_length * unit->scale_length), \
|
||||
3, unit->system, B_UNIT_AREA, do_split, false); \
|
||||
numstr_len = bUnit_AsString( \
|
||||
numstr, sizeof(numstr), \
|
||||
(double)(area * unit->scale_length * unit->scale_length), \
|
||||
3, unit->system, B_UNIT_AREA, do_split, false); \
|
||||
} \
|
||||
else { \
|
||||
BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), conv_float, area); \
|
||||
} \
|
||||
view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); \
|
||||
view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); \
|
||||
} (void)0
|
||||
|
||||
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
|
||||
|
@ -3082,9 +3113,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
|
|||
|
||||
angle = angle_v3v3v3(v1, v2, v3);
|
||||
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
|
||||
interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
|
||||
view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
|
||||
view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3100,6 +3131,7 @@ static void draw_em_indices(BMEditMesh *em)
|
|||
BMVert *v;
|
||||
int i;
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
float pos[3];
|
||||
unsigned char col[4];
|
||||
|
||||
|
@ -3112,8 +3144,8 @@ static void draw_em_indices(BMEditMesh *em)
|
|||
UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", i);
|
||||
view3d_cached_text_draw_add(v->co, numstr, 0, txt_flag, col);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
|
||||
view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -3124,9 +3156,9 @@ static void draw_em_indices(BMEditMesh *em)
|
|||
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", i);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
|
||||
mid_v3_v3v3(pos, e->v1->co, e->v2->co);
|
||||
view3d_cached_text_draw_add(pos, numstr, 0, txt_flag, col);
|
||||
view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -3138,8 +3170,8 @@ static void draw_em_indices(BMEditMesh *em)
|
|||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
||||
BM_face_calc_center_mean(f, pos);
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%d", i);
|
||||
view3d_cached_text_draw_add(pos, numstr, 0, txt_flag, col);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", i);
|
||||
view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -4484,6 +4516,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||
bool select = (ob->flag & SELECT) != 0, create_cdata = false, need_v = false;
|
||||
GLint polygonmode[2];
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
unsigned char tcol[4] = {0, 0, 0, 255};
|
||||
|
||||
/* 1. */
|
||||
|
@ -4831,28 +4864,32 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||
if ((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) &&
|
||||
(v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)
|
||||
{
|
||||
size_t numstr_len;
|
||||
float vec_txt[3];
|
||||
char *val_pos = numstr;
|
||||
numstr[0] = '\0';
|
||||
|
||||
if (part->draw & PART_DRAW_NUM) {
|
||||
if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
|
||||
BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
|
||||
numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health);
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(val_pos, sizeof(numstr), "%d", a);
|
||||
numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%d", a);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) {
|
||||
BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health);
|
||||
numstr_len = BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health);
|
||||
}
|
||||
}
|
||||
|
||||
/* in path drawing state.co is the end point */
|
||||
/* use worldspace beause object matrix is already applied */
|
||||
mul_v3_m4v3(vec_txt, ob->imat, state.co);
|
||||
view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
|
||||
if (numstr[0]) {
|
||||
/* in path drawing state.co is the end point */
|
||||
/* use worldspace beause object matrix is already applied */
|
||||
mul_v3_m4v3(vec_txt, ob->imat, state.co);
|
||||
view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
|
||||
10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4944,10 +4981,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
|||
|
||||
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
|
||||
float vec_txt[3];
|
||||
BLI_snprintf(numstr, sizeof(numstr), "%i", a);
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%i", a);
|
||||
/* use worldspace beause object matrix is already applied */
|
||||
mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co);
|
||||
view3d_cached_text_draw_add(vec_txt, numstr, 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
|
||||
view3d_cached_text_draw_add(vec_txt, numstr, numstr_len,
|
||||
10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6630,7 +6668,7 @@ static void draw_rigid_body_pivot(bRigidBodyJointConstraint *data,
|
|||
/* when const color is set wirecolor is NULL - we could get the current color but
|
||||
* with selection and group instancing its not needed to draw the text */
|
||||
if ((dflag & DRAW_CONSTCOLOR) == 0) {
|
||||
view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
|
||||
view3d_cached_text_draw_add(v, axis_str[axis], 2, 0, V3D_CACHE_TEXT_ASCII, ob_wire_col);
|
||||
}
|
||||
}
|
||||
glLineWidth(1.0f);
|
||||
|
@ -7404,7 +7442,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
|
|||
/* but, we also don't draw names for sets or duplicators */
|
||||
if (dflag == 0) {
|
||||
const float zero[3] = {0, 0, 0};
|
||||
view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, ob_wire_col);
|
||||
view3d_cached_text_draw_add(zero, ob->id.name + 2, strlen(ob->id.name + 2), 10, 0, ob_wire_col);
|
||||
}
|
||||
}
|
||||
/*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
|
||||
|
|
|
@ -140,7 +140,9 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struc
|
|||
void drawaxes(float size, char drawtype);
|
||||
|
||||
void view3d_cached_text_draw_begin(void);
|
||||
void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]);
|
||||
void view3d_cached_text_draw_add(const float co[3],
|
||||
const char *str, const size_t str_len,
|
||||
short xoffs, short flag, const unsigned char col[4]);
|
||||
void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, float mat[4][4]);
|
||||
|
||||
bool check_object_draw_texture(struct Scene *scene, struct View3D *v3d, const char drawtype);
|
||||
|
|
Loading…
Reference in New Issue