diff options
author | YimingWu <xp8110@outlook.com> | 2022-04-25 07:49:25 +0300 |
---|---|---|
committer | YimingWu <xp8110@outlook.com> | 2022-04-25 07:49:25 +0300 |
commit | a3b38c979aab0d355b02533bbac47fb80ec14bd8 (patch) | |
tree | 25e35d155bf73ab2507357968a77a83aed6c83b9 | |
parent | 77afe859a0fecb3b03b9879a4d7419f991dc9f81 (diff) |
Revert "LineArt: CAS-inspired tile tree (WIP)"
This reverts commit 77afe859a0fecb3b03b9879a4d7419f991dc9f81.
4 files changed, 165 insertions, 397 deletions
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt index 85b9b64332e..6108629183c 100644 --- a/source/blender/gpencil_modifiers/CMakeLists.txt +++ b/source/blender/gpencil_modifiers/CMakeLists.txt @@ -17,7 +17,6 @@ set(INC ../windowmanager ../../../intern/eigen ../../../intern/guardedalloc - ../../../intern/atomic # dna_type_offsets.h in BLO_read_write.h ${CMAKE_BINARY_DIR}/source/blender/makesdna/intern diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index d4d39c84c51..830066ac0fb 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -222,11 +222,8 @@ typedef struct LineartRenderBuffer { float overscan; - struct LineartBoundingArea **initial_bounding_areas; - unsigned int bounding_area_initial_count; - - /* Array of thread_count length for spatial locks. */ - SpinLock *lock_bounding_areas; + struct LineartBoundingArea *initial_bounding_areas; + unsigned int bounding_area_count; /* When splitting bounding areas, if there's an ortho camera placed at a straight angle, there * will be a lot of triangles aligned in line which can not be separated by continue subdividing @@ -443,7 +440,7 @@ typedef struct LineartBoundingArea { double cx, cy; /** 1,2,3,4 quadrant */ - struct LineartBoundingArea *child[4]; + struct LineartBoundingArea *child; ListBase lp; ListBase rp; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index 5aa8085b0f3..b666eb677eb 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -459,25 +459,25 @@ static LineartBoundingArea *lineart_bounding_area_get_eci_recursive(LineartRende LineartBoundingArea *root, LineartEdgeChainItem *eci) { - if (root->child[0] == NULL) { + if (root->child == NULL) { return root; } - LineartBoundingArea **ch = root->child; + LineartBoundingArea *ch = root->child; #define IN_BOUND(ba, eci) \ - ba->l <= eci->pos[0] && ba->r >= eci->pos[0] && ba->b <= eci->pos[1] && ba->u >= eci->pos[1] + ba.l <= eci->pos[0] && ba.r >= eci->pos[0] && ba.b <= eci->pos[1] && ba.u >= eci->pos[1] if (IN_BOUND(ch[0], eci)) { - return lineart_bounding_area_get_eci_recursive(rb, ch[0], eci); + return lineart_bounding_area_get_eci_recursive(rb, &ch[0], eci); } if (IN_BOUND(ch[1], eci)) { - return lineart_bounding_area_get_eci_recursive(rb, ch[1], eci); + return lineart_bounding_area_get_eci_recursive(rb, &ch[1], eci); } if (IN_BOUND(ch[2], eci)) { - return lineart_bounding_area_get_eci_recursive(rb, ch[2], eci); + return lineart_bounding_area_get_eci_recursive(rb, &ch[2], eci); } if (IN_BOUND(ch[3], eci)) { - return lineart_bounding_area_get_eci_recursive(rb, ch[3], eci); + return lineart_bounding_area_get_eci_recursive(rb, &ch[3], eci); } #undef IN_BOUND return NULL; @@ -507,7 +507,7 @@ static void lineart_bounding_area_link_point_recursive(LineartRenderBuffer *rb, LineartEdgeChain *ec, LineartEdgeChainItem *eci) { - if (root->child[0] == NULL) { + if (root->child == NULL) { LineartChainRegisterEntry *cre = lineart_list_append_pointer_pool_sized( &root->linked_chains, &rb->render_data_pool, ec, sizeof(LineartChainRegisterEntry)); @@ -518,22 +518,22 @@ static void lineart_bounding_area_link_point_recursive(LineartRenderBuffer *rb, } } else { - LineartBoundingArea **ch = root->child; + LineartBoundingArea *ch = root->child; #define IN_BOUND(ba, eci) \ - ba->l <= eci->pos[0] && ba->r >= eci->pos[0] && ba->b <= eci->pos[1] && ba->u >= eci->pos[1] + ba.l <= eci->pos[0] && ba.r >= eci->pos[0] && ba.b <= eci->pos[1] && ba.u >= eci->pos[1] if (IN_BOUND(ch[0], eci)) { - lineart_bounding_area_link_point_recursive(rb, ch[0], ec, eci); + lineart_bounding_area_link_point_recursive(rb, &ch[0], ec, eci); } else if (IN_BOUND(ch[1], eci)) { - lineart_bounding_area_link_point_recursive(rb, ch[1], ec, eci); + lineart_bounding_area_link_point_recursive(rb, &ch[1], ec, eci); } else if (IN_BOUND(ch[2], eci)) { - lineart_bounding_area_link_point_recursive(rb, ch[2], ec, eci); + lineart_bounding_area_link_point_recursive(rb, &ch[2], ec, eci); } else if (IN_BOUND(ch[3], eci)) { - lineart_bounding_area_link_point_recursive(rb, ch[3], ec, eci); + lineart_bounding_area_link_point_recursive(rb, &ch[3], ec, eci); } #undef IN_BOUND diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index 25b03860d0b..dd08fc6493f 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -51,38 +51,6 @@ #include "lineart_intern.h" -#include "atomic_ops.h" - -typedef struct LineartIsecSingle { - float v1[3], v2[3]; - LineartTriangle *tri1, *tri2; -} 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; - - /* Thread intersection result data. */ - LineartIsecSingle *array; - int current; - int max; - int count_test; - - /* For individual thread reference.*/ - LineartRenderBuffer *rb; -} LineartIsecThread; -typedef struct LineartIsecData { - LineartRenderBuffer *rb; - LineartIsecThread *threads; - int thread_count; -} LineartIsecData; - static LineartBoundingArea *lineart_edge_first_bounding_area(LineartRenderBuffer *rb, LineartEdge *e); @@ -130,21 +98,6 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *spl, static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e); -static void lineart_bounding_area_link_triangle_cas(LineartRenderBuffer *rb, - LineartBoundingArea **root_ba, - LineartTriangle *tri, - double *LRUB, - int recursive, - int recursive_level, - bool do_intersection, - struct LineartIsecThread *th); - -static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, - bool recursive, - bool free_ba); - -static void lineart_free_bounding_area_memories(LineartRenderBuffer *rb); - static LineartCache *lineart_init_cache(void); static void lineart_discard_segment(LineartRenderBuffer *rb, LineartEdgeSegment *es) @@ -368,11 +321,10 @@ static void lineart_bounding_area_triangle_add(LineartRenderBuffer *rb, return; } if (ba->triangle_count >= ba->max_triangle_count) { - LineartTriangle **new_array = MEM_mallocN( - sizeof(LineartTriangle *) * ba->max_triangle_count * 2, "new ba_triangle_array"); + LineartTriangle **new_array = lineart_mem_acquire( + &rb->render_data_pool, sizeof(LineartTriangle *) * ba->max_triangle_count * 2); memcpy(new_array, ba->linked_triangles, sizeof(LineartTriangle *) * ba->max_triangle_count); ba->max_triangle_count *= 2; - MEM_freeN(ba->linked_triangles); ba->linked_triangles = new_array; } ba->linked_triangles[ba->triangle_count] = tri; @@ -390,11 +342,10 @@ static void lineart_bounding_area_line_add(LineartRenderBuffer *rb, return; } if (ba->line_count >= ba->max_line_count) { - LineartEdge **new_array = MEM_mallocN(sizeof(LineartEdge *) * ba->max_line_count * 2, - "new ba_line_array"); + LineartEdge **new_array = lineart_mem_acquire(&rb->render_data_pool, + sizeof(LineartEdge *) * ba->max_line_count * 2); memcpy(new_array, ba->linked_lines, sizeof(LineartEdge *) * ba->max_line_count); ba->max_line_count *= 2; - MEM_freeN(ba->linked_lines); ba->linked_lines = new_array; } ba->linked_lines[ba->line_count] = e; @@ -3786,13 +3737,13 @@ static void lineart_triangle_intersect_in_bounding_area(LineartRenderBuffer *rb, double *G0 = tri->v[0]->gloc, *G1 = tri->v[1]->gloc, *G2 = tri->v[2]->gloc; /* If this is not the smallest subdiv bounding area. */ - // if (ba->child[0]) { - // lineart_triangle_intersect_in_bounding_area(rb, tri, ba->child[0], th); - // lineart_triangle_intersect_in_bounding_area(rb, tri, ba->child[1], th); - // lineart_triangle_intersect_in_bounding_area(rb, tri, ba->child[2], th); - // lineart_triangle_intersect_in_bounding_area(rb, tri, ba->child[3], th); - // return; - //} + if (ba->child) { + lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[0]); + lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[1]); + lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[2]); + lineart_triangle_intersect_in_bounding_area(rb, tri, &ba->child[3]); + return; + } /* If this _is_ the smallest subdiv bounding area, then do the intersections there. */ for (int i = 0; i < ba->triangle_count; i++) { @@ -3875,12 +3826,6 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb) BLI_spin_end(&rb->lock_cuts); BLI_spin_end(&rb->render_data_pool.lock_mem); - for (int i = 0; i < rb->bounding_area_initial_count; i++) { - BLI_spin_end(&rb->lock_bounding_areas[i]); - } - - lineart_free_bounding_area_memories(rb); - lineart_mem_destroy(&rb->render_data_pool); } @@ -4050,22 +3995,14 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb) rb->width_per_tile = span_w; rb->height_per_tile = span_h; - rb->bounding_area_initial_count = sp_w * sp_h; + rb->bounding_area_count = sp_w * sp_h; rb->initial_bounding_areas = lineart_mem_acquire( - &rb->render_data_pool, sizeof(LineartBoundingArea *) * rb->bounding_area_initial_count); - rb->lock_bounding_areas = lineart_mem_acquire( - &rb->render_data_pool, sizeof(SpinLock) * rb->bounding_area_initial_count); - for (int i = 0; i < rb->bounding_area_initial_count; i++) { - rb->initial_bounding_areas[i] = MEM_callocN(sizeof(LineartBoundingArea), "initial ba"); - BLI_spin_init(&rb->lock_bounding_areas[i]); - } - - int i_ba = 0; + &rb->render_data_pool, sizeof(LineartBoundingArea) * rb->bounding_area_count); /* Initialize tiles. */ for (row = 0; row < sp_h; row++) { for (col = 0; col < sp_w; col++) { - ba = rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; + ba = &rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; /* Set the four direction limits. */ ba->l = span_w * col - 1.0; @@ -4079,33 +4016,33 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb) /* Init linked_triangles array. */ ba->max_triangle_count = LRT_TILE_SPLITTING_TRIANGLE_LIMIT; ba->max_line_count = LRT_TILE_EDGE_COUNT_INITIAL; - ba->linked_triangles = MEM_mallocN(sizeof(LineartTriangle *) * ba->max_triangle_count, - "ba_linked_triangles"); - ba->linked_lines = MEM_mallocN(sizeof(LineartEdge *) * ba->max_line_count, - "ba_linked_lines"); + ba->linked_triangles = lineart_mem_acquire( + &rb->render_data_pool, sizeof(LineartTriangle *) * ba->max_triangle_count); + ba->linked_lines = lineart_mem_acquire(&rb->render_data_pool, + sizeof(LineartEdge *) * ba->max_line_count); /* Link adjacent ones. */ if (row) { lineart_list_append_pointer_pool( &ba->up, &rb->render_data_pool, - rb->initial_bounding_areas[(row - 1) * LRT_BA_ROWS + col]); + &rb->initial_bounding_areas[(row - 1) * LRT_BA_ROWS + col]); } if (col) { lineart_list_append_pointer_pool(&ba->lp, &rb->render_data_pool, - rb->initial_bounding_areas[row * LRT_BA_ROWS + col - 1]); + &rb->initial_bounding_areas[row * LRT_BA_ROWS + col - 1]); } if (row != sp_h - 1) { lineart_list_append_pointer_pool( &ba->bp, &rb->render_data_pool, - rb->initial_bounding_areas[(row + 1) * LRT_BA_ROWS + col]); + &rb->initial_bounding_areas[(row + 1) * LRT_BA_ROWS + col]); } if (col != sp_w - 1) { lineart_list_append_pointer_pool(&ba->rp, &rb->render_data_pool, - rb->initial_bounding_areas[row * LRT_BA_ROWS + col + 1]); + &rb->initial_bounding_areas[row * LRT_BA_ROWS + col + 1]); } } } @@ -4116,19 +4053,19 @@ static void lineart_main_bounding_area_make_initial(LineartRenderBuffer *rb) */ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartBoundingArea *root) { - LineartBoundingArea **ba = root->child, *tba; + LineartBoundingArea *ba = root->child, *tba; LinkData *lip2, *next_lip; LineartStaticMemPool *mph = &rb->render_data_pool; /* Inter-connection with newly created 4 child bounding areas. */ - lineart_list_append_pointer_pool(&ba[1]->rp, mph, ba[0]); - lineart_list_append_pointer_pool(&ba[0]->lp, mph, ba[1]); - lineart_list_append_pointer_pool(&ba[1]->bp, mph, ba[2]); - lineart_list_append_pointer_pool(&ba[2]->up, mph, ba[1]); - lineart_list_append_pointer_pool(&ba[2]->rp, mph, ba[3]); - lineart_list_append_pointer_pool(&ba[3]->lp, mph, ba[2]); - lineart_list_append_pointer_pool(&ba[3]->up, mph, ba[0]); - lineart_list_append_pointer_pool(&ba[0]->bp, mph, ba[3]); + lineart_list_append_pointer_pool(&ba[1].rp, mph, &ba[0]); + lineart_list_append_pointer_pool(&ba[0].lp, mph, &ba[1]); + lineart_list_append_pointer_pool(&ba[1].bp, mph, &ba[2]); + lineart_list_append_pointer_pool(&ba[2].up, mph, &ba[1]); + lineart_list_append_pointer_pool(&ba[2].rp, mph, &ba[3]); + lineart_list_append_pointer_pool(&ba[3].lp, mph, &ba[2]); + lineart_list_append_pointer_pool(&ba[3].up, mph, &ba[0]); + lineart_list_append_pointer_pool(&ba[0].bp, mph, &ba[3]); /* Connect 4 child bounding areas to other areas that are * adjacent to their original parents. */ @@ -4141,46 +4078,46 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB /* if this neighbor is adjacent to * the two new areas on the left side of the parent, * then add them to the adjacent list as well. */ - if (ba[1]->u > tba->b && ba[1]->b < tba->u) { - lineart_list_append_pointer_pool(&ba[1]->lp, mph, tba); - lineart_list_append_pointer_pool(&tba->rp, mph, ba[1]); + if (ba[1].u > tba->b && ba[1].b < tba->u) { + lineart_list_append_pointer_pool(&ba[1].lp, mph, tba); + lineart_list_append_pointer_pool(&tba->rp, mph, &ba[1]); } - if (ba[2]->u > tba->b && ba[2]->b < tba->u) { - lineart_list_append_pointer_pool(&ba[2]->lp, mph, tba); - lineart_list_append_pointer_pool(&tba->rp, mph, ba[2]); + if (ba[2].u > tba->b && ba[2].b < tba->u) { + lineart_list_append_pointer_pool(&ba[2].lp, mph, tba); + lineart_list_append_pointer_pool(&tba->rp, mph, &ba[2]); } } LISTBASE_FOREACH (LinkData *, lip, &root->rp) { tba = lip->data; - if (ba[0]->u > tba->b && ba[0]->b < tba->u) { - lineart_list_append_pointer_pool(&ba[0]->rp, mph, tba); - lineart_list_append_pointer_pool(&tba->lp, mph, ba[0]); + if (ba[0].u > tba->b && ba[0].b < tba->u) { + lineart_list_append_pointer_pool(&ba[0].rp, mph, tba); + lineart_list_append_pointer_pool(&tba->lp, mph, &ba[0]); } - if (ba[3]->u > tba->b && ba[3]->b < tba->u) { - lineart_list_append_pointer_pool(&ba[3]->rp, mph, tba); - lineart_list_append_pointer_pool(&tba->lp, mph, ba[3]); + if (ba[3].u > tba->b && ba[3].b < tba->u) { + lineart_list_append_pointer_pool(&ba[3].rp, mph, tba); + lineart_list_append_pointer_pool(&tba->lp, mph, &ba[3]); } } LISTBASE_FOREACH (LinkData *, lip, &root->up) { tba = lip->data; - if (ba[0]->r > tba->l && ba[0]->l < tba->r) { - lineart_list_append_pointer_pool(&ba[0]->up, mph, tba); - lineart_list_append_pointer_pool(&tba->bp, mph, ba[0]); + if (ba[0].r > tba->l && ba[0].l < tba->r) { + lineart_list_append_pointer_pool(&ba[0].up, mph, tba); + lineart_list_append_pointer_pool(&tba->bp, mph, &ba[0]); } - if (ba[1]->r > tba->l && ba[1]->l < tba->r) { - lineart_list_append_pointer_pool(&ba[1]->up, mph, tba); - lineart_list_append_pointer_pool(&tba->bp, mph, ba[1]); + if (ba[1].r > tba->l && ba[1].l < tba->r) { + lineart_list_append_pointer_pool(&ba[1].up, mph, tba); + lineart_list_append_pointer_pool(&tba->bp, mph, &ba[1]); } } LISTBASE_FOREACH (LinkData *, lip, &root->bp) { tba = lip->data; - if (ba[2]->r > tba->l && ba[2]->l < tba->r) { - lineart_list_append_pointer_pool(&ba[2]->bp, mph, tba); - lineart_list_append_pointer_pool(&tba->up, mph, ba[2]); + if (ba[2].r > tba->l && ba[2].l < tba->r) { + lineart_list_append_pointer_pool(&ba[2].bp, mph, tba); + lineart_list_append_pointer_pool(&tba->up, mph, &ba[2]); } - if (ba[3]->r > tba->l && ba[3]->l < tba->r) { - lineart_list_append_pointer_pool(&ba[3]->bp, mph, tba); - lineart_list_append_pointer_pool(&tba->up, mph, ba[3]); + if (ba[3].r > tba->l && ba[3].l < tba->r) { + lineart_list_append_pointer_pool(&ba[3].bp, mph, tba); + lineart_list_append_pointer_pool(&tba->up, mph, &ba[3]); } } @@ -4192,11 +4129,11 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB tba = lip2->data; if (tba == root) { lineart_list_remove_pointer_item_no_free(&((LineartBoundingArea *)lip->data)->rp, lip2); - if (ba[1]->u > tba->b && ba[1]->b < tba->u) { - lineart_list_append_pointer_pool(&tba->rp, mph, ba[1]); + if (ba[1].u > tba->b && ba[1].b < tba->u) { + lineart_list_append_pointer_pool(&tba->rp, mph, &ba[1]); } - if (ba[2]->u > tba->b && ba[2]->b < tba->u) { - lineart_list_append_pointer_pool(&tba->rp, mph, ba[2]); + if (ba[2].u > tba->b && ba[2].b < tba->u) { + lineart_list_append_pointer_pool(&tba->rp, mph, &ba[2]); } } } @@ -4207,11 +4144,11 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB tba = lip2->data; if (tba == root) { lineart_list_remove_pointer_item_no_free(&((LineartBoundingArea *)lip->data)->lp, lip2); - if (ba[0]->u > tba->b && ba[0]->b < tba->u) { - lineart_list_append_pointer_pool(&tba->lp, mph, ba[0]); + if (ba[0].u > tba->b && ba[0].b < tba->u) { + lineart_list_append_pointer_pool(&tba->lp, mph, &ba[0]); } - if (ba[3]->u > tba->b && ba[3]->b < tba->u) { - lineart_list_append_pointer_pool(&tba->lp, mph, ba[3]); + if (ba[3].u > tba->b && ba[3].b < tba->u) { + lineart_list_append_pointer_pool(&tba->lp, mph, &ba[3]); } } } @@ -4222,11 +4159,11 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB tba = lip2->data; if (tba == root) { lineart_list_remove_pointer_item_no_free(&((LineartBoundingArea *)lip->data)->bp, lip2); - if (ba[0]->r > tba->l && ba[0]->l < tba->r) { - lineart_list_append_pointer_pool(&tba->up, mph, ba[0]); + if (ba[0].r > tba->l && ba[0].l < tba->r) { + lineart_list_append_pointer_pool(&tba->up, mph, &ba[0]); } - if (ba[1]->r > tba->l && ba[1]->l < tba->r) { - lineart_list_append_pointer_pool(&tba->up, mph, ba[1]); + if (ba[1].r > tba->l && ba[1].l < tba->r) { + lineart_list_append_pointer_pool(&tba->up, mph, &ba[1]); } } } @@ -4237,11 +4174,11 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB tba = lip2->data; if (tba == root) { lineart_list_remove_pointer_item_no_free(&((LineartBoundingArea *)lip->data)->up, lip2); - if (ba[2]->r > tba->l && ba[2]->l < tba->r) { - lineart_list_append_pointer_pool(&tba->bp, mph, ba[2]); + if (ba[2].r > tba->l && ba[2].l < tba->r) { + lineart_list_append_pointer_pool(&tba->bp, mph, &ba[2]); } - if (ba[3]->r > tba->l && ba[3]->l < tba->r) { - lineart_list_append_pointer_pool(&tba->bp, mph, ba[3]); + if (ba[3].r > tba->l && ba[3].l < tba->r) { + lineart_list_append_pointer_pool(&tba->bp, mph, &ba[3]); } } } @@ -4254,25 +4191,6 @@ static void lineart_bounding_areas_connect_new(LineartRenderBuffer *rb, LineartB BLI_listbase_clear(&root->bp); } -static void lineart_bounding_areas_connect_recursive(LineartRenderBuffer *rb, - LineartBoundingArea *root) -{ - if (root->child[0]) { - lineart_bounding_areas_connect_new(rb, root); - for (int i = 0; i < 4; i++) { - lineart_bounding_areas_connect_recursive(rb, root->child[i]); - } - } -} - -static void lineart_main_bounding_areas_connect_post(LineartRenderBuffer *rb) -{ - int total_tile_initial = rb->tile_count_x * rb->tile_count_y; - for (int i = 0; i < total_tile_initial; i++) { - lineart_bounding_areas_connect_recursive(rb, rb->initial_bounding_areas[i]); - } -} - /** * Subdivide a tile after one tile contains too many triangles. */ @@ -4280,79 +4198,75 @@ static void lineart_bounding_area_split(LineartRenderBuffer *rb, LineartBoundingArea *root, int recursive_level) { - for (int i = 0; i < 4; i++) { - root->child[i] = MEM_callocN(sizeof(LineartBoundingArea), "split bounding area"); - } + LineartBoundingArea *ba = lineart_mem_acquire(&rb->render_data_pool, + sizeof(LineartBoundingArea) * 4); LineartTriangle *tri; - LineartBoundingArea **ba = root->child; - - ba[0]->l = root->cx; - ba[0]->r = root->r; - ba[0]->u = root->u; - ba[0]->b = root->cy; - ba[0]->cx = (ba[0]->l + ba[0]->r) / 2; - ba[0]->cy = (ba[0]->u + ba[0]->b) / 2; - - ba[1]->l = root->l; - ba[1]->r = root->cx; - ba[1]->u = root->u; - ba[1]->b = root->cy; - ba[1]->cx = (ba[1]->l + ba[1]->r) / 2; - ba[1]->cy = (ba[1]->u + ba[1]->b) / 2; - - ba[2]->l = root->l; - ba[2]->r = root->cx; - ba[2]->u = root->cy; - ba[2]->b = root->b; - ba[2]->cx = (ba[2]->l + ba[2]->r) / 2; - ba[2]->cy = (ba[2]->u + ba[2]->b) / 2; - - ba[3]->l = root->cx; - ba[3]->r = root->r; - ba[3]->u = root->cy; - ba[3]->b = root->b; - ba[3]->cx = (ba[3]->l + ba[3]->r) / 2; - ba[3]->cy = (ba[3]->u + ba[3]->b) / 2; + + ba[0].l = root->cx; + ba[0].r = root->r; + ba[0].u = root->u; + ba[0].b = root->cy; + ba[0].cx = (ba[0].l + ba[0].r) / 2; + ba[0].cy = (ba[0].u + ba[0].b) / 2; + + ba[1].l = root->l; + ba[1].r = root->cx; + ba[1].u = root->u; + ba[1].b = root->cy; + ba[1].cx = (ba[1].l + ba[1].r) / 2; + ba[1].cy = (ba[1].u + ba[1].b) / 2; + + ba[2].l = root->l; + ba[2].r = root->cx; + ba[2].u = root->cy; + ba[2].b = root->b; + ba[2].cx = (ba[2].l + ba[2].r) / 2; + ba[2].cy = (ba[2].u + ba[2].b) / 2; + + ba[3].l = root->cx; + ba[3].r = root->r; + ba[3].u = root->cy; + ba[3].b = root->b; + ba[3].cx = (ba[3].l + ba[3].r) / 2; + ba[3].cy = (ba[3].u + ba[3].b) / 2; + + root->child = ba; lineart_bounding_areas_connect_new(rb, root); /* Init linked_triangles array. */ for (int i = 0; i < 4; i++) { - ba[i]->max_triangle_count = LRT_TILE_SPLITTING_TRIANGLE_LIMIT; - ba[i]->max_line_count = LRT_TILE_EDGE_COUNT_INITIAL; - ba[i]->linked_triangles = MEM_mallocN(sizeof(LineartTriangle *) * ba[i]->max_triangle_count, - "ba_linked_triangles"); - ba[i]->linked_lines = MEM_mallocN(sizeof(LineartEdge *) * ba[i]->max_line_count, - "ba_linked_lines"); - // ba[i]->lock = root->lock; + ba[i].max_triangle_count = LRT_TILE_SPLITTING_TRIANGLE_LIMIT; + ba[i].max_line_count = LRT_TILE_EDGE_COUNT_INITIAL; + ba[i].linked_triangles = lineart_mem_acquire( + &rb->render_data_pool, sizeof(LineartTriangle *) * LRT_TILE_SPLITTING_TRIANGLE_LIMIT); + ba[i].linked_lines = lineart_mem_acquire(&rb->render_data_pool, + sizeof(LineartEdge *) * LRT_TILE_EDGE_COUNT_INITIAL); } for (int i = 0; i < root->triangle_count; i++) { tri = root->linked_triangles[i]; + LineartBoundingArea *cba = root->child; double b[4]; b[0] = MIN3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]); b[1] = MAX3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]); b[2] = MAX3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); - if (LRT_BOUND_AREA_CROSSES(b, &ba[0]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[0], tri, b, 0, recursive_level + 1, false, NULL); + if (LRT_BOUND_AREA_CROSSES(b, &cba[0].l)) { + lineart_bounding_area_link_triangle(rb, &cba[0], tri, b, 0, recursive_level + 1, false); } - if (LRT_BOUND_AREA_CROSSES(b, &ba[1]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[1], tri, b, 0, recursive_level + 1, false, NULL); + if (LRT_BOUND_AREA_CROSSES(b, &cba[1].l)) { + lineart_bounding_area_link_triangle(rb, &cba[1], tri, b, 0, recursive_level + 1, false); } - if (LRT_BOUND_AREA_CROSSES(b, &ba[2]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[2], tri, b, 0, recursive_level + 1, false, NULL); + if (LRT_BOUND_AREA_CROSSES(b, &cba[2].l)) { + lineart_bounding_area_link_triangle(rb, &cba[2], tri, b, 0, recursive_level + 1, false); } - if (LRT_BOUND_AREA_CROSSES(b, &ba[3]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[3], tri, b, 0, recursive_level + 1, false, NULL); + if (LRT_BOUND_AREA_CROSSES(b, &cba[3].l)) { + lineart_bounding_area_link_triangle(rb, &cba[3], tri, b, 0, recursive_level + 1, false); } } - // rb->bounding_area_count += 3; + rb->bounding_area_count += 3; } static bool lineart_bounding_area_edge_intersect(LineartRenderBuffer *UNUSED(fb), @@ -4462,7 +4376,7 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, } } else { - LineartBoundingArea **ba = root_ba->child; + LineartBoundingArea *ba = root_ba->child; double *B1 = LRUB; double b[4]; if (!LRUB) { @@ -4472,188 +4386,48 @@ static void lineart_bounding_area_link_triangle(LineartRenderBuffer *rb, b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); B1 = b; } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[0]->l)) { + if (LRT_BOUND_AREA_CROSSES(B1, &ba[0].l)) { lineart_bounding_area_link_triangle( rb, &ba[0], tri, B1, recursive, recursive_level + 1, do_intersection); } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[1]->l)) { + if (LRT_BOUND_AREA_CROSSES(B1, &ba[1].l)) { lineart_bounding_area_link_triangle( rb, &ba[1], tri, B1, recursive, recursive_level + 1, do_intersection); } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[2]->l)) { + if (LRT_BOUND_AREA_CROSSES(B1, &ba[2].l)) { lineart_bounding_area_link_triangle( rb, &ba[2], tri, B1, recursive, recursive_level + 1, do_intersection); } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[3]->l)) { + if (LRT_BOUND_AREA_CROSSES(B1, &ba[3].l)) { lineart_bounding_area_link_triangle( rb, &ba[3], tri, B1, recursive, recursive_level + 1, do_intersection); } } } -__attribute__((optimize("O0"))) static void lineart_bounding_area_copy( - LineartBoundingArea *ba_to, LineartBoundingArea *ba_from) -{ - memcpy(ba_to, ba_from, sizeof(LineartBoundingArea)); - if (ba_from->linked_triangles) { - ba_to->linked_triangles = MEM_mallocN(sizeof(LineartTriangle *) * ba_from->max_triangle_count, - "ba_linked_triangles"); - ba_to->linked_lines = MEM_mallocN(sizeof(LineartEdge *) * ba_from->max_line_count, - "ba_linked_lines"); - memcpy(ba_to->linked_triangles, - ba_from->linked_triangles, - sizeof(LineartTriangle *) * ba_from->triangle_count); - memcpy( - ba_to->linked_lines, ba_from->linked_lines, sizeof(LineartEdge *) * ba_from->line_count); - } -} - -__attribute__((optimize("O0"))) static void lineart_bounding_area_link_triangle_cas( - LineartRenderBuffer *rb, - LineartBoundingArea **root_ba, - LineartTriangle *tri, - double *LRUB, - int recursive, - int recursive_level, - bool do_intersection, - struct LineartIsecThread *th) -{ - if (!lineart_bounding_area_triangle_intersect(rb, tri, *root_ba)) { - return; - } - - LineartBoundingArea *ba_copied = th ? NULL : *root_ba; - bool go_into_child = false; - int last_isec_index = th ? th->current : 0; - LineartBoundingArea *old_ba = (*root_ba); - - do { - if (th) { - if (ba_copied) { - lineart_free_bounding_area_memory(ba_copied, false, false); - } - else { - ba_copied = MEM_callocN(sizeof(LineartBoundingArea), "copied ba"); - } - lineart_bounding_area_copy(ba_copied, *root_ba); - th->current = last_isec_index; - } - // Do remaining stuff the same way as before. - - LineartBoundingArea *use_ba = ba_copied; - - if (use_ba->child[0] == NULL) { - lineart_bounding_area_triangle_add(rb, use_ba, tri); - if (use_ba->triangle_count >= LRT_TILE_SPLITTING_TRIANGLE_LIMIT && recursive && - recursive_level < rb->tile_recursive_level) { - lineart_bounding_area_split(rb, use_ba, recursive_level); - } - if (recursive && do_intersection && rb->use_intersections) { - lineart_triangle_intersect_in_bounding_area(rb, tri, use_ba); - } - } - else { - go_into_child = true; - break; - } - - } while (!atomic_cas_ptr(root_ba, (*root_ba), ba_copied) && th); - - /* If old #root_ba no longer suitable for insertion, then #ba_copied is no longer needed, but if - * insertion succeeded, then old_ba would become the old pointer swapped out by CAS */ - if (th) { - LineartBoundingArea *ba_to_delete; - if (go_into_child) { - ba_to_delete = ba_copied; - } - else { - ba_to_delete = old_ba; - } - // XXX: Can't seem to get the right one to delete? either way it ended up crashing. - // lineart_free_bounding_area_memory(ba_to_delete, false, true); - } - - if (!go_into_child) { - return; - } - - LineartBoundingArea *ba_old = (*root_ba); - - LineartBoundingArea **ba = ba_old->child; - double *B1 = LRUB; - double b[4]; - if (!LRUB) { - b[0] = MIN3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]); - b[1] = MAX3(tri->v[0]->fbcoord[0], tri->v[1]->fbcoord[0], tri->v[2]->fbcoord[0]); - b[2] = MAX3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); - b[3] = MIN3(tri->v[0]->fbcoord[1], tri->v[1]->fbcoord[1], tri->v[2]->fbcoord[1]); - B1 = b; - } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[0]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[0], tri, B1, recursive, recursive_level + 1, do_intersection, th); - } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[1]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[1], tri, B1, recursive, recursive_level + 1, do_intersection, th); - } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[2]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[2], tri, B1, recursive, recursive_level + 1, do_intersection, th); - } - if (LRT_BOUND_AREA_CROSSES(B1, &ba[3]->l)) { - lineart_bounding_area_link_triangle_cas( - rb, &ba[3], tri, B1, recursive, recursive_level + 1, do_intersection, th); - } -} - -__attribute__((optimize("O0"))) static void lineart_free_bounding_area_memory( - LineartBoundingArea *ba, bool recursive, bool free_ba) -{ - MEM_freeN(ba->linked_lines); - MEM_freeN(ba->linked_triangles); - if (recursive && ba->child[0]) { - for (int i = 0; i < 4; i++) { - lineart_free_bounding_area_memory(ba->child[i], recursive, free_ba); - } - } - if (free_ba) { - MEM_freeN(ba); - } -} -static void lineart_free_bounding_area_memories(LineartRenderBuffer *rb) -{ - for (int i = 0; i < rb->tile_count_x; i++) { - for (int j = 0; j < rb->tile_count_y; j++) { - lineart_free_bounding_area_memory( - rb->initial_bounding_areas[i * rb->tile_count_x + j], true, true); - } - } -} - static void lineart_bounding_area_link_edge(LineartRenderBuffer *rb, LineartBoundingArea *root_ba, LineartEdge *e) { - if (root_ba->child[0] == NULL) { + if (root_ba->child == NULL) { lineart_bounding_area_line_add(rb, root_ba, e); } else { if (lineart_bounding_area_edge_intersect( - rb, e->v1->fbcoord, e->v2->fbcoord, root_ba->child[0])) { - lineart_bounding_area_link_edge(rb, root_ba->child[0], e); + rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[0])) { + lineart_bounding_area_link_edge(rb, &root_ba->child[0], e); } if (lineart_bounding_area_edge_intersect( - rb, e->v1->fbcoord, e->v2->fbcoord, root_ba->child[1])) { - lineart_bounding_area_link_edge(rb, root_ba->child[1], e); + rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[1])) { + lineart_bounding_area_link_edge(rb, &root_ba->child[1], e); } if (lineart_bounding_area_edge_intersect( - rb, e->v1->fbcoord, e->v2->fbcoord, root_ba->child[2])) { - lineart_bounding_area_link_edge(rb, root_ba->child[2], e); + rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[2])) { + lineart_bounding_area_link_edge(rb, &root_ba->child[2], e); } if (lineart_bounding_area_edge_intersect( - rb, e->v1->fbcoord, e->v2->fbcoord, root_ba->child[3])) { - lineart_bounding_area_link_edge(rb, root_ba->child[3], e); + rb, e->v1->fbcoord, e->v2->fbcoord, &root_ba->child[3])) { + lineart_bounding_area_link_edge(rb, &root_ba->child[3], e); } } } @@ -4670,7 +4444,7 @@ static void lineart_main_link_lines(LineartRenderBuffer *rb) for (row = r1; row != r2 + 1; row++) { for (col = c1; col != c2 + 1; col++) { lineart_bounding_area_link_edge( - rb, rb->initial_bounding_areas[row * LRT_BA_ROWS + col], e); + rb, &rb->initial_bounding_areas[row * LRT_BA_ROWS + col], e); } } } @@ -4798,7 +4572,7 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartRenderBuffer *r row = 0; } - return rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; + return &rb->initial_bounding_areas[row * LRT_BA_ROWS + col]; } static LineartBoundingArea *lineart_get_bounding_area(LineartRenderBuffer *rb, double x, double y) @@ -4820,22 +4594,22 @@ static LineartBoundingArea *lineart_get_bounding_area(LineartRenderBuffer *rb, d c = rb->tile_count_x - 1; } - iba = rb->initial_bounding_areas[r * LRT_BA_ROWS + c]; - while (iba->child[0]) { + iba = &rb->initial_bounding_areas[r * LRT_BA_ROWS + c]; + while (iba->child) { if (x > iba->cx) { if (y > iba->cy) { - iba = iba->child[0]; + iba = &iba->child[0]; } else { - iba = iba->child[3]; + iba = &iba->child[3]; } } else { if (y > iba->cy) { - iba = iba->child[1]; + iba = &iba->child[1]; } else { - iba = iba->child[2]; + iba = &iba->child[2]; } } } @@ -4872,15 +4646,13 @@ static void lineart_main_add_triangles(LineartRenderBuffer *rb) if (lineart_get_triangle_bounding_areas(rb, tri, &y1, &y2, &x1, &x2)) { for (co = x1; co <= x2; co++) { for (r = y1; r <= y2; r++) { - lineart_bounding_area_link_triangle_cas( - rb, - &rb->initial_bounding_areas[r * LRT_BA_ROWS + co], - tri, - 0, - 1, - 0, - (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION)), - th); + lineart_bounding_area_link_triangle(rb, + &rb->initial_bounding_areas[r * LRT_BA_ROWS + co], + tri, + 0, + 1, + 0, + (!(tri->flags & LRT_TRIANGLE_NO_INTERSECTION))); } } } /* Else throw away. */ |