From bfb4dcaa1a7ec5bfd2b25cf7aa5b6173d6c53358 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 27 Apr 2022 13:03:49 -0700 Subject: Fix T97235: PBVH draw cache invalidation bug The PBVH draw cache wasn't being invalidated in all cases. It is now invalidated whenever a PBVH node's draw buffers are freed. --- source/blender/blenkernel/BKE_pbvh.h | 1 + source/blender/blenkernel/intern/pbvh.c | 21 +++++++++++++++++++-- source/blender/blenkernel/intern/pbvh_bmesh.c | 3 +-- source/blender/blenkernel/intern/pbvh_intern.h | 4 ++++ source/blender/draw/intern/draw_cache_impl_mesh.c | 5 +++++ source/tools | 2 +- 6 files changed, 31 insertions(+), 5 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 978e52d8003..291b9b6b778 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -584,6 +584,7 @@ void BKE_pbvh_vertex_color_set(PBVH *pbvh, int vertex, const float color[4]); void BKE_pbvh_vertex_color_get(const PBVH *pbvh, int vertex, float r_color[4]); void BKE_pbvh_ensure_node_loops(PBVH *pbvh); +bool BKE_pbvh_draw_cache_invalid(const PBVH *pbvh); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 1fb1570b3ff..e1ab4ccfb0a 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -656,6 +656,7 @@ PBVH *BKE_pbvh_new(void) { PBVH *pbvh = MEM_callocN(sizeof(PBVH), "pbvh"); pbvh->respect_hide = true; + pbvh->draw_cache_invalid = true; return pbvh; } @@ -1368,6 +1369,16 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, } } +void pbvh_free_draw_buffers(PBVH *pbvh, PBVHNode *node) +{ + if (node->draw_buffers) { + pbvh->draw_cache_invalid = true; + + GPU_pbvh_buffers_free(node->draw_buffers); + node->draw_buffers = NULL; + } +} + static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag) { if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->type, PBVH_GRIDS, PBVH_BMESH)) { @@ -1375,8 +1386,7 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, for (int n = 0; n < totnode; n++) { PBVHNode *node = nodes[n]; if (node->flag & PBVH_RebuildDrawBuffers) { - GPU_pbvh_buffers_free(node->draw_buffers); - node->draw_buffers = NULL; + pbvh_free_draw_buffers(pbvh, node); } else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_buffers) { if (pbvh->type == PBVH_GRIDS) { @@ -2779,6 +2789,8 @@ void BKE_pbvh_draw_cb(PBVH *pbvh, int totnode; int update_flag = 0; + pbvh->draw_cache_invalid = false; + /* Search for nodes that need updates. */ if (update_only_visible) { /* Get visible nodes with draw updates. */ @@ -3217,3 +3229,8 @@ void BKE_pbvh_ensure_node_loops(PBVH *pbvh) MEM_SAFE_FREE(visit); } + +bool BKE_pbvh_draw_cache_invalid(const PBVH *pbvh) +{ + return pbvh->draw_cache_invalid; +} diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index 55d76938ad3..d4c6dcfbc96 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -348,8 +348,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind n->layer_disp = NULL; if (n->draw_buffers) { - GPU_pbvh_buffers_free(n->draw_buffers); - n->draw_buffers = NULL; + pbvh_free_draw_buffers(pbvh, n); } n->flag &= ~PBVH_Leaf; diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index b7a2b578a1c..b5480673653 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -196,6 +196,9 @@ struct PBVH { AttributeDomain color_domain; bool is_drawing; + + /* Used by DynTopo to invalidate the draw cache. */ + bool draw_cache_invalid; }; /* pbvh.c */ @@ -270,6 +273,7 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode); void pbvh_pixels_free(PBVHNode *node); void pbvh_pixels_free_brush_test(PBVHNode *node); +void pbvh_free_draw_buffers(PBVH *pbvh, PBVHNode *node); #ifdef __cplusplus } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index e4aec17eb69..917216b92e6 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -883,6 +883,11 @@ static bool mesh_batch_cache_valid(Object *object, Mesh *me) if (cache->pbvh_is_drawing != BKE_pbvh_is_drawing(object->sculpt->pbvh)) { return false; } + + if (BKE_pbvh_is_drawing(object->sculpt->pbvh) && + BKE_pbvh_draw_cache_invalid(object->sculpt->pbvh)) { + return false; + } } if (cache->is_editmode != (me->edit_mesh != NULL)) { diff --git a/source/tools b/source/tools index 50c27746f2a..284f78b77d1 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 50c27746f2a7c86ab4a0cfa8899b292af5dd07b6 +Subproject commit 284f78b77d137687bc7bed17c945ef651721cccf -- cgit v1.2.3