[Bf-blender-cvs] [624994caa25] master: Fix T77496: Bones Custom Shapes Wires not drawn

Jeroen Bakker noreply at git.blender.org
Mon Jun 15 16:48:03 CEST 2020


Commit: 624994caa2544823a1c89a868e9bf6760f525269
Author: Jeroen Bakker
Date:   Mon Jun 15 16:46:56 2020 +0200
Branches: master
https://developer.blender.org/rB624994caa2544823a1c89a868e9bf6760f525269

Fix T77496: Bones Custom Shapes Wires not drawn

Lines loose extraction cannot happen on the fly as the render data isn't
complete. This patch will do the lines loose subbuffer extraction as a
simple task and not on the fly.

This patch introduces 2 sub-types of tasks that are executed single threaded.
`EXTRACT_MESH_EXTRACT` would do the extraction using Mesh/BMesh geometry.
`EXTRACT_LINES_LOOSE` creates the `lines_loose` subbuffer from already cached
`lines` IBO.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7964

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

M	source/blender/draw/intern/draw_cache_extract_mesh.c

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

diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 6013bdb2883..f3dc8f0fd2a 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -4558,10 +4558,16 @@ typedef struct ExtractUserData {
   void *user_data;
 } ExtractUserData;
 
+typedef enum ExtractTaskDataType {
+  EXTRACT_MESH_EXTRACT,
+  EXTRACT_LINES_LOOSE,
+} ExtractTaskDataType;
+
 typedef struct ExtractTaskData {
   void *next, *prev;
   const MeshRenderData *mr;
   const MeshExtract *extract;
+  ExtractTaskDataType tasktype;
   eMRIterType iter_type;
   int start, end;
   /** Decremented each time a task is finished. */
@@ -4570,6 +4576,41 @@ typedef struct ExtractTaskData {
   ExtractUserData *user_data;
 } ExtractTaskData;
 
+static ExtractTaskData *extract_task_data_create_mesh_extract(const MeshRenderData *mr,
+                                                              const MeshExtract *extract,
+                                                              void *buf,
+                                                              int32_t *task_counter)
+{
+  ExtractTaskData *taskdata = MEM_mallocN(sizeof(*taskdata), __func__);
+  taskdata->next = NULL;
+  taskdata->prev = NULL;
+  taskdata->tasktype = EXTRACT_MESH_EXTRACT;
+  taskdata->mr = mr;
+  taskdata->extract = extract;
+  taskdata->buf = buf;
+
+  /* ExtractUserData is shared between the iterations as it holds counters to detect if the
+   * extraction is finished. To make sure the duplication of the userdata does not create a new
+   * instance of the counters we allocate the userdata in its own container.
+   *
+   * This structure makes sure that when extract_init is called, that the user data of all
+   * iterations are updated. */
+  taskdata->user_data = MEM_callocN(sizeof(ExtractUserData), __func__);
+  taskdata->iter_type = mesh_extract_iter_type(extract);
+  taskdata->task_counter = task_counter;
+  taskdata->start = 0;
+  taskdata->end = INT_MAX;
+  return taskdata;
+}
+
+static ExtractTaskData *extract_task_data_create_lines_loose(const MeshRenderData *mr)
+{
+  ExtractTaskData *taskdata = MEM_callocN(sizeof(*taskdata), __func__);
+  taskdata->tasktype = EXTRACT_LINES_LOOSE;
+  taskdata->mr = mr;
+  return taskdata;
+}
+
 static void extract_task_data_free(void *data)
 {
   ExtractTaskData *task_data = data;
@@ -4655,23 +4696,30 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
 
 static void extract_init(ExtractTaskData *data)
 {
-  data->user_data->user_data = data->extract->init(data->mr, data->buf);
+  if (data->tasktype == EXTRACT_MESH_EXTRACT) {
+    data->user_data->user_data = data->extract->init(data->mr, data->buf);
+  }
 }
 
 static void extract_run(void *__restrict taskdata)
 {
   ExtractTaskData *data = (ExtractTaskData *)taskdata;
-  mesh_extract_iter(data->mr,
-                    data->iter_type,
-                    data->start,
-                    data->end,
-                    data->extract,
-                    data->user_data->user_data);
-
-  /* If this is the last task, we do the finish function. */
-  int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1);
-  if (remainin_tasks == 0 && data->extract->finish != NULL) {
-    data->extract->finish(data->mr, data->buf, data->user_data->user_data);
+  if (data->tasktype == EXTRACT_MESH_EXTRACT) {
+    mesh_extract_iter(data->mr,
+                      data->iter_type,
+                      data->start,
+                      data->end,
+                      data->extract,
+                      data->user_data->user_data);
+
+    /* If this is the last task, we do the finish function. */
+    int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1);
+    if (remainin_tasks == 0 && data->extract->finish != NULL) {
+      data->extract->finish(data->mr, data->buf, data->user_data->user_data);
+    }
+  }
+  else if (data->tasktype == EXTRACT_LINES_LOOSE) {
+    extract_lines_loose_subbuffer(data->mr);
   }
 }
 
@@ -4695,7 +4743,8 @@ typedef struct MeshRenderDataUpdateTaskData {
 static void mesh_render_data_update_task_data_free(MeshRenderDataUpdateTaskData *taskdata)
 {
   BLI_assert(taskdata);
-  mesh_render_data_free(taskdata->mr);
+  MeshRenderData *mr = taskdata->mr;
+  mesh_render_data_free(mr);
   MEM_freeN(taskdata);
 }
 
@@ -4851,24 +4900,8 @@ static void extract_task_create(struct TaskGraph *task_graph,
   }
 
   /* Divide extraction of the VBO/IBO into sensible chunks of works. */
-  ExtractTaskData *taskdata = MEM_mallocN(sizeof(*taskdata), "ExtractTaskData");
-  taskdata->next = NULL;
-  taskdata->prev = NULL;
-  taskdata->mr = mr;
-  taskdata->extract = extract;
-  taskdata->buf = buf;
-
-  /* ExtractUserData is shared between the iterations as it holds counters to detect if the
-   * extraction is finished. To make sure the duplication of the userdata does not create a new
-   * instance of the counters we allocate the userdata in its own container.
-   *
-   * This structure makes sure that when extract_init is called, that the user data of all
-   * iterations are updated. */
-  taskdata->user_data = MEM_callocN(sizeof(ExtractUserData), __func__);
-  taskdata->iter_type = mesh_extract_iter_type(extract);
-  taskdata->task_counter = task_counter;
-  taskdata->start = 0;
-  taskdata->end = INT_MAX;
+  ExtractTaskData *taskdata = extract_task_data_create_mesh_extract(
+      mr, extract, buf, task_counter);
 
   /* Simple heuristic. */
   const int chunk_size = 8192;
@@ -5009,6 +5042,10 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
   TEST_ASSIGN(IBO, ibo, edituv_points);
   TEST_ASSIGN(IBO, ibo, edituv_fdots);
 
+  if (do_lines_loose_subbuffer) {
+    iter_flag |= MR_ITER_LEDGE;
+  }
+
 #undef TEST_ASSIGN
 
 #ifdef DEBUG_TIME
@@ -5106,12 +5143,8 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
   }
   else {
     if (do_lines_loose_subbuffer) {
-      /* When `lines_loose` is requested without `lines` we can create the sub-buffer on the fly as
-       * the `lines` buffer should then already be up-to-date.
-       * (see `DRW_batch_requested(cache->batch.loose_edges, GPU_PRIM_LINES)` in
-       * `DRW_mesh_batch_cache_create_requested`).
-       */
-      extract_lines_loose_subbuffer(mr);
+      ExtractTaskData *taskdata = extract_task_data_create_lines_loose(mr);
+      BLI_addtail(&single_threaded_task_data->task_datas, taskdata);
     }
   }
   EXTRACT(ibo, points);



More information about the Bf-blender-cvs mailing list