|
|
|
|
@@ -30,6 +30,7 @@
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_task.h"
|
|
|
|
|
#include "BLI_vector.hh"
|
|
|
|
|
|
|
|
|
|
#include "BKE_editmesh.h"
|
|
|
|
|
|
|
|
|
|
@@ -47,79 +48,64 @@
|
|
|
|
|
|
|
|
|
|
#define CHUNK_SIZE 8192
|
|
|
|
|
|
|
|
|
|
namespace blender::draw {
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Mesh Elements Extract Struct
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
typedef struct MeshExtractRunData {
|
|
|
|
|
struct MeshExtractRunData {
|
|
|
|
|
const MeshExtract *extractor;
|
|
|
|
|
void *buffer;
|
|
|
|
|
void *user_data;
|
|
|
|
|
} MeshExtractRunData;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct MeshExtractRunDataArray {
|
|
|
|
|
int len;
|
|
|
|
|
MeshExtractRunData items[M_EXTRACT_LEN];
|
|
|
|
|
} MeshExtractRunDataArray;
|
|
|
|
|
using MeshExtractRunDataArray = blender::Vector<MeshExtractRunData>;
|
|
|
|
|
|
|
|
|
|
static void mesh_extract_run_data_array_init(MeshExtractRunDataArray *array)
|
|
|
|
|
{
|
|
|
|
|
array->len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_extract_run_data_array_add_ex(MeshExtractRunDataArray *array,
|
|
|
|
|
const MeshExtractRunData *run_data)
|
|
|
|
|
{
|
|
|
|
|
array->items[array->len] = *run_data;
|
|
|
|
|
array->len++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_extract_run_data_array_add(MeshExtractRunDataArray *array,
|
|
|
|
|
static void mesh_extract_run_data_array_add(MeshExtractRunDataArray &array,
|
|
|
|
|
const MeshExtract *extractor)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunData run_data;
|
|
|
|
|
run_data.extractor = extractor;
|
|
|
|
|
run_data.buffer = NULL;
|
|
|
|
|
run_data.user_data = NULL;
|
|
|
|
|
mesh_extract_run_data_array_add_ex(array, &run_data);
|
|
|
|
|
array.append(run_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_extract_run_data_array_filter_iter_type(const MeshExtractRunDataArray *src,
|
|
|
|
|
MeshExtractRunDataArray *dst,
|
|
|
|
|
static void mesh_extract_run_data_array_filter_iter_type(const MeshExtractRunDataArray &src,
|
|
|
|
|
MeshExtractRunDataArray &dst,
|
|
|
|
|
eMRIterType iter_type)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < src->len; i++) {
|
|
|
|
|
|
|
|
|
|
const MeshExtractRunData *data = &src->items[i];
|
|
|
|
|
const MeshExtract *extractor = data->extractor;
|
|
|
|
|
for (const MeshExtractRunData &data : src) {
|
|
|
|
|
const MeshExtract *extractor = data.extractor;
|
|
|
|
|
if ((iter_type & MR_ITER_LOOPTRI) && extractor->iter_looptri_bm) {
|
|
|
|
|
BLI_assert(extractor->iter_looptri_mesh);
|
|
|
|
|
mesh_extract_run_data_array_add_ex(dst, data);
|
|
|
|
|
dst.append(data);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((iter_type & MR_ITER_POLY) && extractor->iter_poly_bm) {
|
|
|
|
|
BLI_assert(extractor->iter_poly_mesh);
|
|
|
|
|
mesh_extract_run_data_array_add_ex(dst, data);
|
|
|
|
|
dst.append(data);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((iter_type & MR_ITER_LEDGE) && extractor->iter_ledge_bm) {
|
|
|
|
|
BLI_assert(extractor->iter_ledge_mesh);
|
|
|
|
|
mesh_extract_run_data_array_add_ex(dst, data);
|
|
|
|
|
dst.append(data);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((iter_type & MR_ITER_LVERT) && extractor->iter_lvert_bm) {
|
|
|
|
|
BLI_assert(extractor->iter_lvert_mesh);
|
|
|
|
|
mesh_extract_run_data_array_add_ex(dst, data);
|
|
|
|
|
dst.append(data);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_extract_run_data_array_filter_threading(
|
|
|
|
|
const MeshExtractRunDataArray *src, MeshExtractRunDataArray *dst_multi_threaded)
|
|
|
|
|
const MeshExtractRunDataArray &src, MeshExtractRunDataArray &dst_multi_threaded)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < src->len; i++) {
|
|
|
|
|
const MeshExtract *extractor = src->items[i].extractor;
|
|
|
|
|
for (const MeshExtractRunData &data : src) {
|
|
|
|
|
const MeshExtract *extractor = data.extractor;
|
|
|
|
|
if (extractor->use_threading) {
|
|
|
|
|
mesh_extract_run_data_array_add(dst_multi_threaded, extractor);
|
|
|
|
|
}
|
|
|
|
|
@@ -132,15 +118,15 @@ static void mesh_extract_run_data_array_filter_threading(
|
|
|
|
|
/** \name Extract
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static void extracts_flags_get(const MeshExtractRunDataArray *extractors,
|
|
|
|
|
static void extracts_flags_get(const MeshExtractRunDataArray &extractors,
|
|
|
|
|
eMRIterType *r_iter_type,
|
|
|
|
|
eMRDataType *r_data_flag)
|
|
|
|
|
{
|
|
|
|
|
eMRIterType iter_type = 0;
|
|
|
|
|
eMRDataType data_flag = 0;
|
|
|
|
|
eMRIterType iter_type = static_cast<eMRIterType>(0);
|
|
|
|
|
eMRDataType data_flag = static_cast<eMRDataType>(0);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < extractors->len; i++) {
|
|
|
|
|
const MeshExtract *extractor = extractors->items[i].extractor;
|
|
|
|
|
for (const MeshExtractRunData &data : extractors) {
|
|
|
|
|
const MeshExtract *extractor = data.extractor;
|
|
|
|
|
iter_type |= mesh_extract_iter_type(extractor);
|
|
|
|
|
data_flag |= extractor->data_flag;
|
|
|
|
|
}
|
|
|
|
|
@@ -155,31 +141,28 @@ static void extracts_flags_get(const MeshExtractRunDataArray *extractors,
|
|
|
|
|
|
|
|
|
|
BLI_INLINE void extract_init(const MeshRenderData *mr,
|
|
|
|
|
struct MeshBatchCache *cache,
|
|
|
|
|
MeshExtractRunDataArray *extractors,
|
|
|
|
|
MeshExtractRunDataArray &extractors,
|
|
|
|
|
MeshBufferCache *mbc)
|
|
|
|
|
{
|
|
|
|
|
/* Multi thread. */
|
|
|
|
|
for (int i = 0; i < extractors->len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors->items[i];
|
|
|
|
|
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);
|
|
|
|
|
for (MeshExtractRunData &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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_INLINE void extract_iter_looptri_bm(const MeshRenderData *mr,
|
|
|
|
|
const ExtractTriBMesh_Params *params,
|
|
|
|
|
const MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_LOOPTRI);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_LOOPTRI);
|
|
|
|
|
|
|
|
|
|
EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, elt_index, params)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_looptri_bm(mr, elt, elt_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_looptri_bm(mr, elt, elt_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END;
|
|
|
|
|
@@ -187,17 +170,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_LOOPTRI);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_LOOPTRI);
|
|
|
|
|
|
|
|
|
|
EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(mlt, mlt_index, params)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_looptri_mesh(mr, mlt, mlt_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_looptri_mesh(mr, mlt, mlt_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END;
|
|
|
|
|
@@ -205,17 +186,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_POLY);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_POLY);
|
|
|
|
|
|
|
|
|
|
EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_poly_bm(mr, f, f_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_poly_bm(mr, f, f_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_POLY_FOREACH_BM_END;
|
|
|
|
|
@@ -223,17 +202,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_POLY);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_POLY);
|
|
|
|
|
|
|
|
|
|
EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_poly_mesh(mr, mp, mp_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_poly_mesh(mr, mp, mp_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_POLY_FOREACH_MESH_END;
|
|
|
|
|
@@ -241,17 +218,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_LEDGE);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_LEDGE);
|
|
|
|
|
|
|
|
|
|
EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_ledge_bm(mr, eed, ledge_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_ledge_bm(mr, eed, ledge_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_LEDGE_FOREACH_BM_END;
|
|
|
|
|
@@ -259,17 +234,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_LEDGE);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_LEDGE);
|
|
|
|
|
|
|
|
|
|
EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_ledge_mesh(mr, med, ledge_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_ledge_mesh(mr, med, ledge_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_LEDGE_FOREACH_MESH_END;
|
|
|
|
|
@@ -277,17 +250,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_LVERT);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_LVERT);
|
|
|
|
|
|
|
|
|
|
EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_lvert_bm(mr, eve, lvert_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_lvert_bm(mr, eve, lvert_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_LVERT_FOREACH_BM_END;
|
|
|
|
|
@@ -295,17 +266,15 @@ 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 MeshExtractRunDataArray *_extractors)
|
|
|
|
|
const MeshExtractRunDataArray &all_extractors)
|
|
|
|
|
{
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(_extractors, &extractors, MR_ITER_LVERT);
|
|
|
|
|
mesh_extract_run_data_array_filter_iter_type(all_extractors, extractors, MR_ITER_LVERT);
|
|
|
|
|
|
|
|
|
|
EXTRACT_LVERT_FOREACH_MESH_BEGIN(mv, lvert_index, params, mr)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
MeshExtractRunData *run_data = &extractors.items[i];
|
|
|
|
|
run_data->extractor->iter_lvert_mesh(mr, mv, lvert_index, run_data->user_data);
|
|
|
|
|
for (MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
run_data.extractor->iter_lvert_mesh(mr, mv, lvert_index, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXTRACT_LVERT_FOREACH_MESH_END;
|
|
|
|
|
@@ -313,13 +282,12 @@ BLI_INLINE void extract_iter_lvert_mesh(const MeshRenderData *mr,
|
|
|
|
|
|
|
|
|
|
BLI_INLINE void extract_finish(const MeshRenderData *mr,
|
|
|
|
|
struct MeshBatchCache *cache,
|
|
|
|
|
const MeshExtractRunDataArray *extractors)
|
|
|
|
|
const MeshExtractRunDataArray &extractors)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < extractors->len; i++) {
|
|
|
|
|
const MeshExtractRunData *run_data = &extractors->items[i];
|
|
|
|
|
const MeshExtract *extractor = run_data->extractor;
|
|
|
|
|
for (const MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
const MeshExtract *extractor = run_data.extractor;
|
|
|
|
|
if (extractor->finish) {
|
|
|
|
|
extractor->finish(mr, cache, run_data->buffer, run_data->user_data);
|
|
|
|
|
extractor->finish(mr, cache, run_data.buffer, run_data.user_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -327,7 +295,7 @@ BLI_INLINE void extract_finish(const MeshRenderData *mr,
|
|
|
|
|
/* Single Thread. */
|
|
|
|
|
BLI_INLINE void extract_run_and_finish_init(const MeshRenderData *mr,
|
|
|
|
|
struct MeshBatchCache *cache,
|
|
|
|
|
MeshExtractRunDataArray *extractors,
|
|
|
|
|
MeshExtractRunDataArray &extractors,
|
|
|
|
|
eMRIterType iter_type,
|
|
|
|
|
MeshBufferCache *mbc)
|
|
|
|
|
{
|
|
|
|
|
@@ -336,72 +304,64 @@ BLI_INLINE void extract_run_and_finish_init(const MeshRenderData *mr,
|
|
|
|
|
bool is_mesh = mr->extract_type != MR_EXTRACT_BMESH;
|
|
|
|
|
if (iter_type & MR_ITER_LOOPTRI) {
|
|
|
|
|
if (is_mesh) {
|
|
|
|
|
extract_iter_looptri_mesh(mr,
|
|
|
|
|
&(const ExtractTriMesh_Params){
|
|
|
|
|
.mlooptri = mr->mlooptri,
|
|
|
|
|
.tri_range = {0, mr->tri_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
ExtractTriMesh_Params params;
|
|
|
|
|
params.mlooptri = mr->mlooptri;
|
|
|
|
|
params.tri_range[0] = 0;
|
|
|
|
|
params.tri_range[1] = mr->tri_len;
|
|
|
|
|
extract_iter_looptri_mesh(mr, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
extract_iter_looptri_bm(mr,
|
|
|
|
|
&(const ExtractTriBMesh_Params){
|
|
|
|
|
.looptris = mr->edit_bmesh->looptris,
|
|
|
|
|
.tri_range = {0, mr->tri_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_POLY) {
|
|
|
|
|
if (is_mesh) {
|
|
|
|
|
extract_iter_poly_mesh(mr,
|
|
|
|
|
&(const ExtractPolyMesh_Params){
|
|
|
|
|
.poly_range = {0, mr->poly_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
ExtractPolyMesh_Params params;
|
|
|
|
|
params.poly_range[0] = 0;
|
|
|
|
|
params.poly_range[1] = mr->poly_len;
|
|
|
|
|
extract_iter_poly_mesh(mr, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
extract_iter_poly_bm(mr,
|
|
|
|
|
&(const ExtractPolyBMesh_Params){
|
|
|
|
|
.poly_range = {0, mr->poly_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
ExtractPolyBMesh_Params params;
|
|
|
|
|
params.poly_range[0] = 0;
|
|
|
|
|
params.poly_range[1] = mr->poly_len;
|
|
|
|
|
extract_iter_poly_bm(mr, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_LEDGE) {
|
|
|
|
|
if (is_mesh) {
|
|
|
|
|
extract_iter_ledge_mesh(mr,
|
|
|
|
|
&(const ExtractLEdgeMesh_Params){
|
|
|
|
|
.ledge = mr->ledges,
|
|
|
|
|
.ledge_range = {0, mr->edge_loose_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
extract_iter_ledge_bm(mr,
|
|
|
|
|
&(const ExtractLEdgeBMesh_Params){
|
|
|
|
|
.ledge = mr->ledges,
|
|
|
|
|
.ledge_range = {0, mr->edge_loose_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_LVERT) {
|
|
|
|
|
if (is_mesh) {
|
|
|
|
|
extract_iter_lvert_mesh(mr,
|
|
|
|
|
&(const ExtractLVertMesh_Params){
|
|
|
|
|
.lvert = mr->lverts,
|
|
|
|
|
.lvert_range = {0, mr->vert_loose_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
extract_iter_lvert_bm(mr,
|
|
|
|
|
&(const ExtractLVertBMesh_Params){
|
|
|
|
|
.lvert = mr->lverts,
|
|
|
|
|
.lvert_range = {0, mr->vert_loose_len},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
extract_finish(mr, cache, extractors);
|
|
|
|
|
@@ -412,126 +372,139 @@ BLI_INLINE void extract_run_and_finish_init(const MeshRenderData *mr,
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name ExtractTaskData
|
|
|
|
|
* \{ */
|
|
|
|
|
typedef struct ExtractTaskData {
|
|
|
|
|
void *next, *prev;
|
|
|
|
|
const MeshRenderData *mr;
|
|
|
|
|
struct MeshBatchCache *cache;
|
|
|
|
|
MeshExtractRunDataArray *extractors;
|
|
|
|
|
eMRIterType iter_type;
|
|
|
|
|
int start, end;
|
|
|
|
|
/** Decremented each time a task is finished. */
|
|
|
|
|
int32_t *task_counter;
|
|
|
|
|
MeshBufferCache *mbc;
|
|
|
|
|
} ExtractTaskData;
|
|
|
|
|
|
|
|
|
|
static ExtractTaskData *extract_extract_iter_task_data_create_mesh(
|
|
|
|
|
const MeshRenderData *mr,
|
|
|
|
|
struct MeshBatchCache *cache,
|
|
|
|
|
MeshExtractRunDataArray *extractors,
|
|
|
|
|
MeshBufferCache *mbc,
|
|
|
|
|
int32_t *task_counter)
|
|
|
|
|
{
|
|
|
|
|
ExtractTaskData *taskdata = MEM_mallocN(sizeof(*taskdata), __func__);
|
|
|
|
|
taskdata->next = NULL;
|
|
|
|
|
taskdata->prev = NULL;
|
|
|
|
|
taskdata->mr = mr;
|
|
|
|
|
taskdata->cache = cache;
|
|
|
|
|
taskdata->mbc = mbc;
|
|
|
|
|
struct ExtractTaskData {
|
|
|
|
|
void *next = nullptr;
|
|
|
|
|
void *prev = nullptr;
|
|
|
|
|
|
|
|
|
|
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. */
|
|
|
|
|
taskdata->extractors = extractors;
|
|
|
|
|
taskdata->task_counter = task_counter;
|
|
|
|
|
|
|
|
|
|
extracts_flags_get(extractors, &taskdata->iter_type, NULL);
|
|
|
|
|
taskdata->start = 0;
|
|
|
|
|
taskdata->end = INT_MAX;
|
|
|
|
|
MeshExtractRunDataArray *extractors = nullptr;
|
|
|
|
|
MeshBufferCache *mbc = nullptr;
|
|
|
|
|
int32_t *task_counter = nullptr;
|
|
|
|
|
|
|
|
|
|
eMRIterType iter_type;
|
|
|
|
|
int start = 0;
|
|
|
|
|
int end = INT_MAX;
|
|
|
|
|
/** Decremented each time a task is finished. */
|
|
|
|
|
|
|
|
|
|
ExtractTaskData(const MeshRenderData *mr,
|
|
|
|
|
struct MeshBatchCache *cache,
|
|
|
|
|
MeshExtractRunDataArray *extractors,
|
|
|
|
|
MeshBufferCache *mbc,
|
|
|
|
|
int32_t *task_counter)
|
|
|
|
|
: mr(mr), cache(cache), extractors(extractors), mbc(mbc), task_counter(task_counter)
|
|
|
|
|
{
|
|
|
|
|
extracts_flags_get(*extractors, &iter_type, NULL);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ExtractTaskData(const ExtractTaskData &src) = default;
|
|
|
|
|
|
|
|
|
|
~ExtractTaskData()
|
|
|
|
|
{
|
|
|
|
|
delete extractors;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_CXX_GUARDEDALLOC
|
|
|
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("DRW:ExtractTaskData")
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static ExtractTaskData *extract_extract_iter_task_data_create_mesh(
|
|
|
|
|
const MeshRenderData *mr,
|
|
|
|
|
MeshBatchCache *cache,
|
|
|
|
|
MeshExtractRunDataArray *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 = data;
|
|
|
|
|
MEM_SAFE_FREE(task_data->extractors);
|
|
|
|
|
MEM_freeN(task_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,
|
|
|
|
|
MeshExtractRunDataArray *extractors)
|
|
|
|
|
MeshExtractRunDataArray &extractors)
|
|
|
|
|
{
|
|
|
|
|
switch (mr->extract_type) {
|
|
|
|
|
case MR_EXTRACT_BMESH:
|
|
|
|
|
if (iter_type & MR_ITER_LOOPTRI) {
|
|
|
|
|
extract_iter_looptri_bm(mr,
|
|
|
|
|
&(const ExtractTriBMesh_Params){
|
|
|
|
|
.looptris = mr->edit_bmesh->looptris,
|
|
|
|
|
.tri_range = {start, min_ii(mr->tri_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_POLY) {
|
|
|
|
|
extract_iter_poly_bm(mr,
|
|
|
|
|
&(const ExtractPolyBMesh_Params){
|
|
|
|
|
.poly_range = {start, min_ii(mr->poly_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
ExtractPolyBMesh_Params params;
|
|
|
|
|
params.poly_range[0] = start;
|
|
|
|
|
params.poly_range[1] = min_ii(mr->poly_len, end);
|
|
|
|
|
extract_iter_poly_bm(mr, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_LEDGE) {
|
|
|
|
|
extract_iter_ledge_bm(mr,
|
|
|
|
|
&(const ExtractLEdgeBMesh_Params){
|
|
|
|
|
.ledge = mr->ledges,
|
|
|
|
|
.ledge_range = {start, min_ii(mr->edge_loose_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_LVERT) {
|
|
|
|
|
extract_iter_lvert_bm(mr,
|
|
|
|
|
&(const ExtractLVertBMesh_Params){
|
|
|
|
|
.lvert = mr->lverts,
|
|
|
|
|
.lvert_range = {start, min_ii(mr->vert_loose_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MR_EXTRACT_MAPPED:
|
|
|
|
|
case MR_EXTRACT_MESH:
|
|
|
|
|
if (iter_type & MR_ITER_LOOPTRI) {
|
|
|
|
|
extract_iter_looptri_mesh(mr,
|
|
|
|
|
&(const ExtractTriMesh_Params){
|
|
|
|
|
.mlooptri = mr->mlooptri,
|
|
|
|
|
.tri_range = {start, min_ii(mr->tri_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_POLY) {
|
|
|
|
|
extract_iter_poly_mesh(mr,
|
|
|
|
|
&(const ExtractPolyMesh_Params){
|
|
|
|
|
.poly_range = {start, min_ii(mr->poly_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
ExtractPolyMesh_Params params;
|
|
|
|
|
params.poly_range[0] = start;
|
|
|
|
|
params.poly_range[1] = min_ii(mr->poly_len, end);
|
|
|
|
|
extract_iter_poly_mesh(mr, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_LEDGE) {
|
|
|
|
|
extract_iter_ledge_mesh(mr,
|
|
|
|
|
&(const ExtractLEdgeMesh_Params){
|
|
|
|
|
.ledge = mr->ledges,
|
|
|
|
|
.ledge_range = {start, min_ii(mr->edge_loose_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
if (iter_type & MR_ITER_LVERT) {
|
|
|
|
|
extract_iter_lvert_mesh(mr,
|
|
|
|
|
&(const ExtractLVertMesh_Params){
|
|
|
|
|
.lvert = mr->lverts,
|
|
|
|
|
.lvert_range = {start, min_ii(mr->vert_loose_len, end)},
|
|
|
|
|
},
|
|
|
|
|
extractors);
|
|
|
|
|
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, ¶ms, extractors);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -539,25 +512,26 @@ 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_init(data->mr, data->cache, *data->extractors, data->mbc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
/* 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_finish(data->mr, data->cache, data->extractors);
|
|
|
|
|
extract_finish(data->mr, data->cache, *data->extractors);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void extract_task_init_and_run(void *__restrict taskdata)
|
|
|
|
|
{
|
|
|
|
|
ExtractTaskData *data = (ExtractTaskData *)taskdata;
|
|
|
|
|
extract_run_and_finish_init(data->mr, data->cache, data->extractors, data->iter_type, data->mbc);
|
|
|
|
|
extract_run_and_finish_init(
|
|
|
|
|
data->mr, data->cache, *data->extractors, data->iter_type, data->mbc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
@@ -565,23 +539,31 @@ static void extract_task_init_and_run(void *__restrict taskdata)
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Task Node - Update Mesh Render Data
|
|
|
|
|
* \{ */
|
|
|
|
|
typedef struct MeshRenderDataUpdateTaskData {
|
|
|
|
|
MeshRenderData *mr;
|
|
|
|
|
struct MeshRenderDataUpdateTaskData {
|
|
|
|
|
MeshRenderData *mr = nullptr;
|
|
|
|
|
eMRIterType iter_type;
|
|
|
|
|
eMRDataType data_flag;
|
|
|
|
|
} MeshRenderDataUpdateTaskData;
|
|
|
|
|
|
|
|
|
|
~MeshRenderDataUpdateTaskData()
|
|
|
|
|
{
|
|
|
|
|
mesh_render_data_free(mr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_CXX_GUARDEDALLOC
|
|
|
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("DRW:MeshRenderDataUpdateTaskData")
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void mesh_render_data_update_task_data_free(MeshRenderDataUpdateTaskData *taskdata)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(taskdata);
|
|
|
|
|
MeshRenderData *mr = taskdata->mr;
|
|
|
|
|
mesh_render_data_free(mr);
|
|
|
|
|
MEM_freeN(taskdata);
|
|
|
|
|
delete taskdata;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mesh_extract_render_data_node_exec(void *__restrict task_data)
|
|
|
|
|
{
|
|
|
|
|
MeshRenderDataUpdateTaskData *update_task_data = task_data;
|
|
|
|
|
MeshRenderDataUpdateTaskData *update_task_data = static_cast<MeshRenderDataUpdateTaskData *>(
|
|
|
|
|
task_data);
|
|
|
|
|
MeshRenderData *mr = update_task_data->mr;
|
|
|
|
|
const eMRIterType iter_type = update_task_data->iter_type;
|
|
|
|
|
const eMRDataType data_flag = update_task_data->data_flag;
|
|
|
|
|
@@ -595,8 +577,7 @@ static struct TaskNode *mesh_extract_render_data_node_create(struct TaskGraph *t
|
|
|
|
|
const eMRIterType iter_type,
|
|
|
|
|
const eMRDataType data_flag)
|
|
|
|
|
{
|
|
|
|
|
MeshRenderDataUpdateTaskData *task_data = MEM_mallocN(sizeof(MeshRenderDataUpdateTaskData),
|
|
|
|
|
__func__);
|
|
|
|
|
MeshRenderDataUpdateTaskData *task_data = new (MeshRenderDataUpdateTaskData);
|
|
|
|
|
task_data->mr = mr;
|
|
|
|
|
task_data->iter_type = iter_type;
|
|
|
|
|
task_data->data_flag = data_flag;
|
|
|
|
|
@@ -631,22 +612,28 @@ static struct TaskNode *extract_single_threaded_task_node_create(struct TaskGrap
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
/** \name Task Node - UserData Initializer
|
|
|
|
|
* \{ */
|
|
|
|
|
typedef struct UserDataInitTaskData {
|
|
|
|
|
struct UserDataInitTaskData {
|
|
|
|
|
ExtractTaskData *td;
|
|
|
|
|
int32_t task_counter;
|
|
|
|
|
int32_t task_counter = 0;
|
|
|
|
|
|
|
|
|
|
} UserDataInitTaskData;
|
|
|
|
|
~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(UserDataInitTaskData *taskdata)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(taskdata);
|
|
|
|
|
extract_task_data_free(taskdata->td);
|
|
|
|
|
MEM_freeN(taskdata);
|
|
|
|
|
delete taskdata;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void user_data_init_task_data_exec(void *__restrict task_data)
|
|
|
|
|
{
|
|
|
|
|
UserDataInitTaskData *extract_task_data = task_data;
|
|
|
|
|
UserDataInitTaskData *extract_task_data = static_cast<UserDataInitTaskData *>(task_data);
|
|
|
|
|
ExtractTaskData *taskdata_base = extract_task_data->td;
|
|
|
|
|
extract_task_init(taskdata_base);
|
|
|
|
|
}
|
|
|
|
|
@@ -675,13 +662,13 @@ static void extract_range_task_create(struct TaskGraph *task_graph,
|
|
|
|
|
int start,
|
|
|
|
|
int length)
|
|
|
|
|
{
|
|
|
|
|
taskdata = MEM_dupallocN(taskdata);
|
|
|
|
|
taskdata = new ExtractTaskData(*taskdata);
|
|
|
|
|
atomic_add_and_fetch_int32(taskdata->task_counter, 1);
|
|
|
|
|
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, MEM_freeN);
|
|
|
|
|
task_graph, extract_task_run, taskdata, extract_task_data_free_ex);
|
|
|
|
|
BLI_task_graph_edge_create(task_node_user_data_init, task_node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -751,23 +738,23 @@ static void extract_task_in_ranges_create(struct TaskGraph *task_graph,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
MeshBatchCache *cache,
|
|
|
|
|
MeshBufferCache *mbc,
|
|
|
|
|
MeshBufferExtractionCache *extraction_cache,
|
|
|
|
|
Mesh *me,
|
|
|
|
|
static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
MeshBatchCache *cache,
|
|
|
|
|
MeshBufferCache *mbc,
|
|
|
|
|
MeshBufferExtractionCache *extraction_cache,
|
|
|
|
|
Mesh *me,
|
|
|
|
|
|
|
|
|
|
const bool is_editmode,
|
|
|
|
|
const bool is_paint_mode,
|
|
|
|
|
const bool is_mode_active,
|
|
|
|
|
const float obmat[4][4],
|
|
|
|
|
const bool do_final,
|
|
|
|
|
const bool do_uvedit,
|
|
|
|
|
const bool use_subsurf_fdots,
|
|
|
|
|
const DRW_MeshCDMask *cd_layer_used,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
const ToolSettings *ts,
|
|
|
|
|
const bool use_hide)
|
|
|
|
|
const bool is_editmode,
|
|
|
|
|
const bool is_paint_mode,
|
|
|
|
|
const bool is_mode_active,
|
|
|
|
|
const float obmat[4][4],
|
|
|
|
|
const bool do_final,
|
|
|
|
|
const bool do_uvedit,
|
|
|
|
|
const bool use_subsurf_fdots,
|
|
|
|
|
const DRW_MeshCDMask *cd_layer_used,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
const ToolSettings *ts,
|
|
|
|
|
const bool use_hide)
|
|
|
|
|
{
|
|
|
|
|
/* For each mesh where batches needs to be updated a sub-graph will be added to the task_graph.
|
|
|
|
|
* This sub-graph starts with an extract_render_data_node. This fills/converts the required
|
|
|
|
|
@@ -805,14 +792,13 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
|
|
|
|
|
/* Create an array containing all the extractors that needs to be executed. */
|
|
|
|
|
MeshExtractRunDataArray extractors;
|
|
|
|
|
mesh_extract_run_data_array_init(&extractors);
|
|
|
|
|
|
|
|
|
|
#define EXTRACT_ADD_REQUESTED(type, type_lowercase, name) \
|
|
|
|
|
do { \
|
|
|
|
|
if (DRW_##type_lowercase##_requested(mbc->type_lowercase.name)) { \
|
|
|
|
|
const MeshExtract *extractor = mesh_extract_override_get( \
|
|
|
|
|
&extract_##name, do_hq_normals, do_lines_loose_subbuffer); \
|
|
|
|
|
mesh_extract_run_data_array_add(&extractors, extractor); \
|
|
|
|
|
mesh_extract_run_data_array_add(extractors, extractor); \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
@@ -853,7 +839,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
|
|
|
|
|
#undef EXTRACT_ADD_REQUESTED
|
|
|
|
|
|
|
|
|
|
if (extractors.len == 0) {
|
|
|
|
|
if (extractors.is_empty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -863,7 +849,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
|
|
|
|
|
eMRIterType iter_type;
|
|
|
|
|
eMRDataType data_flag;
|
|
|
|
|
extracts_flags_get(&extractors, &iter_type, &data_flag);
|
|
|
|
|
extracts_flags_get(extractors, &iter_type, &data_flag);
|
|
|
|
|
|
|
|
|
|
MeshRenderData *mr = mesh_render_data_create(me,
|
|
|
|
|
extraction_cache,
|
|
|
|
|
@@ -894,13 +880,11 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
uint threads_to_use = 0;
|
|
|
|
|
|
|
|
|
|
/* First run the requested extractors that do not support asynchronous ranges. */
|
|
|
|
|
for (int i = 0; i < extractors.len; i++) {
|
|
|
|
|
const MeshExtract *extractor = extractors.items[i].extractor;
|
|
|
|
|
for (const MeshExtractRunData &run_data : extractors) {
|
|
|
|
|
const MeshExtract *extractor = run_data.extractor;
|
|
|
|
|
if (!extractor->use_threading) {
|
|
|
|
|
MeshExtractRunDataArray *single_threaded_extractors = MEM_callocN(
|
|
|
|
|
sizeof(MeshExtractRunDataArray),
|
|
|
|
|
"mesh_buffer_cache_create_requested.single_threaded_extractors");
|
|
|
|
|
mesh_extract_run_data_array_add(single_threaded_extractors, extractor);
|
|
|
|
|
MeshExtractRunDataArray *single_threaded_extractors = new MeshExtractRunDataArray();
|
|
|
|
|
mesh_extract_run_data_array_add(*single_threaded_extractors, extractor);
|
|
|
|
|
ExtractTaskData *taskdata = extract_extract_iter_task_data_create_mesh(
|
|
|
|
|
mr, cache, single_threaded_extractors, mbc, NULL);
|
|
|
|
|
struct TaskNode *task_node = extract_single_threaded_task_node_create(task_graph,
|
|
|
|
|
@@ -911,11 +895,9 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Distribute the remaining extractors into ranges per core. */
|
|
|
|
|
MeshExtractRunDataArray *multi_threaded_extractors = MEM_callocN(
|
|
|
|
|
sizeof(MeshExtractRunDataArray),
|
|
|
|
|
"mesh_buffer_cache_create_requested.multi_threaded_extractors");
|
|
|
|
|
mesh_extract_run_data_array_filter_threading(&extractors, multi_threaded_extractors);
|
|
|
|
|
if (multi_threaded_extractors->len) {
|
|
|
|
|
MeshExtractRunDataArray *multi_threaded_extractors = new MeshExtractRunDataArray();
|
|
|
|
|
mesh_extract_run_data_array_filter_threading(extractors, *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
|
|
|
|
|
@@ -926,9 +908,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
num_threads -= threads_to_use;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UserDataInitTaskData *user_data_init_task_data = MEM_callocN(
|
|
|
|
|
sizeof(UserDataInitTaskData),
|
|
|
|
|
"mesh_buffer_cache_create_requested.user_data_init_task_data");
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
@@ -942,14 +922,12 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* No tasks created freeing extractors list. */
|
|
|
|
|
MEM_freeN(multi_threaded_extractors);
|
|
|
|
|
delete multi_threaded_extractors;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Run all requests on the same thread. */
|
|
|
|
|
MeshExtractRunDataArray *extractors_copy = MEM_mallocN(
|
|
|
|
|
sizeof(MeshExtractRunDataArray), "mesh_buffer_cache_create_requested.extractors_copy");
|
|
|
|
|
memcpy(extractors_copy, &extractors, sizeof(MeshExtractRunDataArray));
|
|
|
|
|
MeshExtractRunDataArray *extractors_copy = new MeshExtractRunDataArray(extractors);
|
|
|
|
|
ExtractTaskData *taskdata = extract_extract_iter_task_data_create_mesh(
|
|
|
|
|
mr, cache, extractors_copy, mbc, NULL);
|
|
|
|
|
|
|
|
|
|
@@ -984,4 +962,45 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace blender::draw
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
|
|
|
|
|
MeshBatchCache *cache,
|
|
|
|
|
MeshBufferCache *mbc,
|
|
|
|
|
MeshBufferExtractionCache *extraction_cache,
|
|
|
|
|
Mesh *me,
|
|
|
|
|
|
|
|
|
|
const bool is_editmode,
|
|
|
|
|
const bool is_paint_mode,
|
|
|
|
|
const bool is_mode_active,
|
|
|
|
|
const float obmat[4][4],
|
|
|
|
|
const bool do_final,
|
|
|
|
|
const bool do_uvedit,
|
|
|
|
|
const bool use_subsurf_fdots,
|
|
|
|
|
const DRW_MeshCDMask *cd_layer_used,
|
|
|
|
|
const Scene *scene,
|
|
|
|
|
const ToolSettings *ts,
|
|
|
|
|
const bool use_hide)
|
|
|
|
|
{
|
|
|
|
|
blender::draw::mesh_buffer_cache_create_requested(task_graph,
|
|
|
|
|
cache,
|
|
|
|
|
mbc,
|
|
|
|
|
extraction_cache,
|
|
|
|
|
me,
|
|
|
|
|
is_editmode,
|
|
|
|
|
is_paint_mode,
|
|
|
|
|
is_mode_active,
|
|
|
|
|
obmat,
|
|
|
|
|
do_final,
|
|
|
|
|
do_uvedit,
|
|
|
|
|
use_subsurf_fdots,
|
|
|
|
|
cd_layer_used,
|
|
|
|
|
scene,
|
|
|
|
|
ts,
|
|
|
|
|
use_hide);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // extern "C"
|
|
|
|
|
|
|
|
|
|
/** \} */
|