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:
Diffstat (limited to 'source/blender/draw/intern/draw_cache_extract_mesh.cc')
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc189
1 files changed, 134 insertions, 55 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index 8d6064179ad..7b2c0da4dd9 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -24,11 +24,15 @@
*/
#include "MEM_guardedalloc.h"
+#include <optional>
+
#include "atomic_ops.h"
#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
+#include "BLI_array.hh"
+#include "BLI_math_bits.h"
#include "BLI_task.h"
#include "BLI_vector.hh"
@@ -53,6 +57,8 @@ namespace blender::draw {
/* ---------------------------------------------------------------------- */
/** \name Mesh Elements Extract Struct
* \{ */
+using TaskId = int;
+using TaskLen = int;
struct ExtractorRunData {
/* Extractor where this run data belongs to. */
@@ -62,11 +68,23 @@ struct ExtractorRunData {
/* 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;
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
@@ -111,7 +129,7 @@ class ExtractorRunDatas : public Vector<ExtractorRunData> {
}
}
- eMRIterType iter_types()
+ eMRIterType iter_types() const
{
eMRIterType iter_type = static_cast<eMRIterType>(0);
@@ -122,6 +140,13 @@ class ExtractorRunDatas : public Vector<ExtractorRunData> {
return iter_type;
}
+ const uint iter_types_len() const
+ {
+ const eMRIterType iter_type = iter_types();
+ uint bits = static_cast<uint>(iter_type);
+ return count_bits_i(bits);
+ }
+
eMRDataType data_types()
{
eMRDataType data_type = static_cast<eMRDataType>(0);
@@ -158,7 +183,8 @@ BLI_INLINE void extract_init(const MeshRenderData *mr,
BLI_INLINE void extract_iter_looptri_bm(const MeshRenderData *mr,
const ExtractTriBMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_LOOPTRI);
@@ -166,7 +192,7 @@ BLI_INLINE void extract_iter_looptri_bm(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_looptri_bm(mr, elt, elt_index, run_data[task_id]);
}
}
EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END;
@@ -174,7 +200,8 @@ BLI_INLINE void extract_iter_looptri_bm(const MeshRenderData *mr,
BLI_INLINE void extract_iter_looptri_mesh(const MeshRenderData *mr,
const ExtractTriMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_LOOPTRI);
@@ -182,7 +209,7 @@ BLI_INLINE void extract_iter_looptri_mesh(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_looptri_mesh(mr, mlt, mlt_index, run_data[task_id]);
}
}
EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END;
@@ -190,7 +217,8 @@ BLI_INLINE void extract_iter_looptri_mesh(const MeshRenderData *mr,
BLI_INLINE void extract_iter_poly_bm(const MeshRenderData *mr,
const ExtractPolyBMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_POLY);
@@ -198,7 +226,7 @@ BLI_INLINE void extract_iter_poly_bm(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_poly_bm(mr, f, f_index, run_data[task_id]);
}
}
EXTRACT_POLY_FOREACH_BM_END;
@@ -206,7 +234,8 @@ BLI_INLINE void extract_iter_poly_bm(const MeshRenderData *mr,
BLI_INLINE void extract_iter_poly_mesh(const MeshRenderData *mr,
const ExtractPolyMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_POLY);
@@ -214,7 +243,7 @@ BLI_INLINE void extract_iter_poly_mesh(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_poly_mesh(mr, mp, mp_index, run_data[task_id]);
}
}
EXTRACT_POLY_FOREACH_MESH_END;
@@ -222,7 +251,8 @@ BLI_INLINE void extract_iter_poly_mesh(const MeshRenderData *mr,
BLI_INLINE void extract_iter_ledge_bm(const MeshRenderData *mr,
const ExtractLEdgeBMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_LEDGE);
@@ -230,7 +260,7 @@ BLI_INLINE void extract_iter_ledge_bm(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_ledge_bm(mr, eed, ledge_index, run_data[task_id]);
}
}
EXTRACT_LEDGE_FOREACH_BM_END;
@@ -238,7 +268,8 @@ BLI_INLINE void extract_iter_ledge_bm(const MeshRenderData *mr,
BLI_INLINE void extract_iter_ledge_mesh(const MeshRenderData *mr,
const ExtractLEdgeMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_LEDGE);
@@ -246,7 +277,7 @@ BLI_INLINE void extract_iter_ledge_mesh(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_ledge_mesh(mr, med, ledge_index, run_data[task_id]);
}
}
EXTRACT_LEDGE_FOREACH_MESH_END;
@@ -254,7 +285,8 @@ BLI_INLINE void extract_iter_ledge_mesh(const MeshRenderData *mr,
BLI_INLINE void extract_iter_lvert_bm(const MeshRenderData *mr,
const ExtractLVertBMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_LVERT);
@@ -262,7 +294,7 @@ BLI_INLINE void extract_iter_lvert_bm(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_lvert_bm(mr, eve, lvert_index, run_data[task_id]);
}
}
EXTRACT_LVERT_FOREACH_BM_END;
@@ -270,7 +302,8 @@ BLI_INLINE void extract_iter_lvert_bm(const MeshRenderData *mr,
BLI_INLINE void extract_iter_lvert_mesh(const MeshRenderData *mr,
const ExtractLVertMesh_Params *params,
- const ExtractorRunDatas &all_extractors)
+ const ExtractorRunDatas &all_extractors,
+ const TaskId task_id)
{
ExtractorRunDatas extractors;
all_extractors.filter_into(extractors, MR_ITER_LVERT);
@@ -278,7 +311,7 @@ BLI_INLINE void extract_iter_lvert_mesh(const MeshRenderData *mr,
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.user_data);
+ run_data.extractor->iter_lvert_mesh(mr, mv, lvert_index, run_data[task_id]);
}
}
EXTRACT_LVERT_FOREACH_MESH_END;
@@ -296,6 +329,35 @@ BLI_INLINE void extract_finish(const MeshRenderData *mr,
}
}
+BLI_INLINE void extract_task_init(ExtractorRunDatas &extractors, const TaskLen task_len)
+{
+ 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;
+ }
+ }
+}
+
+BLI_INLINE void extract_task_finish(ExtractorRunDatas &extractors, const TaskLen task_len)
+{
+ 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;
+ }
+ }
+ }
+}
+
/* Single Thread. */
BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
struct MeshBatchCache *cache,
@@ -303,7 +365,11 @@ BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
eMRIterType iter_type,
MeshBufferCache *mbc)
{
+ const TaskLen task_len = 1;
+ const TaskId task_id = 0;
+
extract_init(mr, cache, extractors, mbc);
+ extract_task_init(extractors, task_len);
bool is_mesh = mr->extract_type != MR_EXTRACT_BMESH;
if (iter_type & MR_ITER_LOOPTRI) {
@@ -312,14 +378,14 @@ BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
params.mlooptri = mr->mlooptri;
params.tri_range[0] = 0;
params.tri_range[1] = mr->tri_len;
- extract_iter_looptri_mesh(mr, &params, extractors);
+ 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);
+ extract_iter_looptri_bm(mr, &params, extractors, task_id);
}
}
if (iter_type & MR_ITER_POLY) {
@@ -327,13 +393,13 @@ BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
ExtractPolyMesh_Params params;
params.poly_range[0] = 0;
params.poly_range[1] = mr->poly_len;
- extract_iter_poly_mesh(mr, &params, extractors);
+ 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);
+ extract_iter_poly_bm(mr, &params, extractors, task_id);
}
}
if (iter_type & MR_ITER_LEDGE) {
@@ -342,14 +408,14 @@ BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
params.ledge = mr->ledges;
params.ledge_range[0] = 0;
params.ledge_range[1] = mr->edge_loose_len;
- extract_iter_ledge_mesh(mr, &params, extractors);
+ 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);
+ extract_iter_ledge_bm(mr, &params, extractors, task_id);
}
}
if (iter_type & MR_ITER_LVERT) {
@@ -358,16 +424,17 @@ BLI_INLINE void extract_run_single_threaded(const MeshRenderData *mr,
params.lvert = mr->lverts;
params.lvert_range[0] = 0;
params.lvert_range[1] = mr->vert_loose_len;
- extract_iter_lvert_mesh(mr, &params, extractors);
+ 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);
+ extract_iter_lvert_bm(mr, &params, extractors, task_id);
}
}
+ extract_task_finish(extractors, task_len);
extract_finish(mr, cache, extractors);
}
@@ -390,6 +457,13 @@ struct ExtractTaskData {
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;
@@ -399,8 +473,14 @@ struct ExtractTaskData {
struct MeshBatchCache *cache,
ExtractorRunDatas *extractors,
MeshBufferCache *mbc,
- int32_t *task_counter)
- : mr(mr), cache(cache), extractors(extractors), mbc(mbc), task_counter(task_counter)
+ 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();
};
@@ -417,17 +497,6 @@ struct ExtractTaskData {
#endif
};
-static ExtractTaskData *extract_extract_iter_task_data_create_mesh(const MeshRenderData *mr,
- MeshBatchCache *cache,
- ExtractorRunDatas *extractors,
- MeshBufferCache *mbc,
- int32_t *task_counter)
-
-{
- ExtractTaskData *taskdata = new ExtractTaskData(mr, cache, extractors, mbc, task_counter);
- return taskdata;
-}
-
static void extract_task_data_free(void *data)
{
ExtractTaskData *task_data = static_cast<ExtractTaskData *>(data);
@@ -445,7 +514,8 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
const eMRIterType iter_type,
int start,
int end,
- ExtractorRunDatas &extractors)
+ ExtractorRunDatas &extractors,
+ const TaskId task_id)
{
switch (mr->extract_type) {
case MR_EXTRACT_BMESH:
@@ -454,27 +524,27 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
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);
+ 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);
+ 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);
+ 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);
+ extract_iter_lvert_bm(mr, &params, extractors, task_id);
}
break;
case MR_EXTRACT_MAPPED:
@@ -484,27 +554,27 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
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);
+ 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);
+ 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);
+ 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);
+ extract_iter_lvert_mesh(mr, &params, extractors, task_id);
}
break;
}
@@ -513,16 +583,19 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
static void extract_task_init(ExtractTaskData *data)
{
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);
+ 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);
}
}
@@ -668,7 +741,8 @@ static void extract_range_task_create(struct TaskGraph *task_graph,
int length)
{
taskdata = new ExtractTaskData(*taskdata);
- atomic_add_and_fetch_int32(taskdata->task_counter, 1);
+ 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;
@@ -900,8 +974,8 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
if (!extractor->use_threading) {
ExtractorRunDatas *single_threaded_extractors = new ExtractorRunDatas();
single_threaded_extractors->append(extractor);
- ExtractTaskData *taskdata = extract_extract_iter_task_data_create_mesh(
- mr, cache, single_threaded_extractors, mbc, nullptr);
+ 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);
BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
@@ -920,13 +994,19 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
*/
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 = extract_extract_iter_task_data_create_mesh(
- mr, cache, multi_threaded_extractors, mbc, &user_data_init_task_data->task_counter);
+ 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);
@@ -941,8 +1021,7 @@ 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 = extract_extract_iter_task_data_create_mesh(
- mr, cache, extractors_copy, mbc, nullptr);
+ ExtractTaskData *taskdata = new ExtractTaskData(mr, cache, extractors_copy, mbc, nullptr, 1);
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);