[Bf-blender-cvs] [129b0d545c7] temp-lineart-contained: LineArt: Experimental smaller chunks on add_triangles.
YimingWu
noreply at git.blender.org
Fri Apr 22 10:42:54 CEST 2022
Commit: 129b0d545c7de8dab492085ba0a8a31e846d5678
Author: YimingWu
Date: Fri Apr 22 15:04:12 2022 +0800
Branches: temp-lineart-contained
https://developer.blender.org/rB129b0d545c7de8dab492085ba0a8a31e846d5678
LineArt: Experimental smaller chunks on add_triangles.
===================================================================
M release/datafiles/locale
M release/scripts/addons
M source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
M source/tools
===================================================================
diff --git a/release/datafiles/locale b/release/datafiles/locale
index 245306b56bd..11e2ea5c359 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit 245306b56bda2aa39af219c3dd705666363e2c54
+Subproject commit 11e2ea5c35988130f09ac10d4cbbad87ff2a7501
diff --git a/release/scripts/addons b/release/scripts/addons
index 754d05ac7eb..a254b56d417 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 754d05ac7ebb78377bbe6d80068542c43d347974
+Subproject commit a254b56d417a3cd6d23a29a1d45c5ac1e16f0fbe
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index ac3cdc43235..b9c9a74ac4f 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -238,6 +238,9 @@ typedef struct LineartRenderBuffer {
ListBase line_buffer_pointers;
ListBase triangle_buffer_pointers;
+ LineartElementLinkNode *isect_scheduled_up_to;
+ int isect_scheduled_up_to_index;
+
/** This one's memory is not from main pool and is free()ed after culling stage. */
ListBase triangle_adjacent_pointers;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index dd3d5f3f5d8..23cc0b1a835 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -58,14 +58,12 @@ typedef struct LineartIsecSingle {
} LineartIsecSingle;
typedef struct LineartIsecThread {
int thread_id;
- /* Thread triangle data. */
- /* Used to roughly spread the load. */
- int count_pending;
- /* An array of triangle element link nodes. */
- LineartElementLinkNode **pending_triangle_nodes;
- /* Count of above array. */
- int current_pending;
- int max_pending;
+
+ /* Scheduled work range. */
+ LineartElementLinkNode *pending_from;
+ LineartElementLinkNode *pending_to;
+ int index_from;
+ int index_to;
/* Thread intersection result data. */
LineartIsecSingle *array;
@@ -2729,13 +2727,13 @@ static void lineart_object_load_worker(TaskPool *__restrict UNUSED(pool),
//- Print size of pending objects.
//- Try to feed this with an array instead of via the pool instead of a custom list
//- Assign the number of objects instead of number of threads
- printf("thread start: %d\n", olti->thread_id);
+ // printf("thread start: %d\n", olti->thread_id);
for (LineartObjectInfo *obi = olti->pending; obi; obi = obi->next) {
lineart_geometry_object_load_no_bmesh(obi, olti->rb);
// lineart_geometry_object_load(obi, olti->rb);
- printf("thread id: %d processed: %d\n", olti->thread_id, obi->original_me->totpoly);
+ // printf("thread id: %d processed: %d\n", olti->thread_id, obi->original_me->totpoly);
}
- printf("thread end: %d\n", olti->thread_id);
+ // printf("thread end: %d\n", olti->thread_id);
}
static uchar lineart_intersection_mask_check(Collection *c, Object *ob)
@@ -3644,21 +3642,44 @@ static void lineart_add_isec_thread(LineartIsecThread *th,
th->current++;
}
-static void lineart_add_eln_thread(LineartIsecThread *th, LineartElementLinkNode *eln)
+#define LRT_ISECT_TRIANGLE_PER_THREAD 4096;
+
+static bool lineart_schedule_new_triangle_task(LineartIsecThread *th)
{
- if (th->current_pending == th->max_pending) {
-
- LineartElementLinkNode **new_array = MEM_mallocN(
- sizeof(LineartElementLinkNode *) * th->max_pending * 2, "LineartIsecSingle");
- memcpy(
- new_array, th->pending_triangle_nodes, sizeof(LineartElementLinkNode *) * th->max_pending);
- th->max_pending *= 2;
- MEM_freeN(th->pending_triangle_nodes);
- th->pending_triangle_nodes = new_array;
- }
- th->pending_triangle_nodes[th->current_pending] = eln;
- th->count_pending += eln->element_count;
- th->current_pending++;
+ LineartRenderBuffer *rb = th->rb;
+ int remaining = LRT_ISECT_TRIANGLE_PER_THREAD;
+
+ BLI_spin_lock(&rb->lock_task);
+ LineartElementLinkNode *eln = rb->isect_scheduled_up_to;
+
+ if (!eln) {
+ BLI_spin_unlock(&rb->lock_task);
+ return false;
+ }
+
+ th->pending_from = eln;
+ th->index_from = rb->isect_scheduled_up_to_index;
+
+ while (remaining > 0 && eln) {
+ int remaining_this_eln = eln->element_count - rb->isect_scheduled_up_to_index;
+ int added_count = MIN2(remaining, remaining_this_eln);
+ remaining -= added_count;
+ if (remaining || added_count == remaining_this_eln) {
+ eln = eln->next;
+ rb->isect_scheduled_up_to = eln;
+ rb->isect_scheduled_up_to_index = 0;
+ }
+ else {
+ rb->isect_scheduled_up_to_index += added_count;
+ }
+ }
+
+ th->pending_to = eln ? eln : rb->triangle_buffer_pointers.last;
+ th->index_to = rb->isect_scheduled_up_to_index;
+
+ BLI_spin_unlock(&rb->lock_task);
+
+ return true;
}
static void lineart_init_isec_thread(LineartIsecData *d, LineartRenderBuffer *rb, int thread_count)
@@ -3666,6 +3687,10 @@ static void lineart_init_isec_thread(LineartIsecData *d, LineartRenderBuffer *rb
d->threads = MEM_callocN(sizeof(LineartIsecThread) * thread_count, "LineartIsecThread arr");
d->rb = rb;
d->thread_count = thread_count;
+
+ rb->isect_scheduled_up_to = rb->triangle_buffer_pointers.first;
+ rb->isect_scheduled_up_to_index = 0;
+
for (int i = 0; i < thread_count; i++) {
LineartIsecThread *it = &d->threads[i];
it->array = MEM_mallocN(sizeof(LineartIsecSingle) * 100, "LineartIsecSingle arr");
@@ -3677,26 +3702,9 @@ static void lineart_init_isec_thread(LineartIsecData *d, LineartRenderBuffer *rb
#define OBJ_PER_ISEC_THREAD 8 /* Largely arbitrary, no need to be big. */
for (int i = 0; i < thread_count; i++) {
LineartIsecThread *it = &d->threads[i];
- it->pending_triangle_nodes = MEM_mallocN(
- sizeof(LineartElementLinkNode *) * OBJ_PER_ISEC_THREAD, "LineartIsec eln arr");
- it->max_pending = OBJ_PER_ISEC_THREAD;
- it->current_pending = 0;
it->rb = rb;
}
#undef OBJ_PER_ISEC_THREAD
-
- for (LineartElementLinkNode *eln = rb->triangle_buffer_pointers.first; eln; eln = eln->next) {
- /* Find threads with least triangle count inside. */
- LineartIsecThread *min_tri = &d->threads[0];
- for (int i = 0; i < thread_count; i++) {
- LineartIsecThread *it = &d->threads[i];
- if (min_tri->count_pending > it->count_pending) {
- min_tri = it;
- }
- }
- /* Assign it. */
- lineart_add_eln_thread(min_tri, eln);
- }
}
static void lineart_destroy_isec_thread(LineartIsecData *d)
@@ -3704,7 +3712,6 @@ static void lineart_destroy_isec_thread(LineartIsecData *d)
for (int i = 0; i < d->thread_count; i++) {
LineartIsecThread *it = &d->threads[i];
MEM_freeN(it->array);
- MEM_freeN(it->pending_triangle_nodes);
}
MEM_freeN(d->threads);
}
@@ -4708,45 +4715,48 @@ LineartBoundingArea *MOD_lineart_get_bounding_area(LineartRenderBuffer *rb, doub
static void lineart_add_triangles_worker(TaskPool *__restrict UNUSED(pool), LineartIsecThread *th)
{
- for (int ei = 0; ei < th->current_pending; ei++) {
- LineartElementLinkNode *eln = th->pending_triangle_nodes[ei];
- LineartTriangle *tri = eln->pointer;
- int i, lim = eln->element_count;
- int x1, x2, y1, y2;
- int r, co;
- LineartRenderBuffer *rb = th->rb;
- int _dir_control = 0;
-
- for (i = 0; i < lim; i++) {
- if ((tri->flags & LRT_CULL_USED) || (tri->flags & LRT_CULL_DISCARD)) {
- tri = (void *)(((uchar *)tri) + rb->triangle_size);
- continue;
- }
- if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) {
- _dir_control++;
- for (co = x1; co <= x2; co++) {
- for (r = y1; r <= y2; r++) {
- int col = co, row = r;
- if (_dir_control % 2) {
- col = x2 - (co - x1);
- }
- if ((_dir_control / 2) % 2) {
- row = y2 - (r - y1);
+ LineartRenderBuffer *rb = th->rb;
+ int _dir_control = 0;
+ while (lineart_schedule_new_triangle_task(th)) {
+ for (LineartElementLinkNode *eln = th->pending_from; eln != th->pending_to->next;
+ eln = eln->next) {
+ int index_start = eln == th->pending_from ? th->index_from : 0;
+ int index_end = eln == th->pending_to ? th->index_to : eln->element_count;
+ LineartTriangle *tri = (void *)(((uchar *)eln->pointer) + rb->triangle_size * index_start);
+ for (int ei = index_start; ei < index_end; ei++) {
+ int x1, x2, y1, y2;
+ int r, co;
+ LineartRenderBuffer *rb = th->rb;
+ if ((tri->flags & LRT_CULL_USED) || (tri->flags & LRT_CULL_DISCARD)) {
+ tri = (void *)(((uchar *)tri) + rb->triangle_size);
+ continue;
+ }
+ if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) {
+ _dir_control++;
+ for (co = x1; co <= x2; co++) {
+ for (r = y1; r <= y2; r++) {
+ int col = co, row = r;
+ if (_dir_control % 2) {
+ col = x2 - (co - x1);
+ }
+ if ((_dir_control / 2) % 2) {
+ row = y2 - (r - y1);
+ }
+ lineart_bounding_area_link_triangle(
+ rb,
+ &rb->initial_bounding_areas[row * LRT_BA_ROWS + col],
+ tri,
+ 0,
+ 1,
+ 0,
+ (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)),
+ true,
+ th);
}
- lineart_bounding_area_link_triangle(
- rb,
- &rb->initial_bounding_areas[row * LRT_BA_ROWS + col],
- tri,
- 0,
- 1,
- 0,
- (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)),
- true,
- th);
}
- }
- } /* Else throw away. */
- tri = (void *)(((uchar *)tri) + rb->triangle_size);
+ } /* Else throw away. */
+ tri = (void *)(((uchar *)tri) + rb->triangle_size);
+ }
}
}
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list