Page MenuHome
Paste P1490

Experimental patch to optimize single threaded edit-mesh conversion
ActivePublic

Authored by Campbell Barton (campbellbarton) on Sun, Jun 28, 2:40 PM.
commit b8cfa0c96c9f7d42c4dfa09bd93615d70188d012
Author: Campbell Barton <ideasman42@gmail.com>
Date: Sun Jun 28 16:19:06 2020 +1000
Inline bmesh extraction functions (apply to 4b96f4783197c6bbf34230385b711d685df2b545).
This is an experimental patch that avoids calling a function for every element that's extracted,
using macros to avoid manually copying function calls.
While this gives a speedup when running single threaded mode (~20%),
it's still slower compared to threaded execution on a heavy mesh.
A less intrusive solution is to move the loop inside each callback,
while loops may run multiple times it will avoid the overhead of using callbacks.
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 0b1f625dc2c..0a048ed94f1 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -66,6 +66,7 @@ typedef enum eMRIterType {
MR_ITER_LOOP = 1 << 1,
MR_ITER_LEDGE = 1 << 2,
MR_ITER_LVERT = 1 << 3,
+ MR_ITER_VERT = 1 << 4,
} eMRIterType;
typedef enum eMRDataType {
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 39797af40c7..c840ce34ff9 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -511,10 +511,12 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e
* \{ */
typedef void *(ExtractInitFn)(const MeshRenderData *mr, void *buffer);
+typedef void(ExtractEditVertFn)(const MeshRenderData *mr, int t, BMVert *v, void *data);
typedef void(ExtractEditTriFn)(const MeshRenderData *mr, int t, BMLoop **e, void *data);
typedef void(ExtractEditLoopFn)(const MeshRenderData *mr, int l, BMLoop *el, void *data);
typedef void(ExtractEditLedgeFn)(const MeshRenderData *mr, int e, BMEdge *ed, void *data);
typedef void(ExtractEditLvertFn)(const MeshRenderData *mr, int v, BMVert *ev, void *data);
+typedef void(ExtractVertFn)(const MeshRenderData *mr, int t, const MVert *mv, void *data);
typedef void(ExtractTriFn)(const MeshRenderData *mr, int t, const MLoopTri *mlt, void *data);
typedef void(ExtractLoopFn)(
const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data);
@@ -525,6 +527,10 @@ typedef void(ExtractFinishFn)(const MeshRenderData *mr, void *buffer, void *data
typedef struct MeshExtract {
/** Executed on main thread and return user data for iteration functions. */
ExtractInitFn *init;
+
+ /** Extract vertices. */
+ ExtractEditVertFn *iter_vert_bm;
+ ExtractVertFn *iter_vert;
/** Executed on one (or more if use_threading) worker thread(s). */
ExtractEditTriFn *iter_looptri_bm;
ExtractTriFn *iter_looptri;
@@ -545,6 +551,7 @@ typedef struct MeshExtract {
BLI_INLINE eMRIterType mesh_extract_iter_type(const MeshExtract *ext)
{
eMRIterType type = 0;
+ SET_FLAG_FROM_TEST(type, (ext->iter_vert_bm || ext->iter_vert), MR_ITER_VERT);
SET_FLAG_FROM_TEST(type, (ext->iter_looptri_bm || ext->iter_looptri), MR_ITER_LOOPTRI);
SET_FLAG_FROM_TEST(type, (ext->iter_loop_bm || ext->iter_loop), MR_ITER_LOOP);
SET_FLAG_FROM_TEST(type, (ext->iter_ledge_bm || ext->iter_ledge), MR_ITER_LEDGE);
@@ -552,6 +559,132 @@ BLI_INLINE eMRIterType mesh_extract_iter_type(const MeshExtract *ext)
return type;
}
+/* These are no-ops, allowing is to reference functions that don't exist. */
+#define extract_lnor_iter_vert_bm 0
+#define extract_uv_iter_vert_bm 0
+#define extract_tan_iter_vert_bm 0
+#define extract_vcol_iter_vert_bm 0
+#define extract_orco_iter_vert_bm 0
+#define extract_edge_fac_iter_vert_bm 0
+#define extract_weights_iter_vert_bm 0
+#define extract_edit_data_iter_vert_bm 0
+#define extract_edituv_data_iter_vert_bm 0
+#define extract_stretch_area_iter_vert_bm 0
+#define extract_stretch_angle_iter_vert_bm 0
+#define extract_mesh_analysis_iter_vert_bm 0
+#define extract_fdots_pos_iter_vert_bm 0
+#define extract_fdots_nor_iter_vert_bm 0
+#define extract_fdots_uv_iter_vert_bm 0
+#define extract_fdots_edituv_data_iter_vert_bm 0
+#define extract_poly_idx_iter_vert_bm 0
+#define extract_edge_idx_iter_vert_bm 0
+#define extract_vert_idx_iter_vert_bm 0
+#define extract_fdot_idx_iter_vert_bm 0
+#define extract_skin_roots_iter_vert_bm 0
+#define extract_tris_iter_vert_bm 0
+#define extract_lines_iter_vert_bm 0
+#define extract_points_iter_vert_bm 0
+#define extract_fdots_iter_vert_bm 0
+#define extract_lines_paint_mask_iter_vert_bm 0
+#define extract_lines_adjacency_iter_vert_bm 0
+#define extract_edituv_tris_iter_vert_bm 0
+#define extract_edituv_lines_iter_vert_bm 0
+#define extract_edituv_points_iter_vert_bm 0
+#define extract_edituv_fdots_iter_vert_bm 0
+#define extract_pos_nor_iter_looptri_bm 0
+#define extract_lnor_iter_looptri_bm 0
+#define extract_uv_iter_looptri_bm 0
+#define extract_tan_iter_looptri_bm 0
+#define extract_vcol_iter_looptri_bm 0
+#define extract_orco_iter_looptri_bm 0
+#define extract_edge_fac_iter_looptri_bm 0
+#define extract_weights_iter_looptri_bm 0
+#define extract_edit_data_iter_looptri_bm 0
+#define extract_edituv_data_iter_looptri_bm 0
+#define extract_stretch_area_iter_looptri_bm 0
+#define extract_stretch_angle_iter_looptri_bm 0
+#define extract_mesh_analysis_iter_looptri_bm 0
+#define extract_fdots_pos_iter_looptri_bm 0
+#define extract_fdots_nor_iter_looptri_bm 0
+#define extract_fdots_uv_iter_looptri_bm 0
+#define extract_fdots_edituv_data_iter_looptri_bm 0
+#define extract_poly_idx_iter_looptri_bm 0
+#define extract_edge_idx_iter_looptri_bm 0
+#define extract_vert_idx_iter_looptri_bm 0
+#define extract_fdot_idx_iter_looptri_bm 0
+#define extract_skin_roots_iter_looptri_bm 0
+#define extract_lines_iter_looptri_bm 0
+#define extract_points_iter_looptri_bm 0
+#define extract_fdots_iter_looptri_bm 0
+#define extract_lines_paint_mask_iter_looptri_bm 0
+#define extract_edituv_lines_iter_looptri_bm 0
+#define extract_edituv_points_iter_looptri_bm 0
+#define extract_edituv_fdots_iter_looptri_bm 0
+#define extract_uv_iter_loop_bm 0
+#define extract_tan_iter_loop_bm 0
+#define extract_vcol_iter_loop_bm 0
+#define extract_fdots_nor_iter_loop_bm 0
+#define extract_tris_iter_loop_bm 0
+#define extract_stretch_area_iter_loop_bm 0
+#define extract_mesh_analysis_iter_loop_bm 0
+#define extract_skin_roots_iter_loop_bm 0
+#define extract_lines_paint_mask_iter_loop_bm 0
+#define extract_lines_adjacency_iter_loop_bm 0
+#define extract_edituv_tris_iter_loop_bm 0
+#define extract_lnor_iter_ledge_bm 0
+#define extract_uv_iter_ledge_bm 0
+#define extract_tan_iter_ledge_bm 0
+#define extract_vcol_iter_ledge_bm 0
+#define extract_orco_iter_ledge_bm 0
+#define extract_weights_iter_ledge_bm 0
+#define extract_edituv_data_iter_ledge_bm 0
+#define extract_stretch_area_iter_ledge_bm 0
+#define extract_stretch_angle_iter_ledge_bm 0
+#define extract_mesh_analysis_iter_ledge_bm 0
+#define extract_fdots_pos_iter_ledge_bm 0
+#define extract_fdots_nor_iter_ledge_bm 0
+#define extract_fdots_uv_iter_ledge_bm 0
+#define extract_fdots_edituv_data_iter_ledge_bm 0
+#define extract_poly_idx_iter_ledge_bm 0
+#define extract_fdot_idx_iter_ledge_bm 0
+#define extract_skin_roots_iter_ledge_bm 0
+#define extract_tris_iter_ledge_bm 0
+#define extract_fdots_iter_ledge_bm 0
+#define extract_lines_paint_mask_iter_ledge_bm 0
+#define extract_lines_adjacency_iter_ledge_bm 0
+#define extract_edituv_tris_iter_ledge_bm 0
+#define extract_edituv_lines_iter_ledge_bm 0
+#define extract_edituv_points_iter_ledge_bm 0
+#define extract_edituv_fdots_iter_ledge_bm 0
+#define extract_lnor_iter_lvert_bm 0
+#define extract_uv_iter_lvert_bm 0
+#define extract_tan_iter_lvert_bm 0
+#define extract_vcol_iter_lvert_bm 0
+#define extract_orco_iter_lvert_bm 0
+#define extract_edge_fac_iter_lvert_bm 0
+#define extract_weights_iter_lvert_bm 0
+#define extract_edituv_data_iter_lvert_bm 0
+#define extract_stretch_area_iter_lvert_bm 0
+#define extract_stretch_angle_iter_lvert_bm 0
+#define extract_mesh_analysis_iter_lvert_bm 0
+#define extract_fdots_pos_iter_lvert_bm 0
+#define extract_fdots_nor_iter_lvert_bm 0
+#define extract_fdots_uv_iter_lvert_bm 0
+#define extract_fdots_edituv_data_iter_lvert_bm 0
+#define extract_poly_idx_iter_lvert_bm 0
+#define extract_edge_idx_iter_lvert_bm 0
+#define extract_fdot_idx_iter_lvert_bm 0
+#define extract_skin_roots_iter_lvert_bm 0
+#define extract_tris_iter_lvert_bm 0
+#define extract_lines_iter_lvert_bm 0
+#define extract_fdots_iter_lvert_bm 0
+#define extract_lines_paint_mask_iter_lvert_bm 0
+#define extract_lines_adjacency_iter_lvert_bm 0
+#define extract_edituv_tris_iter_lvert_bm 0
+#define extract_edituv_lines_iter_lvert_bm 0
+#define extract_edituv_points_iter_lvert_bm 0
+#define extract_edituv_fdots_iter_lvert_bm 0
+
/** \} */
/* ---------------------------------------------------------------------- */
@@ -610,10 +743,10 @@ static void *extract_tris_init(const MeshRenderData *mr, void *UNUSED(ibo))
return data;
}
-static void extract_tris_looptri_bmesh(const MeshRenderData *mr,
- int UNUSED(t),
- BMLoop **elt,
- void *_data)
+BLI_INLINE void extract_tris_iter_looptri_bm(const MeshRenderData *mr,
+ int UNUSED(t),
+ BMLoop **elt,
+ void *_data)
{
if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
MeshExtract_Tri_Data *data = _data;
@@ -665,7 +798,9 @@ static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data
static const MeshExtract extract_tris = {
extract_tris_init,
- extract_tris_looptri_bmesh,
+ NULL,
+ NULL,
+ extract_tris_iter_looptri_bm,
extract_tris_looptri_mesh,
NULL,
NULL,
@@ -693,10 +828,10 @@ static void *extract_lines_init(const MeshRenderData *mr, void *UNUSED(buf))
return elb;
}
-static void extract_lines_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *elb)
+BLI_INLINE void extract_lines_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *elb)
{
if (!BM_elem_flag_test(loop->e, BM_ELEM_HIDDEN)) {
GPU_indexbuf_set_line_verts(elb, BM_elem_index_get(loop->e), l, BM_elem_index_get(loop->next));
@@ -726,7 +861,10 @@ static void extract_lines_loop_mesh(const MeshRenderData *mr,
}
}
-static void extract_lines_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *elb)
+BLI_INLINE void extract_lines_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *eed,
+ void *elb)
{
int ledge_idx = mr->edge_len + e;
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
@@ -766,13 +904,15 @@ static void extract_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, vo
MEM_freeN(elb);
}
-static const MeshExtract extract_lines = {
+static const MeshExtract extract_lines_without_lines_loose = {
extract_lines_init,
NULL,
NULL,
- extract_lines_loop_bmesh,
+ NULL,
+ NULL,
+ extract_lines_iter_loop_bm,
extract_lines_loop_mesh,
- extract_lines_ledge_bmesh,
+ extract_lines_iter_ledge_bm,
extract_lines_ledge_mesh,
NULL,
NULL,
@@ -808,9 +948,11 @@ static const MeshExtract extract_lines_with_lines_loose = {
extract_lines_init,
NULL,
NULL,
- extract_lines_loop_bmesh,
+ NULL,
+ NULL,
+ extract_lines_iter_loop_bm,
extract_lines_loop_mesh,
- extract_lines_ledge_bmesh,
+ extract_lines_iter_ledge_bm,
extract_lines_ledge_mesh,
NULL,
NULL,
@@ -859,10 +1001,10 @@ BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb,
}
}
-static void extract_points_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *elb)
+BLI_INLINE void extract_points_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *elb)
{
vert_set_bmesh(elb, loop->v, l);
}
@@ -877,7 +1019,10 @@ static void extract_points_loop_mesh(const MeshRenderData *mr,
vert_set_mesh(elb, mr, mloop->v, l);
}
-static void extract_points_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *elb)
+BLI_INLINE void extract_points_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *eed,
+ void *elb)
{
vert_set_bmesh(elb, eed->v1, mr->loop_len + e * 2);
vert_set_bmesh(elb, eed->v2, mr->loop_len + e * 2 + 1);
@@ -892,7 +1037,10 @@ static void extract_points_ledge_mesh(const MeshRenderData *mr,
vert_set_mesh(elb, mr, medge->v2, mr->loop_len + e * 2 + 1);
}
-static void extract_points_lvert_bmesh(const MeshRenderData *mr, int v, BMVert *eve, void *elb)
+BLI_INLINE void extract_points_iter_lvert_bm(const MeshRenderData *mr,
+ int v,
+ BMVert *eve,
+ void *elb)
{
vert_set_bmesh(elb, eve, mr->loop_len + mr->edge_loose_len * 2 + v);
}
@@ -915,11 +1063,13 @@ static const MeshExtract extract_points = {
extract_points_init,
NULL,
NULL,
- extract_points_loop_bmesh,
+ NULL,
+ NULL,
+ extract_points_iter_loop_bm,
extract_points_loop_mesh,
- extract_points_ledge_bmesh,
+ extract_points_iter_ledge_bm,
extract_points_ledge_mesh,
- extract_points_lvert_bmesh,
+ extract_points_iter_lvert_bm,
extract_points_lvert_mesh,
extract_points_finish,
0,
@@ -939,10 +1089,10 @@ static void *extract_fdots_init(const MeshRenderData *mr, void *UNUSED(buf))
return elb;
}
-static void extract_fdots_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int UNUSED(l),
- BMLoop *loop,
- void *elb)
+BLI_INLINE void extract_fdots_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int UNUSED(l),
+ BMLoop *loop,
+ void *elb)
{
int face_idx = BM_elem_index_get(loop->f);
if (!BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN)) {
@@ -980,7 +1130,9 @@ static const MeshExtract extract_fdots = {
extract_fdots_init,
NULL,
NULL,
- extract_fdots_loop_bmesh,
+ NULL,
+ NULL,
+ extract_fdots_iter_loop_bm,
extract_fdots_loop_mesh,
NULL,
NULL,
@@ -1063,6 +1215,8 @@ static const MeshExtract extract_lines_paint_mask = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
extract_lines_paint_mask_loop_mesh,
NULL,
NULL,
@@ -1146,10 +1300,10 @@ BLI_INLINE void lines_adjacency_triangle(
}
}
-static void extract_lines_adjacency_looptri_bmesh(const MeshRenderData *UNUSED(mr),
- int UNUSED(t),
- BMLoop **elt,
- void *data)
+BLI_INLINE void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
+ int UNUSED(t),
+ BMLoop **elt,
+ void *data)
{
if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
lines_adjacency_triangle(BM_elem_index_get(elt[0]->v),
@@ -1212,7 +1366,9 @@ static void extract_lines_adjacency_finish(const MeshRenderData *mr, void *ibo,
static const MeshExtract extract_lines_adjacency = {
extract_lines_adjacency_init,
- extract_lines_adjacency_looptri_bmesh,
+ NULL,
+ NULL,
+ extract_lines_adjacency_iter_looptri_bm,
extract_lines_adjacency_looptri_mesh,
NULL,
NULL,
@@ -1252,10 +1408,10 @@ BLI_INLINE void edituv_tri_add(
}
}
-static void extract_edituv_tris_looptri_bmesh(const MeshRenderData *UNUSED(mr),
- int UNUSED(t),
- BMLoop **elt,
- void *data)
+BLI_INLINE void extract_edituv_tris_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
+ int UNUSED(t),
+ BMLoop **elt,
+ void *data)
{
edituv_tri_add(data,
BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN),
@@ -1288,7 +1444,9 @@ static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr), void *i
static const MeshExtract extract_edituv_tris = {
extract_edituv_tris_init,
- extract_edituv_tris_looptri_bmesh,
+ NULL,
+ NULL,
+ extract_edituv_tris_iter_looptri_bm,
extract_edituv_tris_looptri_mesh,
NULL,
NULL,
@@ -1324,10 +1482,10 @@ BLI_INLINE void edituv_edge_add(
}
}
-static void extract_edituv_lines_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_edituv_lines_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *data)
{
edituv_edge_add(data,
BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN),
@@ -1364,7 +1522,9 @@ static const MeshExtract extract_edituv_lines = {
extract_edituv_lines_init,
NULL,
NULL,
- extract_edituv_lines_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edituv_lines_iter_loop_bm,
extract_edituv_lines_loop_mesh,
NULL,
NULL,
@@ -1400,10 +1560,10 @@ BLI_INLINE void edituv_point_add(MeshExtract_EditUvElem_Data *data,
}
}
-static void extract_edituv_points_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_edituv_points_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *data)
{
edituv_point_add(data,
BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN),
@@ -1435,7 +1595,9 @@ static const MeshExtract extract_edituv_points = {
extract_edituv_points_init,
NULL,
NULL,
- extract_edituv_points_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edituv_points_iter_loop_bm,
extract_edituv_points_loop_mesh,
NULL,
NULL,
@@ -1474,10 +1636,10 @@ BLI_INLINE void edituv_facedot_add(MeshExtract_EditUvElem_Data *data,
}
}
-static void extract_edituv_fdots_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int UNUSED(l),
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_edituv_fdots_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int UNUSED(l),
+ BMLoop *loop,
+ void *data)
{
edituv_facedot_add(data,
BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN),
@@ -1513,7 +1675,9 @@ static const MeshExtract extract_edituv_fdots = {
extract_edituv_fdots_init,
NULL,
NULL,
- extract_edituv_fdots_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edituv_fdots_iter_loop_bm,
extract_edituv_fdots_loop_mesh,
NULL,
NULL,
@@ -1557,26 +1721,31 @@ static void *extract_pos_nor_init(const MeshRenderData *mr, void *buf)
size_t packed_nor_len = sizeof(GPUPackedNormal) * mr->vert_len;
MeshExtract_PosNor_Data *data = MEM_mallocN(sizeof(*data) + packed_nor_len, __func__);
data->vbo_data = (PosNorLoop *)vbo->data;
-
- /* Quicker than doing it for each loop. */
- if (mr->extract_type == MR_EXTRACT_BMESH) {
- BMIter iter;
- BMVert *eve;
- int v;
- BM_ITER_MESH_INDEX (eve, &iter, mr->bm, BM_VERTS_OF_MESH, v) {
- data->packed_nor[v] = GPU_normal_convert_i10_v3(bm_vert_no_get(mr, eve));
- }
- }
- else {
- const MVert *mvert = mr->mvert;
- for (int v = 0; v < mr->vert_len; v++, mvert++) {
- data->packed_nor[v] = GPU_normal_convert_i10_s3(mvert->no);
- }
- }
return data;
}
-static void extract_pos_nor_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *_data)
+BLI_INLINE void extract_pos_nor_iter_vert_bm(const MeshRenderData *mr,
+ int t,
+ BMVert *eve,
+ void *_data)
+{
+ MeshExtract_PosNor_Data *data = _data;
+ data->packed_nor[t] = GPU_normal_convert_i10_v3(bm_vert_no_get(mr, eve));
+}
+
+static void extract_pos_nor_vert_mesh(const MeshRenderData *UNUSED(mr),
+ int t,
+ const MVert *mv,
+ void *_data)
+{
+ MeshExtract_PosNor_Data *data = _data;
+ data->packed_nor[t] = GPU_normal_convert_i10_s3(mv->no);
+}
+
+BLI_INLINE void extract_pos_nor_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_PosNor_Data *data = _data;
PosNorLoop *vert = data->vbo_data + l;
@@ -1612,7 +1781,10 @@ static void extract_pos_nor_loop_mesh(const MeshRenderData *mr,
}
}
-static void extract_pos_nor_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *_data)
+BLI_INLINE void extract_pos_nor_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *eed,
+ void *_data)
{
int l = mr->loop_len + e * 2;
MeshExtract_PosNor_Data *data = _data;
@@ -1637,7 +1809,10 @@ static void extract_pos_nor_ledge_mesh(const MeshRenderData *mr,
vert[1].nor = data->packed_nor[medge->v2];
}
-static void extract_pos_nor_lvert_bmesh(const MeshRenderData *mr, int v, BMVert *eve, void *_data)
+BLI_INLINE void extract_pos_nor_iter_lvert_bm(const MeshRenderData *mr,
+ int v,
+ BMVert *eve,
+ void *_data)
{
int l = mr->loop_len + mr->edge_loose_len * 2 + v;
MeshExtract_PosNor_Data *data = _data;
@@ -1666,13 +1841,15 @@ static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr), void *UNUSE
static const MeshExtract extract_pos_nor = {
extract_pos_nor_init,
+ extract_pos_nor_iter_vert_bm,
+ extract_pos_nor_vert_mesh,
NULL,
NULL,
- extract_pos_nor_loop_bmesh,
+ extract_pos_nor_iter_loop_bm,
extract_pos_nor_loop_mesh,
- extract_pos_nor_ledge_bmesh,
+ extract_pos_nor_iter_ledge_bm,
extract_pos_nor_ledge_mesh,
- extract_pos_nor_lvert_bmesh,
+ extract_pos_nor_iter_lvert_bm,
extract_pos_nor_lvert_mesh,
extract_pos_nor_finish,
0,
@@ -1702,7 +1879,10 @@ static void *extract_lnor_hq_init(const MeshRenderData *mr, void *buf)
return vbo->data;
}
-static void extract_lnor_hq_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *data)
+BLI_INLINE void extract_lnor_hq_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *data)
{
if (mr->loop_normals) {
normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]);
@@ -1749,7 +1929,9 @@ static const MeshExtract extract_lnor_hq = {
extract_lnor_hq_init,
NULL,
NULL,
- extract_lnor_hq_loop_bmesh,
+ NULL,
+ NULL,
+ extract_lnor_hq_iter_loop_bm,
extract_lnor_hq_loop_mesh,
NULL,
NULL,
@@ -1779,7 +1961,10 @@ static void *extract_lnor_init(const MeshRenderData *mr, void *buf)
return vbo->data;
}
-static void extract_lnor_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *data)
+BLI_INLINE void extract_lnor_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *data)
{
if (mr->loop_normals) {
((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(mr->loop_normals[l]);
@@ -1828,7 +2013,9 @@ static const MeshExtract extract_lnor = {
extract_lnor_init,
NULL,
NULL,
- extract_lnor_loop_bmesh,
+ NULL,
+ NULL,
+ extract_lnor_iter_loop_bm,
extract_lnor_loop_mesh,
NULL,
NULL,
@@ -1905,6 +2092,7 @@ static void *extract_uv_init(const MeshRenderData *mr, void *buf)
for (int i = 0; i < MAX_MTFACE; i++) {
if (uv_layers & (1 << i)) {
if (mr->extract_type == MR_EXTRACT_BMESH) {
+ printf("Getting UV's\n");
int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_MLOOPUV, i);
BMIter f_iter;
BMFace *efa;
@@ -1941,6 +2129,8 @@ static const MeshExtract extract_uv = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
0,
false,
};
@@ -2137,6 +2327,8 @@ static const MeshExtract extract_tan = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI,
false,
};
@@ -2164,6 +2356,8 @@ static const MeshExtract extract_tan_hq = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI,
false,
};
@@ -2320,6 +2514,8 @@ static const MeshExtract extract_vcol = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
0,
false,
};
@@ -2360,10 +2556,10 @@ static void *extract_orco_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_orco_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_orco_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *data)
{
MeshExtract_Orco_Data *orco_data = (MeshExtract_Orco_Data *)data;
float *loop_orco = orco_data->vbo_data[l];
@@ -2393,7 +2589,9 @@ static const MeshExtract extract_orco = {
extract_orco_init,
NULL,
NULL,
- extract_orco_loop_bmesh,
+ NULL,
+ NULL,
+ extract_orco_iter_loop_bm,
extract_orco_loop_mesh,
NULL,
NULL,
@@ -2470,7 +2668,10 @@ static void *extract_edge_fac_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_edge_fac_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *_data)
+BLI_INLINE void extract_edge_fac_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data;
if (BM_edge_is_manifold(loop->e)) {
@@ -2517,10 +2718,10 @@ static void extract_edge_fac_loop_mesh(
}
}
-static void extract_edge_fac_ledge_bmesh(const MeshRenderData *mr,
- int e,
- BMEdge *UNUSED(eed),
- void *_data)
+BLI_INLINE void extract_edge_fac_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *UNUSED(eed),
+ void *_data)
{
MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data;
data->vbo_data[mr->loop_len + e * 2 + 0] = 255;
@@ -2572,9 +2773,11 @@ static const MeshExtract extract_edge_fac = {
extract_edge_fac_init,
NULL,
NULL,
- extract_edge_fac_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edge_fac_iter_loop_bm,
extract_edge_fac_loop_mesh,
- extract_edge_fac_ledge_bmesh,
+ extract_edge_fac_iter_ledge_bm,
extract_edge_fac_ledge_mesh,
NULL,
NULL,
@@ -2678,10 +2881,10 @@ static void *extract_weights_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_weights_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *_data)
+BLI_INLINE void extract_weights_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_Weight_Data *data = (MeshExtract_Weight_Data *)_data;
const MDeformVert *dvert = (data->cd_ofs != -1) ? BM_ELEM_CD_GET_VOID_P(loop->v, data->cd_ofs) :
@@ -2710,7 +2913,9 @@ static const MeshExtract extract_weights = {
extract_weights_init,
NULL,
NULL,
- extract_weights_loop_bmesh,
+ NULL,
+ NULL,
+ extract_weights_iter_loop_bm,
extract_weights_loop_mesh,
NULL,
NULL,
@@ -2879,10 +3084,10 @@ static void *extract_edit_data_init(const MeshRenderData *mr, void *buf)
return vbo->data;
}
-static void extract_edit_data_loop_bmesh(const MeshRenderData *mr,
- int l,
- BMLoop *loop,
- void *_data)
+BLI_INLINE void extract_edit_data_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *_data)
{
EditLoopData *data = (EditLoopData *)_data + l;
memset(data, 0x0, sizeof(*data));
@@ -2914,10 +3119,10 @@ static void extract_edit_data_loop_mesh(const MeshRenderData *mr,
}
}
-static void extract_edit_data_ledge_bmesh(const MeshRenderData *mr,
- int e,
- BMEdge *eed,
- void *_data)
+BLI_INLINE void extract_edit_data_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *eed,
+ void *_data)
{
EditLoopData *data = (EditLoopData *)_data + mr->loop_len + e * 2;
memset(data, 0x0, sizeof(*data) * 2);
@@ -2950,10 +3155,10 @@ static void extract_edit_data_ledge_mesh(const MeshRenderData *mr,
}
}
-static void extract_edit_data_lvert_bmesh(const MeshRenderData *mr,
- int v,
- BMVert *eve,
- void *_data)
+BLI_INLINE void extract_edit_data_iter_lvert_bm(const MeshRenderData *mr,
+ int v,
+ BMVert *eve,
+ void *_data)
{
EditLoopData *data = (EditLoopData *)_data + mr->loop_len + mr->edge_loose_len * 2 + v;
memset(data, 0x0, sizeof(*data));
@@ -2978,11 +3183,13 @@ static const MeshExtract extract_edit_data = {
extract_edit_data_init,
NULL,
NULL,
- extract_edit_data_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edit_data_iter_loop_bm,
extract_edit_data_loop_mesh,
- extract_edit_data_ledge_bmesh,
+ extract_edit_data_iter_ledge_bm,
extract_edit_data_ledge_mesh,
- extract_edit_data_lvert_bmesh,
+ extract_edit_data_iter_lvert_bm,
extract_edit_data_lvert_mesh,
NULL,
0,
@@ -3021,10 +3228,10 @@ static void *extract_edituv_data_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_edituv_data_loop_bmesh(const MeshRenderData *mr,
- int l,
- BMLoop *loop,
- void *_data)
+BLI_INLINE void extract_edituv_data_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_EditUVData_Data *data = (MeshExtract_EditUVData_Data *)_data;
EditLoopData *eldata = data->vbo_data + l;
@@ -3079,7 +3286,9 @@ static const MeshExtract extract_edituv_data = {
extract_edituv_data_init,
NULL,
NULL,
- extract_edituv_data_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edituv_data_iter_loop_bm,
extract_edituv_data_loop_mesh,
NULL,
NULL,
@@ -3210,6 +3419,8 @@ static const MeshExtract extract_stretch_area = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
mesh_stretch_area_finish,
0,
false,
@@ -3302,10 +3513,10 @@ static void *extract_stretch_angle_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_stretch_angle_loop_bmesh(const MeshRenderData *mr,
- int l,
- BMLoop *loop,
- void *_data)
+BLI_INLINE void extract_stretch_angle_iter_loop_bm(const MeshRenderData *mr,
+ int l,
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_StretchAngle_Data *data = (MeshExtract_StretchAngle_Data *)_data;
float(*auv)[2] = data->auv, *last_auv = data->last_auv;
@@ -3403,7 +3614,9 @@ static const MeshExtract extract_stretch_angle = {
extract_stretch_angle_init,
NULL,
NULL,
- extract_stretch_angle_loop_bmesh,
+ NULL,
+ NULL,
+ extract_stretch_angle_iter_loop_bm,
extract_stretch_angle_loop_mesh,
NULL,
NULL,
@@ -4018,6 +4231,8 @@ static const MeshExtract extract_mesh_analysis = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
extract_mesh_analysis_finish,
/* This is not needed for all visualization types.
* Maybe split into different extract. */
@@ -4047,10 +4262,10 @@ static void *extract_fdots_pos_init(const MeshRenderData *mr, void *buf)
return vbo->data;
}
-static void extract_fdots_pos_loop_bmesh(const MeshRenderData *mr,
- int UNUSED(l),
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_fdots_pos_iter_loop_bm(const MeshRenderData *mr,
+ int UNUSED(l),
+ BMLoop *loop,
+ void *data)
{
float(*center)[3] = (float(*)[3])data;
float w = 1.0f / (float)loop->f->len;
@@ -4081,7 +4296,9 @@ static const MeshExtract extract_fdots_pos = {
extract_fdots_pos_init,
NULL,
NULL,
- extract_fdots_pos_loop_bmesh,
+ NULL,
+ NULL,
+ extract_fdots_pos_iter_loop_bm,
extract_fdots_pos_loop_mesh,
NULL,
NULL,
@@ -4171,6 +4388,8 @@ static const MeshExtract extract_fdots_nor = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
extract_fdots_nor_finish,
MR_DATA_POLY_NOR,
false,
@@ -4217,10 +4436,10 @@ static void *extract_fdots_uv_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_fdots_uv_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int UNUSED(l),
- BMLoop *loop,
- void *_data)
+BLI_INLINE void extract_fdots_uv_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int UNUSED(l),
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_FdotUV_Data *data = (MeshExtract_FdotUV_Data *)_data;
float w = 1.0f / (float)loop->f->len;
@@ -4255,7 +4474,9 @@ static const MeshExtract extract_fdots_uv = {
extract_fdots_uv_init,
NULL,
NULL,
- extract_fdots_uv_loop_bmesh,
+ NULL,
+ NULL,
+ extract_fdots_uv_iter_loop_bm,
extract_fdots_uv_loop_mesh,
NULL,
NULL,
@@ -4292,10 +4513,10 @@ static void *extract_fdots_edituv_data_init(const MeshRenderData *mr, void *buf)
return data;
}
-static void extract_fdots_edituv_data_loop_bmesh(const MeshRenderData *mr,
- int UNUSED(l),
- BMLoop *loop,
- void *_data)
+BLI_INLINE void extract_fdots_edituv_data_iter_loop_bm(const MeshRenderData *mr,
+ int UNUSED(l),
+ BMLoop *loop,
+ void *_data)
{
MeshExtract_EditUVFdotData_Data *data = (MeshExtract_EditUVFdotData_Data *)_data;
EditLoopData *eldata = data->vbo_data + BM_elem_index_get(loop->f);
@@ -4330,7 +4551,9 @@ static const MeshExtract extract_fdots_edituv_data = {
extract_fdots_edituv_data_init,
NULL,
NULL,
- extract_fdots_edituv_data_loop_bmesh,
+ NULL,
+ NULL,
+ extract_fdots_edituv_data_iter_loop_bm,
extract_fdots_edituv_data_loop_mesh,
NULL,
NULL,
@@ -4399,6 +4622,8 @@ static const MeshExtract extract_skin_roots = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
0,
false,
};
@@ -4427,43 +4652,52 @@ static void *extract_select_idx_init(const MeshRenderData *mr, void *buf)
* index VBO's. We could upload the p/e/v_origindex as a buffer texture and sample it inside the
* shader to output original index. */
-static void extract_poly_idx_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_poly_idx_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *data)
{
((uint32_t *)data)[l] = BM_elem_index_get(loop->f);
}
-static void extract_edge_idx_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_edge_idx_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *data)
{
((uint32_t *)data)[l] = BM_elem_index_get(loop->e);
}
-static void extract_vert_idx_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int l,
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_vert_idx_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int l,
+ BMLoop *loop,
+ void *data)
{
((uint32_t *)data)[l] = BM_elem_index_get(loop->v);
}
-static void extract_edge_idx_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *data)
+BLI_INLINE void extract_edge_idx_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *eed,
+ void *data)
{
((uint32_t *)data)[mr->loop_len + e * 2 + 0] = BM_elem_index_get(eed);
((uint32_t *)data)[mr->loop_len + e * 2 + 1] = BM_elem_index_get(eed);
}
-static void extract_vert_idx_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *data)
+BLI_INLINE void extract_vert_idx_iter_ledge_bm(const MeshRenderData *mr,
+ int e,
+ BMEdge *eed,
+ void *data)
{
((uint32_t *)data)[mr->loop_len + e * 2 + 0] = BM_elem_index_get(eed->v1);
((uint32_t *)data)[mr->loop_len + e * 2 + 1] = BM_elem_index_get(eed->v2);
}
-static void extract_vert_idx_lvert_bmesh(const MeshRenderData *mr, int v, BMVert *eve, void *data)
+BLI_INLINE void extract_vert_idx_iter_lvert_bm(const MeshRenderData *mr,
+ int v,
+ BMVert *eve,
+ void *data)
{
((uint32_t *)data)[mr->loop_len + mr->edge_loose_len * 2 + v] = BM_elem_index_get(eve);
}
@@ -4534,7 +4768,9 @@ static const MeshExtract extract_poly_idx = {
extract_select_idx_init,
NULL,
NULL,
- extract_poly_idx_loop_bmesh,
+ NULL,
+ NULL,
+ extract_poly_idx_iter_loop_bm,
extract_poly_idx_loop_mesh,
NULL,
NULL,
@@ -4549,9 +4785,11 @@ static const MeshExtract extract_edge_idx = {
extract_select_idx_init,
NULL,
NULL,
- extract_edge_idx_loop_bmesh,
+ NULL,
+ NULL,
+ extract_edge_idx_iter_loop_bm,
extract_edge_idx_loop_mesh,
- extract_edge_idx_ledge_bmesh,
+ extract_edge_idx_iter_ledge_bm,
extract_edge_idx_ledge_mesh,
NULL,
NULL,
@@ -4564,11 +4802,13 @@ static const MeshExtract extract_vert_idx = {
extract_select_idx_init,
NULL,
NULL,
- extract_vert_idx_loop_bmesh,
+ NULL,
+ NULL,
+ extract_vert_idx_iter_loop_bm,
extract_vert_idx_loop_mesh,
- extract_vert_idx_ledge_bmesh,
+ extract_vert_idx_iter_ledge_bm,
extract_vert_idx_ledge_mesh,
- extract_vert_idx_lvert_bmesh,
+ extract_vert_idx_iter_lvert_bm,
extract_vert_idx_lvert_mesh,
NULL,
0,
@@ -4588,10 +4828,10 @@ static void *extract_select_fdot_idx_init(const MeshRenderData *mr, void *buf)
return vbo->data;
}
-static void extract_fdot_idx_loop_bmesh(const MeshRenderData *UNUSED(mr),
- int UNUSED(l),
- BMLoop *loop,
- void *data)
+BLI_INLINE void extract_fdot_idx_iter_loop_bm(const MeshRenderData *UNUSED(mr),
+ int UNUSED(l),
+ BMLoop *loop,
+ void *data)
{
((uint32_t *)data)[BM_elem_index_get(loop->f)] = BM_elem_index_get(loop->f);
}
@@ -4610,7 +4850,9 @@ static const MeshExtract extract_fdot_idx = {
extract_select_fdot_idx_init,
NULL,
NULL,
- extract_fdot_idx_loop_bmesh,
+ NULL,
+ NULL,
+ extract_fdot_idx_iter_loop_bm,
extract_fdot_idx_loop_mesh,
NULL,
NULL,
@@ -4699,6 +4941,13 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
{
switch (mr->extract_type) {
case MR_EXTRACT_BMESH:
+ if (iter_type & MR_ITER_VERT) {
+ int t_end = min_ii(mr->vert_len, end);
+ for (int t = start; t < t_end; t++) {
+ BMVert *eve = BM_vert_at_index(mr->bm, t);
+ extract->iter_vert_bm(mr, t, eve, user_data);
+ }
+ }
if (iter_type & MR_ITER_LOOPTRI) {
int t_end = min_ii(mr->tri_len, end);
for (int t = start; t < t_end; t++) {
@@ -4734,6 +4983,12 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
break;
case MR_EXTRACT_MAPPED:
case MR_EXTRACT_MESH:
+ if (iter_type & MR_ITER_VERT) {
+ int v_end = min_ii(mr->vert_len, end);
+ for (int v = start; v < v_end; v++) {
+ extract->iter_vert(mr, v, &mr->mvert[v], user_data);
+ }
+ }
if (iter_type & MR_ITER_LOOPTRI) {
int t_end = min_ii(mr->tri_len, end);
for (int t = start; t < t_end; t++) {
@@ -5072,6 +5327,12 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
const bool do_lines_loose_subbuffer = mbc.ibo.lines_loose != NULL;
+ /* When `lines` and `lines_loose` are requested, schedule lines extraction that also creates
+ * the `lines_loose` sub-buffer. */
+ /* XXX: copy since macro reference as if it's a value, not a pointer. */
+ MeshExtract extract_lines = do_lines_loose_subbuffer ? extract_lines_with_lines_loose :
+ extract_lines_without_lines_loose;
+
#define TEST_ASSIGN(type, type_lowercase, name) \
do { \
if (DRW_TEST_ASSIGN_##type(mbc.type_lowercase.name)) { \
@@ -5143,22 +5404,210 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
double rdata_end = PIL_check_seconds_timer();
#endif
- size_t counters_size = (sizeof(mbc) / sizeof(void *)) * sizeof(int32_t);
- int32_t *task_counters = MEM_callocN(counters_size, __func__);
- int counter_used = 0;
-
- struct TaskNode *task_node_mesh_render_data = mesh_extract_render_data_node_create(
- task_graph, mr, iter_flag, data_flag);
- ExtractSingleThreadedTaskData *single_threaded_task_data = MEM_callocN(
- sizeof(ExtractSingleThreadedTaskData), __func__);
- UserDataInitTaskData *user_data_init_task_data = MEM_callocN(sizeof(UserDataInitTaskData),
- __func__);
- user_data_init_task_data->task_counters = task_counters;
- struct TaskNode *task_node_user_data_init = user_data_init_task_node_create(
- task_graph, user_data_init_task_data);
-
-#define EXTRACT(buf, name) \
+#define BUFFER_ID_BLOCK \
+ BUFFER_APPLY(vbo, pos_nor) \
+ BUFFER_APPLY(vbo, lnor) \
+ BUFFER_APPLY(vbo, uv) \
+ BUFFER_APPLY(vbo, tan) \
+ BUFFER_APPLY(vbo, vcol) \
+ BUFFER_APPLY(vbo, orco) \
+ BUFFER_APPLY(vbo, edge_fac) \
+ BUFFER_APPLY(vbo, weights) \
+ BUFFER_APPLY(vbo, edit_data) \
+ BUFFER_APPLY(vbo, edituv_data) \
+ BUFFER_APPLY(vbo, stretch_area) \
+ BUFFER_APPLY(vbo, stretch_angle) \
+ BUFFER_APPLY(vbo, mesh_analysis) \
+ BUFFER_APPLY(vbo, fdots_pos) \
+ BUFFER_APPLY(vbo, fdots_nor) \
+ BUFFER_APPLY(vbo, fdots_uv) \
+ BUFFER_APPLY(vbo, fdots_edituv_data) \
+ BUFFER_APPLY(vbo, poly_idx) \
+ BUFFER_APPLY(vbo, edge_idx) \
+ BUFFER_APPLY(vbo, vert_idx) \
+ BUFFER_APPLY(vbo, fdot_idx) \
+ BUFFER_APPLY(vbo, skin_roots) \
+ BUFFER_APPLY(ibo, tris) \
+ BUFFER_APPLY(ibo, lines) \
+ BUFFER_APPLY(ibo, points) \
+ BUFFER_APPLY(ibo, fdots) \
+ BUFFER_APPLY(ibo, lines_paint_mask) \
+ BUFFER_APPLY(ibo, lines_adjacency) \
+ BUFFER_APPLY(ibo, edituv_tris) \
+ BUFFER_APPLY(ibo, edituv_lines) \
+ BUFFER_APPLY(ibo, edituv_points) \
+ BUFFER_APPLY(ibo, edituv_fdots)
+
+ /* Define ID's */
+#define BUFFER_APPLY(_, name) _EXTRACT_ID_##name,
+ enum { BUFFER_ID_BLOCK };
+#undef BUFFER_APPLY
+
+#define BUFFER_APPLY(_, name) const uint32_t EXTRACT_FLAG_##name = 1 << _EXTRACT_ID_##name;
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+
+#define FLAG_FROM_NAME(name) EXTRACT_FLAG_##name
+
+ if (is_editmode && (mr->extract_type == MR_EXTRACT_BMESH)) {
+ BMesh *bm = mr->bm;
+
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Waddress"
+#endif
+
+ uint32_t extract_flag = 0;
+
+#define BUFFER_APPLY(buf, name) \
if (mbc.buf.name) { \
+ extract_flag |= EXTRACT_FLAG_##name; \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+
+/* First run the init functions (use callbacks). */
+#define BUFFER_APPLY(buf, name) \
+ void *extract_user_data_##name = (mbc.buf.name && extract_##name.init) ? \
+ extract_##name.init(mr, mbc.buf.name) : \
+ NULL;
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+
+ /* Extract data inline. */
+ if (iter_flag & MR_ITER_VERT) {
+ BMIter iter;
+ BMVert *eve;
+ int elem_id;
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, elem_id) {
+#define BUFFER_APPLY(buf, name) \
+ if (extract_##name##_iter_vert_bm != NULL) { /* Will be optimized out. */ \
+ if (extract_flag & EXTRACT_FLAG_##name) { \
+ ((ExtractEditVertFn *)extract_##name##_iter_vert_bm)( \
+ mr, elem_id, eve, extract_user_data_##name); \
+ } \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+ }
+ }
+
+ if (iter_flag & MR_ITER_LOOPTRI) {
+ BMLoop **elt = &mr->edit_bmesh->looptris[0][0];
+ const int elem_len = mr->tri_len;
+ for (int elem_id = 0; elem_id < elem_len; elem_id += 1, elt += 3) {
+#define BUFFER_APPLY(buf, name) \
+ if (extract_##name##_iter_looptri_bm) { /* Will be optimized out. */ \
+ if (extract_flag & EXTRACT_FLAG_##name) { \
+ ((ExtractEditTriFn *)extract_##name##_iter_looptri_bm)( \
+ mr, elem_id, elt, extract_user_data_##name); \
+ } \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+ }
+ }
+
+ if (iter_flag & MR_ITER_LOOP) {
+ BMIter iter;
+ BMFace *efa;
+ int elem_id;
+ int elem_id_loop = 0;
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, elem_id) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+#define BUFFER_APPLY(buf, name) \
+ if (extract_##name##_iter_loop_bm != NULL) { /* Will be optimized out. */ \
+ if (extract_flag & EXTRACT_FLAG_##name) { \
+ ((ExtractEditLoopFn *)extract_##name##_iter_loop_bm)( \
+ mr, elem_id_loop, l_iter, extract_user_data_##name); \
+ } \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+ elem_id_loop += 1;
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ if (iter_flag & MR_ITER_LEDGE) {
+ const int le_end = mr->edge_loose_len;
+ for (int e = 0; e < le_end; e++) {
+ BMEdge *eed = BM_edge_at_index(mr->bm, mr->ledges[e]);
+#define BUFFER_APPLY(buf, name) \
+ if (extract_##name##_iter_ledge_bm != NULL) { /* Will be optimized out. */ \
+ if (extract_flag & EXTRACT_FLAG_##name) { \
+ ((ExtractEditLedgeFn *)extract_##name##_iter_ledge_bm)( \
+ mr, e, eed, extract_user_data_##name); \
+ } \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+ }
+ }
+
+ if (iter_flag & MR_ITER_LVERT) {
+ const int lv_end = mr->vert_loose_len;
+ for (int v = 0; v < lv_end; v++) {
+ BMVert *eve = BM_vert_at_index(mr->bm, mr->lverts[v]);
+
+#define BUFFER_APPLY(buf, name) \
+ if (extract_##name##_iter_lvert_bm != NULL) { /* Will be optimized out. */ \
+ if (extract_flag & EXTRACT_FLAG_##name) { \
+ ((ExtractEditLvertFn *)extract_##name##_iter_lvert_bm)( \
+ mr, v, eve, extract_user_data_##name); \
+ } \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+ }
+ }
+
+ /* End data extract loop. */
+
+ /* Handle lines separately. */
+ if (mbc.ibo.lines) {
+ /* pass */
+ }
+ else {
+ if (do_lines_loose_subbuffer) {
+ extract_lines_loose_subbuffer(mr);
+ }
+ }
+
+ /* Finish. */
+#define BUFFER_APPLY(buf, name) \
+ if (mbc.buf.name && extract_##name.finish) { \
+ extract_##name.finish(mr, mbc.buf.name, extract_user_data_##name); \
+ }
+ BUFFER_ID_BLOCK
+#undef BUFFER_APPLY
+
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+ }
+ else {
+ size_t counters_size = (sizeof(mbc) / sizeof(void *)) * sizeof(int32_t);
+ int32_t *task_counters = MEM_callocN(counters_size, __func__);
+ int counter_used = 0;
+
+ struct TaskNode *task_node_mesh_render_data = mesh_extract_render_data_node_create(
+ task_graph, mr, iter_flag, data_flag);
+ ExtractSingleThreadedTaskData *single_threaded_task_data = MEM_callocN(
+ sizeof(ExtractSingleThreadedTaskData), __func__);
+ UserDataInitTaskData *user_data_init_task_data = MEM_callocN(sizeof(UserDataInitTaskData),
+ __func__);
+ user_data_init_task_data->task_counters = task_counters;
+ struct TaskNode *task_node_user_data_init = user_data_init_task_node_create(
+ task_graph, user_data_init_task_data);
+
+#define BUFFER_APPLY(buf, name) \
+ if (FLAG_FROM_NAME(name) == FLAG_FROM_NAME(lines)) { \
+ /* skip lines */ \
+ } \
+ else if (mbc.buf.name) { \
extract_task_create(task_graph, \
task_node_mesh_render_data, \
task_node_user_data_init, \
@@ -5169,85 +5618,53 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
&extract_##name, \
mbc.buf.name, \
&task_counters[counter_used++]); \
- } \
- ((void)0)
-
- EXTRACT(vbo, pos_nor);
- EXTRACT(vbo, lnor);
- EXTRACT(vbo, uv);
- EXTRACT(vbo, tan);
- EXTRACT(vbo, vcol);
- EXTRACT(vbo, orco);
- EXTRACT(vbo, edge_fac);
- EXTRACT(vbo, weights);
- EXTRACT(vbo, edit_data);
- EXTRACT(vbo, edituv_data);
- EXTRACT(vbo, stretch_area);
- EXTRACT(vbo, stretch_angle);
- EXTRACT(vbo, mesh_analysis);
- EXTRACT(vbo, fdots_pos);
- EXTRACT(vbo, fdots_nor);
- EXTRACT(vbo, fdots_uv);
- EXTRACT(vbo, fdots_edituv_data);
- EXTRACT(vbo, poly_idx);
- EXTRACT(vbo, edge_idx);
- EXTRACT(vbo, vert_idx);
- EXTRACT(vbo, fdot_idx);
- EXTRACT(vbo, skin_roots);
-
- EXTRACT(ibo, tris);
- if (mbc.ibo.lines) {
- /* When `lines` and `lines_loose` are requested, schedule lines extraction that also creates
- * the `lines_loose` sub-buffer. */
- const MeshExtract *lines_extractor = do_lines_loose_subbuffer ?
- &extract_lines_with_lines_loose :
- &extract_lines;
- extract_task_create(task_graph,
- task_node_mesh_render_data,
- task_node_user_data_init,
- &single_threaded_task_data->task_datas,
- &user_data_init_task_data->task_datas,
- scene,
- mr,
- lines_extractor,
- mbc.ibo.lines,
- &task_counters[counter_used++]);
}
- else {
- if (do_lines_loose_subbuffer) {
- ExtractTaskData *taskdata = extract_task_data_create_lines_loose(mr);
- BLI_addtail(&single_threaded_task_data->task_datas, taskdata);
+
+ BUFFER_ID_BLOCK;
+
+ /* Hanle lines separately. */
+ if (mbc.ibo.lines) {
+ extract_task_create(task_graph,
+ task_node_mesh_render_data,
+ task_node_user_data_init,
+ &single_threaded_task_data->task_datas,
+ &user_data_init_task_data->task_datas,
+ scene,
+ mr,
+ &extract_lines,
+ mbc.ibo.lines,
+ &task_counters[counter_used++]);
+ }
+ else {
+ if (do_lines_loose_subbuffer) {
+ ExtractTaskData *taskdata = extract_task_data_create_lines_loose(mr);
+ BLI_addtail(&single_threaded_task_data->task_datas, taskdata);
+ }
}
- }
- EXTRACT(ibo, points);
- EXTRACT(ibo, fdots);
- EXTRACT(ibo, lines_paint_mask);
- EXTRACT(ibo, lines_adjacency);
- EXTRACT(ibo, edituv_tris);
- EXTRACT(ibo, edituv_lines);
- EXTRACT(ibo, edituv_points);
- EXTRACT(ibo, edituv_fdots);
-
- /* Only create the edge when there is user data that needs to be initialized.
- * The task is still part of the graph so the task_data will be freed when the graph is freed.
- */
- if (!BLI_listbase_is_empty(&user_data_init_task_data->task_datas)) {
- BLI_task_graph_edge_create(task_node_mesh_render_data, task_node_user_data_init);
- }
- if (!BLI_listbase_is_empty(&single_threaded_task_data->task_datas)) {
- struct TaskNode *task_node = extract_single_threaded_task_node_create(
- task_graph, single_threaded_task_data);
- BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
- }
- else {
- extract_single_threaded_task_data_free(single_threaded_task_data);
- }
+ /* Only create the edge when there is user data that needs to be initialized.
+ * The task is still part of the graph so the task_data will be freed when the graph is freed.
+ */
+ if (!BLI_listbase_is_empty(&user_data_init_task_data->task_datas)) {
+ BLI_task_graph_edge_create(task_node_mesh_render_data, task_node_user_data_init);
+ }
- /* Trigger the sub-graph for this mesh. */
- BLI_task_graph_node_push_work(task_node_mesh_render_data);
+ if (!BLI_listbase_is_empty(&single_threaded_task_data->task_datas)) {
+ struct TaskNode *task_node = extract_single_threaded_task_node_create(
+ task_graph, single_threaded_task_data);
+ BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
+ }
+ else {
+ extract_single_threaded_task_data_free(single_threaded_task_data);
+ }
+
+ /* Trigger the sub-graph for this mesh. */
+ BLI_task_graph_node_push_work(task_node_mesh_render_data);
+
+#undef BUFFER_APPLY
+ }
-#undef EXTRACT
+#undef BUFFER_ID_BLOCK
#ifdef DEBUG_TIME
BLI_task_graph_work_and_wait(task_graph);

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from Experemental patch to optimize single threaded edit-mesh conversion (approx ~20% speedup) to Experemental patch to optimize single threaded edit-mesh conversion.Sun, Jun 28, 2:44 PM
Campbell Barton (campbellbarton) changed the title of this paste from Experemental patch to optimize single threaded edit-mesh conversion to Experimental patch to optimize single threaded edit-mesh conversion.Mon, Jun 29, 4:40 AM
Campbell Barton (campbellbarton) edited the content of this paste. (Show Details)
Campbell Barton (campbellbarton) edited the content of this paste. (Show Details)