diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2021-01-05 22:23:25 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2021-01-05 22:23:41 +0300 |
commit | 2ed605520959eca9c0ab3c497c85578e138936b4 (patch) | |
tree | 14844c62b2976b9d5d857866b282de65cd468b37 /source/blender/blenkernel/intern/pbvh.c | |
parent | c20e4827144d26e4260f817512e60531fb61c8d2 (diff) |
Fix T79146: Sculpt Mode lags until the entire mesh is visible
This was caused when the BKE_pbvh_draw_cb function was used with
update_only_visible set to false. In that case, all nodes with the flag
were updating, but the update flag was only cleared for visible nodes.
This was causing constant updates per redraw in no visible nodes until
they enter the view frustum and their flag was cleared.
In order to fix this and prevent it from happening again:
- Updating the buffers, flushing the updates and clearing the flags are
now part of the same function. It does not make sense to do these in
separate places.
- The BKE_pbvh_draw_cb function was refactored so the
pbvh_update_draw_buffers is only called once. It should now be easier to
understand what the function does when it is used to update only visible
nodes or all nodes.
Reviewed By: mont29
Maniphest Tasks: T79146
Differential Revision: https://developer.blender.org/D9935
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh.c')
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 47d2ae8e283..8a98780d918 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1365,6 +1365,17 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); BLI_task_parallel_range(0, totnode, &data, pbvh_update_draw_buffer_cb, &settings); + + for (int i = 0; i < totnode; i++) { + PBVHNode *node = nodes[i]; + + if (node->flag & PBVH_UpdateDrawBuffers) { + /* Flush buffers uses OpenGL, so not in parallel. */ + GPU_pbvh_buffers_update_flush(node->draw_buffers); + } + + node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers); + } } static int pbvh_flush_bb(PBVH *pbvh, PBVHNode *node, int flag) @@ -2704,49 +2715,35 @@ void BKE_pbvh_draw_cb(PBVH *pbvh, { PBVHNode **nodes; int totnode; + int update_flag = 0; - const int update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers; - - if (!update_only_visible) { - /* Update all draw buffers, also those outside the view. */ - BKE_pbvh_search_gather( - pbvh, update_search_cb, POINTER_FROM_INT(update_flag), &nodes, &totnode); - - if (totnode) { - pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag); - } - - MEM_SAFE_FREE(nodes); + /* Search for nodes that need updates. */ + if (update_only_visible) { + /* Get visible nodes with draw updates. */ + PBVHDrawSearchData data = {.frustum = update_frustum, .accum_update_flag = 0}; + BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode); + update_flag = data.accum_update_flag; } - - /* Gather visible nodes. */ - PBVHDrawSearchData data = {.frustum = update_frustum, .accum_update_flag = 0}; - BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode); - - if (update_only_visible && (data.accum_update_flag & update_flag)) { - /* Update draw buffers in visible nodes. */ - pbvh_update_draw_buffers(pbvh, nodes, totnode, data.accum_update_flag); + else { + /* Get all nodes with draw updates, also those outside the view. */ + const int search_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers; + BKE_pbvh_search_gather( + pbvh, update_search_cb, POINTER_FROM_INT(search_flag), &nodes, &totnode); + update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers; } - /* Draw. */ - for (int a = 0; a < totnode; a++) { - PBVHNode *node = nodes[a]; - - if (node->flag & PBVH_UpdateDrawBuffers) { - /* Flush buffers uses OpenGL, so not in parallel. */ - GPU_pbvh_buffers_update_flush(node->draw_buffers); - } - - node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers); + /* Update draw buffers. */ + if (totnode != 0 && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) { + pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag); } - MEM_SAFE_FREE(nodes); + /* Draw visible nodes. */ PBVHDrawSearchData draw_data = {.frustum = draw_frustum, .accum_update_flag = 0}; BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &draw_data, &nodes, &totnode); - for (int a = 0; a < totnode; a++) { - PBVHNode *node = nodes[a]; + for (int i = 0; i < totnode; i++) { + PBVHNode *node = nodes[i]; if (!(node->flag & PBVH_FullyHidden)) { draw_fn(user_data, node->draw_buffers); } |