From 9f60188cd805d10155c79ddb99adb703d6da7ba1 Mon Sep 17 00:00:00 2001 From: YimingWu Date: Tue, 25 May 2021 23:32:04 +0800 Subject: Cleanup: Use ListBase in various places in line art. This clarifies the data structures for storing edges for different calculation stages. Reviewed By: Sebastian Parborg (zeddb) Differential Revision: https://developer.blender.org/D11386 --- .../gpencil_modifiers/intern/lineart/MOD_lineart.h | 54 ++++----------- .../gpencil_modifiers/intern/lineart/lineart_cpu.c | 81 ++++++++++------------ .../intern/lineart/lineart_intern.h | 39 +++++++---- .../intern/lineart/lineart_util.c | 6 +- 4 files changed, 79 insertions(+), 101 deletions(-) (limited to 'source/blender/gpencil_modifiers/intern') diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 56b1ff87f0b..e679dce2f2d 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -237,31 +237,14 @@ typedef struct LineartRenderBuffer { int triangle_size; - unsigned int contour_count; - unsigned int contour_processed; - LineartEdge *contour_managed; - /** A single linked list (cast to #LinkNode). */ - LineartEdge *contours; - - unsigned int intersection_count; - unsigned int intersection_processed; - LineartEdge *intersection_managed; - LineartEdge *intersection_lines; - - unsigned int crease_count; - unsigned int crease_processed; - LineartEdge *crease_managed; - LineartEdge *crease_lines; - - unsigned int material_line_count; - unsigned int material_processed; - LineartEdge *material_managed; - LineartEdge *material_lines; - - unsigned int edge_mark_count; - unsigned int edge_mark_processed; - LineartEdge *edge_mark_managed; - LineartEdge *edge_marks; + /* Although using ListBase here, LineartEdge is single linked list. + * list.last is used to store worker progress along the list. + * See lineart_main_occlusion_begin() for more info. */ + ListBase contour; + ListBase intersection; + ListBase crease; + ListBase material; + ListBase edge_mark; ListBase chains; @@ -334,20 +317,13 @@ typedef struct LineartRenderTaskInfo { int thread_id; - LineartEdge *contour; - LineartEdge *contour_end; - - LineartEdge *intersection; - LineartEdge *intersection_end; - - LineartEdge *crease; - LineartEdge *crease_end; - - LineartEdge *material; - LineartEdge *material_end; - - LineartEdge *edge_mark; - LineartEdge *edge_mark_end; + /* These lists only denote the part of the main edge list that the thread should iterate over. + * Be careful to not iterate outside of these bounds as it is not thread safe to do so. */ + ListBase contour; + ListBase intersection; + ListBase crease; + ListBase material; + ListBase edge_mark; } LineartRenderTaskInfo; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index d43b9a3426f..ae8157e1a97 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -376,18 +376,18 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend BLI_spin_lock(&rb->lock_task); #define LRT_ASSIGN_OCCLUSION_TASK(name) \ - if (rb->name##_managed) { \ - data = rb->name##_managed; \ - rti->name = (void *)data; \ + if (rb->name.last) { \ + data = rb->name.last; \ + rti->name.first = (void *)data; \ for (i = 0; i < LRT_THREAD_EDGE_COUNT && data; i++) { \ data = data->next; \ } \ - rti->name##_end = data; \ - rb->name##_managed = data; \ + rti->name.last = data; \ + rb->name.last = data; \ res = 1; \ } \ else { \ - rti->name = NULL; \ + rti->name.first = rti->name.last = NULL; \ } LRT_ASSIGN_OCCLUSION_TASK(contour); @@ -410,23 +410,23 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR while (lineart_occlusion_make_task_info(rb, rti)) { - for (eip = rti->contour; eip && eip != rti->contour_end; eip = eip->next) { + for (eip = rti->contour.first; eip && eip != rti->contour.last; eip = eip->next) { lineart_occlusion_single_line(rb, eip, rti->thread_id); } - for (eip = rti->crease; eip && eip != rti->crease_end; eip = eip->next) { + for (eip = rti->crease.first; eip && eip != rti->crease.last; eip = eip->next) { lineart_occlusion_single_line(rb, eip, rti->thread_id); } - for (eip = rti->intersection; eip && eip != rti->intersection_end; eip = eip->next) { + for (eip = rti->intersection.first; eip && eip != rti->intersection.last; eip = eip->next) { lineart_occlusion_single_line(rb, eip, rti->thread_id); } - for (eip = rti->material; eip && eip != rti->material_end; eip = eip->next) { + for (eip = rti->material.first; eip && eip != rti->material.last; eip = eip->next) { lineart_occlusion_single_line(rb, eip, rti->thread_id); } - for (eip = rti->edge_mark; eip && eip != rti->edge_mark_end; eip = eip->next) { + for (eip = rti->edge_mark.first; eip && eip != rti->edge_mark.last; eip = eip->next) { lineart_occlusion_single_line(rb, eip, rti->thread_id); } } @@ -444,11 +444,13 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb) "Task Pool"); int i; - rb->contour_managed = rb->contours; - rb->crease_managed = rb->crease_lines; - rb->intersection_managed = rb->intersection_lines; - rb->material_managed = rb->material_lines; - rb->edge_mark_managed = rb->edge_marks; + /* The "last" entry is used to store worker progress in the whole list. + * These list themselves are single-direction linked, with list.first being the head. */ + rb->contour.last = rb->contour.first; + rb->crease.last = rb->crease.first; + rb->intersection.last = rb->intersection.first; + rb->material.last = rb->material.first; + rb->edge_mark.last = rb->edge_mark.first; TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH); @@ -853,7 +855,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, INCREASE_EDGE if (allow_boundaries) { e->flags = LRT_EDGE_FLAG_CONTOUR; - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); } /* NOTE: inverting `e->v1/v2` (left/right point) doesn't matter as long as * `tri->edge` and `tri->v` has the same sequence. and the winding direction @@ -902,7 +904,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, INCREASE_EDGE if (allow_boundaries) { e->flags = LRT_EDGE_FLAG_CONTOUR; - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); } e->v1 = &vt[0]; e->v2 = &vt[1]; @@ -943,7 +945,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, INCREASE_EDGE if (allow_boundaries) { e->flags = LRT_EDGE_FLAG_CONTOUR; - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); } e->v1 = &vt[1]; e->v2 = &vt[0]; @@ -1018,7 +1020,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, INCREASE_EDGE if (allow_boundaries) { e->flags = LRT_EDGE_FLAG_CONTOUR; - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); } e->v1 = &vt[1]; e->v2 = &vt[0]; @@ -1070,7 +1072,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, INCREASE_EDGE if (allow_boundaries) { e->flags = LRT_EDGE_FLAG_CONTOUR; - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); } e->v1 = &vt[1]; e->v2 = &vt[0]; @@ -1118,7 +1120,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb, INCREASE_EDGE if (allow_boundaries) { e->flags = LRT_EDGE_FLAG_CONTOUR; - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); } e->v1 = &vt[1]; e->v2 = &vt[0]; @@ -1431,19 +1433,19 @@ static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e) { switch (e->flags) { case LRT_EDGE_FLAG_CONTOUR: - lineart_prepend_edge_direct(&rb->contours, e); + lineart_prepend_edge_direct(&rb->contour.first, e); break; case LRT_EDGE_FLAG_CREASE: - lineart_prepend_edge_direct(&rb->crease_lines, e); + lineart_prepend_edge_direct(&rb->crease.first, e); break; case LRT_EDGE_FLAG_MATERIAL: - lineart_prepend_edge_direct(&rb->material_lines, e); + lineart_prepend_edge_direct(&rb->material.first, e); break; case LRT_EDGE_FLAG_EDGE_MARK: - lineart_prepend_edge_direct(&rb->edge_marks, e); + lineart_prepend_edge_direct(&rb->edge_mark.first, e); break; case LRT_EDGE_FLAG_INTERSECTION: - lineart_prepend_edge_direct(&rb->intersection_lines, e); + lineart_prepend_edge_direct(&rb->intersection.first, e); break; } } @@ -2497,7 +2499,7 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb, BLI_addtail(&result->segments, es); /* Don't need to OR flags right now, just a type mark. */ result->flags = LRT_EDGE_FLAG_INTERSECTION; - lineart_prepend_edge_direct(&rb->intersection_lines, result); + lineart_prepend_edge_direct(&rb->intersection.first, result); int r1, r2, c1, c2, row, col; if (lineart_get_edge_bounding_areas(rb, result, &r1, &r2, &c1, &c2)) { for (row = r1; row != r2 + 1; row++) { @@ -2508,8 +2510,6 @@ static LineartEdge *lineart_triangle_intersect(LineartRenderBuffer *rb, } } - rb->intersection_count++; - return result; } @@ -2598,22 +2598,11 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb) return; } - rb->contour_count = 0; - rb->contour_managed = NULL; - rb->intersection_count = 0; - rb->intersection_managed = NULL; - rb->material_line_count = 0; - rb->material_managed = NULL; - rb->crease_count = 0; - rb->crease_managed = NULL; - rb->edge_mark_count = 0; - rb->edge_mark_managed = NULL; - - rb->contours = NULL; - rb->intersection_lines = NULL; - rb->crease_lines = NULL; - rb->material_lines = NULL; - rb->edge_marks = NULL; + memset(&rb->contour, 0, sizeof(ListBase)); + memset(&rb->crease, 0, sizeof(ListBase)); + memset(&rb->intersection, 0, sizeof(ListBase)); + memset(&rb->edge_mark, 0, sizeof(ListBase)); + memset(&rb->material, 0, sizeof(ListBase)); BLI_listbase_clear(&rb->chains); BLI_listbase_clear(&rb->wasted_cuts); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h index 47ca6e45bd5..9ed98b38f07 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h @@ -58,7 +58,7 @@ void *lineart_mem_acquire(struct LineartStaticMemPool *smp, size_t size); void *lineart_mem_acquire_thread(struct LineartStaticMemPool *smp, size_t size); void lineart_mem_destroy(struct LineartStaticMemPool *smp); -void lineart_prepend_edge_direct(struct LineartEdge **first, void *node); +void lineart_prepend_edge_direct(void **list_head, void *node); void lineart_prepend_pool(LinkNode **first, struct LineartStaticMemPool *smp, void *link); void lineart_matrix_ortho_44d(double (*mProjection)[4], @@ -76,29 +76,42 @@ int lineart_count_intersection_segment_count(struct LineartRenderBuffer *rb); void lineart_count_and_print_render_buffer_memory(struct LineartRenderBuffer *rb); #define LRT_ITER_ALL_LINES_BEGIN \ - LineartEdge *e, *next_e, **current_list; \ - e = rb->contours; \ - for (current_list = &rb->contours; e; e = next_e) { \ + LineartEdge *e, *next_e; \ + void **current_head; \ + e = rb->contour.first; \ + if (!e) { \ + e = rb->crease.first; \ + } \ + if (!e) { \ + e = rb->material.first; \ + } \ + if (!e) { \ + e = rb->edge_mark.first; \ + } \ + if (!e) { \ + e = rb->intersection.first; \ + } \ + for (current_head = &rb->contour.first; e; e = next_e) { \ next_e = e->next; #define LRT_ITER_ALL_LINES_NEXT \ while (!next_e) { \ - if (current_list == &rb->contours) { \ - current_list = &rb->crease_lines; \ + if (current_head == &rb->contour.first) { \ + current_head = &rb->crease.first; \ } \ - else if (current_list == &rb->crease_lines) { \ - current_list = &rb->material_lines; \ + else if (current_head == &rb->crease.first) { \ + current_head = &rb->material.first; \ } \ - else if (current_list == &rb->material_lines) { \ - current_list = &rb->edge_marks; \ + else if (current_head == &rb->material.first) { \ + current_head = &rb->edge_mark.first; \ } \ - else if (current_list == &rb->edge_marks) { \ - current_list = &rb->intersection_lines; \ + else if (current_head == &rb->edge_mark.first) { \ + current_head = &rb->intersection.first; \ } \ else { \ break; \ } \ - next_e = *current_list; \ + next_e = *current_head; \ } #define LRT_ITER_ALL_LINES_END \ diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c index dcb1f9cde5d..d05f931f75d 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c @@ -135,11 +135,11 @@ void lineart_mem_destroy(LineartStaticMemPool *smp) } } -void lineart_prepend_edge_direct(LineartEdge **first, void *node) +void lineart_prepend_edge_direct(void **list_head, void *node) { LineartEdge *e_n = (LineartEdge *)node; - e_n->next = (*first); - (*first) = e_n; + e_n->next = (*list_head); + (*list_head) = e_n; } void lineart_prepend_pool(LinkNode **first, LineartStaticMemPool *smp, void *link) -- cgit v1.2.3