[Bf-blender-cvs] [be97238308a] blender2.8: DwM: use BLI_memiter for draw storage & iteration
Campbell Barton
noreply at git.blender.org
Sat Jul 29 18:12:43 CEST 2017
Commit: be97238308a88d65903fb002cf8db2158d26ef7e
Author: Campbell Barton
Date: Sun Jul 30 02:17:11 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBbe97238308a88d65903fb002cf8db2158d26ef7e
DwM: use BLI_memiter for draw storage & iteration
This will only be noticeable for drawing many instances.
In contrived use-case with many instances, and `USE_PROFILE` disabled
this can close to double playback FPS.
The option to disable this is left in the code in case we want to
debug memory use.
See D2756 for details.
===================================================================
M source/blender/draw/intern/draw_manager.c
===================================================================
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index caf1894dc91..ce4390c40fb 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -129,6 +129,13 @@
/* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
#define USE_GPU_SELECT
+/* Use BLI_memiter */
+#define USE_MEM_ITER
+
+#ifdef USE_MEM_ITER
+#include "BLI_memiter.h"
+#endif
+
#ifdef USE_GPU_SELECT
# include "ED_view3d.h"
# include "ED_armature.h"
@@ -230,7 +237,10 @@ struct DRWPass {
};
typedef struct DRWCallHeader {
+#ifndef USE_MEM_ITER
void *next, *prev;
+#endif
+
#ifdef USE_GPU_SELECT
int select_id;
#endif
@@ -267,7 +277,14 @@ struct DRWShadingGroup {
GPUShader *shader; /* Shader to bind */
DRWInterface *interface; /* Uniforms pointers */
- ListBase calls; /* DRWCall or DRWCallDynamic depending of type */
+
+ /* DRWCall or DRWCallDynamic depending of type */
+#ifdef USE_MEM_ITER
+ BLI_memiter *calls;
+#else
+ ListBase calls;
+#endif
+
DRWState state_extra; /* State changes for this batch only (or'd with the pass's state) */
DRWState state_extra_disable; /* State changes for this batch only (and'd with the pass's state) */
int type;
@@ -729,6 +746,7 @@ static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRW
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
{
DRWShadingGroup *shgroup = MEM_mallocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
+ BLI_addtail(&pass->shgroups, shgroup);
shgroup->type = DRW_SHG_NORMAL;
shgroup->shader = shader;
@@ -738,8 +756,11 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
shgroup->batch_geom = NULL;
shgroup->instance_geom = NULL;
- BLI_addtail(&pass->shgroups, shgroup);
+#ifdef USE_MEM_ITER
+ shgroup->calls = BLI_memiter_create(BLI_MEMITER_DEFAULT_SIZE);
+#else
BLI_listbase_clear(&shgroup->calls);
+#endif
#ifdef USE_GPU_SELECT
shgroup->pass_parent = pass;
@@ -875,7 +896,12 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DR
void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
{
+#ifdef USE_MEM_ITER
+ BLI_memiter_destroy(shgroup->calls);
+#else
BLI_freelistN(&shgroup->calls);
+#endif
+
BLI_freelistN(&shgroup->interface->uniforms);
BLI_freelistN(&shgroup->interface->attribs);
@@ -902,7 +928,14 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm
{
BLI_assert(geom != NULL);
- DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+ DRWCall *call;
+
+#ifdef USE_MEM_ITER
+ call = BLI_memiter_calloc(shgroup->calls, sizeof(DRWCall));
+#else
+ call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+ BLI_addtail(&shgroup->calls, call);
+#endif
call->head.type = DRW_CALL_SINGLE;
#ifdef USE_GPU_SELECT
@@ -915,14 +948,22 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm
call->geometry = geom;
- BLI_addtail(&shgroup->calls, call);
+
+
}
void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob)
{
BLI_assert(geom != NULL);
- DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+ DRWCall *call;
+
+#ifdef USE_MEM_ITER
+ call = BLI_memiter_calloc(shgroup->calls, sizeof(DRWCall));
+#else
+ call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+ BLI_addtail(&shgroup->calls, call);
+#endif
call->head.type = DRW_CALL_SINGLE;
#ifdef USE_GPU_SELECT
@@ -933,7 +974,6 @@ void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Obje
call->geometry = geom;
call->ob_data = ob->data;
- BLI_addtail(&shgroup->calls, call);
}
void DRW_shgroup_call_generate_add(
@@ -943,7 +983,14 @@ void DRW_shgroup_call_generate_add(
{
BLI_assert(geometry_fn != NULL);
- DRWCallGenerate *call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate");
+ DRWCallGenerate *call;
+
+#ifdef USE_MEM_ITER
+ call = BLI_memiter_calloc(shgroup->calls, sizeof(DRWCallGenerate));
+#else
+ call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate");
+ BLI_addtail(&shgroup->calls, call);
+#endif
call->head.type = DRW_CALL_GENERATE;
#ifdef USE_GPU_SELECT
@@ -956,8 +1003,6 @@ void DRW_shgroup_call_generate_add(
call->geometry_fn = geometry_fn;
call->user_data = user_data;
-
- BLI_addtail(&shgroup->calls, call);
}
static void sculpt_draw_cb(
@@ -987,7 +1032,12 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
#ifdef USE_GPU_SELECT
if ((G.f & G_PICKSEL) && (interface->instance_count > 0)) {
shgroup = MEM_dupallocN(shgroup);
+
+#ifdef USE_MEM_ITER
+ shgroup->calls = BLI_memiter_create(BLI_MEMITER_DEFAULT_SIZE);
+#else
BLI_listbase_clear(&shgroup->calls);
+#endif
shgroup->interface = interface = DRW_interface_duplicate(interface);
interface->instance_count = 0;
@@ -999,7 +1049,16 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
unsigned int data_size = sizeof(void *) * interface->attribs_count;
int size = sizeof(DRWCallDynamic) + data_size;
- DRWCallDynamic *call = MEM_callocN(size, "DRWCallDynamic");
+ DRWCallDynamic *call;
+
+#ifdef USE_MEM_ITER
+ call = BLI_memiter_alloc(shgroup->calls, size);
+#else
+ call = MEM_mallocN(size, "DRWCallDynamic");
+ BLI_addtail(&shgroup->calls, call);
+#endif
+
+ memset(call, 0x0, sizeof(DRWCallDynamic));
BLI_assert(attr_len == interface->attribs_count);
UNUSED_VARS_NDEBUG(attr_len);
@@ -1014,8 +1073,6 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
}
interface->instance_count += 1;
-
- BLI_addtail(&shgroup->calls, call);
}
/* Used for instancing with no attributes */
@@ -1181,7 +1238,14 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
GWN_vertbuf_data_alloc(vbo, nbr);
int j = 0;
- for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next, j++) {
+#ifdef USE_MEM_ITER
+ BLI_memiter_handle calls_iter;
+ BLI_memiter_iter_init(shgroup->calls, &calls_iter);
+ for (DRWCallDynamic *call; (call = BLI_memiter_iter_step(&calls_iter)); j++)
+#else
+ for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next, j++)
+#endif
+ {
int i = 0;
for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
GWN_vertbuf_attr_set(vbo, attrib->format_id, j, call->data[i]);
@@ -1229,7 +1293,14 @@ static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count;
float *data = MEM_mallocN(buffer_size, "Instance VBO data");
- for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next) {
+#ifdef USE_MEM_ITER
+ BLI_memiter_handle calls_iter;
+ BLI_memiter_iter_init(shgroup->calls, &calls_iter);
+ for (DRWCallDynamic *call; (call = BLI_memiter_iter_step(&calls_iter)); )
+#else
+ for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next)
+#endif
+ {
for (int j = 0; j < interface->attribs_count; ++j) {
memcpy(data + offset, call->data[j], sizeof(float) * interface->attribs_size[j]);
offset += interface->attribs_size[j];
@@ -1307,11 +1378,21 @@ typedef struct ZSortData {
static int pass_shgroup_dist_sort(void *thunk, const void *a, const void *b)
{
+ const ZSortData *zsortdata = (ZSortData *)thunk;
const DRWShadingGroup *shgrp_a = (const DRWShadingGroup *)a;
const DRWShadingGroup *shgrp_b = (const DRWShadingGroup *)b;
- const DRWCall *call_a = (DRWCall *)(shgrp_a)->calls.first;
- const DRWCall *call_b = (DRWCall *)(shgrp_b)->calls.first;
- const ZSortData *zsortdata = (ZSortData *)thunk;
+
+ const DRWCall *call_a;
+ const DRWCall *call_b;
+
+#ifdef USE_MEM_ITER
+ call_a = BLI_memiter_elem_first(shgrp_a->calls);
+ call_b = BLI_memiter_elem_first(shgrp_b->calls);
+#else
+ call_a = shgrp_a->calls.first;
+ call_b = shgrp_b->calls.first;
+#endif
+
float tmp[3];
sub_v3_v3v3(tmp, zsortdata->origin, call_a->obmat[3]);
@@ -1858,11 +1939,24 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
if ((G.f & G_PICKSEL) && (_call)) { \
GPU_select_load_id((_call)->head.select_id); \
} ((void)0)
+
+#ifdef USE_MEM_ITER
+# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \
+ if (G.f & G_PICKSEL) { \
+ DRWCall *call_test = BLI_memiter_elem_first(*(_call_ls)); \
+ if (call_test != NULL) { \
+ BLI_assert(BLI_memiter_count(*(_call_ls)) == 1); \
+ GPU_select_load_id(call_test->head.select_id); \
+ } \
+ } ((void)0)
+#else
# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \
if ((G.f & G_PICKSEL) && (_call_ls)->first) { \
BLI_assert(BLI_listbase_is_single(_call_ls)); \
GPU_select_load_id(((DRWCall *)(_call_ls)->first)->head.select_id); \
} ((void)0)
+#endif
+
#else
# define GPU_SELECT_LOAD_IF_PICKSEL(call)
# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(call)
@@ -1889,7 +1983,14 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
}
else {
- for (DRWCall *call = shgroup->calls.first; call; call = call->head.next) {
+#ifdef USE_MEM_ITER
+ BLI_memiter_handle calls_iter;
+ BLI_memiter_iter_init(shgroup->calls, &calls_iter);
+ for (DRWCall *call; (call = BLI_memiter_iter_step(&calls_iter)); )
+#else
+ for (DRWCall *call = shgroup->calls.first; call; call = call->head.next)
+#endif
+ {
bool neg_scale = is_negative_m4(call->obmat);
/* Negative scale objects */
More information about the Bf-blender-cvs
mailing list