[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