[Bf-blender-cvs] [10c1823899c] greasepencil-refactor: GPencil: Refactor: Use iterator to populate draw passes

Clément Foucault noreply at git.blender.org
Sun Dec 8 01:39:01 CET 2019


Commit: 10c1823899ccd27c8c62a50c29d9db8bb86ab394
Author: Clément Foucault
Date:   Sat Dec 7 18:22:16 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB10c1823899ccd27c8c62a50c29d9db8bb86ab394

GPencil: Refactor: Use iterator to populate draw passes

Also remove a bug in gpencil_batch_cache_valid that prevented the use
of gpencil_batches_ensure more than once per redraw.

===================================================================

M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_draw_utils.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/shaders/gpencil_vert.glsl
M	source/blender/makesdna/DNA_gpencil_types.h

===================================================================

diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 350c6ce003f..194f7d40845 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -42,9 +42,8 @@
 #include "DEG_depsgraph.h"
 
 /* TODO remove the _new suffix. */
-GPENCIL_tObject *gpencil_object_cache_add_new(GPENCIL_Data *vedata, Object *UNUSED(ob))
+GPENCIL_tObject *gpencil_object_cache_add_new(GPENCIL_PrivateData *pd, Object *UNUSED(ob))
 {
-  GPENCIL_PrivateData *pd = vedata->stl->pd;
   GPENCIL_tObject *tgp_ob = BLI_memblock_alloc(pd->gp_object_pool);
 
   tgp_ob->layers.first = tgp_ob->layers.last = NULL;
@@ -54,12 +53,11 @@ GPENCIL_tObject *gpencil_object_cache_add_new(GPENCIL_Data *vedata, Object *UNUS
 }
 
 /* TODO remove the _new suffix. */
-GPENCIL_tLayer *gpencil_layer_cache_add_new(GPENCIL_Data *vedata,
+GPENCIL_tLayer *gpencil_layer_cache_add_new(GPENCIL_PrivateData *pd,
                                             Object *UNUSED(ob),
                                             bGPDlayer *UNUSED(layer))
 {
   // bGPdata *gpd = (bGPdata *)ob->data;
-  GPENCIL_PrivateData *pd = vedata->stl->pd;
   GPENCIL_tLayer *tgp_layer = BLI_memblock_alloc(pd->gp_layer_pool);
 
   DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
@@ -269,9 +267,12 @@ static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, in
     valid = false;
   }
   else if (cache->is_editmode) {
-    valid = false;
+    /* XXX FIXME This is bad as it means we cannot call gpencil_batch_cache_get twice in a row.
+     * Disabling for now. Edit: seems to work without it... */
+    // valid = false;
   }
   else if (cache->is_dirty) {
+    /* TODO, maybe get rid of the other dirty flags. */
     valid = false;
   }
 
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index ef22161561f..f4fd90f6e92 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -99,45 +99,49 @@ typedef struct gpIterData {
   GPUIndexBufBuilder ibo;
   int vert_len;
   int tri_len;
-  /** Index during vbo filling. */
-  int vidx;
 } gpIterData;
 
-static void gpencil_buffer_add_point(gpStrokeVert *verts, const bGPDspoint *pt)
+static int gpencil_stroke_is_cyclic(const bGPDstroke *stroke)
+{
+  return ((stroke->flag & GP_STROKE_CYCLIC) != 0) && (stroke->totpoints > 2);
+}
+
+static void gpencil_buffer_add_point(gpStrokeVert *verts, const bGPDspoint *pt, bool is_endpoint)
 {
   /* TODO other attribs */
   copy_v3_v3(verts->pos, &pt->x);
+  /* Tag endpoint material to -1 so they get discarded by vertex shader. */
+  verts->mat = (is_endpoint) ? -1 : 0;
 }
 
 static void gpencil_buffer_add_stroke(gpStrokeVert *verts, const bGPDstroke *stroke)
 {
   const bGPDspoint *pts = stroke->points;
   int pts_len = stroke->totpoints;
-  bool is_cyclic = ((stroke->flag & GP_STROKE_CYCLIC) != 0) && (pts_len > 2);
-  int v = 0;
+  bool is_cyclic = gpencil_stroke_is_cyclic(stroke);
+  int v = stroke->runtime.stroke_start;
 
   /* First point for adjacency (not drawn). */
   int adj_idx = (is_cyclic) ? (pts_len - 1) : 1;
-  gpencil_buffer_add_point(&verts[v++], &pts[adj_idx]);
+  gpencil_buffer_add_point(&verts[v++], &pts[adj_idx], true);
 
   for (int i = 0; i < pts_len; i++) {
-    gpencil_buffer_add_point(&verts[v++], &pts[i]);
+    gpencil_buffer_add_point(&verts[v++], &pts[i], false);
   }
   /* Draw line to first point to complete the loop for cyclic strokes. */
   if (is_cyclic) {
-    gpencil_buffer_add_point(&verts[v++], &pts[0]);
+    gpencil_buffer_add_point(&verts[v++], &pts[0], false);
   }
   /* Last adjacency point (not drawn). */
   adj_idx = (is_cyclic) ? 1 : (pts_len - 2);
-  gpencil_buffer_add_point(&verts[v++], &pts[adj_idx]);
+  gpencil_buffer_add_point(&verts[v++], &pts[adj_idx], true);
 }
 
-static void gpencil_buffer_add_fill(GPUIndexBufBuilder *ibo,
-                                    int start_idx,
-                                    const bGPDstroke *stroke)
+static void gpencil_buffer_add_fill(GPUIndexBufBuilder *ibo, const bGPDstroke *stroke)
 {
+  int v = stroke->runtime.fill_start;
   /* TODO ibo filling. */
-  UNUSED_VARS(ibo, start_idx, stroke);
+  UNUSED_VARS(v, ibo);
 }
 
 static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(layer),
@@ -146,17 +150,11 @@ static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(layer),
                                    void *thunk)
 {
   gpIterData *iter = (gpIterData *)thunk;
-  bool is_fill = true; /* TODO */
+  gpencil_buffer_add_stroke(iter->verts, stroke);
 
-  gpencil_buffer_add_stroke(&iter->verts[iter->vidx], stroke);
-
-  if (is_fill) {
-    gpencil_buffer_add_fill(&iter->ibo, iter->vidx, stroke);
+  if (true) { /* TODO */
+    gpencil_buffer_add_fill(&iter->ibo, stroke);
   }
-
-  /* Consider strokes always cyclic, hence the +1. */
-  iter->vidx += stroke->totpoints + 2 + 1;
-  BLI_assert(iter->vidx <= iter->vert_len);
 }
 
 static void gp_object_verts_count_cb(bGPDlayer *UNUSED(layer),
@@ -165,13 +163,18 @@ static void gp_object_verts_count_cb(bGPDlayer *UNUSED(layer),
                                      void *thunk)
 {
   gpIterData *iter = (gpIterData *)thunk;
-  /* Consider strokes always cyclic, hence the +1. */
-  iter->vert_len += stroke->totpoints + 2 + 1;
+
+  /* Store first index offset */
+  stroke->runtime.stroke_start = iter->vert_len;
+  stroke->runtime.fill_start = iter->tri_len;
+  iter->vert_len += stroke->totpoints + 2 + gpencil_stroke_is_cyclic(stroke);
   iter->tri_len += stroke->totpoints - 1;
 }
 
 static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
 {
+  bGPdata *gpd = (bGPdata *)ob->data;
+
   if (cache->vbo == NULL) {
     /* Should be discarded together. */
     BLI_assert(cache->vbo == NULL && cache->ibo == NULL);
@@ -183,9 +186,8 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
         .ibo = {0},
         .vert_len = 0,
         .tri_len = 0,
-        .vidx = 0,
     };
-    gpencil_object_visible_stroke_iter(ob, gp_object_verts_count_cb, &iter);
+    gpencil_object_visible_stroke_iter(ob, NULL, gp_object_verts_count_cb, &iter);
 
     /* Create VBO. */
     GPUVertFormat *format = gpencil_stroke_format();
@@ -196,7 +198,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
     GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len);
 
     /* Fill buffers with data. */
-    gpencil_object_visible_stroke_iter(ob, gpencil_stroke_iter_cb, &iter);
+    gpencil_object_visible_stroke_iter(ob, NULL, gpencil_stroke_iter_cb, &iter);
 
     /* Finish the IBO. */
     cache->ibo = GPU_indexbuf_build(&iter.ibo);
@@ -204,6 +206,9 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
     /* Create the batches */
     cache->fill_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo);
     cache->stroke_batch = GPU_batch_create(GPU_PRIM_LINE_STRIP, cache->vbo, NULL);
+
+    gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
+    cache->is_dirty = false;
   }
 }
 
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 3e7b77e8427..7c98035bbc0 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -60,9 +60,10 @@
  *
  * \{ */
 
-typedef void (*gpIterCb)(bGPDlayer *layer, bGPDframe *frame, bGPDstroke *stroke, void *thunk);
-
-void gpencil_object_visible_stroke_iter(Object *ob, gpIterCb stroke_cb, void *thunk)
+void gpencil_object_visible_stroke_iter(Object *ob,
+                                        gpIterCb layer_cb,
+                                        gpIterCb stroke_cb,
+                                        void *thunk)
 {
   bGPdata *gpd = (bGPdata *)ob->data;
   const bool main_onion = false; /* TODO */  // stl->storage->is_main_onion;
@@ -81,7 +82,7 @@ void gpencil_object_visible_stroke_iter(Object *ob, gpIterCb stroke_cb, void *th
 
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
     bGPDframe *init_gpf = NULL;
-    const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN));
+    const bool is_onion = (do_onion && (gpl->onion_flag & GP_LAYER_ONIONSKIN));
     if (gpl->flag & GP_LAYER_HIDE) {
       idx_eval++;
       continue;
@@ -90,7 +91,7 @@ void gpencil_object_visible_stroke_iter(Object *ob, gpIterCb stroke_cb, void *th
     /* Relative onion mode needs to find the frame range before. */
     int frame_from = -INT_MAX;
     int frame_to = INT_MAX;
-    if ((is_onion) && (mode == GP_ONION_MODE_RELATIVE)) {
+    if (is_onion && (mode == GP_ONION_MODE_RELATIVE)) {
       /* 1) Found first Frame. */
       int idx = 0;
       if (gpl->actframe) {
@@ -114,7 +115,7 @@ void gpencil_object_visible_stroke_iter(Object *ob, gpIterCb stroke_cb, void *th
     }
 
     /* If multiedit or onion skin need to count all frames of the layer. */
-    if ((is_multiedit) || (is_onion)) {
+    if (is_multiedit || is_onion) {
       init_gpf = gpl->frames.first;
     }
     else {
@@ -125,16 +126,20 @@ void gpencil_object_visible_stroke_iter(Object *ob, gpIterCb stroke_cb, void *th
       continue;
     }
 
+    if (layer_cb) {
+      layer_cb(gpl, NULL, NULL, thunk);
+    }
+
     for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
       LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
         if (!is_onion) {
           if ((!is_multiedit) ||
-              ((is_multiedit) && ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)))) {
+              (is_multiedit && ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)))) {
             stroke_cb(gpl, gpf, gps, thunk);
           }
         }
         else {
-          bool select = ((is_multiedit) &&
+          bool select = (is_multiedit &&
                          ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)));
 
           if (!select) {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/so

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list