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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h17
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c140
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c36
3 files changed, 121 insertions, 72 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index a3e43ff2ec5..14cbba82fba 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -150,6 +150,18 @@ typedef struct MeshBufferCache {
GPUIndexBuf **tris_per_mat;
} MeshBufferCache;
+/**
+ * Data that are kept around between extractions to reduce rebuilding time.
+ *
+ * - Loose geometry.
+ */
+typedef struct MeshBufferExtractionCache {
+ int edge_loose_len;
+ int vert_loose_len;
+ int *lverts;
+ int *ledges;
+} MeshBufferExtractionCache;
+
typedef enum DRWBatchFlag {
MBC_SURFACE = (1 << 0),
MBC_SURFACE_WEIGHTS = (1 << 1),
@@ -195,6 +207,10 @@ typedef enum DRWBatchFlag {
typedef struct MeshBatchCache {
MeshBufferCache final, cage, uv_cage;
+ MeshBufferExtractionCache final_extraction_cache;
+ MeshBufferExtractionCache cage_extraction_cache;
+ MeshBufferExtractionCache uv_cage_extraction_cache;
+
struct {
/* Surfaces / Render */
GPUBatch *surface;
@@ -271,6 +287,7 @@ typedef struct MeshBatchCache {
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,
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index fe162e6ea6d..62d8040e88b 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -134,79 +134,85 @@ typedef struct MeshRenderData {
int *lverts, *ledges;
} MeshRenderData;
-static void mesh_render_data_update_loose_geom(MeshRenderData *mr,
- const eMRIterType iter_type,
- const eMRDataType UNUSED(data_flag))
+static void mesh_render_data_loose_geom_load(MeshRenderData *mr, MeshBufferExtractionCache *cache)
{
+ mr->ledges = cache->ledges;
+ mr->lverts = cache->lverts;
+ mr->vert_loose_len = cache->vert_loose_len;
+ mr->edge_loose_len = cache->edge_loose_len;
+
+ mr->loop_loose_len = mr->vert_loose_len + (mr->edge_loose_len * 2);
+}
+
+static void mesh_render_data_loose_geom_ensure(const MeshRenderData *mr,
+ MeshBufferExtractionCache *cache)
+{
+ /* Early exit: Are loose geometry already available. Only checking for loose verts as loose edges
+ * and verts are calculated at the same time.*/
+ if (cache->lverts) {
+ return;
+ }
+
+ cache->vert_loose_len = 0;
+ cache->edge_loose_len = 0;
+
if (mr->extract_type != MR_EXTRACT_BMESH) {
/* Mesh */
- if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
- mr->vert_loose_len = 0;
- mr->edge_loose_len = 0;
- BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, __func__);
+ BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, __func__);
- mr->ledges = MEM_mallocN(mr->edge_len * sizeof(int), __func__);
- const MEdge *med = mr->medge;
- for (int med_index = 0; med_index < mr->edge_len; med_index++, med++) {
- if (med->flag & ME_LOOSEEDGE) {
- mr->ledges[mr->edge_loose_len++] = med_index;
- }
- /* Tag verts as not loose. */
- BLI_BITMAP_ENABLE(lvert_map, med->v1);
- BLI_BITMAP_ENABLE(lvert_map, med->v2);
- }
- if (mr->edge_loose_len < mr->edge_len) {
- mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
+ cache->ledges = MEM_mallocN(mr->edge_len * sizeof(*cache->ledges), __func__);
+ const MEdge *med = mr->medge;
+ for (int med_index = 0; med_index < mr->edge_len; med_index++, med++) {
+ if (med->flag & ME_LOOSEEDGE) {
+ cache->ledges[cache->edge_loose_len++] = med_index;
}
+ /* Tag verts as not loose. */
+ BLI_BITMAP_ENABLE(lvert_map, med->v1);
+ BLI_BITMAP_ENABLE(lvert_map, med->v2);
+ }
+ if (cache->edge_loose_len < mr->edge_len) {
+ cache->ledges = MEM_reallocN(cache->ledges, cache->edge_loose_len * sizeof(*cache->ledges));
+ }
- mr->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
- for (int v = 0; v < mr->vert_len; v++) {
- if (!BLI_BITMAP_TEST(lvert_map, v)) {
- mr->lverts[mr->vert_loose_len++] = v;
- }
+ cache->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
+ for (int v = 0; v < mr->vert_len; v++) {
+ if (!BLI_BITMAP_TEST(lvert_map, v)) {
+ cache->lverts[cache->vert_loose_len++] = v;
}
- if (mr->vert_loose_len < mr->vert_len) {
- mr->lverts = MEM_reallocN(mr->lverts, mr->vert_loose_len * sizeof(*mr->lverts));
- }
-
- MEM_freeN(lvert_map);
-
- mr->loop_loose_len = mr->vert_loose_len + (mr->edge_loose_len * 2);
}
+ if (cache->vert_loose_len < mr->vert_len) {
+ cache->lverts = MEM_reallocN(cache->lverts, cache->vert_loose_len * sizeof(*cache->lverts));
+ }
+
+ MEM_freeN(lvert_map);
}
else {
/* #BMesh */
BMesh *bm = mr->bm;
- if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
- int elem_id;
- BMIter iter;
- BMVert *eve;
- BMEdge *ede;
- mr->vert_loose_len = 0;
- mr->edge_loose_len = 0;
-
- mr->lverts = MEM_mallocN(mr->vert_len * sizeof(*mr->lverts), __func__);
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, elem_id) {
- if (eve->e == NULL) {
- mr->lverts[mr->vert_loose_len++] = elem_id;
- }
- }
- if (mr->vert_loose_len < mr->vert_len) {
- mr->lverts = MEM_reallocN(mr->lverts, mr->vert_loose_len * sizeof(*mr->lverts));
- }
+ int elem_id;
+ BMIter iter;
+ BMVert *eve;
+ BMEdge *ede;
- mr->ledges = MEM_mallocN(mr->edge_len * sizeof(*mr->ledges), __func__);
- BM_ITER_MESH_INDEX (ede, &iter, bm, BM_EDGES_OF_MESH, elem_id) {
- if (ede->l == NULL) {
- mr->ledges[mr->edge_loose_len++] = elem_id;
- }
- }
- if (mr->edge_loose_len < mr->edge_len) {
- mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges));
+ cache->lverts = MEM_mallocN(mr->vert_len * sizeof(*cache->lverts), __func__);
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, elem_id) {
+ if (eve->e == NULL) {
+ cache->lverts[cache->vert_loose_len++] = elem_id;
}
+ }
+ if (cache->vert_loose_len < mr->vert_len) {
+ cache->lverts = MEM_reallocN(cache->lverts, cache->vert_loose_len * sizeof(*cache->lverts));
+ }
- mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
+ cache->ledges = MEM_mallocN(mr->edge_len * sizeof(*cache->ledges), __func__);
+ BM_ITER_MESH_INDEX (ede, &iter, bm, BM_EDGES_OF_MESH, elem_id) {
+ if (ede->l == NULL) {
+ cache->ledges[cache->edge_loose_len++] = elem_id;
+ }
+ }
+ if (cache->edge_loose_len < mr->edge_len) {
+ cache->ledges = MEM_reallocN(cache->ledges, cache->edge_loose_len * sizeof(*cache->ledges));
}
}
}
@@ -317,6 +323,7 @@ static void mesh_render_data_update_normals(MeshRenderData *mr,
* otherwise don't use modifiers as they are not from this object.
*/
static MeshRenderData *mesh_render_data_create(Mesh *me,
+ MeshBufferExtractionCache *cache,
const bool is_editmode,
const bool is_paint_mode,
const bool is_mode_active,
@@ -325,8 +332,7 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
const bool do_uvedit,
const DRW_MeshCDMask *UNUSED(cd_used),
const ToolSettings *ts,
- const eMRIterType iter_type,
- const eMRDataType data_flag)
+ const eMRIterType iter_type)
{
MeshRenderData *mr = MEM_callocN(sizeof(*mr), __func__);
mr->toolsettings = ts;
@@ -435,7 +441,11 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
mr->poly_len = bm->totface;
mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
}
- mesh_render_data_update_loose_geom(mr, iter_type, data_flag);
+
+ if (iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) {
+ mesh_render_data_loose_geom_ensure(mr, cache);
+ mesh_render_data_loose_geom_load(mr, cache);
+ }
return mr;
}
@@ -446,8 +456,9 @@ static void mesh_render_data_free(MeshRenderData *mr)
MEM_SAFE_FREE(mr->poly_normals);
MEM_SAFE_FREE(mr->loop_normals);
- MEM_SAFE_FREE(mr->lverts);
- MEM_SAFE_FREE(mr->ledges);
+ /* Loose geometry are owned by MeshBufferExtractionCache. */
+ mr->ledges = NULL;
+ mr->lverts = NULL;
MEM_freeN(mr);
}
@@ -5908,6 +5919,7 @@ static void extract_task_create(struct TaskGraph *task_graph,
void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
MeshBatchCache *cache,
MeshBufferCache mbc,
+ MeshBufferExtractionCache *extraction_cache,
Mesh *me,
const bool is_editmode,
@@ -6017,6 +6029,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
#endif
MeshRenderData *mr = mesh_render_data_create(me,
+ extraction_cache,
is_editmode,
is_paint_mode,
is_mode_active,
@@ -6025,8 +6038,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
do_uvedit,
cd_layer_used,
ts,
- iter_flag,
- data_flag);
+ iter_flag);
mr->use_hide = use_hide;
mr->use_subsurf_fdots = use_subsurf_fdots;
mr->use_final_mesh = do_final;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 8d5fdcc5276..c2dc9b3ad8d 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -707,6 +707,26 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
}
}
+static void mesh_buffer_cache_clear(MeshBufferCache *mbufcache)
+{
+ GPUVertBuf **vbos = (GPUVertBuf **)&mbufcache->vbo;
+ GPUIndexBuf **ibos = (GPUIndexBuf **)&mbufcache->ibo;
+ for (int i = 0; i < sizeof(mbufcache->vbo) / sizeof(void *); i++) {
+ GPU_VERTBUF_DISCARD_SAFE(vbos[i]);
+ }
+ for (int i = 0; i < sizeof(mbufcache->ibo) / sizeof(void *); i++) {
+ GPU_INDEXBUF_DISCARD_SAFE(ibos[i]);
+ }
+}
+
+static void mesh_buffer_extraction_cache_clear(MeshBufferExtractionCache *extraction_cache)
+{
+ MEM_SAFE_FREE(extraction_cache->lverts);
+ MEM_SAFE_FREE(extraction_cache->ledges);
+ extraction_cache->edge_loose_len = 0;
+ extraction_cache->vert_loose_len = 0;
+}
+
static void mesh_batch_cache_clear(Mesh *me)
{
MeshBatchCache *cache = me->runtime.batch_cache;
@@ -714,16 +734,13 @@ static void mesh_batch_cache_clear(Mesh *me)
return;
}
FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
- GPUVertBuf **vbos = (GPUVertBuf **)&mbufcache->vbo;
- GPUIndexBuf **ibos = (GPUIndexBuf **)&mbufcache->ibo;
- for (int i = 0; i < sizeof(mbufcache->vbo) / sizeof(void *); i++) {
- GPU_VERTBUF_DISCARD_SAFE(vbos[i]);
- }
- for (int i = 0; i < sizeof(mbufcache->ibo) / sizeof(void *); i++) {
- GPU_INDEXBUF_DISCARD_SAFE(ibos[i]);
- }
+ mesh_buffer_cache_clear(mbufcache);
}
+ mesh_buffer_extraction_cache_clear(&cache->final_extraction_cache);
+ mesh_buffer_extraction_cache_clear(&cache->cage_extraction_cache);
+ mesh_buffer_extraction_cache_clear(&cache->uv_cage_extraction_cache);
+
for (int i = 0; i < cache->mat_len; i++) {
GPU_INDEXBUF_DISCARD_SAFE(cache->final.tris_per_mat[i]);
}
@@ -1543,6 +1560,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
mesh_buffer_cache_create_requested(task_graph,
cache,
cache->uv_cage,
+ &cache->uv_cage_extraction_cache,
me,
is_editmode,
is_paint_mode,
@@ -1561,6 +1579,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
mesh_buffer_cache_create_requested(task_graph,
cache,
cache->cage,
+ &cache->cage_extraction_cache,
me,
is_editmode,
is_paint_mode,
@@ -1578,6 +1597,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
mesh_buffer_cache_create_requested(task_graph,
cache,
cache->final,
+ &cache->final_extraction_cache,
me,
is_editmode,
is_paint_mode,