[Bf-blender-cvs] [cb089c25e2d] greasepencil-refactor: GPencil: Refactor: Speedup: Add drawcall merging of consecutive strokes
Clément Foucault
noreply at git.blender.org
Sat Jan 18 00:44:08 CET 2020
Commit: cb089c25e2d4a55fe1a1b374274905eebde71a6d
Author: Clément Foucault
Date: Sat Jan 18 00:42:27 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rBcb089c25e2d4a55fe1a1b374274905eebde71a6d
GPencil: Refactor: Speedup: Add drawcall merging of consecutive strokes
This reduces driver & DRW overhead when a lot of strokes are drawn with
the same material pool.
===================================================================
M source/blender/draw/engines/gpencil/gpencil_engine.c
===================================================================
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 8fbe0a61750..f1438e45755 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -314,8 +314,58 @@ typedef struct gpIterPopulateData {
/* Indices to do correct insertion of the sbuffer stroke. */
int stroke_index_last;
int stroke_index_offset;
+ /* Infos for call batching. */
+ struct GPUBatch *geom;
+ bool instancing;
+ int vfirst, vcount;
} gpIterPopulateData;
+#define DISABLE_BATCHING 0
+
+static void gp_drawcall_flush(gpIterPopulateData *iter)
+{
+#if !DISABLE_BATCHING
+ if (iter->geom != NULL) {
+ if (iter->instancing) {
+ DRW_shgroup_call_instance_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
+ }
+ else {
+ DRW_shgroup_call_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
+ }
+ }
+#endif
+
+ iter->geom = NULL;
+ iter->vfirst = -1;
+ iter->vcount = 0;
+}
+
+/* Group drawcalls that are consecutive and with the same type. Reduces GPU driver overhead. */
+static void gp_drawcall_add(
+ gpIterPopulateData *iter, struct GPUBatch *geom, bool instancing, int v_first, int v_count)
+{
+#if DISABLE_BATCHING
+ if (instancing) {
+ DRW_shgroup_call_instance_range(iter->grp, iter->ob, geom, v_first, v_count);
+ }
+ else {
+ DRW_shgroup_call_range(iter->grp, iter->ob, geom, v_first, v_count);
+ }
+#endif
+
+ int last = iter->vfirst + iter->vcount;
+ /* Interupt drawcall grouping if the sequence is not consecutive. */
+ if ((geom != iter->geom) || (v_first - last > 3)) {
+ gp_drawcall_flush(iter);
+ }
+ iter->geom = geom;
+ iter->instancing = instancing;
+ if (iter->vfirst == -1) {
+ iter->vfirst = v_first;
+ }
+ iter->vcount = v_first + v_count - iter->vfirst;
+}
+
static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
bGPDframe *UNUSED(gpf),
bGPDstroke *gps,
@@ -340,6 +390,7 @@ static void gp_sbuffer_cache_populate(gpIterPopulateData *iter)
}
gp_stroke_cache_populate(NULL, NULL, iter->pd->sbuffer_stroke, iter);
+ gp_drawcall_flush(iter);
iter->stroke_index_offset = iter->pd->sbuffer_stroke->totpoints + 1;
iter->do_sbuffer_call = 0;
@@ -355,6 +406,8 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
gpIterPopulateData *iter = (gpIterPopulateData *)thunk;
bGPdata *gpd = (bGPdata *)iter->ob->data;
+ gp_drawcall_flush(iter);
+
if (iter->do_sbuffer_call) {
gp_sbuffer_cache_populate(iter);
}
@@ -460,6 +513,8 @@ static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
(tex_stroke && (iter->tex_stroke != tex_stroke));
if (resource_changed) {
+ gp_drawcall_flush(iter);
+
iter->grp = DRW_shgroup_create_sub(iter->grp);
if (iter->ubo_mat != ubo_mat) {
DRW_shgroup_uniform_block(iter->grp, "gpMaterialBlock", ubo_mat);
@@ -482,7 +537,7 @@ static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
DRW_cache_gpencil_fills_get(iter->ob, iter->pd->cfra);
int vfirst = gps->runtime.fill_start * 3;
int vcount = gps->tot_triangles * 3;
- DRW_shgroup_call_range(iter->grp, iter->ob, geom, vfirst, vcount);
+ gp_drawcall_add(iter, geom, false, vfirst, vcount);
}
if (show_stroke) {
@@ -492,7 +547,7 @@ static void gp_stroke_cache_populate(bGPDlayer *UNUSED(gpl),
int vfirst = gps->runtime.stroke_start - 1;
/* Include "potential" cyclic vertex and start adj vertex (see shader). */
int vcount = gps->totpoints + 1 + 1;
- DRW_shgroup_call_instance_range(iter->grp, iter->ob, geom, vfirst, vcount);
+ gp_drawcall_add(iter, geom, true, vfirst, vcount);
}
iter->stroke_index_last = gps->runtime.stroke_start + gps->totpoints + 1;
@@ -529,6 +584,7 @@ static void gp_sbuffer_cache_populate_fast(GPENCIL_Data *vedata, gpIterPopulateD
iter->do_sbuffer_call = DRAW_NOW;
gp_stroke_cache_populate(NULL, NULL, iter->pd->sbuffer_stroke, iter);
+ gp_drawcall_flush(iter);
gpencil_vfx_cache_populate(vedata, iter->ob, iter->tgp_ob);
@@ -560,6 +616,8 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
BKE_gpencil_visible_stroke_iter(
ob, gp_layer_cache_populate, gp_stroke_cache_populate, &iter, pd->do_onion, pd->cfra);
+ gp_drawcall_flush(&iter);
+
if (iter.do_sbuffer_call) {
gp_sbuffer_cache_populate(&iter);
}
@@ -605,7 +663,6 @@ void GPENCIL_cache_finish(void *ved)
GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
GPENCIL_PrivateData *pd = vedata->stl->pd;
GPENCIL_FramebufferList *fbl = vedata->fbl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
/* Upload UBO data. */
BLI_memblock_iter iter;
More information about the Bf-blender-cvs
mailing list