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
diff options
context:
space:
mode:
-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