diff options
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract.h | 17 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract_mesh.c | 140 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 36 |
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, |