[Bf-blender-cvs] [209de896f1b] lineart-fn-thread-loading: LineArt: Multithread object loading.

YimingWu noreply at git.blender.org
Tue Jun 1 15:32:25 CEST 2021


Commit: 209de896f1b11ba881957762a9d150ad0b0fa219
Author: YimingWu
Date:   Tue Mar 23 09:36:12 2021 +0800
Branches: lineart-fn-thread-loading
https://developer.blender.org/rB209de896f1b11ba881957762a9d150ad0b0fa219

LineArt: Multithread object loading.

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

M	source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c

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

diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 44ff0616fe9..389d0fa4fee 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "BLI_linklist.h"
 #include "BLI_listbase.h"
 #include "BLI_math.h" /* Needed here for inline functions. */
 #include "BLI_threads.h"
@@ -215,6 +216,7 @@ typedef struct LineartRenderBuffer {
   int tile_count_x, tile_count_y;
   double width_per_tile, height_per_tile;
   double view_projection[4][4];
+  double view[4][4];
 
   struct LineartBoundingArea *initial_bounding_areas;
   unsigned int bounding_area_count;
@@ -351,6 +353,33 @@ typedef struct LineartRenderTaskInfo {
 
 } LineartRenderTaskInfo;
 
+typedef struct LineartObjectInfo {
+  struct LineartObjectInfo *next;
+  struct Object *ob;
+  LineartElementLinkNode *v_reln;
+  int override_usage;
+  int global_i_offset;
+
+  /* Threads will add lines inside here, when all threads are done, we combine those into the ones
+   * in LineartRenderBuffer.  */
+  LineartEdge *contour;
+  LineartEdge *contour_last;
+  LineartEdge *crease;
+  LineartEdge *crease_last;
+  LineartEdge *material;
+  LineartEdge *material_last;
+  LineartEdge *edge_mark;
+  LineartEdge *edge_mark_last;
+  LineartEdge *intersection;
+  LineartEdge *intersection_last;
+} LineartObjectInfo;
+
+typedef struct LineartObjectLoadTaskInfo {
+  struct LineartRenderBuffer *rb;
+  struct Depsgraph *dg;
+  LineartObjectInfo *pending; /* LinkNode styled list */
+} LineartObjectLoadTaskInfo;
+
 /**
  * Bounding area diagram:
  * \code{.txt}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 52f7d3652a7..e886101969b 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1448,6 +1448,66 @@ static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e)
   }
 }
 
+static void lineart_add_edge_to_list_thread(LineartObjectInfo *obi, LineartEdge *e)
+{
+  switch (e->flags) {
+    case LRT_EDGE_FLAG_CONTOUR:
+      lineart_prepend_edge_direct(&obi->contour, e);
+      if (!obi->contour_last) {
+        obi->contour_last = e;
+      }
+      break;
+    case LRT_EDGE_FLAG_CREASE:
+      lineart_prepend_edge_direct(&obi->crease, e);
+      if (!obi->crease_last) {
+        obi->crease_last = e;
+      }
+      break;
+    case LRT_EDGE_FLAG_MATERIAL:
+      lineart_prepend_edge_direct(&obi->material, e);
+      if (!obi->material_last) {
+        obi->material_last = e;
+      }
+      break;
+    case LRT_EDGE_FLAG_EDGE_MARK:
+      lineart_prepend_edge_direct(&obi->edge_mark, e);
+      if (!obi->edge_mark_last) {
+        obi->edge_mark_last = e;
+      }
+      break;
+    case LRT_EDGE_FLAG_INTERSECTION:
+      lineart_prepend_edge_direct(&obi->intersection, e);
+      if (!obi->intersection_last) {
+        obi->intersection_last = e;
+      }
+      break;
+  }
+}
+
+static void lineart_finalize_object_edge_list(LineartRenderBuffer *rb, LineartObjectInfo *obi)
+{
+  if (obi->contour_last) {
+    obi->contour_last->next = rb->contours;
+    rb->contours = obi->contour;
+  }
+  if (obi->crease_last) {
+    obi->crease_last->next = rb->crease_lines;
+    rb->crease_lines = obi->crease;
+  }
+  if (obi->material_last) {
+    obi->material_last->next = rb->material_lines;
+    rb->material_lines = obi->material;
+  }
+  if (obi->edge_mark) {
+    obi->edge_mark->next = rb->edge_marks;
+    rb->edge_marks = obi->edge_mark;
+  }
+  if (obi->intersection_last) {
+    obi->intersection_last->next = rb->intersection_lines;
+    rb->intersection_lines = obi->intersection;
+  }
+}
+
 static void lineart_triangle_adjacent_assign(LineartTriangle *rt,
                                              LineartTriangleAdjacent *rta,
                                              LineartEdge *e)
@@ -1464,12 +1524,8 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *rt,
 }
 
 static void lineart_geometry_object_load(Depsgraph *dg,
-                                         Object *ob,
-                                         double (*mv_mat)[4],
-                                         double (*mvp_mat)[4],
-                                         LineartRenderBuffer *rb,
-                                         int override_usage,
-                                         int *global_vindex)
+                                         LineartObjectInfo *obi,
+                                         LineartRenderBuffer *rb)
 {
   BMesh *bm;
   BMVert *v;
@@ -1477,6 +1533,7 @@ static void lineart_geometry_object_load(Depsgraph *dg,
   BMEdge *e;
   BMLoop *loop;
   LineartEdge *la_e;
+  LineartLineSegment *la_s;
   LineartTriangle *rt;
   LineartTriangleAdjacent *orta;
   double new_mvp[4][4], new_mv[4][4], normal[4][4];
@@ -1484,14 +1541,16 @@ static void lineart_geometry_object_load(Depsgraph *dg,
   LineartElementLinkNode *reln;
   LineartVert *orv;
   LineartEdge *o_la_e;
+  LineartLineSegment *o_la_s;
   LineartTriangle *ort;
   Object *orig_ob;
   int CanFindFreestyle = 0;
-  int i, global_i = (*global_vindex);
+  Object *ob = obi->ob;
+  int i, global_i = 0;
   Mesh *use_mesh;
   float use_crease = 0;
 
-  int usage = override_usage ? override_usage : ob->lineart.usage;
+  int usage = obi->override_usage ? obi->override_usage : ob->lineart.usage;
 
 #define LRT_MESH_FINISH \
   BM_mesh_free(bm); \
@@ -1519,8 +1578,8 @@ static void lineart_geometry_object_load(Depsgraph *dg,
     }
 
     /* First we need to prepare the matrix used for transforming this specific object.  */
-    mul_m4db_m4db_m4fl_uniq(new_mvp, mvp_mat, ob->obmat);
-    mul_m4db_m4db_m4fl_uniq(new_mv, mv_mat, ob->obmat);
+    mul_m4db_m4db_m4fl_uniq(new_mvp, rb->view_projection, ob->obmat);
+    mul_m4db_m4db_m4fl_uniq(new_mv, rb->view, ob->obmat);
 
     invert_m4_m4(imat, ob->obmat);
     transpose_m4(imat);
@@ -1576,13 +1635,16 @@ static void lineart_geometry_object_load(Depsgraph *dg,
 
     /* Only allocate memory for verts and tris as we don't know how many lines we will generate
      * yet. */
-    orv = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert);
-    ort = lineart_mem_acquire(&rb->render_data_pool, bm->totface * rb->triangle_size);
+    orv = lineart_mem_aquire_thread(&rb->render_data_pool, sizeof(LineartVert) * bm->totvert);
+    ort = lineart_mem_aquire_thread(&rb->render_data_pool, bm->totface * rb->triangle_size);
 
     orig_ob = ob->id.orig_id ? (Object *)ob->id.orig_id : ob;
 
+    BLI_spin_lock(rb->lock_task);
     reln = lineart_list_append_pointer_pool_sized(
         &rb->vertex_buffer_pointers, &rb->render_data_pool, orv, sizeof(LineartElementLinkNode));
+    BLI_spin_unlock(rb->lock_task);
+
     reln->element_count = bm->totvert;
     reln->object_ref = orig_ob;
 
@@ -1599,8 +1661,10 @@ static void lineart_geometry_object_load(Depsgraph *dg,
       reln->flags |= LRT_ELEMENT_BORDER_ONLY;
     }
 
+    BLI_spin_lock(rb->lock_task);
     reln = lineart_list_append_pointer_pool_sized(
         &rb->triangle_buffer_pointers, &rb->render_data_pool, ort, sizeof(LineartElementLinkNode));
+    BLI_spin_unlock(rb->lock_task);
     reln->element_count = bm->totface;
     reln->object_ref = orig_ob;
     reln->flags |= (usage == OBJECT_LRT_NO_INTERSECTION ? LRT_ELEMENT_NO_INTERSECTION : 0);
@@ -1619,7 +1683,7 @@ static void lineart_geometry_object_load(Depsgraph *dg,
      * #lineart_main_load_geometries() for detailed. It's okay that global_vindex might eventually
      * overflow, in such large scene it's virtually impossible for two vertex of the same numeric
      * index to come close together. */
-    (*global_vindex) += bm->totvert;
+    obi->global_i_offset += bm->totvert;
 
     rt = ort;
     for (i = 0; i < bm->totface; i++) {
@@ -1675,13 +1739,18 @@ static void lineart_geometry_object_load(Depsgraph *dg,
       e->head.hflag = eflag;
     }
 
-    o_la_e = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * allocate_la_e);
+    o_la_e = lineart_mem_aquire_thread(&rb->render_data_pool, sizeof(LineartEdge) * allocate_la_e);
+    o_la_s = lineart_mem_aquire_thread(&rb->render_data_pool,
+                                       sizeof(LineartLineSegment) * allocate_la_e);
+    BLI_spin_lock(rb->lock_task);
     reln = lineart_list_append_pointer_pool_sized(
         &rb->line_buffer_pointers, &rb->render_data_pool, o_la_e, sizeof(LineartElementLinkNode));
+    BLI_spin_unlock(rb->lock_task);
     reln->element_count = allocate_la_e;
     reln->object_ref = orig_ob;
 
     la_e = o_la_e;
+    la_s = o_la_s;
     for (i = 0; i < bm->totedge; i++) {
       e = BM_edge_at_index(bm, i);
 
@@ -1706,15 +1775,14 @@ static void lineart_geometry_object_load(Depsgraph *dg,
       }
       la_e->flags = e->head.hflag;
       la_e->object_ref = orig_ob;
-
-      LineartLineSegment *rls = lineart_mem_acquire(&rb->render_data_pool,
-                                                    sizeof(LineartLineSegment));
-      BLI_addtail(&la_e->segments, rls);
-      if (ELEM(usage, OBJECT_LRT_INHERIT, OBJECT_LRT_INCLUDE, OBJECT_LRT_NO_INTERSECTION)) {
-        lineart_add_edge_to_list(rb, la_e);
+      BLI_addtail(&la_e->segments, la_s);
+      if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE ||
+          usage == OBJECT_LRT_NO_INTERSECTION) {
+        lineart_add_edge_to_list_thread(obi, la_e);
       }
 
       la_e++;
+      la_s++;
     }
 
     LRT_MESH_FINISH
@@ -1723,6 +1791,15 @@ static void lineart_geometry_object_load(Depsgraph *dg,
 #undef LRT_MESH_FINISH
 }
 
+static void lineart_object_load_worker(TaskPool *__restrict UNUSED(pool),
+                                       LineartObjectLoadTaskInfo *olti)
+{
+  LineartRenderBuffer *rb = olti->rb;
+  for (LineartObjectInfo *obi = olti->pending; obi; obi = obi->next) {
+    lineart_geometry_object_load(olti->dg, obi, olti->rb);
+  }
+}
+
 static bool _lineart_object_not_in_source_collection(Collection *sou

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list