Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorGermano Cavalcante <mano-wii>2021-06-10 17:01:36 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2021-06-11 16:45:12 +0300
commit2330cec2c6a7632459c21f51723497e349a042bf (patch)
treeba4ed258743ceb269990d0352d2be87aa2aaa901 /source
parentfe22635bf664af844933695ba3a0d79a01807818 (diff)
Refactor: Draw Cache: use 'BLI_task_parallel_range'
This is an adaptation of {D11488}. A disadvantage of manually setting the iter ranges per thread is that we don't know how many threads are running in the background and so we don't know how to best distribute the ranges. To solve this limitation we can use `parallel_reduce` and thus let the driver choose the best distribution of ranges among the threads. This proved to be especially beneficial for computers with few cores. **Benchmarking:** Here's the result on an 4-core laptop: ||master:|PATCH: |---|---|---| |large_mesh_editing:|Average: 5.203638 FPS|Average: 5.398925 FPS ||rdata 15ms iter 43ms (frame 193ms)|rdata 14ms iter 36ms (frame 187ms) Here's the result on an 8-core PC: ||master:|PATCH: |---|---|---| |large_mesh_editing:|Average: 15.267482 FPS|Average: 15.906881 FPS ||rdata 9ms iter 28ms (frame 65ms)|rdata 9ms iter 25ms (frame 63ms) |large_mesh_editing_ledge: |Average: 15.145966 FPS|Average: 15.520474 FPS ||rdata 9ms iter 29ms (frame 65ms)|rdata 9ms iter 25ms (frame 64ms) |looptris_test:|Average: 4.001917 FPS|Average: 4.061105 FPS ||rdata 12ms iter 90ms (frame 236ms)|rdata 12ms iter 87ms (frame 230ms) |subdiv_mesh_cage_and_final:|Average: 1.917769 FPS|Average: 1.971790 FPS ||rdata 7ms iter 37ms (frame 261ms)|rdata 7ms iter 31ms (frame 258ms) ||rdata 7ms iter 38ms (frame 252ms)|rdata 7ms iter 33ms (frame 249ms) |subdiv_mesh_final_only:|Average: 6.387240 FPS|Average: 6.591251 FPS ||rdata 3ms iter 25ms (frame 151ms)|rdata 3ms iter 16ms (frame 145ms) |subdiv_mesh_final_only_ledge:|Average: 6.247393 FPS|Average: 6.596024 FPS ||rdata 3ms iter 26ms (frame 158ms)|rdata 3ms iter 16ms (frame 148ms) **Notes:** - The improvement can only be noticed if all extracts are multithreaded. - This patch touches different areas of the code, so it can be split into another patch if the idea is accepted. These screenshots show how threads behave in a quadcore: Master: {F10164664} Patch: {F10164666} Differential Revision: https://developer.blender.org/D11558
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc817
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_extractors.c475
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_private.h245
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc58
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc14
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc51
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc18
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc18
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc41
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc47
-rw-r--r--source/blender/gpu/GPU_index_buffer.h14
-rw-r--r--source/blender/gpu/intern/gpu_index_buffer.cc21
m---------source/tools0
13 files changed, 626 insertions, 1193 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index 6b5877e6759..c6303d541b3 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -50,7 +50,7 @@
# include "PIL_time_utildefines.h"
#endif
-#define CHUNK_SIZE 8192
+#define CHUNK_SIZE 1024
namespace blender::draw {
@@ -65,26 +65,12 @@ struct ExtractorRunData {
const MeshExtract *extractor;
/* During iteration the VBO/IBO that is being build. */
void *buffer = nullptr;
- /* User data during iteration. Created in MeshExtract.init and passed along to other MeshExtract
- * functions. */
- void *user_data = nullptr;
- std::optional<Array<void *>> task_user_datas;
+ uint32_t data_offset = 0;
ExtractorRunData(const MeshExtract *extractor) : extractor(extractor)
{
}
- void init_task_user_datas(const TaskLen task_len)
- {
- task_user_datas = Array<void *>(task_len);
- }
-
- void *&operator[](const TaskId task_id)
- {
- BLI_assert(task_user_datas);
- return (*task_user_datas)[task_id];
- }
-
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("DRAW:ExtractorRunData")
#endif
@@ -157,6 +143,16 @@ class ExtractorRunDatas : public Vector<ExtractorRunData> {
return data_type;
}
+ size_t data_size_total()
+ {
+ size_t data_size = 0;
+ for (const ExtractorRunData &data : *this) {
+ const MeshExtract *extractor = data.extractor;
+ data_size += extractor->data_size;
+ }
+ return data_size;
+ }
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("DRAW:ExtractorRunDatas")
#endif
@@ -165,446 +161,334 @@ class ExtractorRunDatas : public Vector<ExtractorRunData> {
/** \} */
/* ---------------------------------------------------------------------- */
-/** \name Extract
+/** \name ExtractTaskData
+ * \{ */
+struct ExtractTaskData {
+ const MeshRenderData *mr = nullptr;
+ MeshBatchCache *cache = nullptr;
+ ExtractorRunDatas *extractors = nullptr;
+ MeshBufferCache *mbc = nullptr;
+
+ eMRIterType iter_type;
+ bool use_threading = false;
+
+ ExtractTaskData(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ ExtractorRunDatas *extractors,
+ MeshBufferCache *mbc,
+ const bool use_threading)
+ : mr(mr), cache(cache), extractors(extractors), mbc(mbc), use_threading(use_threading)
+ {
+ iter_type = extractors->iter_types();
+ };
+
+ ExtractTaskData(const ExtractTaskData &src) = default;
+
+ ~ExtractTaskData()
+ {
+ delete extractors;
+ }
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("DRW:ExtractTaskData")
+#endif
+};
+
+static void extract_task_data_free(void *data)
+{
+ ExtractTaskData *task_data = static_cast<ExtractTaskData *>(data);
+ delete task_data;
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Extract Init and Finish
* \{ */
BLI_INLINE void extract_init(const MeshRenderData *mr,
struct MeshBatchCache *cache,
ExtractorRunDatas &extractors,
- MeshBufferCache *mbc)
+ MeshBufferCache *mbc,
+ void *data_stack)
{
- /* Multi thread. */
+ uint32_t data_offset = 0;
for (ExtractorRunData &run_data : extractors) {
const MeshExtract *extractor = run_data.extractor;
run_data.buffer = mesh_extract_buffer_get(extractor, mbc);
- run_data.user_data = extractor->init(mr, cache, run_data.buffer);
+ run_data.data_offset = data_offset;
+ extractor->init(mr, cache, run_data.buffer, POINTER_OFFSET(data_stack, data_offset));
+ data_offset += (uint32_t)extractor->data_size;
}
}
-BLI_INLINE void extract_iter_looptri_bm(const MeshRenderData *mr,
- const ExtractTriBMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+BLI_INLINE void extract_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ const ExtractorRunDatas &extractors,
+ void *data_stack)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_LOOPTRI);
-
- EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, elt_index, params)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_looptri_bm(mr, elt, elt_index, run_data[task_id]);
+ for (const ExtractorRunData &run_data : extractors) {
+ const MeshExtract *extractor = run_data.extractor;
+ if (extractor->finish) {
+ extractor->finish(
+ mr, cache, run_data.buffer, POINTER_OFFSET(data_stack, run_data.data_offset));
}
}
- EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END;
}
-BLI_INLINE void extract_iter_looptri_mesh(const MeshRenderData *mr,
- const ExtractTriMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
-{
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Extract In Parallel Ranges
+ * \{ */
+
+struct ExtractorIterData {
ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_LOOPTRI);
+ const MeshRenderData *mr = nullptr;
+ const void *elems = nullptr;
+ const int *loose_elems = nullptr;
- EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(mlt, mlt_index, params)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_looptri_mesh(mr, mlt, mlt_index, run_data[task_id]);
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("DRW:MeshRenderDataUpdateTaskData")
+#endif
+};
+
+static void extract_task_reduce(const void *__restrict userdata,
+ void *__restrict chunk_to,
+ void *__restrict chunk_from)
+{
+ const ExtractorIterData *data = static_cast<const ExtractorIterData *>(userdata);
+ for (const ExtractorRunData &run_data : data->extractors) {
+ const MeshExtract *extractor = run_data.extractor;
+ if (extractor->task_reduce) {
+ extractor->task_reduce(POINTER_OFFSET(chunk_to, run_data.data_offset),
+ POINTER_OFFSET(chunk_from, run_data.data_offset));
}
}
- EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END;
}
-BLI_INLINE void extract_iter_poly_bm(const MeshRenderData *mr,
- const ExtractPolyBMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+static void extract_range_iter_looptri_bm(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_POLY);
-
- EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_poly_bm(mr, f, f_index, run_data[task_id]);
- }
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ void *extract_data = tls->userdata_chunk;
+ const MeshRenderData *mr = data->mr;
+ BMLoop **elt = ((BMLoop * (*)[3]) data->elems)[iter];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_looptri_bm(
+ mr, elt, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
- EXTRACT_POLY_FOREACH_BM_END;
}
-BLI_INLINE void extract_iter_poly_mesh(const MeshRenderData *mr,
- const ExtractPolyMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+static void extract_range_iter_looptri_mesh(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_POLY);
+ void *extract_data = tls->userdata_chunk;
- EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_poly_mesh(mr, mp, mp_index, run_data[task_id]);
- }
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const MLoopTri *mlt = &((const MLoopTri *)data->elems)[iter];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_looptri_mesh(
+ mr, mlt, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
- EXTRACT_POLY_FOREACH_MESH_END;
}
-BLI_INLINE void extract_iter_ledge_bm(const MeshRenderData *mr,
- const ExtractLEdgeBMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+static void extract_range_iter_poly_bm(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_LEDGE);
+ void *extract_data = tls->userdata_chunk;
- EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_ledge_bm(mr, eed, ledge_index, run_data[task_id]);
- }
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const BMFace *f = ((const BMFace **)data->elems)[iter];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_poly_bm(
+ mr, f, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
- EXTRACT_LEDGE_FOREACH_BM_END;
}
-BLI_INLINE void extract_iter_ledge_mesh(const MeshRenderData *mr,
- const ExtractLEdgeMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+static void extract_range_iter_poly_mesh(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_LEDGE);
+ void *extract_data = tls->userdata_chunk;
- EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_ledge_mesh(mr, med, ledge_index, run_data[task_id]);
- }
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const MPoly *mp = &((const MPoly *)data->elems)[iter];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_poly_mesh(
+ mr, mp, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
- EXTRACT_LEDGE_FOREACH_MESH_END;
}
-BLI_INLINE void extract_iter_lvert_bm(const MeshRenderData *mr,
- const ExtractLVertBMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+static void extract_range_iter_ledge_bm(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_LVERT);
+ void *extract_data = tls->userdata_chunk;
- EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_lvert_bm(mr, eve, lvert_index, run_data[task_id]);
- }
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const int ledge_index = data->loose_elems[iter];
+ const BMEdge *eed = ((const BMEdge **)data->elems)[ledge_index];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_ledge_bm(
+ mr, eed, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
- EXTRACT_LVERT_FOREACH_BM_END;
}
-BLI_INLINE void extract_iter_lvert_mesh(const MeshRenderData *mr,
- const ExtractLVertMesh_Params *params,
- const ExtractorRunDatas &all_extractors,
- const TaskId task_id)
+static void extract_range_iter_ledge_mesh(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- ExtractorRunDatas extractors;
- all_extractors.filter_into(extractors, MR_ITER_LVERT);
+ void *extract_data = tls->userdata_chunk;
- EXTRACT_LVERT_FOREACH_MESH_BEGIN(mv, lvert_index, params, mr)
- {
- for (ExtractorRunData &run_data : extractors) {
- run_data.extractor->iter_lvert_mesh(mr, mv, lvert_index, run_data[task_id]);
- }
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const int ledge_index = data->loose_elems[iter];
+ const MEdge *med = &((const MEdge *)data->elems)[ledge_index];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_ledge_mesh(
+ mr, med, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
- EXTRACT_LVERT_FOREACH_MESH_END;
}
-BLI_INLINE void extract_finish(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- const ExtractorRunDatas &extractors)
+static void extract_range_iter_lvert_bm(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- for (const ExtractorRunData &run_data : extractors) {
- const MeshExtract *extractor = run_data.extractor;
- if (extractor->finish) {
- extractor->finish(mr, cache, run_data.buffer, run_data.user_data);
- }
+ void *extract_data = tls->userdata_chunk;
+
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const int lvert_index = data->loose_elems[iter];
+ const BMVert *eve = ((const BMVert **)data->elems)[lvert_index];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_lvert_bm(
+ mr, eve, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
-BLI_INLINE void extract_task_init(ExtractorRunDatas &extractors, const TaskLen task_len)
+static void extract_range_iter_lvert_mesh(void *__restrict userdata,
+ const int iter,
+ const TaskParallelTLS *__restrict tls)
{
- for (ExtractorRunData &run_data : extractors) {
- run_data.init_task_user_datas(task_len);
- const MeshExtract *extractor = run_data.extractor;
- for (TaskId task_id = 0; task_id < task_len; task_id++) {
- void *user_task_data = run_data.user_data;
- if (extractor->task_init) {
- user_task_data = extractor->task_init(run_data.user_data);
- }
- run_data[task_id] = user_task_data;
- }
+ void *extract_data = tls->userdata_chunk;
+
+ const ExtractorIterData *data = static_cast<ExtractorIterData *>(userdata);
+ const MeshRenderData *mr = data->mr;
+ const int lvert_index = data->loose_elems[iter];
+ const MVert *mv = &((const MVert *)data->elems)[lvert_index];
+ for (const ExtractorRunData &run_data : data->extractors) {
+ run_data.extractor->iter_lvert_mesh(
+ mr, mv, iter, POINTER_OFFSET(extract_data, run_data.data_offset));
}
}
-BLI_INLINE void extract_task_finish(ExtractorRunDatas &extractors, const TaskLen task_len)
+BLI_INLINE void extract_task_range_run_iter(const MeshRenderData *mr,
+ ExtractorRunDatas *extractors,
+ const eMRIterType iter_type,
+ bool is_mesh,
+ TaskParallelSettings *settings)
{
- for (ExtractorRunData &run_data : extractors) {
- const MeshExtract *extractor = run_data.extractor;
- if (extractor->task_finish) {
- for (TaskId task_id = 0; task_id < task_len; task_id++) {
- void *task_user_data = run_data[task_id];
- extractor->task_finish(run_data.user_data, task_user_data);
- run_data[task_id] = nullptr;
- }
- }
+ ExtractorIterData range_data;
+ range_data.mr = mr;
+
+ TaskParallelRangeFunc func;
+ int stop;
+ switch (iter_type) {
+ case MR_ITER_LOOPTRI:
+ range_data.elems = is_mesh ? mr->mlooptri : (void *)mr->edit_bmesh->looptris;
+ func = is_mesh ? extract_range_iter_looptri_mesh : extract_range_iter_looptri_bm;
+ stop = mr->tri_len;
+ break;
+ case MR_ITER_POLY:
+ range_data.elems = is_mesh ? mr->mpoly : (void *)mr->bm->ftable;
+ func = is_mesh ? extract_range_iter_poly_mesh : extract_range_iter_poly_bm;
+ stop = mr->poly_len;
+ break;
+ case MR_ITER_LEDGE:
+ range_data.loose_elems = mr->ledges;
+ range_data.elems = is_mesh ? mr->medge : (void *)mr->bm->etable;
+ func = is_mesh ? extract_range_iter_ledge_mesh : extract_range_iter_ledge_bm;
+ stop = mr->edge_loose_len;
+ break;
+ case MR_ITER_LVERT:
+ range_data.loose_elems = mr->lverts;
+ range_data.elems = is_mesh ? mr->mvert : (void *)mr->bm->vtable;
+ func = is_mesh ? extract_range_iter_lvert_mesh : extract_range_iter_lvert_bm;
+ stop = mr->vert_loose_len;
+ break;
+ default:
+ BLI_assert(false);
+ return;
}
+
+ extractors->filter_into(range_data.extractors, iter_type);
+ BLI_task_parallel_range(0, stop, &range_data, func, settings);
}
-/* Single Thread. */
-BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- ExtractorRunDatas &extractors,
- eMRIterType iter_type,
- MeshBufferCache *mbc)
+static void extract_task_range_run(void *__restrict taskdata)
{
- const TaskLen task_len = 1;
- const TaskId task_id = 0;
+ ExtractTaskData *data = (ExtractTaskData *)taskdata;
+ const eMRIterType iter_type = data->iter_type;
+ const bool is_mesh = data->mr->extract_type != MR_EXTRACT_BMESH;
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.func_reduce = extract_task_reduce;
+ settings.min_iter_per_thread = CHUNK_SIZE;
+ settings.use_threading = data->use_threading;
- extract_init(mr, cache, extractors, mbc);
- extract_task_init(extractors, task_len);
+ size_t chunk_size = data->extractors->data_size_total();
+ char *chunk = new char[chunk_size];
+ extract_init(data->mr, data->cache, *data->extractors, data->mbc, (void *)chunk);
+
+ settings.userdata_chunk = chunk;
+ settings.userdata_chunk_size = chunk_size;
- bool is_mesh = mr->extract_type != MR_EXTRACT_BMESH;
if (iter_type & MR_ITER_LOOPTRI) {
- if (is_mesh) {
- ExtractTriMesh_Params params;
- params.mlooptri = mr->mlooptri;
- params.tri_range[0] = 0;
- params.tri_range[1] = mr->tri_len;
- extract_iter_looptri_mesh(mr, &params, extractors, task_id);
- }
- else {
- ExtractTriBMesh_Params params;
- params.looptris = mr->edit_bmesh->looptris;
- params.tri_range[0] = 0;
- params.tri_range[1] = mr->tri_len;
- extract_iter_looptri_bm(mr, &params, extractors, task_id);
- }
+ extract_task_range_run_iter(data->mr, data->extractors, MR_ITER_LOOPTRI, is_mesh, &settings);
}
if (iter_type & MR_ITER_POLY) {
- if (is_mesh) {
- ExtractPolyMesh_Params params;
- params.poly_range[0] = 0;
- params.poly_range[1] = mr->poly_len;
- extract_iter_poly_mesh(mr, &params, extractors, task_id);
- }
- else {
- ExtractPolyBMesh_Params params;
- params.poly_range[0] = 0;
- params.poly_range[1] = mr->poly_len;
- extract_iter_poly_bm(mr, &params, extractors, task_id);
- }
+ extract_task_range_run_iter(data->mr, data->extractors, MR_ITER_POLY, is_mesh, &settings);
}
if (iter_type & MR_ITER_LEDGE) {
- if (is_mesh) {
- ExtractLEdgeMesh_Params params;
- params.ledge = mr->ledges;
- params.ledge_range[0] = 0;
- params.ledge_range[1] = mr->edge_loose_len;
- extract_iter_ledge_mesh(mr, &params, extractors, task_id);
- }
- else {
- ExtractLEdgeBMesh_Params params;
- params.ledge = mr->ledges;
- params.ledge_range[0] = 0;
- params.ledge_range[1] = mr->edge_loose_len;
- extract_iter_ledge_bm(mr, &params, extractors, task_id);
- }
+ extract_task_range_run_iter(data->mr, data->extractors, MR_ITER_LEDGE, is_mesh, &settings);
}
if (iter_type & MR_ITER_LVERT) {
- if (is_mesh) {
- ExtractLVertMesh_Params params;
- params.lvert = mr->lverts;
- params.lvert_range[0] = 0;
- params.lvert_range[1] = mr->vert_loose_len;
- extract_iter_lvert_mesh(mr, &params, extractors, task_id);
- }
- else {
- ExtractLVertBMesh_Params params;
- params.lvert = mr->lverts;
- params.lvert_range[0] = 0;
- params.lvert_range[1] = mr->vert_loose_len;
- extract_iter_lvert_bm(mr, &params, extractors, task_id);
- }
+ extract_task_range_run_iter(data->mr, data->extractors, MR_ITER_LVERT, is_mesh, &settings);
}
- extract_task_finish(extractors, task_len);
- extract_finish(mr, cache, extractors);
+
+ extract_finish(data->mr, data->cache, *data->extractors, (void *)chunk);
+ delete[] chunk;
}
/** \} */
/* ---------------------------------------------------------------------- */
-/** \name ExtractTaskData
+/** \name Extract Single Thread
* \{ */
-struct ExtractTaskData {
- const MeshRenderData *mr = nullptr;
- MeshBatchCache *cache = nullptr;
- /* #UserData is shared between the iterations as it holds counters to detect if the
- * extraction is finished. To make sure the duplication of the user_data does not create a new
- * instance of the counters we allocate the user_data in its own container.
- *
- * This structure makes sure that when extract_init is called, that the user data of all
- * iterations are updated. */
- ExtractorRunDatas *extractors = nullptr;
- MeshBufferCache *mbc = nullptr;
- int32_t *task_counter = nullptr;
-
- /* Total number of tasks that are created for multi threaded extraction.
- * (= 1 for single threaded extractors). */
- uint task_len;
- /* Task id of the extraction task. Must never exceed task_len. (= 0 for single threaded
- * extractors). */
- uint task_id = 0;
-
- eMRIterType iter_type;
- int start = 0;
- int end = INT_MAX;
- /** Decremented each time a task is finished. */
-
- ExtractTaskData(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- ExtractorRunDatas *extractors,
- MeshBufferCache *mbc,
- int32_t *task_counter,
- const uint task_len)
- : mr(mr),
- cache(cache),
- extractors(extractors),
- mbc(mbc),
- task_counter(task_counter),
- task_len(task_len)
- {
- iter_type = extractors->iter_types();
- };
-
- ExtractTaskData(const ExtractTaskData &src) = default;
-
- ~ExtractTaskData()
- {
- delete extractors;
- }
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DRW:ExtractTaskData")
-#endif
-};
-
-static void extract_task_data_free(void *data)
-{
- ExtractTaskData *task_data = static_cast<ExtractTaskData *>(data);
- delete task_data;
-}
-
-static void extract_task_data_free_ex(void *data)
-{
- ExtractTaskData *task_data = static_cast<ExtractTaskData *>(data);
- task_data->extractors = nullptr;
- delete task_data;
-}
-
-BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
- const eMRIterType iter_type,
- int start,
- int end,
- ExtractorRunDatas &extractors,
- const TaskId task_id)
-{
- switch (mr->extract_type) {
- case MR_EXTRACT_BMESH:
- if (iter_type & MR_ITER_LOOPTRI) {
- ExtractTriBMesh_Params params;
- params.looptris = mr->edit_bmesh->looptris;
- params.tri_range[0] = start;
- params.tri_range[1] = min_ii(mr->tri_len, end);
- extract_iter_looptri_bm(mr, &params, extractors, task_id);
- }
- if (iter_type & MR_ITER_POLY) {
- ExtractPolyBMesh_Params params;
- params.poly_range[0] = start;
- params.poly_range[1] = min_ii(mr->poly_len, end);
- extract_iter_poly_bm(mr, &params, extractors, task_id);
- }
- if (iter_type & MR_ITER_LEDGE) {
- ExtractLEdgeBMesh_Params params;
- params.ledge = mr->ledges;
- params.ledge_range[0] = start;
- params.ledge_range[1] = min_ii(mr->edge_loose_len, end);
- extract_iter_ledge_bm(mr, &params, extractors, task_id);
- }
- if (iter_type & MR_ITER_LVERT) {
- ExtractLVertBMesh_Params params;
- params.lvert = mr->lverts;
- params.lvert_range[0] = start;
- params.lvert_range[1] = min_ii(mr->vert_loose_len, end);
- extract_iter_lvert_bm(mr, &params, extractors, task_id);
- }
- break;
- case MR_EXTRACT_MAPPED:
- case MR_EXTRACT_MESH:
- if (iter_type & MR_ITER_LOOPTRI) {
- ExtractTriMesh_Params params;
- params.mlooptri = mr->mlooptri;
- params.tri_range[0] = start;
- params.tri_range[1] = min_ii(mr->tri_len, end);
- extract_iter_looptri_mesh(mr, &params, extractors, task_id);
- }
- if (iter_type & MR_ITER_POLY) {
- ExtractPolyMesh_Params params;
- params.poly_range[0] = start;
- params.poly_range[1] = min_ii(mr->poly_len, end);
- extract_iter_poly_mesh(mr, &params, extractors, task_id);
- }
- if (iter_type & MR_ITER_LEDGE) {
- ExtractLEdgeMesh_Params params;
- params.ledge = mr->ledges;
- params.ledge_range[0] = start;
- params.ledge_range[1] = min_ii(mr->edge_loose_len, end);
- extract_iter_ledge_mesh(mr, &params, extractors, task_id);
- }
- if (iter_type & MR_ITER_LVERT) {
- ExtractLVertMesh_Params params;
- params.lvert = mr->lverts;
- params.lvert_range[0] = start;
- params.lvert_range[1] = min_ii(mr->vert_loose_len, end);
- extract_iter_lvert_mesh(mr, &params, extractors, task_id);
- }
- break;
- }
-}
-
-static void extract_task_init(ExtractTaskData *data)
+static struct TaskNode *extract_task_node_create(struct TaskGraph *task_graph,
+ const MeshRenderData *mr,
+ MeshBatchCache *cache,
+ ExtractorRunDatas *extractors,
+ MeshBufferCache *mbc,
+ const bool use_threading)
{
- extract_init(data->mr, data->cache, *data->extractors, data->mbc);
- extract_task_init(*data->extractors, data->task_len);
-}
-
-static void extract_task_run(void *__restrict taskdata)
-{
- ExtractTaskData *data = (ExtractTaskData *)taskdata;
- mesh_extract_iter(
- data->mr, data->iter_type, data->start, data->end, *data->extractors, data->task_id);
-
- /* If this is the last task, we do the finish function. */
- int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1);
- if (remainin_tasks == 0) {
- extract_task_finish(*data->extractors, data->task_len);
- extract_finish(data->mr, data->cache, *data->extractors);
- }
-}
-
-static void extract_task_init_and_run(void *__restrict taskdata)
-{
- ExtractTaskData *data = (ExtractTaskData *)taskdata;
- extract_run_single_threaded(
- data->mr, data->cache, *data->extractors, data->iter_type, data->mbc);
+ ExtractTaskData *taskdata = new ExtractTaskData(mr, cache, extractors, mbc, use_threading);
+ struct TaskNode *task_node = BLI_task_graph_node_create(
+ task_graph,
+ extract_task_range_run,
+ taskdata,
+ (TaskGraphNodeFreeFunction)extract_task_data_free);
+ return task_node;
}
/** \} */
@@ -670,153 +554,9 @@ static struct TaskNode *mesh_extract_render_data_node_create(struct TaskGraph *t
/** \} */
/* ---------------------------------------------------------------------- */
-/** \name Task Node - Extract Single Threaded
- * \{ */
-
-static struct TaskNode *extract_single_threaded_task_node_create(struct TaskGraph *task_graph,
- ExtractTaskData *task_data)
-{
- struct TaskNode *task_node = BLI_task_graph_node_create(
- task_graph,
- extract_task_init_and_run,
- task_data,
- (TaskGraphNodeFreeFunction)extract_task_data_free);
- return task_node;
-}
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
-/** \name Task Node - UserData Initializer
- * \{ */
-struct UserDataInitTaskData {
- ExtractTaskData *td = nullptr;
- int32_t task_counter = 0;
-
- ~UserDataInitTaskData()
- {
- extract_task_data_free(td);
- }
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("DRW:UserDataInitTaskData")
-#endif
-};
-
-static void user_data_init_task_data_free(void *data)
-{
- UserDataInitTaskData *taskdata = static_cast<UserDataInitTaskData *>(data);
- delete taskdata;
-}
-
-static void user_data_init_task_data_exec(void *__restrict task_data)
-{
- UserDataInitTaskData *extract_task_data = static_cast<UserDataInitTaskData *>(task_data);
- ExtractTaskData *taskdata_base = extract_task_data->td;
- extract_task_init(taskdata_base);
-}
-
-static struct TaskNode *user_data_init_task_node_create(struct TaskGraph *task_graph,
- UserDataInitTaskData *task_data)
-{
- struct TaskNode *task_node = BLI_task_graph_node_create(
- task_graph,
- user_data_init_task_data_exec,
- task_data,
- (TaskGraphNodeFreeFunction)user_data_init_task_data_free);
- return task_node;
-}
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
/** \name Extract Loop
* \{ */
-static void extract_range_task_create(struct TaskGraph *task_graph,
- struct TaskNode *task_node_user_data_init,
- ExtractTaskData *taskdata,
- const eMRIterType type,
- int start,
- int length)
-{
- taskdata = new ExtractTaskData(*taskdata);
- taskdata->task_id = atomic_fetch_and_add_int32(taskdata->task_counter, 1);
- BLI_assert(taskdata->task_id < taskdata->task_len);
- taskdata->iter_type = type;
- taskdata->start = start;
- taskdata->end = start + length;
- struct TaskNode *task_node = BLI_task_graph_node_create(
- task_graph, extract_task_run, taskdata, extract_task_data_free_ex);
- BLI_task_graph_edge_create(task_node_user_data_init, task_node);
-}
-
-static int extract_range_task_num_elements_get(const MeshRenderData *mr,
- const eMRIterType iter_type)
-{
- /* Divide task into sensible chunks. */
- int iter_len = 0;
- if (iter_type & MR_ITER_LOOPTRI) {
- iter_len += mr->tri_len;
- }
- if (iter_type & MR_ITER_POLY) {
- iter_len += mr->poly_len;
- }
- if (iter_type & MR_ITER_LEDGE) {
- iter_len += mr->edge_loose_len;
- }
- if (iter_type & MR_ITER_LVERT) {
- iter_len += mr->vert_loose_len;
- }
- return iter_len;
-}
-
-static int extract_range_task_chunk_size_get(const MeshRenderData *mr,
- const eMRIterType iter_type,
- const int num_threads)
-{
- /* Divide task into sensible chunks. */
- const int num_elements = extract_range_task_num_elements_get(mr, iter_type);
- int range_len = (num_elements + num_threads) / num_threads;
- CLAMP_MIN(range_len, CHUNK_SIZE);
- return range_len;
-}
-
-static void extract_task_in_ranges_create(struct TaskGraph *task_graph,
- struct TaskNode *task_node_user_data_init,
- ExtractTaskData *taskdata_base,
- const int num_threads)
-{
- const MeshRenderData *mr = taskdata_base->mr;
- const int range_len = extract_range_task_chunk_size_get(
- mr, taskdata_base->iter_type, num_threads);
-
- if (taskdata_base->iter_type & MR_ITER_LOOPTRI) {
- for (int i = 0; i < mr->tri_len; i += range_len) {
- extract_range_task_create(
- task_graph, task_node_user_data_init, taskdata_base, MR_ITER_LOOPTRI, i, range_len);
- }
- }
- if (taskdata_base->iter_type & MR_ITER_POLY) {
- for (int i = 0; i < mr->poly_len; i += range_len) {
- extract_range_task_create(
- task_graph, task_node_user_data_init, taskdata_base, MR_ITER_POLY, i, range_len);
- }
- }
- if (taskdata_base->iter_type & MR_ITER_LEDGE) {
- for (int i = 0; i < mr->edge_loose_len; i += range_len) {
- extract_range_task_create(
- task_graph, task_node_user_data_init, taskdata_base, MR_ITER_LEDGE, i, range_len);
- }
- }
- if (taskdata_base->iter_type & MR_ITER_LVERT) {
- for (int i = 0; i < mr->vert_loose_len; i += range_len) {
- extract_range_task_create(
- task_graph, task_node_user_data_init, taskdata_base, MR_ITER_LVERT, i, range_len);
- }
- }
-}
-
static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
MeshBatchCache *cache,
MeshBufferCache *mbc,
@@ -968,20 +708,16 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
const bool use_thread = (mr->loop_len + mr->loop_loose_len) > CHUNK_SIZE;
if (use_thread) {
- uint single_threaded_extractors_len = 0;
-
/* First run the requested extractors that do not support asynchronous ranges. */
for (const ExtractorRunData &run_data : extractors) {
const MeshExtract *extractor = run_data.extractor;
if (!extractor->use_threading) {
ExtractorRunDatas *single_threaded_extractors = new ExtractorRunDatas();
single_threaded_extractors->append(extractor);
- ExtractTaskData *taskdata = new ExtractTaskData(
- mr, cache, single_threaded_extractors, mbc, nullptr, 1);
- struct TaskNode *task_node = extract_single_threaded_task_node_create(task_graph,
- taskdata);
+ struct TaskNode *task_node = extract_task_node_create(
+ task_graph, mr, cache, single_threaded_extractors, mbc, false);
+
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
- single_threaded_extractors_len++;
}
}
@@ -989,31 +725,10 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
ExtractorRunDatas *multi_threaded_extractors = new ExtractorRunDatas();
extractors.filter_threaded_extractors_into(*multi_threaded_extractors);
if (!multi_threaded_extractors->is_empty()) {
- /*
- * Determine the number of thread to use for multithreading.
- * Thread can be used for single threaded tasks. These typically take longer to execute so
- * fill the rest of the threads for range operations.
- */
- int num_threads = BLI_task_scheduler_num_threads();
- num_threads -= single_threaded_extractors_len % num_threads;
- const int max_multithreaded_task_len = multi_threaded_extractors->iter_types_len() +
- num_threads;
-
- UserDataInitTaskData *user_data_init_task_data = new UserDataInitTaskData();
- struct TaskNode *task_node_user_data_init = user_data_init_task_node_create(
- task_graph, user_data_init_task_data);
-
- user_data_init_task_data->td = new ExtractTaskData(mr,
- cache,
- multi_threaded_extractors,
- mbc,
- &user_data_init_task_data->task_counter,
- max_multithreaded_task_len);
-
- extract_task_in_ranges_create(
- task_graph, task_node_user_data_init, user_data_init_task_data->td, num_threads);
-
- BLI_task_graph_edge_create(task_node_mesh_render_data, task_node_user_data_init);
+ struct TaskNode *task_node = extract_task_node_create(
+ task_graph, mr, cache, multi_threaded_extractors, mbc, true);
+
+ BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
else {
/* No tasks created freeing extractors list. */
@@ -1023,9 +738,9 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
else {
/* Run all requests on the same thread. */
ExtractorRunDatas *extractors_copy = new ExtractorRunDatas(extractors);
- ExtractTaskData *taskdata = new ExtractTaskData(mr, cache, extractors_copy, mbc, nullptr, 1);
+ struct TaskNode *task_node = extract_task_node_create(
+ task_graph, mr, cache, extractors_copy, mbc, false);
- struct TaskNode *task_node = extract_single_threaded_task_node_create(task_graph, taskdata);
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
}
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c b/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c
index 3cac391c42d..3a8edcad463 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c
@@ -130,12 +130,13 @@ typedef struct PosNorLoop {
typedef struct MeshExtract_PosNor_Data {
PosNorLoop *vbo_data;
- GPUNormal normals[];
+ GPUNormal *normals;
} MeshExtract_PosNor_Data;
-static void *extract_pos_nor_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_pos_nor_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -149,9 +150,9 @@ static void *extract_pos_nor_init(const MeshRenderData *mr,
GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
/* Pack normals per vert, reduce amount of computation. */
- size_t packed_nor_len = sizeof(GPUNormal) * mr->vert_len;
- MeshExtract_PosNor_Data *data = MEM_mallocN(sizeof(*data) + packed_nor_len, __func__);
+ MeshExtract_PosNor_Data *data = tls_data;
data->vbo_data = (PosNorLoop *)GPU_vertbuf_get_data(vbo);
+ data->normals = MEM_mallocN(sizeof(GPUNormal) * mr->vert_len, __func__);
/* Quicker than doing it for each loop. */
if (mr->extract_type == MR_EXTRACT_BMESH) {
@@ -168,11 +169,10 @@ static void *extract_pos_nor_init(const MeshRenderData *mr,
data->normals[v].low = GPU_normal_convert_i10_s3(mv->no);
}
}
- return data;
}
static void extract_pos_nor_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -220,7 +220,7 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_pos_nor_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *_data)
{
@@ -249,7 +249,7 @@ static void extract_pos_nor_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_pos_nor_iter_lvert_bm(const MeshRenderData *mr,
- BMVert *eve,
+ const BMVert *eve,
const int lvert_index,
void *_data)
{
@@ -280,9 +280,10 @@ static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr,
static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr),
struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
- void *data)
+ void *_data)
{
- MEM_freeN(data);
+ MeshExtract_PosNor_Data *data = _data;
+ MEM_freeN(data->normals);
}
const MeshExtract extract_pos_nor = {
@@ -295,6 +296,7 @@ const MeshExtract extract_pos_nor = {
.iter_lvert_mesh = extract_pos_nor_iter_lvert_mesh,
.finish = extract_pos_nor_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_PosNor_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.pos_nor),
};
@@ -312,12 +314,13 @@ typedef struct PosNorHQLoop {
typedef struct MeshExtract_PosNorHQ_Data {
PosNorHQLoop *vbo_data;
- GPUNormal normals[];
+ GPUNormal *normals;
} MeshExtract_PosNorHQ_Data;
-static void *extract_pos_nor_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_pos_nor_hq_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -331,9 +334,9 @@ static void *extract_pos_nor_hq_init(const MeshRenderData *mr,
GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
/* Pack normals per vert, reduce amount of computation. */
- size_t packed_nor_len = sizeof(GPUNormal) * mr->vert_len;
- MeshExtract_PosNorHQ_Data *data = MEM_mallocN(sizeof(*data) + packed_nor_len, __func__);
+ MeshExtract_PosNorHQ_Data *data = tls_data;
data->vbo_data = (PosNorHQLoop *)GPU_vertbuf_get_data(vbo);
+ data->normals = MEM_mallocN(sizeof(GPUNormal) * mr->vert_len, __func__);
/* Quicker than doing it for each loop. */
if (mr->extract_type == MR_EXTRACT_BMESH) {
@@ -350,11 +353,10 @@ static void *extract_pos_nor_hq_init(const MeshRenderData *mr,
copy_v3_v3_short(data->normals[v].high, mv->no);
}
}
- return data;
}
static void extract_pos_nor_hq_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -404,7 +406,7 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_pos_nor_hq_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *_data)
{
@@ -436,7 +438,7 @@ static void extract_pos_nor_hq_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_pos_nor_hq_iter_lvert_bm(const MeshRenderData *mr,
- BMVert *eve,
+ const BMVert *eve,
const int lvert_index,
void *_data)
{
@@ -469,9 +471,10 @@ static void extract_pos_nor_hq_iter_lvert_mesh(const MeshRenderData *mr,
static void extract_pos_nor_hq_finish(const MeshRenderData *UNUSED(mr),
struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
- void *data)
+ void *_data)
{
- MEM_freeN(data);
+ MeshExtract_PosNorHQ_Data *data = _data;
+ MEM_freeN(data->normals);
}
const MeshExtract extract_pos_nor_hq = {
@@ -484,6 +487,7 @@ const MeshExtract extract_pos_nor_hq = {
.iter_lvert_mesh = extract_pos_nor_hq_iter_lvert_mesh,
.finish = extract_pos_nor_hq_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_PosNorHQ_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.pos_nor)};
@@ -496,9 +500,10 @@ typedef struct gpuHQNor {
short x, y, z, w;
} gpuHQNor;
-static void *extract_lnor_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_lnor_hq_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -509,11 +514,11 @@ static void *extract_lnor_hq_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
- return GPU_vertbuf_get_data(vbo);
+ *(gpuHQNor **)tls_data = GPU_vertbuf_get_data(vbo);
}
static void extract_lnor_hq_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *data)
{
@@ -522,14 +527,14 @@ static void extract_lnor_hq_iter_poly_bm(const MeshRenderData *mr,
do {
const int l_index = BM_elem_index_get(l_iter);
if (mr->loop_normals) {
- normal_float_to_short_v3(&((gpuHQNor *)data)[l_index].x, mr->loop_normals[l_index]);
+ normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, mr->loop_normals[l_index]);
}
else {
if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
- normal_float_to_short_v3(&((gpuHQNor *)data)[l_index].x, bm_vert_no_get(mr, l_iter->v));
+ normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, bm_vert_no_get(mr, l_iter->v));
}
else {
- normal_float_to_short_v3(&((gpuHQNor *)data)[l_index].x, bm_face_no_get(mr, f));
+ normal_float_to_short_v3(&(*(gpuHQNor **)data)[l_index].x, bm_face_no_get(mr, f));
}
}
} while ((l_iter = l_iter->next) != l_first);
@@ -544,7 +549,7 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
- gpuHQNor *lnor_data = &((gpuHQNor *)data)[ml_index];
+ gpuHQNor *lnor_data = &(*(gpuHQNor **)data)[ml_index];
if (mr->loop_normals) {
normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[ml_index]);
}
@@ -576,6 +581,7 @@ const MeshExtract extract_lnor_hq = {
.iter_poly_bm = extract_lnor_hq_iter_poly_bm,
.iter_poly_mesh = extract_lnor_hq_iter_poly_mesh,
.data_type = MR_DATA_LOOP_NOR,
+ .data_size = sizeof(gpuHQNor *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.lnor),
};
@@ -585,9 +591,10 @@ const MeshExtract extract_lnor_hq = {
/** \name Extract Loop Normal
* \{ */
-static void *extract_lnor_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_lnor_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -598,11 +605,11 @@ static void *extract_lnor_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
- return GPU_vertbuf_get_data(vbo);
+ *(GPUPackedNormal **)tls_data = GPU_vertbuf_get_data(vbo);
}
static void extract_lnor_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *data)
{
@@ -611,18 +618,18 @@ static void extract_lnor_iter_poly_bm(const MeshRenderData *mr,
do {
const int l_index = BM_elem_index_get(l_iter);
if (mr->loop_normals) {
- ((GPUPackedNormal *)data)[l_index] = GPU_normal_convert_i10_v3(mr->loop_normals[l_index]);
+ (*(GPUPackedNormal **)data)[l_index] = GPU_normal_convert_i10_v3(mr->loop_normals[l_index]);
}
else {
if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
- ((GPUPackedNormal *)data)[l_index] = GPU_normal_convert_i10_v3(
+ (*(GPUPackedNormal **)data)[l_index] = GPU_normal_convert_i10_v3(
bm_vert_no_get(mr, l_iter->v));
}
else {
- ((GPUPackedNormal *)data)[l_index] = GPU_normal_convert_i10_v3(bm_face_no_get(mr, f));
+ (*(GPUPackedNormal **)data)[l_index] = GPU_normal_convert_i10_v3(bm_face_no_get(mr, f));
}
}
- ((GPUPackedNormal *)data)[l_index].w = BM_elem_flag_test(f, BM_ELEM_HIDDEN) ? -1 : 0;
+ (*(GPUPackedNormal **)data)[l_index].w = BM_elem_flag_test(f, BM_ELEM_HIDDEN) ? -1 : 0;
} while ((l_iter = l_iter->next) != l_first);
}
@@ -635,7 +642,7 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
- GPUPackedNormal *lnor_data = &((GPUPackedNormal *)data)[ml_index];
+ GPUPackedNormal *lnor_data = &(*(GPUPackedNormal **)data)[ml_index];
if (mr->loop_normals) {
*lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[ml_index]);
}
@@ -667,6 +674,7 @@ const MeshExtract extract_lnor = {
.iter_poly_bm = extract_lnor_iter_poly_bm,
.iter_poly_mesh = extract_lnor_iter_poly_mesh,
.data_type = MR_DATA_LOOP_NOR,
+ .data_size = sizeof(GPUPackedNormal *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.lnor),
};
@@ -677,7 +685,10 @@ const MeshExtract extract_lnor = {
/** \name Extract UV layers
* \{ */
-static void *extract_uv_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
+static void extract_uv_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
GPUVertFormat format = {0};
@@ -757,13 +768,12 @@ static void *extract_uv_init(const MeshRenderData *mr, struct MeshBatchCache *ca
}
}
}
-
- return NULL;
}
const MeshExtract extract_uv = {
.init = extract_uv_init,
.data_type = 0,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.uv),
};
@@ -946,15 +956,18 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
CustomData_free(&loop_data, mr->loop_len);
}
-static void *extract_tan_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
+static void extract_tan_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *UNUSED(tls_data))
{
extract_tan_ex_init(mr, cache, buf, false);
- return NULL;
}
const MeshExtract extract_tan = {
.init = extract_tan_init,
.data_type = MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.tan),
};
@@ -965,15 +978,18 @@ const MeshExtract extract_tan = {
/** \name Extract HQ Tangent layers
* \{ */
-static void *extract_tan_hq_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
+static void extract_tan_hq_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *UNUSED(tls_data))
{
extract_tan_ex_init(mr, cache, buf, true);
- return NULL;
}
const MeshExtract extract_tan_hq = {
.init = extract_tan_hq_init,
.data_type = MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI,
+ .data_size = 0,
.use_threading = false,
};
@@ -983,9 +999,10 @@ const MeshExtract extract_tan_hq = {
/** \name Extract Sculpt Data
* \{ */
-static void *extract_sculpt_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_sculpt_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
GPUVertFormat format = {0};
@@ -1066,13 +1083,12 @@ static void *extract_sculpt_data_init(const MeshRenderData *mr,
}
}
}
-
- return NULL;
}
const MeshExtract extract_sculpt_data = {
.init = extract_sculpt_data_init,
.data_type = 0,
+ .data_size = 0,
/* TODO: enable threading. */
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.sculpt_data)};
@@ -1083,7 +1099,10 @@ const MeshExtract extract_sculpt_data = {
/** \name Extract VCol
* \{ */
-static void *extract_vcol_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
+static void extract_vcol_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
GPUVertFormat format = {0};
@@ -1216,12 +1235,12 @@ static void *extract_vcol_init(const MeshRenderData *mr, struct MeshBatchCache *
}
}
}
- return NULL;
}
const MeshExtract extract_vcol = {
.init = extract_vcol_init,
.data_type = 0,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.vcol),
};
@@ -1237,9 +1256,10 @@ typedef struct MeshExtract_Orco_Data {
float (*orco)[3];
} MeshExtract_Orco_Data;
-static void *extract_orco_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_orco_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -1256,16 +1276,15 @@ static void *extract_orco_init(const MeshRenderData *mr,
CustomData *cd_vdata = &mr->me->vdata;
- MeshExtract_Orco_Data *data = MEM_mallocN(sizeof(*data), __func__);
+ MeshExtract_Orco_Data *data = tls_data;
data->vbo_data = (float(*)[4])GPU_vertbuf_get_data(vbo);
data->orco = CustomData_get_layer(cd_vdata, CD_ORCO);
/* Make sure `orco` layer was requested only if needed! */
BLI_assert(data->orco);
- return data;
}
static void extract_orco_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *data)
{
@@ -1296,20 +1315,12 @@ static void extract_orco_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_orco_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
- void *data)
-{
- MEM_freeN(data);
-}
-
const MeshExtract extract_orco = {
.init = extract_orco_init,
.iter_poly_bm = extract_orco_iter_poly_bm,
.iter_poly_mesh = extract_orco_iter_poly_mesh,
- .finish = extract_orco_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_Orco_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.orco),
};
@@ -1325,7 +1336,7 @@ typedef struct MeshExtract_EdgeFac_Data {
uchar *vbo_data;
bool use_edge_render;
/* Number of loop per edge. */
- uchar edge_loop_count[0];
+ uchar *edge_loop_count;
} MeshExtract_EdgeFac_Data;
static float loop_edge_factor_get(const float f_no[3],
@@ -1344,9 +1355,10 @@ static float loop_edge_factor_get(const float f_no[3],
return d;
}
-static void *extract_edge_fac_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_edge_fac_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -1357,11 +1369,10 @@ static void *extract_edge_fac_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
- MeshExtract_EdgeFac_Data *data;
+ MeshExtract_EdgeFac_Data *data = tls_data;
if (mr->extract_type == MR_EXTRACT_MESH) {
- size_t edge_loop_count_size = sizeof(uint32_t) * mr->edge_len;
- data = MEM_callocN(sizeof(*data) + edge_loop_count_size, __func__);
+ data->edge_loop_count = MEM_callocN(sizeof(uint32_t) * mr->edge_len, __func__);
/* HACK(fclem) Detecting the need for edge render.
* We could have a flag in the mesh instead or check the modifier stack. */
@@ -1374,17 +1385,15 @@ static void *extract_edge_fac_init(const MeshRenderData *mr,
}
}
else {
- data = MEM_callocN(sizeof(*data), __func__);
/* HACK to bypass non-manifold check in mesh_edge_fac_finish(). */
data->use_edge_render = true;
}
data->vbo_data = GPU_vertbuf_get_data(vbo);
- return data;
}
static void extract_edge_fac_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -1450,7 +1459,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edge_fac_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *UNUSED(eed),
+ const BMEdge *UNUSED(eed),
const int ledge_index,
void *_data)
{
@@ -1501,7 +1510,7 @@ static void extract_edge_fac_finish(const MeshRenderData *mr,
/* Free old byte data. */
MEM_freeN(data->vbo_data);
}
- MEM_freeN(data);
+ MEM_SAFE_FREE(data->edge_loop_count);
}
const MeshExtract extract_edge_fac = {
@@ -1512,6 +1521,7 @@ const MeshExtract extract_edge_fac = {
.iter_ledge_mesh = extract_edge_fac_iter_ledge_mesh,
.finish = extract_edge_fac_finish,
.data_type = MR_DATA_POLY_NOR,
+ .data_size = sizeof(MeshExtract_EdgeFac_Data),
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.edge_fac)};
@@ -1580,9 +1590,10 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
return input;
}
-static void *extract_weights_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- void *buf)
+static void extract_weights_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -1592,7 +1603,7 @@ static void *extract_weights_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
- MeshExtract_Weight_Data *data = MEM_callocN(sizeof(*data), __func__);
+ MeshExtract_Weight_Data *data = tls_data;
data->vbo_data = (float *)GPU_vertbuf_get_data(vbo);
data->wstate = &cache->weight_state;
@@ -1609,11 +1620,10 @@ static void *extract_weights_init(const MeshRenderData *mr,
data->dvert = CustomData_get_layer(&mr->me->vdata, CD_MDEFORMVERT);
data->cd_ofs = -1;
}
- return data;
}
static void extract_weights_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -1653,20 +1663,12 @@ static void extract_weights_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_weights_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
- void *data)
-{
- MEM_freeN(data);
-}
-
const MeshExtract extract_weights = {
.init = extract_weights_init,
.iter_poly_bm = extract_weights_iter_poly_bm,
.iter_poly_mesh = extract_weights_iter_poly_mesh,
- .finish = extract_weights_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_Weight_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.weights),
};
@@ -1685,7 +1687,7 @@ typedef struct EditLoopData {
} EditLoopData;
static void mesh_render_data_face_flag(const MeshRenderData *mr,
- BMFace *efa,
+ const BMFace *efa,
const int cd_ofs,
EditLoopData *eattr)
{
@@ -1713,7 +1715,9 @@ static void mesh_render_data_face_flag(const MeshRenderData *mr,
#endif
}
-static void mesh_render_data_edge_flag(const MeshRenderData *mr, BMEdge *eed, EditLoopData *eattr)
+static void mesh_render_data_edge_flag(const MeshRenderData *mr,
+ const BMEdge *eed,
+ EditLoopData *eattr)
{
const ToolSettings *ts = mr->toolsettings;
const bool is_vertex_select_mode = (ts != NULL) && (ts->selectmode & SCE_SELECT_VERTEX) != 0;
@@ -1805,7 +1809,9 @@ static void mesh_render_data_loop_edge_flag(const MeshRenderData *mr,
}
}
-static void mesh_render_data_vert_flag(const MeshRenderData *mr, BMVert *eve, EditLoopData *eattr)
+static void mesh_render_data_vert_flag(const MeshRenderData *mr,
+ const BMVert *eve,
+ EditLoopData *eattr)
{
if (eve == mr->eve_act) {
eattr->e_flag |= VFLAG_VERT_ACTIVE;
@@ -1815,9 +1821,10 @@ static void mesh_render_data_vert_flag(const MeshRenderData *mr, BMVert *eve, Ed
}
}
-static void *extract_edit_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_edit_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -1828,20 +1835,23 @@ static void *extract_edit_data_init(const MeshRenderData *mr,
}
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
- return GPU_vertbuf_get_data(vbo);
+ EditLoopData *vbo_data = GPU_vertbuf_get_data(vbo);
+ *(EditLoopData **)tls_data = vbo_data;
}
static void extract_edit_data_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
+ EditLoopData *vbo_data = *(EditLoopData **)_data;
+
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const int l_index = BM_elem_index_get(l_iter);
- EditLoopData *data = (EditLoopData *)_data + l_index;
+ EditLoopData *data = vbo_data + l_index;
memset(data, 0x0, sizeof(*data));
mesh_render_data_face_flag(mr, f, -1, data);
mesh_render_data_edge_flag(mr, l_iter->e, data);
@@ -1854,11 +1864,13 @@ static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr,
const int mp_index,
void *_data)
{
+ EditLoopData *vbo_data = *(EditLoopData **)_data;
+
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
- EditLoopData *data = (EditLoopData *)_data + ml_index;
+ EditLoopData *data = vbo_data + ml_index;
memset(data, 0x0, sizeof(*data));
BMFace *efa = bm_original_face_get(mr, mp_index);
BMEdge *eed = bm_original_edge_get(mr, ml->e);
@@ -1876,11 +1888,12 @@ static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edit_data_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *_data)
{
- EditLoopData *data = (EditLoopData *)_data + mr->loop_len + (ledge_index * 2);
+ EditLoopData *vbo_data = *(EditLoopData **)_data;
+ EditLoopData *data = vbo_data + mr->loop_len + (ledge_index * 2);
memset(data, 0x0, sizeof(*data) * 2);
mesh_render_data_edge_flag(mr, eed, &data[0]);
data[1] = data[0];
@@ -1893,7 +1906,8 @@ static void extract_edit_data_iter_ledge_mesh(const MeshRenderData *mr,
const int ledge_index,
void *_data)
{
- EditLoopData *data = (EditLoopData *)_data + mr->loop_len + ledge_index * 2;
+ EditLoopData *vbo_data = *(EditLoopData **)_data;
+ EditLoopData *data = vbo_data + mr->loop_len + ledge_index * 2;
memset(data, 0x0, sizeof(*data) * 2);
const int e_index = mr->ledges[ledge_index];
BMEdge *eed = bm_original_edge_get(mr, e_index);
@@ -1912,12 +1926,13 @@ static void extract_edit_data_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_edit_data_iter_lvert_bm(const MeshRenderData *mr,
- BMVert *eve,
+ const BMVert *eve,
const int lvert_index,
void *_data)
{
+ EditLoopData *vbo_data = *(EditLoopData **)_data;
const int offset = mr->loop_len + (mr->edge_loose_len * 2);
- EditLoopData *data = (EditLoopData *)_data + offset + lvert_index;
+ EditLoopData *data = vbo_data + offset + lvert_index;
memset(data, 0x0, sizeof(*data));
mesh_render_data_vert_flag(mr, eve, data);
}
@@ -1927,9 +1942,10 @@ static void extract_edit_data_iter_lvert_mesh(const MeshRenderData *mr,
const int lvert_index,
void *_data)
{
+ EditLoopData *vbo_data = *(EditLoopData **)_data;
const int offset = mr->loop_len + (mr->edge_loose_len * 2);
- EditLoopData *data = (EditLoopData *)_data + offset + lvert_index;
+ EditLoopData *data = vbo_data + offset + lvert_index;
memset(data, 0x0, sizeof(*data));
const int v_index = mr->lverts[lvert_index];
BMVert *eve = bm_original_vert_get(mr, v_index);
@@ -1947,6 +1963,7 @@ const MeshExtract extract_edit_data = {
.iter_lvert_bm = extract_edit_data_iter_lvert_bm,
.iter_lvert_mesh = extract_edit_data_iter_lvert_mesh,
.data_type = 0,
+ .data_size = sizeof(EditLoopData *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.edit_data)};
@@ -1961,9 +1978,10 @@ typedef struct MeshExtract_EditUVData_Data {
int cd_ofs;
} MeshExtract_EditUVData_Data;
-static void *extract_edituv_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_edituv_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -1978,14 +1996,13 @@ static void *extract_edituv_data_init(const MeshRenderData *mr,
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
- MeshExtract_EditUVData_Data *data = MEM_callocN(sizeof(*data), __func__);
+ MeshExtract_EditUVData_Data *data = tls_data;
data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo);
data->cd_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV);
- return data;
}
static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -2044,20 +2061,12 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_edituv_data_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
- void *data)
-{
- MEM_freeN(data);
-}
-
const MeshExtract extract_edituv_data = {
.init = extract_edituv_data_init,
.iter_poly_bm = extract_edituv_data_iter_poly_bm,
.iter_poly_mesh = extract_edituv_data_iter_poly_mesh,
- .finish = extract_edituv_data_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_EditUVData_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.edituv_data)};
@@ -2067,9 +2076,10 @@ const MeshExtract extract_edituv_data = {
/** \name Extract Edit UV area stretch
* \{ */
-static void *extract_edituv_stretch_area_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_edituv_stretch_area_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -2079,8 +2089,6 @@ static void *extract_edituv_stretch_area_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
-
- return NULL;
}
BLI_INLINE float area_ratio_get(float area, float uvarea)
@@ -2174,6 +2182,7 @@ const MeshExtract extract_edituv_stretch_area = {
.init = extract_edituv_stretch_area_init,
.finish = extract_edituv_stretch_area_finish,
.data_type = 0,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.edituv_stretch_area)};
@@ -2237,9 +2246,10 @@ static void edituv_get_edituv_stretch_angle(float auv[2][2],
#endif
}
-static void *extract_edituv_stretch_angle_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_edituv_stretch_angle_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -2252,7 +2262,7 @@ static void *extract_edituv_stretch_angle_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
- MeshExtract_StretchAngle_Data *data = MEM_callocN(sizeof(*data), __func__);
+ MeshExtract_StretchAngle_Data *data = tls_data;
data->vbo_data = (UVStretchAngle *)GPU_vertbuf_get_data(vbo);
/* Special iterator needed to save about half of the computing cost. */
@@ -2263,11 +2273,10 @@ static void *extract_edituv_stretch_angle_init(const MeshRenderData *mr,
BLI_assert(ELEM(mr->extract_type, MR_EXTRACT_MAPPED, MR_EXTRACT_MESH));
data->luv = CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
}
- return data;
}
static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -2363,20 +2372,12 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr
}
}
-static void extract_edituv_stretch_angle_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
- void *data)
-{
- MEM_freeN(data);
-}
-
const MeshExtract extract_edituv_stretch_angle = {
.init = extract_edituv_stretch_angle_init,
.iter_poly_bm = extract_edituv_stretch_angle_iter_poly_bm,
.iter_poly_mesh = extract_edituv_stretch_angle_iter_poly_mesh,
- .finish = extract_edituv_stretch_angle_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_StretchAngle_Data),
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.edituv_stretch_angle)};
@@ -2386,9 +2387,10 @@ const MeshExtract extract_edituv_stretch_angle = {
/** \name Extract Edit Mesh Analysis Colors
* \{ */
-static void *extract_mesh_analysis_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_mesh_analysis_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -2398,8 +2400,6 @@ static void *extract_mesh_analysis_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len);
-
- return NULL;
}
static void axis_from_enum_v3(float v[3], const char axis)
@@ -2984,6 +2984,7 @@ const MeshExtract extract_mesh_analysis = {
/* This is not needed for all visualization types.
* * Maybe split into different extract. */
.data_type = MR_DATA_POLY_NOR | MR_DATA_LOOPTRI,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.mesh_analysis)};
@@ -2993,9 +2994,10 @@ const MeshExtract extract_mesh_analysis = {
/** \name Extract Face-dots positions
* \{ */
-static void *extract_fdots_pos_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_fdots_pos_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3005,15 +3007,15 @@ static void *extract_fdots_pos_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->poly_len);
- return GPU_vertbuf_get_data(vbo);
+ *(float(**)[3])tls_data = GPU_vertbuf_get_data(vbo);
}
static void extract_fdots_pos_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int f_index,
void *data)
{
- float(*center)[3] = data;
+ float(*center)[3] = *(float(**)[3])data;
float *co = center[f_index];
zero_v3(co);
@@ -3031,7 +3033,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
const int mp_index,
void *data)
{
- float(*center)[3] = (float(*)[3])data;
+ float(*center)[3] = *(float(**)[3])data;
float *co = center[mp_index];
zero_v3(co);
@@ -3064,6 +3066,7 @@ const MeshExtract extract_fdots_pos = {
.iter_poly_bm = extract_fdots_pos_iter_poly_bm,
.iter_poly_mesh = extract_fdots_pos_iter_poly_mesh,
.data_type = 0,
+ .data_size = sizeof(float (*)[3]),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.fdots_pos)};
@@ -3077,9 +3080,10 @@ const MeshExtract extract_fdots_pos = {
#define NOR_AND_FLAG_ACTIVE -1
#define NOR_AND_FLAG_HIDDEN -2
-static void *extract_fdots_nor_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_fdots_nor_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3089,8 +3093,6 @@ static void *extract_fdots_nor_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->poly_len);
-
- return NULL;
}
static void extract_fdots_nor_finish(const MeshRenderData *mr,
@@ -3146,6 +3148,7 @@ const MeshExtract extract_fdots_nor = {
.init = extract_fdots_nor_init,
.finish = extract_fdots_nor_finish,
.data_type = MR_DATA_POLY_NOR,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.fdots_nor)};
@@ -3154,9 +3157,10 @@ const MeshExtract extract_fdots_nor = {
/* ---------------------------------------------------------------------- */
/** \name Extract Face-dots High Quality Normal and edit flag
* \{ */
-static void *extract_fdots_nor_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_fdots_nor_hq_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3166,8 +3170,6 @@ static void *extract_fdots_nor_hq_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->poly_len);
-
- return NULL;
}
static void extract_fdots_nor_hq_finish(const MeshRenderData *mr,
@@ -3223,6 +3225,7 @@ const MeshExtract extract_fdots_nor_hq = {
.init = extract_fdots_nor_hq_init,
.finish = extract_fdots_nor_hq_finish,
.data_type = MR_DATA_POLY_NOR,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.fdots_nor)};
@@ -3238,9 +3241,10 @@ typedef struct MeshExtract_FdotUV_Data {
int cd_ofs;
} MeshExtract_FdotUV_Data;
-static void *extract_fdots_uv_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_fdots_uv_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3258,7 +3262,7 @@ static void *extract_fdots_uv_init(const MeshRenderData *mr,
memset(GPU_vertbuf_get_data(vbo), 0x0, mr->poly_len * GPU_vertbuf_get_format(vbo)->stride);
}
- MeshExtract_FdotUV_Data *data = MEM_callocN(sizeof(*data), __func__);
+ MeshExtract_FdotUV_Data *data = tls_data;
data->vbo_data = (float(*)[2])GPU_vertbuf_get_data(vbo);
if (mr->extract_type == MR_EXTRACT_BMESH) {
@@ -3267,11 +3271,10 @@ static void *extract_fdots_uv_init(const MeshRenderData *mr,
else {
data->uv_data = CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
}
- return data;
}
static void extract_fdots_uv_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -3308,20 +3311,12 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_fdots_uv_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
- void *data)
-{
- MEM_freeN(data);
-}
-
const MeshExtract extract_fdots_uv = {
.init = extract_fdots_uv_init,
.iter_poly_bm = extract_fdots_uv_iter_poly_bm,
.iter_poly_mesh = extract_fdots_uv_iter_poly_mesh,
- .finish = extract_fdots_uv_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_FdotUV_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.fdots_uv)};
@@ -3336,9 +3331,10 @@ typedef struct MeshExtract_EditUVFdotData_Data {
int cd_ofs;
} MeshExtract_EditUVFdotData_Data;
-static void *extract_fdots_edituv_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_fdots_edituv_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3349,14 +3345,13 @@ static void *extract_fdots_edituv_data_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->poly_len);
- MeshExtract_EditUVFdotData_Data *data = MEM_callocN(sizeof(*data), __func__);
+ MeshExtract_EditUVFdotData_Data *data = tls_data;
data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo);
data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV);
- return data;
}
static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -3380,20 +3375,12 @@ static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_fdots_edituv_data_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf),
- void *data)
-{
- MEM_freeN(data);
-}
-
const MeshExtract extract_fdots_edituv_data = {
.init = extract_fdots_edituv_data_init,
.iter_poly_bm = extract_fdots_edituv_data_iter_poly_bm,
.iter_poly_mesh = extract_fdots_edituv_data_iter_poly_mesh,
- .finish = extract_fdots_edituv_data_finish,
.data_type = 0,
+ .data_size = sizeof(MeshExtract_EditUVFdotData_Data),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.fdots_edituv_data)};
@@ -3408,9 +3395,10 @@ typedef struct SkinRootData {
float local_pos[3];
} SkinRootData;
-static void *extract_skin_roots_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_skin_roots_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(tls_data))
{
GPUVertBuf *vbo = buf;
/* Exclusively for edit mode. */
@@ -3444,13 +3432,12 @@ static void *extract_skin_roots_init(const MeshRenderData *mr,
/* It's really unlikely that all verts will be roots. Resize to avoid losing VRAM. */
GPU_vertbuf_data_len_set(vbo, root_len);
-
- return NULL;
}
const MeshExtract extract_skin_roots = {
.init = extract_skin_roots_init,
.data_type = 0,
+ .data_size = 0,
.use_threading = false,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.skin_roots)};
@@ -3460,9 +3447,10 @@ const MeshExtract extract_skin_roots = {
/** \name Extract Selection Index
* \{ */
-static void *extract_select_idx_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_select_idx_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3472,7 +3460,7 @@ static void *extract_select_idx_init(const MeshRenderData *mr,
}
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
- return GPU_vertbuf_get_data(vbo);
+ *(uint32_t **)tls_data = GPU_vertbuf_get_data(vbo);
}
/* TODO Use #glVertexID to get loop index and use the data structure on the CPU to retrieve the
@@ -3481,7 +3469,7 @@ static void *extract_select_idx_init(const MeshRenderData *mr,
* shader to output original index. */
static void extract_poly_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int f_index,
void *data)
{
@@ -3489,12 +3477,12 @@ static void extract_poly_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const int l_index = BM_elem_index_get(l_iter);
- ((uint32_t *)data)[l_index] = f_index;
+ (*(uint32_t **)data)[l_index] = f_index;
} while ((l_iter = l_iter->next) != l_first);
}
static void extract_edge_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *data)
{
@@ -3502,12 +3490,12 @@ static void extract_edge_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const int l_index = BM_elem_index_get(l_iter);
- ((uint32_t *)data)[l_index] = BM_elem_index_get(l_iter->e);
+ (*(uint32_t **)data)[l_index] = BM_elem_index_get(l_iter->e);
} while ((l_iter = l_iter->next) != l_first);
}
static void extract_vert_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *data)
{
@@ -3515,36 +3503,36 @@ static void extract_vert_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
const int l_index = BM_elem_index_get(l_iter);
- ((uint32_t *)data)[l_index] = BM_elem_index_get(l_iter->v);
+ (*(uint32_t **)data)[l_index] = BM_elem_index_get(l_iter->v);
} while ((l_iter = l_iter->next) != l_first);
}
static void extract_edge_idx_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *data)
{
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed);
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed);
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed);
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed);
}
static void extract_vert_idx_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *data)
{
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed->v1);
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed->v2);
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed->v1);
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed->v2);
}
static void extract_vert_idx_iter_lvert_bm(const MeshRenderData *mr,
- BMVert *eve,
+ const BMVert *eve,
const int lvert_index,
void *data)
{
const int offset = mr->loop_len + (mr->edge_loose_len * 2);
- ((uint32_t *)data)[offset + lvert_index] = BM_elem_index_get(eve);
+ (*(uint32_t **)data)[offset + lvert_index] = BM_elem_index_get(eve);
}
static void extract_poly_idx_iter_poly_mesh(const MeshRenderData *mr,
@@ -3554,7 +3542,7 @@ static void extract_poly_idx_iter_poly_mesh(const MeshRenderData *mr,
{
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
- ((uint32_t *)data)[ml_index] = (mr->p_origindex) ? mr->p_origindex[mp_index] : mp_index;
+ (*(uint32_t **)data)[ml_index] = (mr->p_origindex) ? mr->p_origindex[mp_index] : mp_index;
}
}
@@ -3567,7 +3555,7 @@ static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
- ((uint32_t *)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[ml->e] : ml->e;
+ (*(uint32_t **)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[ml->e] : ml->e;
}
}
@@ -3580,7 +3568,7 @@ static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
- ((uint32_t *)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[ml->v] : ml->v;
+ (*(uint32_t **)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[ml->v] : ml->v;
}
}
@@ -3591,8 +3579,8 @@ static void extract_edge_idx_iter_ledge_mesh(const MeshRenderData *mr,
{
const int e_index = mr->ledges[ledge_index];
const int e_orig = (mr->e_origindex) ? mr->e_origindex[e_index] : e_index;
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = e_orig;
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = e_orig;
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = e_orig;
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = e_orig;
}
static void extract_vert_idx_iter_ledge_mesh(const MeshRenderData *mr,
@@ -3602,8 +3590,8 @@ static void extract_vert_idx_iter_ledge_mesh(const MeshRenderData *mr,
{
int v1_orig = (mr->v_origindex) ? mr->v_origindex[med->v1] : med->v1;
int v2_orig = (mr->v_origindex) ? mr->v_origindex[med->v2] : med->v2;
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = v1_orig;
- ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = v2_orig;
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = v1_orig;
+ (*(uint32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = v2_orig;
}
static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr,
@@ -3615,7 +3603,7 @@ static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr,
const int v_index = mr->lverts[lvert_index];
const int v_orig = (mr->v_origindex) ? mr->v_origindex[v_index] : v_index;
- ((uint32_t *)data)[offset + lvert_index] = v_orig;
+ (*(uint32_t **)data)[offset + lvert_index] = v_orig;
}
const MeshExtract extract_poly_idx = {
@@ -3623,6 +3611,7 @@ const MeshExtract extract_poly_idx = {
.iter_poly_bm = extract_poly_idx_iter_poly_bm,
.iter_poly_mesh = extract_poly_idx_iter_poly_mesh,
.data_type = 0,
+ .data_size = sizeof(uint32_t *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.poly_idx)};
@@ -3633,6 +3622,7 @@ const MeshExtract extract_edge_idx = {
.iter_ledge_bm = extract_edge_idx_iter_ledge_bm,
.iter_ledge_mesh = extract_edge_idx_iter_ledge_mesh,
.data_type = 0,
+ .data_size = sizeof(uint32_t *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.edge_idx)};
@@ -3645,12 +3635,14 @@ const MeshExtract extract_vert_idx = {
.iter_lvert_bm = extract_vert_idx_iter_lvert_bm,
.iter_lvert_mesh = extract_vert_idx_iter_lvert_mesh,
.data_type = 0,
+ .data_size = sizeof(uint32_t *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.vert_idx)};
-static void *extract_fdot_idx_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *buf)
+static void extract_fdot_idx_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *tls_data)
{
GPUVertBuf *vbo = buf;
static GPUVertFormat format = {0};
@@ -3661,15 +3653,15 @@ static void *extract_fdot_idx_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->poly_len);
- return GPU_vertbuf_get_data(vbo);
+ *(uint32_t **)tls_data = GPU_vertbuf_get_data(vbo);
}
static void extract_fdot_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *UNUSED(f),
+ const BMFace *UNUSED(f),
const int f_index,
void *data)
{
- ((uint32_t *)data)[f_index] = f_index;
+ (*(uint32_t **)data)[f_index] = f_index;
}
static void extract_fdot_idx_iter_poly_mesh(const MeshRenderData *mr,
@@ -3678,10 +3670,10 @@ static void extract_fdot_idx_iter_poly_mesh(const MeshRenderData *mr,
void *data)
{
if (mr->p_origindex != NULL) {
- ((uint32_t *)data)[mp_index] = mr->p_origindex[mp_index];
+ (*(uint32_t **)data)[mp_index] = mr->p_origindex[mp_index];
}
else {
- ((uint32_t *)data)[mp_index] = mp_index;
+ (*(uint32_t **)data)[mp_index] = mp_index;
}
}
@@ -3690,5 +3682,6 @@ const MeshExtract extract_fdot_idx = {
.iter_poly_bm = extract_fdot_idx_iter_poly_bm,
.iter_poly_mesh = extract_fdot_idx_iter_poly_mesh,
.data_type = 0,
+ .data_size = sizeof(uint32_t *),
.use_threading = true,
.mesh_buffer_offset = offsetof(MeshBufferCache, vbo.fdot_idx)};
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_private.h b/source/blender/draw/intern/draw_cache_extract_mesh_private.h
index 2eea53354f2..26849eca08c 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_private.h
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_private.h
@@ -150,278 +150,56 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e
return efa->no;
}
-/* TODO(jbakker): phase out batch iteration macros as they are only used once. */
/* ---------------------------------------------------------------------- */
-/** \name Mesh Elements Extract: Loop Triangles
+/** \name Mesh Elements Extract Struct
* \{ */
-
-typedef struct ExtractTriBMesh_Params {
- BMLoop *(*looptris)[3];
- int tri_range[2];
-} ExtractTriBMesh_Params;
+/* TODO(jbakker): move parameters inside a struct. */
typedef void(ExtractTriBMeshFn)(const MeshRenderData *mr,
BMLoop **elt,
const int elt_index,
void *data);
-
-#define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elem_tri, index_tri, params) \
- CHECK_TYPE(params, const ExtractTriBMesh_Params *); \
- { \
- const int _tri_index_end = (params)->tri_range[1]; \
- BMLoop **elem_tri = (params)->looptris[(params)->tri_range[0]]; \
- for (int index_tri = (params)->tri_range[0]; index_tri < _tri_index_end; \
- index_tri += 1, elem_tri += 3)
-#define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END }
-
-typedef struct ExtractTriMesh_Params {
- const MLoopTri *mlooptri;
- int tri_range[2];
-} ExtractTriMesh_Params;
typedef void(ExtractTriMeshFn)(const MeshRenderData *mr,
const MLoopTri *mlt,
const int elt_index,
void *data);
-
-#define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(elem_tri, index_tri, params) \
- CHECK_TYPE(params, const ExtractTriMesh_Params *); \
- { \
- const int _tri_index_end = (params)->tri_range[1]; \
- const MLoopTri *elem_tri = &(params)->mlooptri[(params)->tri_range[0]]; \
- for (int index_tri = (params)->tri_range[0]; index_tri < _tri_index_end; \
- index_tri += 1, elem_tri += 1)
-#define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END }
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
-/** \name Mesh Elements Extract: Polygons, Loops
- * \{ */
-
-typedef struct ExtractPolyBMesh_Params {
- BMLoop *(*looptris)[3];
- int poly_range[2];
-} ExtractPolyBMesh_Params;
typedef void(ExtractPolyBMeshFn)(const MeshRenderData *mr,
- BMFace *f,
+ const BMFace *f,
const int f_index,
void *data);
-
-#define EXTRACT_POLY_FOREACH_BM_BEGIN(elem_poly, index_poly, params, mr) \
- CHECK_TYPE(params, const ExtractPolyBMesh_Params *); \
- { \
- BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \
- BMFace **_ftable = mr->bm->ftable; \
- const int _poly_index_end = (params)->poly_range[1]; \
- for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
- index_poly += 1) { \
- BMFace *elem_poly = _ftable[index_poly]; \
- (void)elem_poly;
-
-#define EXTRACT_POLY_FOREACH_BM_END \
- } \
- }
-
-/* Iterate over polygon and loop. */
-#define EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(elem_loop, index_loop, params, mr) \
- CHECK_TYPE(params, const ExtractPolyBMesh_Params *); \
- { \
- BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \
- BMFace **_ftable = mr->bm->ftable; \
- const int _poly_index_end = (params)->poly_range[1]; \
- for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
- index_poly += 1) { \
- BMFace *elem_face = _ftable[index_poly]; \
- BMLoop *elem_loop, *l_first; \
- elem_loop = l_first = BM_FACE_FIRST_LOOP(elem_face); \
- do { \
- const int index_loop = BM_elem_index_get(elem_loop); \
- (void)index_loop; /* Quiet warning when unused. */
-
-#define EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(elem_loop) \
- } \
- while ((elem_loop = elem_loop->next) != l_first) \
- ; \
- } \
- }
-
-typedef struct ExtractPolyMesh_Params {
- int poly_range[2];
-} ExtractPolyMesh_Params;
typedef void(ExtractPolyMeshFn)(const MeshRenderData *mr,
const MPoly *mp,
const int mp_index,
void *data);
-
-#define EXTRACT_POLY_FOREACH_MESH_BEGIN(elem_poly, index_poly, params, mr) \
- CHECK_TYPE(params, const ExtractPolyMesh_Params *); \
- { \
- const MPoly *_mpoly = mr->mpoly; \
- const int _poly_index_end = (params)->poly_range[1]; \
- for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
- index_poly += 1) { \
- const MPoly *elem_poly = &_mpoly[index_poly]; \
- (void)elem_poly;
-
-#define EXTRACT_POLY_FOREACH_MESH_END \
- } \
- }
-
-/* Iterate over polygon and loop. */
-#define EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN( \
- elem_poly, index_poly, elem_loop, index_loop, params, mr) \
- CHECK_TYPE(params, const ExtractPolyMesh_Params *); \
- { \
- const MPoly *_mpoly = mr->mpoly; \
- const MLoop *_mloop = mr->mloop; \
- const int _poly_index_end = (params)->poly_range[1]; \
- for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \
- index_poly += 1) { \
- const MPoly *elem_poly = &_mpoly[index_poly]; \
- const int _index_end = elem_poly->loopstart + elem_poly->totloop; \
- for (int index_loop = elem_poly->loopstart; index_loop < _index_end; index_loop += 1) { \
- const MLoop *elem_loop = &_mloop[index_loop]; \
- (void)elem_loop;
-
-#define EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END \
- } \
- } \
- }
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
-/** \name Mesh Elements Extract: Loose Edges
- * \{ */
-
-typedef struct ExtractLEdgeBMesh_Params {
- const int *ledge;
- int ledge_range[2];
-} ExtractLEdgeBMesh_Params;
typedef void(ExtractLEdgeBMeshFn)(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *data);
-
-#define EXTRACT_LEDGE_FOREACH_BM_BEGIN(elem_edge, index_ledge, params) \
- CHECK_TYPE(params, const ExtractLEdgeBMesh_Params *); \
- { \
- BLI_assert((mr->bm->elem_table_dirty & BM_EDGE) == 0); \
- BMEdge **_etable = mr->bm->etable; \
- const int *_ledge = (params)->ledge; \
- const int _ledge_index_end = (params)->ledge_range[1]; \
- for (int index_ledge = (params)->ledge_range[0]; index_ledge < _ledge_index_end; \
- index_ledge += 1) { \
- BMEdge *elem_edge = _etable[_ledge[index_ledge]]; \
- (void)elem_edge; /* Quiet warning when unused. */ \
- {
-#define EXTRACT_LEDGE_FOREACH_BM_END \
- } \
- } \
- }
-
-typedef struct ExtractLEdgeMesh_Params {
- const int *ledge;
- int ledge_range[2];
-} ExtractLEdgeMesh_Params;
typedef void(ExtractLEdgeMeshFn)(const MeshRenderData *mr,
const MEdge *med,
const int ledge_index,
void *data);
-
-#define EXTRACT_LEDGE_FOREACH_MESH_BEGIN(elem_edge, index_ledge, params, mr) \
- CHECK_TYPE(params, const ExtractLEdgeMesh_Params *); \
- { \
- const MEdge *_medge = mr->medge; \
- const int *_ledge = (params)->ledge; \
- const int _ledge_index_end = (params)->ledge_range[1]; \
- for (int index_ledge = (params)->ledge_range[0]; index_ledge < _ledge_index_end; \
- index_ledge += 1) { \
- const MEdge *elem_edge = &_medge[_ledge[index_ledge]]; \
- (void)elem_edge; /* Quiet warning when unused. */ \
- {
-#define EXTRACT_LEDGE_FOREACH_MESH_END \
- } \
- } \
- }
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
-/** \name Mesh Elements Extract: Loose Vertices
- * \{ */
-
-typedef struct ExtractLVertBMesh_Params {
- const int *lvert;
- int lvert_range[2];
-} ExtractLVertBMesh_Params;
typedef void(ExtractLVertBMeshFn)(const MeshRenderData *mr,
- BMVert *eve,
+ const BMVert *eve,
const int lvert_index,
void *data);
-
-#define EXTRACT_LVERT_FOREACH_BM_BEGIN(elem_vert, index_lvert, params) \
- CHECK_TYPE(params, const ExtractLVertBMesh_Params *); \
- { \
- BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \
- BMVert **vtable = mr->bm->vtable; \
- const int *lverts = (params)->lvert; \
- const int _lvert_index_end = (params)->lvert_range[1]; \
- for (int index_lvert = (params)->lvert_range[0]; index_lvert < _lvert_index_end; \
- index_lvert += 1) { \
- BMVert *elem_vert = vtable[lverts[index_lvert]]; \
- (void)elem_vert; /* Quiet warning when unused. */ \
- {
-#define EXTRACT_LVERT_FOREACH_BM_END \
- } \
- } \
- }
-
-typedef struct ExtractLVertMesh_Params {
- const int *lvert;
- int lvert_range[2];
-} ExtractLVertMesh_Params;
typedef void(ExtractLVertMeshFn)(const MeshRenderData *mr,
const MVert *mv,
const int lvert_index,
void *data);
-
-#define EXTRACT_LVERT_FOREACH_MESH_BEGIN(elem, index_lvert, params, mr) \
- CHECK_TYPE(params, const ExtractLVertMesh_Params *); \
- { \
- const MVert *mvert = mr->mvert; \
- const int *lverts = (params)->lvert; \
- const int _lvert_index_end = (params)->lvert_range[1]; \
- for (int index_lvert = (params)->lvert_range[0]; index_lvert < _lvert_index_end; \
- index_lvert += 1) { \
- const MVert *elem = &mvert[lverts[index_lvert]]; \
- (void)elem; /* Quiet warning when unused. */ \
- {
-#define EXTRACT_LVERT_FOREACH_MESH_END \
- } \
- } \
- }
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
-/** \name Mesh Elements Extract Struct
- * \{ */
-/* TODO(jbakker): move parameters inside a struct. */
-typedef void *(ExtractInitFn)(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- void *buffer);
+typedef void(ExtractInitFn)(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buffer,
+ void *r_data);
typedef void(ExtractFinishFn)(const MeshRenderData *mr,
struct MeshBatchCache *cache,
void *buffer,
void *data);
-typedef void *(ExtractTaskInitFn)(void *userdata);
+typedef void(ExtractTaskInitFn)(void *userdata, void *r_task_userdata);
typedef void(ExtractTaskFinishFn)(void *userdata, void *task_userdata);
typedef struct MeshExtract {
/** Executed on main thread and return user data for iteration functions. */
ExtractInitFn *init;
- /** Task local data. */
- ExtractTaskInitFn *task_init;
/** Executed on one (or more if use_threading) worker thread(s). */
ExtractTriBMeshFn *iter_looptri_bm;
ExtractTriMeshFn *iter_looptri_mesh;
@@ -432,10 +210,11 @@ typedef struct MeshExtract {
ExtractLVertBMeshFn *iter_lvert_bm;
ExtractLVertMeshFn *iter_lvert_mesh;
/** Executed on one worker thread after all elements iterations. */
- ExtractTaskFinishFn *task_finish;
+ ExtractTaskFinishFn *task_reduce;
ExtractFinishFn *finish;
/** Used to request common data. */
eMRDataType data_type;
+ size_t data_size;
/** Used to know if the element callbacks are thread-safe and can be parallelized. */
bool use_threading;
/**
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
index 20b0ec738ee..565f8834ab1 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
@@ -37,15 +37,14 @@ struct MeshExtract_EditUvElem_Data {
bool sync_selection;
};
-static void *extract_edituv_tris_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_edituv_tris_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(
- MEM_callocN(sizeof(*data), __func__));
+ MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, mr->tri_len, mr->loop_len);
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
- return data;
}
BLI_INLINE void edituv_tri_add(
@@ -93,7 +92,6 @@ static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr),
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
}
constexpr MeshExtract create_extractor_edituv_tris()
@@ -104,6 +102,7 @@ constexpr MeshExtract create_extractor_edituv_tris()
extractor.iter_looptri_mesh = extract_edituv_tris_iter_looptri_mesh;
extractor.finish = extract_edituv_tris_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.edituv_tris);
return extractor;
@@ -115,15 +114,14 @@ constexpr MeshExtract create_extractor_edituv_tris()
/** \name Extract Edit UV Line Indices around faces
* \{ */
-static void *extract_edituv_lines_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_edituv_lines_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(
- MEM_callocN(sizeof(*data), __func__));
+ MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES, mr->loop_len, mr->loop_len);
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
- return data;
}
BLI_INLINE void edituv_edge_add(
@@ -135,7 +133,7 @@ BLI_INLINE void edituv_edge_add(
}
static void extract_edituv_lines_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -184,7 +182,6 @@ static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr),
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
}
constexpr MeshExtract create_extractor_edituv_lines()
@@ -195,6 +192,7 @@ constexpr MeshExtract create_extractor_edituv_lines()
extractor.iter_poly_mesh = extract_edituv_lines_iter_poly_mesh;
extractor.finish = extract_edituv_lines_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.edituv_lines);
return extractor;
@@ -206,15 +204,14 @@ constexpr MeshExtract create_extractor_edituv_lines()
/** \name Extract Edit UV Points Indices
* \{ */
-static void *extract_edituv_points_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_edituv_points_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(
- MEM_callocN(sizeof(*data), __func__));
+ MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
GPU_indexbuf_init(&data->elb, GPU_PRIM_POINTS, mr->loop_len, mr->loop_len);
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
- return data;
}
BLI_INLINE void edituv_point_add(MeshExtract_EditUvElem_Data *data,
@@ -228,7 +225,7 @@ BLI_INLINE void edituv_point_add(MeshExtract_EditUvElem_Data *data,
}
static void extract_edituv_points_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_data)
{
@@ -269,7 +266,6 @@ static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr),
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
}
constexpr MeshExtract create_extractor_edituv_points()
@@ -280,6 +276,7 @@ constexpr MeshExtract create_extractor_edituv_points()
extractor.iter_poly_mesh = extract_edituv_points_iter_poly_mesh;
extractor.finish = extract_edituv_points_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.edituv_points);
return extractor;
@@ -291,15 +288,14 @@ constexpr MeshExtract create_extractor_edituv_points()
/** \name Extract Edit UV Face-dots Indices
* \{ */
-static void *extract_edituv_fdots_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_edituv_fdots_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(
- MEM_callocN(sizeof(*data), __func__));
+ MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(tls_data);
GPU_indexbuf_init(&data->elb, GPU_PRIM_POINTS, mr->poly_len, mr->poly_len);
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
- return data;
}
BLI_INLINE void edituv_facedot_add(MeshExtract_EditUvElem_Data *data,
@@ -316,7 +312,7 @@ BLI_INLINE void edituv_facedot_add(MeshExtract_EditUvElem_Data *data,
}
static void extract_edituv_fdots_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int f_index,
void *_data)
{
@@ -366,7 +362,6 @@ static void extract_edituv_fdots_finish(const MeshRenderData *UNUSED(mr),
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
}
constexpr MeshExtract create_extractor_edituv_fdots()
@@ -377,6 +372,7 @@ constexpr MeshExtract create_extractor_edituv_fdots()
extractor.iter_poly_mesh = extract_edituv_fdots_iter_poly_mesh;
extractor.finish = extract_edituv_fdots_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.edituv_fdots);
return extractor;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
index 9bd918dc9a5..1d1a000061d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
@@ -32,17 +32,17 @@ namespace blender::draw {
/** \name Extract Face-dots Indices
* \{ */
-static void *extract_fdots_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf))
+static void extract_fdots_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf),
+ void *tls_data)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(MEM_mallocN(sizeof(*elb), __func__));
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr->poly_len, mr->poly_len);
- return elb;
}
static void extract_fdots_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int f_index,
void *_userdata)
{
@@ -93,7 +93,6 @@ static void extract_fdots_finish(const MeshRenderData *UNUSED(mr),
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(elb, ibo);
- MEM_freeN(elb);
}
constexpr MeshExtract create_extractor_fdots()
@@ -104,6 +103,7 @@ constexpr MeshExtract create_extractor_fdots()
extractor.iter_poly_mesh = extract_fdots_iter_poly_mesh;
extractor.finish = extract_fdots_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(GPUIndexBufBuilder);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.fdots);
return extractor;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
index 74a3d3825c5..683794d4d66 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
@@ -31,28 +31,19 @@ namespace blender::draw {
/** \name Extract Edges Indices
* \{ */
-static void *extract_lines_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf))
+static void extract_lines_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf),
+ void *tls_data)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(MEM_mallocN(sizeof(*elb), __func__));
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
/* Put loose edges at the end. */
GPU_indexbuf_init(
elb, GPU_PRIM_LINES, mr->edge_len + mr->edge_loose_len, mr->loop_len + mr->loop_loose_len);
- return elb;
-}
-
-static void *extract_lines_task_init(void *_userdata)
-{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
- GPUIndexBufBuilder *sub_builder = static_cast<GPUIndexBufBuilder *>(
- MEM_mallocN(sizeof(*sub_builder), __func__));
- GPU_indexbuf_subbuilder_init(elb, sub_builder);
- return sub_builder;
}
static void extract_lines_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *data)
{
@@ -109,7 +100,7 @@ static void extract_lines_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_lines_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *data)
{
@@ -147,12 +138,11 @@ static void extract_lines_iter_ledge_mesh(const MeshRenderData *mr,
GPU_indexbuf_set_line_restart(elb, e_index);
}
-static void extract_lines_task_finish(void *_userdata, void *_task_userdata)
+static void extract_lines_task_finish(void *_userdata_to, void *_userdata_from)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
- GPUIndexBufBuilder *sub_builder = static_cast<GPUIndexBufBuilder *>(_task_userdata);
- GPU_indexbuf_subbuilder_finish(elb, sub_builder);
- MEM_freeN(sub_builder);
+ GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
+ GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
+ GPU_indexbuf_join_copies(elb_to, elb_from);
}
static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
@@ -163,21 +153,20 @@ static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(elb, ibo);
- MEM_freeN(elb);
}
constexpr MeshExtract create_extractor_lines()
{
MeshExtract extractor = {0};
extractor.init = extract_lines_init;
- extractor.task_init = extract_lines_task_init;
extractor.iter_poly_bm = extract_lines_iter_poly_bm;
extractor.iter_poly_mesh = extract_lines_iter_poly_mesh;
extractor.iter_ledge_bm = extract_lines_iter_ledge_bm;
extractor.iter_ledge_mesh = extract_lines_iter_ledge_mesh;
- extractor.task_finish = extract_lines_task_finish;
+ extractor.task_reduce = extract_lines_task_finish;
extractor.finish = extract_lines_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(GPUIndexBufBuilder);
extractor.use_threading = true;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines);
return extractor;
@@ -209,21 +198,20 @@ static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr,
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(elb, ibo);
extract_lines_loose_subbuffer(mr, cache);
- MEM_freeN(elb);
}
constexpr MeshExtract create_extractor_lines_with_lines_loose()
{
MeshExtract extractor = {0};
extractor.init = extract_lines_init;
- extractor.task_init = extract_lines_task_init;
extractor.iter_poly_bm = extract_lines_iter_poly_bm;
extractor.iter_poly_mesh = extract_lines_iter_poly_mesh;
extractor.iter_ledge_bm = extract_lines_iter_ledge_bm;
extractor.iter_ledge_mesh = extract_lines_iter_ledge_mesh;
- extractor.task_finish = extract_lines_task_finish;
+ extractor.task_reduce = extract_lines_task_finish;
extractor.finish = extract_lines_with_lines_loose_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(GPUIndexBufBuilder);
extractor.use_threading = true;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines);
return extractor;
@@ -235,14 +223,14 @@ constexpr MeshExtract create_extractor_lines_with_lines_loose()
/** \name Extract Loose Edges Sub Buffer
* \{ */
-static void *extract_lines_loose_only_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- void *buf)
+static void extract_lines_loose_only_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *UNUSED(tls_data))
{
BLI_assert(buf == cache->final.ibo.lines_loose);
UNUSED_VARS_NDEBUG(buf);
extract_lines_loose_subbuffer(mr, cache);
- return NULL;
}
constexpr MeshExtract create_extractor_lines_loose_only()
@@ -250,6 +238,7 @@ constexpr MeshExtract create_extractor_lines_loose_only()
MeshExtract extractor = {0};
extractor.init = extract_lines_loose_only_init;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = 0;
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines_loose);
return extractor;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
index 6140ae86c96..cace18b0c08 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
@@ -41,26 +41,25 @@ struct MeshExtract_LineAdjacency_Data {
EdgeHash *eh;
bool is_manifold;
/* Array to convert vert index to any loop index of this vert. */
- uint vert_to_loop[0];
+ uint *vert_to_loop;
};
-static void *extract_lines_adjacency_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf))
+static void extract_lines_adjacency_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf),
+ void *tls_data)
{
/* Similar to poly_to_tri_count().
* There is always (loop + triangle - 1) edges inside a polygon.
* Accumulate for all polys and you get : */
uint tess_edge_len = mr->loop_len + mr->tri_len - mr->poly_len;
- size_t vert_to_loop_size = sizeof(uint) * mr->vert_len;
+ MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(tls_data);
+ data->vert_to_loop = static_cast<uint *>(MEM_callocN(sizeof(uint) * mr->vert_len, __func__));
- MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(
- MEM_callocN(sizeof(*data) + vert_to_loop_size, __func__));
GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES_ADJ, tess_edge_len, mr->loop_len);
data->eh = BLI_edgehash_new_ex(__func__, tess_edge_len);
data->is_manifold = true;
- return data;
}
BLI_INLINE void lines_adjacency_triangle(
@@ -169,7 +168,7 @@ static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
cache->is_manifold = data->is_manifold;
GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
+ MEM_freeN(data->vert_to_loop);
}
#undef NO_EDGE
@@ -184,6 +183,7 @@ constexpr MeshExtract create_extractor_lines_adjacency()
extractor.iter_looptri_mesh = extract_lines_adjacency_iter_looptri_mesh;
extractor.finish = extract_lines_adjacency_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_LineAdjacency_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines_adjacency);
return extractor;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
index 6bbd0188f65..a142692ab4e 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
@@ -37,18 +37,17 @@ namespace blender::draw {
struct MeshExtract_LinePaintMask_Data {
GPUIndexBufBuilder elb;
/** One bit per edge set if face is selected. */
- BLI_bitmap select_map[0];
+ BLI_bitmap *select_map;
};
-static void *extract_lines_paint_mask_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_lines_paint_mask_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- size_t bitmap_size = BLI_BITMAP_SIZE(mr->edge_len);
- MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(
- MEM_callocN(sizeof(*data) + bitmap_size, __func__));
+ MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(tls_data);
+ data->select_map = BLI_BITMAP_NEW(mr->edge_len, __func__);
GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES, mr->edge_len, mr->loop_len);
- return data;
}
static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
@@ -101,7 +100,7 @@ static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr),
MeshExtract_LinePaintMask_Data *data = static_cast<MeshExtract_LinePaintMask_Data *>(_data);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
+ MEM_freeN(data->select_map);
}
/** \} */
@@ -113,6 +112,7 @@ constexpr MeshExtract create_extractor_lines_paint_mask()
extractor.iter_poly_mesh = extract_lines_paint_mask_iter_poly_mesh;
extractor.finish = extract_lines_paint_mask_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_LinePaintMask_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines_paint_mask);
return extractor;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
index 9220198d799..25d1a159f60 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
@@ -32,25 +32,16 @@ namespace blender::draw {
/* ---------------------------------------------------------------------- */
/** \name Extract Point Indices
* \{ */
-static void *extract_points_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf))
+static void extract_points_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf),
+ void *tls_data)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(MEM_mallocN(sizeof(*elb), __func__));
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr->vert_len, mr->loop_len + mr->loop_loose_len);
- return elb;
}
-static void *extract_points_task_init(void *_userdata)
-{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
- GPUIndexBufBuilder *sub_builder = static_cast<GPUIndexBufBuilder *>(
- MEM_mallocN(sizeof(*sub_builder), __func__));
- GPU_indexbuf_subbuilder_init(elb, sub_builder);
- return sub_builder;
-}
-
-BLI_INLINE void vert_set_bm(GPUIndexBufBuilder *elb, BMVert *eve, int l_index)
+BLI_INLINE void vert_set_bm(GPUIndexBufBuilder *elb, const BMVert *eve, int l_index)
{
const int v_index = BM_elem_index_get(eve);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
@@ -78,7 +69,7 @@ BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb,
}
static void extract_points_iter_poly_bm(const MeshRenderData *UNUSED(mr),
- BMFace *f,
+ const BMFace *f,
const int UNUSED(f_index),
void *_userdata)
{
@@ -107,7 +98,7 @@ static void extract_points_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_points_iter_ledge_bm(const MeshRenderData *mr,
- BMEdge *eed,
+ const BMEdge *eed,
const int ledge_index,
void *_userdata)
{
@@ -127,7 +118,7 @@ static void extract_points_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_points_iter_lvert_bm(const MeshRenderData *mr,
- BMVert *eve,
+ const BMVert *eve,
const int lvert_index,
void *_userdata)
{
@@ -146,12 +137,11 @@ static void extract_points_iter_lvert_mesh(const MeshRenderData *mr,
vert_set_mesh(elb, mr, mr->lverts[lvert_index], offset + lvert_index);
}
-static void extract_points_task_finish(void *_userdata, void *_task_userdata)
+static void extract_points_task_finish(void *_userdata_to, void *_userdata_from)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
- GPUIndexBufBuilder *sub_builder = static_cast<GPUIndexBufBuilder *>(_task_userdata);
- GPU_indexbuf_subbuilder_finish(elb, sub_builder);
- MEM_freeN(sub_builder);
+ GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
+ GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
+ GPU_indexbuf_join_copies(elb_to, elb_from);
}
static void extract_points_finish(const MeshRenderData *UNUSED(mr),
@@ -162,24 +152,23 @@ static void extract_points_finish(const MeshRenderData *UNUSED(mr),
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
GPU_indexbuf_build_in_place(elb, ibo);
- MEM_freeN(elb);
}
constexpr MeshExtract create_extractor_points()
{
MeshExtract extractor = {0};
extractor.init = extract_points_init;
- extractor.task_init = extract_points_task_init;
extractor.iter_poly_bm = extract_points_iter_poly_bm;
extractor.iter_poly_mesh = extract_points_iter_poly_mesh;
extractor.iter_ledge_bm = extract_points_iter_ledge_bm;
extractor.iter_ledge_mesh = extract_points_iter_ledge_mesh;
extractor.iter_lvert_bm = extract_points_iter_lvert_bm;
extractor.iter_lvert_mesh = extract_points_iter_lvert_mesh;
- extractor.task_finish = extract_points_task_finish;
+ extractor.task_reduce = extract_points_task_finish;
extractor.finish = extract_points_finish;
extractor.use_threading = true;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(GPUIndexBufBuilder);
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.points);
return extractor;
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
index acfffdacb88..27929fa8ba3 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
@@ -37,12 +37,12 @@ struct MeshExtract_Tri_Data {
int *tri_mat_end;
};
-static void *extract_tris_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_tris_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(
- MEM_callocN(sizeof(*data), __func__));
+ MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(tls_data);
size_t mat_tri_idx_size = sizeof(int) * mr->mat_len;
data->tri_mat_start = static_cast<int *>(MEM_callocN(mat_tri_idx_size, __func__));
@@ -82,8 +82,6 @@ static void *extract_tris_init(const MeshRenderData *mr,
int visible_tri_tot = ofs;
GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, visible_tri_tot, mr->loop_len);
-
- return data;
}
static void extract_tris_iter_looptri_bm(const MeshRenderData *mr,
@@ -150,7 +148,6 @@ static void extract_tris_finish(const MeshRenderData *mr,
}
MEM_freeN(data->tri_mat_start);
MEM_freeN(data->tri_mat_end);
- MEM_freeN(data);
}
constexpr MeshExtract create_extractor_tris()
@@ -161,6 +158,7 @@ constexpr MeshExtract create_extractor_tris()
extractor.iter_looptri_mesh = extract_tris_iter_looptri_mesh;
extractor.finish = extract_tris_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(MeshExtract_Tri_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.tris);
return extractor;
@@ -171,22 +169,13 @@ constexpr MeshExtract create_extractor_tris()
/** \name Extract Triangles Indices (single material)
* \{ */
-static void *extract_tris_single_mat_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(ibo))
+static void extract_tris_single_mat_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo),
+ void *tls_data)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(MEM_mallocN(sizeof(*elb), __func__));
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
GPU_indexbuf_init(elb, GPU_PRIM_TRIS, mr->tri_len, mr->loop_len);
- return elb;
-}
-
-static void *extract_tris_single_mat_task_init(void *_userdata)
-{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
- GPUIndexBufBuilder *sub_builder = static_cast<GPUIndexBufBuilder *>(
- MEM_mallocN(sizeof(*sub_builder), __func__));
- GPU_indexbuf_subbuilder_init(elb, sub_builder);
- return sub_builder;
}
static void extract_tris_single_mat_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
@@ -222,12 +211,11 @@ static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData *mr,
}
}
-static void extract_tris_single_mat_task_finish(void *_userdata, void *_task_userdata)
+static void extract_tris_single_mat_task_finish(void *_userdata_to, void *_userdata_from)
{
- GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
- GPUIndexBufBuilder *sub_builder = static_cast<GPUIndexBufBuilder *>(_task_userdata);
- GPU_indexbuf_subbuilder_finish(elb, sub_builder);
- MEM_freeN(sub_builder);
+ GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
+ GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
+ GPU_indexbuf_join_copies(elb_to, elb_from);
}
static void extract_tris_single_mat_finish(const MeshRenderData *mr,
@@ -254,19 +242,18 @@ static void extract_tris_single_mat_finish(const MeshRenderData *mr,
GPU_indexbuf_create_subrange_in_place(mbc->tris_per_mat[i], ibo, 0, len);
}
}
- MEM_freeN(elb);
}
constexpr MeshExtract create_extractor_tris_single_mat()
{
MeshExtract extractor = {0};
extractor.init = extract_tris_single_mat_init;
- extractor.task_init = extract_tris_single_mat_task_init;
extractor.iter_looptri_bm = extract_tris_single_mat_iter_looptri_bm;
extractor.iter_looptri_mesh = extract_tris_single_mat_iter_looptri_mesh;
- extractor.task_finish = extract_tris_single_mat_task_finish;
+ extractor.task_reduce = extract_tris_single_mat_task_finish;
extractor.finish = extract_tris_single_mat_finish;
extractor.data_type = MR_DATA_NONE;
+ extractor.data_size = sizeof(GPUIndexBufBuilder);
extractor.use_threading = true;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.tris);
return extractor;
diff --git a/source/blender/gpu/GPU_index_buffer.h b/source/blender/gpu/GPU_index_buffer.h
index 03d60c60b4b..48f80e321b6 100644
--- a/source/blender/gpu/GPU_index_buffer.h
+++ b/source/blender/gpu/GPU_index_buffer.h
@@ -44,7 +44,6 @@ typedef struct GPUIndexBufBuilder {
uint index_max;
GPUPrimType prim_type;
uint32_t *data;
- const struct GPUIndexBufBuilder *parent;
} GPUIndexBufBuilder;
/* supports all primitive types. */
@@ -55,17 +54,12 @@ void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint ve
GPUIndexBuf *GPU_indexbuf_build_on_device(uint index_len);
/*
- * Thread safe sub builders.
+ * Thread safe.
*
- * Note that `GPU_indexbuf_subbuilder_init` and `GPU_indexbuf_subbuilder_finish` are not thread
- * safe and should be called when no threads are active. The pattern is to create a subbuilder for
- * each thread/task. Each thread/task would update their sub builder. When all thread are completed
- * the sub-builders can then be merged back to the parent builder.
+ * Function inspired by the reduction directives of multithread work APIs..
*/
-void GPU_indexbuf_subbuilder_init(const GPUIndexBufBuilder *parent_builder,
- GPUIndexBufBuilder *sub_builder);
-void GPU_indexbuf_subbuilder_finish(GPUIndexBufBuilder *builder,
- const GPUIndexBufBuilder *parent_builder);
+void GPU_indexbuf_join_copies(GPUIndexBufBuilder *builder,
+ const GPUIndexBufBuilder *parent_builder);
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v);
void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *);
diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc
index 3cdcaac5544..993bcdf743b 100644
--- a/source/blender/gpu/intern/gpu_index_buffer.cc
+++ b/source/blender/gpu/intern/gpu_index_buffer.cc
@@ -57,7 +57,6 @@ void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder,
builder->index_max = 0;
builder->prim_type = prim_type;
builder->data = (uint *)MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data");
- builder->parent = nullptr;
}
void GPU_indexbuf_init(GPUIndexBufBuilder *builder,
@@ -80,21 +79,13 @@ GPUIndexBuf *GPU_indexbuf_build_on_device(uint index_len)
return elem_;
}
-void GPU_indexbuf_subbuilder_init(const GPUIndexBufBuilder *parent_builder,
- GPUIndexBufBuilder *sub_builder)
+void GPU_indexbuf_join_copies(GPUIndexBufBuilder *builder_to,
+ const GPUIndexBufBuilder *builder_from)
{
- BLI_assert(parent_builder->parent == nullptr);
- memcpy(sub_builder, parent_builder, sizeof(GPUIndexBufBuilder));
- sub_builder->parent = parent_builder;
-}
-
-void GPU_indexbuf_subbuilder_finish(GPUIndexBufBuilder *parent_builder,
- const GPUIndexBufBuilder *sub_builder)
-{
- BLI_assert(parent_builder == sub_builder->parent);
- parent_builder->index_len = max_uu(parent_builder->index_len, sub_builder->index_len);
- parent_builder->index_min = min_uu(parent_builder->index_min, sub_builder->index_min);
- parent_builder->index_max = max_uu(parent_builder->index_max, sub_builder->index_max);
+ BLI_assert(builder_to->data == builder_from->data);
+ builder_to->index_len = max_uu(builder_to->index_len, builder_from->index_len);
+ builder_to->index_min = min_uu(builder_to->index_min, builder_from->index_min);
+ builder_to->index_max = max_uu(builder_to->index_max, builder_from->index_max);
}
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *builder, uint v)
diff --git a/source/tools b/source/tools
-Subproject 01f51a0e551ab730f0934dc6488613690ac4bf8
+Subproject 2afbb8ec472cac5102eb239f57b006f8c938768