[Bf-blender-cvs] [2b445dac83f] lineart-shadow: LineArt: threaded shadow

Yiming Wu noreply at git.blender.org
Thu Jun 2 05:17:20 CEST 2022


Commit: 2b445dac83f0ddfae0049bc7d4bdd2423332d446
Author: Yiming Wu
Date:   Thu Jun 2 10:11:17 2022 +0800
Branches: lineart-shadow
https://developer.blender.org/rB2b445dac83f0ddfae0049bc7d4bdd2423332d446

LineArt: threaded shadow

LineArt: threaded shadow

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

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

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

diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 38bc230fa7d..66bd31a843f 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -346,7 +346,8 @@ typedef struct LineartRenderBuffer {
   ListBase chains;
 
   /* Intermediate shadow results, list of LineartShadowSegmentContainer */
-  ListBase shadow_containers;
+  LineartShadowSegmentContainer *shadow_containers;
+  int shadow_containers_count;
 
   /* For managing calculation tasks for multiple threads. */
   SpinLock lock_task;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c
index 936c9c80601..b3c0604bf52 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c
@@ -9,26 +9,13 @@
 
 #include "lineart_intern.h"
 
-#include "BKE_camera.h"
-#include "BKE_collection.h"
-#include "BKE_customdata.h"
-#include "BKE_deform.h"
-#include "BKE_duplilist.h"
-#include "BKE_editmesh.h"
 #include "BKE_global.h"
-#include "BKE_gpencil.h"
-#include "BKE_gpencil_geom.h"
 #include "BKE_gpencil_modifier.h"
 #include "BKE_lib_id.h"
 #include "BKE_material.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_mapping.h"
-#include "BKE_mesh_runtime.h"
 #include "BKE_object.h"
-#include "BKE_pointcache.h"
 #include "BKE_scene.h"
 #include "DEG_depsgraph_query.h"
-#include "DNA_camera_types.h"
 #include "DNA_collection_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_light_types.h"
@@ -39,6 +26,9 @@
 #include "DNA_scene_types.h"
 #include "MEM_guardedalloc.h"
 
+#include "BLI_task.h"
+#include "PIL_time.h"
+
 /* Shadow loading etc. ================== */
 
 LineartElementLinkNode *lineart_find_matching_eln(ListBase *shadow_elns, int obindex)
@@ -149,8 +139,8 @@ static void lineart_shadow_segment_slice_get(double *fbl,
   interp_v3_v3v3_db(r_g, gl, gr, ga);
 }
 
-/* Returns true when a new cut is needed in the middle, otherwise `*r_new_xxx` are not touched.
- */
+/* Returns true when a new cut is needed in the middle, otherwise returns false, and `*r_new_xxx`
+ * are not touched. */
 static bool lineart_do_closest_segment(bool is_persp,
                                        double *s1fbl,
                                        double *s1fbr,
@@ -285,6 +275,9 @@ static void lineart_shadow_create_container_array(LineartRenderBuffer *rb,
   LineartShadowSegment *ss = lineart_mem_acquire(&rb->render_data_pool,
                                                  sizeof(LineartShadowSegment) * segment_count * 2);
 
+  rb->shadow_containers = ssc;
+  rb->shadow_containers_count = segment_count;
+
   int i = 0;
   LRT_ITER_ALL_LINES_BEGIN
   {
@@ -334,7 +327,6 @@ static void lineart_shadow_create_container_array(LineartRenderBuffer *rb,
       }
 
       ssc[i].es_ref = es;
-      BLI_addtail(&rb->shadow_containers, &ssc[i]);
 
       i++;
     }
@@ -730,57 +722,72 @@ static bool lineart_shadow_cast_onto_triangle(LineartRenderBuffer *rb,
   return true;
 }
 
-static void lineart_shadow_cast(LineartRenderBuffer *rb,
-                                bool transform_edge_cuts,
-                                bool do_light_contour)
+static void lineart_shadow_cast_task(void *__restrict userdata,
+                                     const int ssc_index,
+                                     const TaskParallelTLS *__restrict UNUSED(tls))
 {
+  LineartRenderBuffer *rb = (LineartRenderBuffer *)userdata;
+  LineartShadowSegmentContainer *ssc = &rb->shadow_containers[ssc_index];
+
   LineartTriangleThread *tri;
   double at_l, at_r;
   double fb_l[4], fb_r[4];
   double global_l[3], global_r[3];
   bool facing_light;
 
-  lineart_shadow_create_container_array(rb, transform_edge_cuts, do_light_contour);
-
-  LISTBASE_FOREACH (LineartShadowSegmentContainer *, ssc, &rb->shadow_containers) {
-    LRT_EDGE_BA_MARCHING_BEGIN(ssc->fbc1, ssc->fbc2)
-    {
-      for (int i = 0; i < nba->triangle_count; i++) {
-        tri = (LineartTriangleThread *)nba->linked_triangles[i];
-        if (tri->testing_e[0] == (LineartEdge *)ssc ||
-            lineart_edge_from_triangle(
-                (LineartTriangle *)tri, ssc->e_ref, rb->allow_overlapping_edges)) {
-          continue;
-        }
-        tri->testing_e[0] = (LineartEdge *)ssc;
-
-        if (lineart_shadow_cast_onto_triangle(rb,
-                                              (LineartTriangle *)tri,
-                                              ssc,
-                                              &at_l,
-                                              &at_r,
-                                              fb_l,
-                                              fb_r,
-                                              global_l,
-                                              global_r,
-                                              &facing_light)) {
-          lineart_shadow_edge_cut(rb,
-                                  ssc,
-                                  at_l,
-                                  at_r,
-                                  global_l,
-                                  global_r,
-                                  fb_l,
-                                  fb_r,
-                                  facing_light,
-                                  tri->base.target_reference,
-                                  tri->base.silhouette_group);
-        }
+  LRT_EDGE_BA_MARCHING_BEGIN(ssc->fbc1, ssc->fbc2)
+  {
+    for (int i = 0; i < nba->triangle_count; i++) {
+      tri = (LineartTriangleThread *)nba->linked_triangles[i];
+      if (tri->testing_e[0] == (LineartEdge *)ssc ||
+          lineart_edge_from_triangle(
+              (LineartTriangle *)tri, ssc->e_ref, rb->allow_overlapping_edges)) {
+        continue;
+      }
+      tri->testing_e[0] = (LineartEdge *)ssc;
+
+      if (lineart_shadow_cast_onto_triangle(rb,
+                                            (LineartTriangle *)tri,
+                                            ssc,
+                                            &at_l,
+                                            &at_r,
+                                            fb_l,
+                                            fb_r,
+                                            global_l,
+                                            global_r,
+                                            &facing_light)) {
+        lineart_shadow_edge_cut(rb,
+                                ssc,
+                                at_l,
+                                at_r,
+                                global_l,
+                                global_r,
+                                fb_l,
+                                fb_r,
+                                facing_light,
+                                tri->base.target_reference,
+                                tri->base.silhouette_group);
       }
-      LRT_EDGE_BA_MARCHING_NEXT(ssc->fbc1, ssc->fbc2);
     }
-    LRT_EDGE_BA_MARCHING_END;
+    LRT_EDGE_BA_MARCHING_NEXT(ssc->fbc1, ssc->fbc2);
   }
+  LRT_EDGE_BA_MARCHING_END;
+}
+
+static void lineart_shadow_cast(LineartRenderBuffer *rb,
+                                bool transform_edge_cuts,
+                                bool do_light_contour)
+{
+
+  lineart_shadow_create_container_array(rb, transform_edge_cuts, do_light_contour);
+
+  TaskParallelSettings cast_settings;
+  BLI_parallel_range_settings_defaults(&cast_settings);
+  /* Set the minimum amount of edges a thread has to process. */
+  cast_settings.min_iter_per_thread = 2000;
+
+  BLI_task_parallel_range(
+      0, rb->shadow_containers_count, rb, lineart_shadow_cast_task, &cast_settings);
 }
 
 static bool lineart_shadow_cast_generate_edges(LineartRenderBuffer *rb,
@@ -790,7 +797,8 @@ static bool lineart_shadow_cast_generate_edges(LineartRenderBuffer *rb,
 {
   int tot_edges = 0;
   int tot_orig_edges = 0;
-  LISTBASE_FOREACH (LineartShadowSegmentContainer *, ssc, &rb->shadow_containers) {
+  for (int i = 0; i < rb->shadow_containers_count; i++) {
+    LineartShadowSegmentContainer *ssc = &rb->shadow_containers[i];
     LISTBASE_FOREACH (LineartShadowSegment *, ss, &ssc->shadow_segments) {
       if (!(ss->flag & LRT_SHADOW_CASTED)) {
         continue;
@@ -829,8 +837,9 @@ static bool lineart_shadow_cast_generate_edges(LineartRenderBuffer *rb,
   LineartVert *vlist = veln->pointer;
   LineartEdge *elist = eeln->pointer;
 
-  int i = 0;
-  LISTBASE_FOREACH (LineartShadowSegmentContainer *, ssc, &rb->shadow_containers) {
+  int ei = 0;
+  for (int i = 0; i < rb->shadow_containers_count; i++) {
+    LineartShadowSegmentContainer *ssc = &rb->shadow_containers[i];
     LISTBASE_FOREACH (LineartShadowSegment *, ss, &ssc->shadow_segments) {
       if (!(ss->flag & LRT_SHADOW_CASTED)) {
         continue;
@@ -838,9 +847,9 @@ static bool lineart_shadow_cast_generate_edges(LineartRenderBuffer *rb,
       if (!ss->next) {
         break;
       }
-      LineartEdge *e = &elist[i];
-      BLI_addtail(&e->segments, &es[i]);
-      LineartVert *v1 = &vlist[i * 2], *v2 = &vlist[i * 2 + 1];
+      LineartEdge *e = &elist[ei];
+      BLI_addtail(&e->segments, &es[ei]);
+      LineartVert *v1 = &vlist[ei * 2], *v2 = &vlist[ei * 2 + 1];
       copy_v3_v3_db(v1->gloc, ss->g2);
       copy_v3_v3_db(v2->gloc, ((LineartShadowSegment *)ss->next)->g1);
       e->v1 = v1;
@@ -852,13 +861,13 @@ static bool lineart_shadow_cast_generate_edges(LineartRenderBuffer *rb,
       e->silhouette_group = ss->silhouette_group;
       e->flags = (LRT_EDGE_FLAG_PROJECTED_SHADOW |
                   ((ss->flag & LRT_SHADOW_FACING_LIGHT) ? LRT_EDGE_FLAG_SHADOW_FACING_LIGHT : 0));
-      i++;
+      ei++;
     }
     if (do_original_edges) {
       /* Occlusion-corrected light contour. */
-      LineartEdge *e = &elist[i];
-      BLI_addtail(&e->segments, &es[i]);
-      LineartVert *v1 = &vlist[i * 2], *v2 = &vlist[i * 2 + 1];
+      LineartEdge *e = &elist[ei];
+      BLI_addtail(&e->segments, &es[ei]);
+      LineartVert *v1 = &vlist[ei * 2], *v2 = &vlist[ei * 2 + 1];
       // if (ssc->e_ref->t1 && ssc->

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list