diff options
Diffstat (limited to 'source/blender/blenlib')
20 files changed, 197 insertions, 102 deletions
diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h index 6e47fd4ddb3..e776f594a84 100644 --- a/source/blender/blenlib/BLI_dlrbTree.h +++ b/source/blender/blenlib/BLI_dlrbTree.h @@ -76,19 +76,19 @@ typedef struct DLRBT_Tree { /* Callback Types --------------------------------- */ /* return -1, 0, 1 for whether the given data is less than, equal to, or greater than the given node - * - node: <DLRBT_Node> the node to compare to - * - data: pointer to the relevant data or values stored in the bitpattern dependent on the function + * - node: <DLRBT_Node> the node to compare to + * - data: pointer to the relevant data or values stored in the bitpattern dependent on the function */ typedef short (*DLRBT_Comparator_FP)(void *node, void *data); /* return a new node instance wrapping the given data - * - data: pointer to the relevant data to create a subclass of node from + * - data: pointer to the relevant data to create a subclass of node from */ typedef DLRBT_Node *(*DLRBT_NAlloc_FP)(void *data); /* update an existing node instance accordingly to be in sync with the given data * - * - node: <DLRBT_Node> the node to update - * - data: pointer to the relevant data or values stored in the bitpattern dependent on the function + * - node: <DLRBT_Node> the node to update + * - data: pointer to the relevant data or values stored in the bitpattern dependent on the function */ typedef void (*DLRBT_NUpdate_FP)(void *node, void *data); diff --git a/source/blender/blenlib/BLI_math.h b/source/blender/blenlib/BLI_math.h index ec3fbdc9bfc..5bdf8b7791f 100644 --- a/source/blender/blenlib/BLI_math.h +++ b/source/blender/blenlib/BLI_math.h @@ -28,23 +28,24 @@ /** \file BLI_math.h * \ingroup bli - * \section mathabbrev Abbreviations * - * - ``fl`` = float - * - ``db`` = double - * - ``v2`` = vec2 = vector 2 - * - ``v3`` = vec3 = vector 3 - * - ``v4`` = vec4 = vector 4 - * - ``vn`` = vec4 = vector N dimensions, *passed as an arg, after the vector*. - * - ``qt`` = quat = quaternion - * - ``dq`` = dquat = dual quaternion - * - ``m2`` = mat2 = matrix 2x2 - * - ``m3`` = mat3 = matrix 3x3 - * - ``m4`` = mat4 = matrix 4x4 - * - ``eul`` = euler rotation - * - ``eulO`` = euler with order - * - ``plane`` = plane 4, (vec3, distance) - * - ``plane3`` = plane 3 (same as a ``plane`` with a zero 4th component) + * \section mathabbrev Abbreviations + * + * - ``fl`` = float + * - ``db`` = double + * - ``v2`` = vec2 = vector 2 + * - ``v3`` = vec3 = vector 3 + * - ``v4`` = vec4 = vector 4 + * - ``vn`` = vec4 = vector N dimensions, *passed as an arg, after the vector*. + * - ``qt`` = quat = quaternion + * - ``dq`` = dquat = dual quaternion + * - ``m2`` = mat2 = matrix 2x2 + * - ``m3`` = mat3 = matrix 3x3 + * - ``m4`` = mat4 = matrix 4x4 + * - ``eul`` = euler rotation + * - ``eulO`` = euler with order + * - ``plane`` = plane 4, (vec3, distance) + * - ``plane3`` = plane 3 (same as a ``plane`` with a zero 4th component) * * \subsection mathabbrev_all Function Type Abbreviations * @@ -57,13 +58,13 @@ * - ``_char`` = char * - ``_uchar`` = unsigned char * - * \section mathvarnames Variable Names + * \section mathvarnames Variable Names * - * - f = single value - * - a, b, c = vectors - * - r = result vector - * - A, B, C = matrices - * - R = result matrix + * - f = single value + * - a, b, c = vectors + * - r = result vector + * - A, B, C = matrices + * - R = result matrix */ #include "BLI_math_base.h" diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index b3a95d65752..e4cf4839b45 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -186,6 +186,11 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist); #define ISECT_LINE_LINE_CROSS 2 int isect_seg_seg_v2(const float a1[2], const float a2[2], const float b1[2], const float b2[2]); +void isect_seg_seg_v3( + const float a0[3], const float a1[3], + const float b0[3], const float b1[3], + float r_a[3], float r_b[3]); + int isect_seg_seg_v2_int(const int a1[2], const int a2[2], const int b1[2], const int b2[2]); int isect_seg_seg_v2_point_ex( const float v0[2], const float v1[2], const float v2[2], const float v3[2], const float endpoint_bias, diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 59c9341f75c..c23c0409f81 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -272,6 +272,7 @@ MINLINE bool compare_v4v4_relative(const float a[4], const float b[4], const flo MINLINE bool compare_len_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT; MINLINE bool compare_len_squared_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT; +MINLINE bool compare_len_squared_v4v4(const float a[4], const float b[4], const float limit) ATTR_WARN_UNUSED_RESULT; MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index a6670266643..221d328dd9e 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -34,7 +34,8 @@ */ #include "DNA_vec_types.h" -#include "BLI_utildefines.h" +#include "BLI_sys_types.h" /* bool */ +#include "BLI_compiler_compat.h" struct rctf; struct rcti; diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 3d4b227ffa7..98c27bd053b 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -508,11 +508,11 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size); /* Warning-free macros for storing ints in pointers. Use these _only_ * for storing an int in a pointer, not a pointer in an int (64bit)! */ -#define SET_INT_IN_POINTER(i) ((void *)(intptr_t)(i)) -#define GET_INT_FROM_POINTER(i) ((void)0, ((int)(intptr_t)(i))) +#define POINTER_FROM_INT(i) ((void *)(intptr_t)(i)) +#define POINTER_AS_INT(i) ((void)0, ((int)(intptr_t)(i))) -#define SET_UINT_IN_POINTER(i) ((void *)(uintptr_t)(i)) -#define GET_UINT_FROM_POINTER(i) ((void)0, ((unsigned int)(uintptr_t)(i))) +#define POINTER_FROM_UINT(i) ((void *)(uintptr_t)(i)) +#define POINTER_AS_UINT(i) ((void)0, ((unsigned int)(uintptr_t)(i))) /* Set flag from a single test */ #define SET_FLAG_FROM_TEST(value, test, flag) \ diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c index 6554ee7c92f..a0d9fefe465 100644 --- a/source/blender/blenlib/intern/BLI_ghash_utils.c +++ b/source/blender/blenlib/intern/BLI_ghash_utils.c @@ -54,14 +54,16 @@ uint BLI_ghashutil_ptrhash(const void *key) return (uint)(intptr_t)key; } #else -/* based python3.3's pointer hashing function */ +/* Based Python3.7's pointer hashing function. */ uint BLI_ghashutil_ptrhash(const void *key) { size_t y = (size_t)key; /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid * excessive hash collisions for dicts and sets */ - y = (y >> 4) | (y << (8 * sizeof(void *) - 4)); - return (uint)y; + + /* Note: Unlike Python 'sizeof(uint)' is used instead of 'sizeof(void *)', + * Otherwise casting to 'uint' ignores the upper bits on 64bit platforms. */ + return (uint)(y >> 4) | ((uint)y << (8 * sizeof(uint) - 4)); } #endif bool BLI_ghashutil_ptrcmp(const void *a, const void *b) @@ -126,7 +128,7 @@ uint BLI_ghashutil_inthash_p_murmur(const void *ptr) uint BLI_ghashutil_inthash_p_simple(const void *ptr) { - return GET_UINT_FROM_POINTER(ptr); + return POINTER_AS_UINT(ptr); } bool BLI_ghashutil_intcmp(const void *a, const void *b) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 1676bf5d779..467eed97a74 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -738,9 +738,9 @@ static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, con * All tree types >= 2 are supported. * * Advantages of the used trees include: - * - No need to store child/parent relations (they are implicit); - * - Any node child always has an index greater than the parent; - * - Brother nodes are sequential in memory; + * - No need to store child/parent relations (they are implicit); + * - Any node child always has an index greater than the parent; + * - Brother nodes are sequential in memory; * * * Some math relations derived for general implicit trees: @@ -764,9 +764,9 @@ static int implicit_needed_branches(int tree_type, int leafs) * This function handles the problem of "sorting" the leafs (along the split_axis). * * It arranges the elements in the given partitions such that: - * - any element in partition N is less or equal to any element in partition N+1. - * - if all elements are different all partition will get the same subset of elements - * as if the array was sorted. + * - any element in partition N is less or equal to any element in partition N+1. + * - if all elements are different all partition will get the same subset of elements + * as if the array was sorted. * * partition P is described as the elements in the range ( nth[P], nth[P+1] ] * @@ -863,9 +863,9 @@ static void non_recursive_bvh_div_nodes_task_cb( /** * This functions builds an optimal implicit tree from the given leafs. * Where optimal stands for: - * - The resulting tree will have the smallest number of branches; - * - At most only one branch will have NULL childs; - * - All leafs will be stored at level N or N+1. + * - The resulting tree will have the smallest number of branches; + * - At most only one branch will have NULL childs; + * - All leafs will be stored at level N or N+1. * * This function creates an implicit tree on branches_array, the leafs are given on the leafs_array. * diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c index eb3a79502ae..e331e070a4a 100644 --- a/source/blender/blenlib/intern/DLRB_tree.c +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -102,8 +102,8 @@ static void linkedlist_sync_add_node(DLRBT_Tree *tree, DLRBT_Node *node) linkedlist_sync_add_node(tree, node->left); /* now add self - * - must remove detach from other links first - * (for now, only clear own pointers) + * - must remove detach from other links first + * (for now, only clear own pointers) */ node->prev = node->next = NULL; BLI_addtail((ListBase *)tree, (Link *)node); diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index df93dad4c32..153ba3ea0d0 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -1760,7 +1760,7 @@ bool BLI_array_store_is_valid( } GHASH_ITER (gh_iter, chunk_list_map) { const struct BChunkList *chunk_list = BLI_ghashIterator_getKey(&gh_iter); - const int users = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); + const int users = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); if (!(chunk_list->users == users)) { ok = false; goto user_finally; @@ -1790,7 +1790,7 @@ bool BLI_array_store_is_valid( GHASH_ITER (gh_iter, chunk_map) { const struct BChunk *chunk = BLI_ghashIterator_getKey(&gh_iter); - const int users = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); + const int users = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); if (!(chunk->users == users)) { ok = false; goto user_finally; diff --git a/source/blender/blenlib/intern/astar.c b/source/blender/blenlib/intern/astar.c index 1b57dc5a683..86c1faad096 100644 --- a/source/blender/blenlib/intern/astar.c +++ b/source/blender/blenlib/intern/astar.c @@ -228,10 +228,10 @@ bool BLI_astar_graph_solve( todo_nodes = BLI_heap_new(); BLI_heap_insert(todo_nodes, f_cost_cb(as_graph, r_solution, NULL, -1, node_index_src, node_index_dst), - SET_INT_IN_POINTER(node_index_src)); + POINTER_FROM_INT(node_index_src)); while (!BLI_heap_is_empty(todo_nodes)) { - const int node_curr_idx = GET_INT_FROM_POINTER(BLI_heap_pop_min(todo_nodes)); + const int node_curr_idx = POINTER_AS_INT(BLI_heap_pop_min(todo_nodes)); BLI_AStarGNode *node_curr = &as_graph->nodes[node_curr_idx]; LinkData *ld; @@ -271,7 +271,7 @@ bool BLI_astar_graph_solve( * no problem. */ BLI_heap_insert(todo_nodes, f_cost_cb(as_graph, r_solution, link, node_curr_idx, node_next_idx, node_index_dst), - SET_INT_IN_POINTER(node_next_idx)); + POINTER_FROM_INT(node_next_idx)); } } } diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index c7604b3cd6d..b493b97863c 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -99,7 +99,7 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData * che->index = charcode; che->width = glyph->advance.x * scale; - BLI_ghash_insert(vfd->characters, SET_UINT_IN_POINTER(che->index), che); + BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che); /* Start converting the FT data */ onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints"); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index e8ccef4d55e..dca9d4204c3 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -911,6 +911,70 @@ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], co return ISECT_LINE_LINE_NONE; } +/* Returns a point on each segment that is closest to the other. */ +void isect_seg_seg_v3( + const float a0[3], const float a1[3], + const float b0[3], const float b1[3], + float r_a[3], float r_b[3]) +{ + float fac_a, fac_b; + float a_dir[3], b_dir[3], a0b0[3], crs_ab[3]; + sub_v3_v3v3(a_dir, a1, a0); + sub_v3_v3v3(b_dir, b1, b0); + sub_v3_v3v3(a0b0, b0, a0); + cross_v3_v3v3(crs_ab, b_dir, a_dir); + const float nlen = len_squared_v3(crs_ab); + + if (nlen == 0.0f) { + /* Parallel Lines */ + /* In this case return any point that + * is between the closest segments. */ + float a0b1[3], a1b0[3], len_a, len_b, fac1, fac2; + sub_v3_v3v3(a0b1, b1, a0); + sub_v3_v3v3(a1b0, b0, a1); + len_a = len_squared_v3(a_dir); + len_b = len_squared_v3(b_dir); + + if (len_a) { + fac1 = dot_v3v3(a0b0, a_dir); + fac2 = dot_v3v3(a0b1, a_dir); + CLAMP(fac1, 0.0f, len_a); + CLAMP(fac2, 0.0f, len_a); + fac_a = (fac1 + fac2) / (2 * len_a); + } + else { + fac_a = 0.0f; + } + + if (len_b) { + fac1 = -dot_v3v3(a0b0, b_dir); + fac2 = -dot_v3v3(a1b0, b_dir); + CLAMP(fac1, 0.0f, len_b); + CLAMP(fac2, 0.0f, len_b); + fac_b = (fac1 + fac2) / (2 * len_b); + } + else { + fac_b = 0.0f; + } + } + else { + float c[3], cray[3]; + sub_v3_v3v3(c, crs_ab, a0b0); + + cross_v3_v3v3(cray, c, b_dir); + fac_a = dot_v3v3(cray, crs_ab) / nlen; + + cross_v3_v3v3(cray, c, a_dir); + fac_b = dot_v3v3(cray, crs_ab) / nlen; + + CLAMP(fac_a, 0.0f, 1.0f); + CLAMP(fac_b, 0.0f, 1.0f); + } + + madd_v3_v3v3fl(r_a, a0, a_dir, fac_a); + madd_v3_v3v3fl(r_b, b0, b_dir, fac_b); +} + /** * Get intersection point of two 2D segments. * diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 311d963f64d..f117c815ee9 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -822,12 +822,11 @@ bool invert_m4(float m[4][4]) } /* - * invertmat - - * computes the inverse of mat and puts it in inverse. Returns - * true on success (i.e. can always find a pivot) and false on failure. - * Uses Gaussian Elimination with partial (maximal column) pivoting. + * Computes the inverse of mat and puts it in inverse. + * Returns true on success (i.e. can always find a pivot) and false on failure. + * Uses Gaussian Elimination with partial (maximal column) pivoting. * - * Mark Segal - 1992 + * Mark Segal - 1992 */ bool invert_m4_m4(float inverse[4][4], float mat[4][4]) @@ -2188,11 +2187,11 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]) * negligible elements in the s and e arrays. On * completion the variables kase and k are set as follows. * - * kase = 1 if s(p) and e[k - 1] are negligible and k<p - * kase = 2 if s(k) is negligible and k<p - * kase = 3 if e[k - 1] is negligible, k<p, and - * s(k), ..., s(p) are not negligible (qr step). - * kase = 4 if e(p - 1) is negligible (convergence). */ + * kase = 1: if s(p) and e[k - 1] are negligible and k<p + * kase = 2: if s(k) is negligible and k<p + * kase = 3: if e[k - 1] is negligible, k<p, and + * s(k), ..., s(p) are not negligible (qr step). + * kase = 4: if e(p - 1) is negligible (convergence). */ for (k = p - 2; k >= -1; k--) { if (k == -1) { diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 29e7cf32ddc..f0c830d33c6 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1477,7 +1477,7 @@ static const RotOrderInfo rotOrders[] = { /* Get relevant pointer to rotation order set from the array * NOTE: since we start at 1 for the values, but arrays index from 0, - * there is -1 factor involved in this process... + * there is -1 factor involved in this process... */ static const RotOrderInfo *get_rotation_order_info(const short order) { diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 715e2e65c96..37eab44c6e8 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -1087,24 +1087,23 @@ MINLINE bool compare_v4v4_relative(const float v1[4], const float v2[4], const f MINLINE bool compare_len_v3v3(const float v1[3], const float v2[3], const float limit) { - float x, y, z; - - x = v1[0] - v2[0]; - y = v1[1] - v2[1]; - z = v1[2] - v2[2]; - - return ((x * x + y * y + z * z) <= (limit * limit)); + float d[3]; + sub_v3_v3v3(d, v1, v2); + return (dot_v3v3(d, d) <= (limit * limit)); } MINLINE bool compare_len_squared_v3v3(const float v1[3], const float v2[3], const float limit_sq) { - float x, y, z; - - x = v1[0] - v2[0]; - y = v1[1] - v2[1]; - z = v1[2] - v2[2]; + float d[3]; + sub_v3_v3v3(d, v1, v2); + return (dot_v3v3(d, d) <= limit_sq); +} - return ((x * x + y * y + z * z) <= limit_sq); +MINLINE bool compare_len_squared_v4v4(const float v1[4], const float v2[4], const float limit_sq) +{ + float d[4]; + sub_v4_v4v4(d, v1, v2); + return (dot_v4v4(d, d) <= limit_sq); } /** diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 10ca0fa6cbf..84c932db1c7 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1160,12 +1160,12 @@ bool BLI_path_program_search( do { temp = strchr(path, separator); if (temp) { - strncpy(filename, path, temp - path); + memcpy(filename, path, temp - path); filename[temp - path] = 0; path = temp + 1; } else { - strncpy(filename, path, sizeof(filename)); + BLI_strncpy(filename, path, sizeof(filename)); } BLI_path_append(filename, maxlen, name); diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 110757ac3c0..23905be4ced 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -42,7 +42,7 @@ #include "BLI_math.h" /* defines BLI_INLINE */ -#include "BLI_utildefines.h" +#include "BLI_compiler_compat.h" #include "BLI_sys_types.h" #include "BLI_strict_flags.h" diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index e0d92e8a19f..5b1e378a2da 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -39,8 +39,10 @@ #include <limits.h> #include <float.h> -#include "DNA_vec_types.h" #include "BLI_rect.h" +#include "BLI_utildefines.h" + +#include "DNA_vec_types.h" /* avoid including BLI_math */ static void unit_m4(float m[4][4]); diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 2bb5d5397a9..b6d704d8d82 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -1221,6 +1221,31 @@ static void parallel_listbase_func( } } +static void task_parallel_listbase_no_threads( + struct ListBase *listbase, + void *userdata, + TaskParallelListbaseFunc func) +{ + int i = 0; + for (Link *link = listbase->first; link != NULL; link = link->next, ++i) { + func(userdata, link, i); + } +} + +/* NOTE: The idea here is to compensate for rather measurable threading + * overhead caused by fetching tasks. With too many CPU threads we are starting + * to spend too much time in those overheads. */ +BLI_INLINE int task_parallel_listbasecalc_chunk_size(const int num_threads) +{ + if (num_threads > 32) { + return 128; + } + else if (num_threads > 16) { + return 64; + } + return 32; +} + /** * This function allows to parallelize for loops over ListBase items. * @@ -1238,41 +1263,37 @@ void BLI_task_parallel_listbase( TaskParallelListbaseFunc func, const bool use_threading) { - TaskScheduler *task_scheduler; - TaskPool *task_pool; - ParallelListState state; - int i, num_threads, num_tasks; - if (BLI_listbase_is_empty(listbase)) { return; } - if (!use_threading) { - i = 0; - for (Link *link = listbase->first; link != NULL; link = link->next, ++i) { - func(userdata, link, i); - } + task_parallel_listbase_no_threads(listbase, userdata, func); + return; + } + TaskScheduler *task_scheduler = BLI_task_scheduler_get(); + const int num_threads = BLI_task_scheduler_num_threads(task_scheduler); + /* TODO(sergey): Consider making chunk size configurable. */ + const int chunk_size = task_parallel_listbasecalc_chunk_size(num_threads); + const int num_tasks = min_ii( + num_threads, + BLI_listbase_count(listbase) / chunk_size); + if (num_tasks <= 1) { + task_parallel_listbase_no_threads(listbase, userdata, func); return; } - task_scheduler = BLI_task_scheduler_get(); - task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); - num_threads = BLI_task_scheduler_num_threads(task_scheduler); - - /* The idea here is to prevent creating task for each of the loop iterations - * and instead have tasks which are evenly distributed across CPU cores and - * pull next iter to be crunched using the queue. - */ - num_tasks = num_threads + 2; + ParallelListState state; + TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); state.index = 0; state.link = listbase->first; state.userdata = userdata; state.func = func; - state.chunk_size = 32; + state.chunk_size = chunk_size; BLI_spin_init(&state.lock); - for (i = 0; i < num_tasks; i++) { + BLI_assert(num_tasks > 0); + for (int i = 0; i < num_tasks; i++) { /* Use this pool's pre-allocated tasks. */ BLI_task_pool_push_from_thread(task_pool, parallel_listbase_func, |