[Bf-blender-cvs] [2ed60552095] master: Fix T79146: Sculpt Mode lags until the entire mesh is visible

Pablo Dobarro noreply at git.blender.org
Tue Jan 5 21:02:53 CET 2021


Commit: 2ed605520959eca9c0ab3c497c85578e138936b4
Author: Pablo Dobarro
Date:   Tue Jan 5 20:23:25 2021 +0100
Branches: master
https://developer.blender.org/rB2ed605520959eca9c0ab3c497c85578e138936b4

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

===================================================================

M	source/blender/blenkernel/intern/pbvh.c

===================================================================

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);
     }



More information about the Bf-blender-cvs mailing list