Blender V4.3
draw_cache_extract_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "MEM_guardedalloc.h"
11
12#include "DNA_mesh_types.h"
13#include "DNA_scene_types.h"
14
15#include "BLI_array.hh"
16#include "BLI_task.h"
17#include "BLI_vector.hh"
18
19#include "BKE_editmesh.hh"
20#include "BKE_object.hh"
21
22#include "GPU_capabilities.hh"
23
24#include "draw_cache_extract.hh"
25#include "draw_cache_inline.hh"
26#include "draw_subdivision.hh"
27
29
30// #define DEBUG_TIME
31
32#ifdef DEBUG_TIME
33# include "BLI_time_utildefines.h"
34#endif
35
36namespace blender::draw {
37
38int mesh_render_mat_len_get(const Object &object, const Mesh &mesh)
39{
40 if (mesh.runtime->edit_mesh != nullptr) {
41 const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(&object);
42 if (editmesh_eval_final != nullptr) {
43 return std::max<int>(1, editmesh_eval_final->totcol);
44 }
45 }
46 return std::max<int>(1, mesh.totcol);
47}
48
50 std::unique_ptr<MeshRenderData> mr;
52};
53
54static void mesh_extract_render_data_node_exec(void *__restrict task_data)
55{
56 auto *update_task_data = static_cast<MeshRenderDataUpdateTaskData *>(task_data);
57 MeshRenderData &mr = *update_task_data->mr;
58 MeshBufferList &buffers = update_task_data->cache.buff;
59
60 const bool request_face_normals = DRW_vbo_requested(buffers.vbo.nor) ||
61 DRW_vbo_requested(buffers.vbo.fdots_nor) ||
62 DRW_vbo_requested(buffers.vbo.edge_fac) ||
63 DRW_vbo_requested(buffers.vbo.mesh_analysis);
64 const bool request_corner_normals = DRW_vbo_requested(buffers.vbo.nor);
65 const bool force_corner_normals = DRW_vbo_requested(buffers.vbo.tan);
66
67 if (request_face_normals) {
69 }
70 if ((request_corner_normals && !mr.use_simplify_normals) || force_corner_normals) {
72 }
73
74 const bool calc_loose_geom = DRW_ibo_requested(buffers.ibo.lines) ||
75 DRW_ibo_requested(buffers.ibo.lines_loose) ||
76 DRW_ibo_requested(buffers.ibo.points) ||
77 DRW_vbo_requested(buffers.vbo.pos) ||
78 DRW_vbo_requested(buffers.vbo.edit_data) ||
79 DRW_vbo_requested(buffers.vbo.vnor) ||
80 DRW_vbo_requested(buffers.vbo.vert_idx) ||
81 DRW_vbo_requested(buffers.vbo.edge_idx) ||
82 DRW_vbo_requested(buffers.vbo.edge_fac);
83
84 if (calc_loose_geom) {
85 mesh_render_data_update_loose_geom(mr, update_task_data->cache);
86 }
87}
88
91/* ---------------------------------------------------------------------- */
96{
97 for (const int i : IndexRange(ARRAY_SIZE(buffers.vbo.attr))) {
98 if (DRW_vbo_requested(buffers.vbo.attr[i])) {
99 return true;
100 }
101 }
102 return false;
103}
104
106 MeshBatchCache &cache,
107 MeshBufferCache &mbc,
108 Object &object,
109 Mesh &mesh,
110 const bool is_editmode,
111 const bool is_paint_mode,
112 const bool edit_mode_active,
113 const float4x4 &object_to_world,
114 const bool do_final,
115 const bool do_uvedit,
116 const Scene &scene,
117 const ToolSettings *ts,
118 const bool use_hide)
119{
120 /* For each mesh where batches needs to be updated a sub-graph will be added to the task_graph.
121 * This sub-graph starts with an extract_render_data_node. This fills/converts the required
122 * data from Mesh.
123 *
124 * Small extractions and extractions that can't be multi-threaded are grouped in a single
125 * `extract_single_threaded_task_node`.
126 *
127 * Other extractions will create a node for each loop exceeding 8192 items. these nodes are
128 * linked to the `user_data_init_task_node`. the `user_data_init_task_node` prepares the
129 * user_data needed for the extraction based on the data extracted from the mesh.
130 * counters are used to check if the finalize of a task has to be called.
131 *
132 * Mesh extraction sub graph
133 *
134 * +----------------------+
135 * +-----> | extract_task1_loop_1 |
136 * | +----------------------+
137 * +------------------+ +----------------------+ +----------------------+
138 * | mesh_render_data | --> | | --> | extract_task1_loop_2 |
139 * +------------------+ | | +----------------------+
140 * | | | +----------------------+
141 * | | user_data_init | --> | extract_task2_loop_1 |
142 * v | | +----------------------+
143 * +------------------+ | | +----------------------+
144 * | single_threaded | | | --> | extract_task2_loop_2 |
145 * +------------------+ +----------------------+ +----------------------+
146 * | +----------------------+
147 * +-----> | extract_task2_loop_3 |
148 * +----------------------+
149 */
150 const bool do_hq_normals = (scene.r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 ||
152
154 const bool attrs_requested = any_attr_requested(buffers);
155 if (!DRW_ibo_requested(buffers.ibo.lines) && !DRW_ibo_requested(buffers.ibo.lines_loose) &&
156 !DRW_ibo_requested(buffers.ibo.tris) && !DRW_ibo_requested(buffers.ibo.points) &&
157 !DRW_ibo_requested(buffers.ibo.fdots) && !DRW_vbo_requested(buffers.vbo.pos) &&
158 !DRW_vbo_requested(buffers.vbo.fdots_pos) && !DRW_vbo_requested(buffers.vbo.nor) &&
159 !DRW_vbo_requested(buffers.vbo.vnor) && !DRW_vbo_requested(buffers.vbo.fdots_nor) &&
160 !DRW_vbo_requested(buffers.vbo.edge_fac) && !DRW_vbo_requested(buffers.vbo.tan) &&
161 !DRW_vbo_requested(buffers.vbo.edit_data) && !DRW_vbo_requested(buffers.vbo.face_idx) &&
162 !DRW_vbo_requested(buffers.vbo.edge_idx) && !DRW_vbo_requested(buffers.vbo.vert_idx) &&
163 !DRW_vbo_requested(buffers.vbo.fdot_idx) && !DRW_vbo_requested(buffers.vbo.weights) &&
164 !DRW_vbo_requested(buffers.vbo.fdots_uv) &&
165 !DRW_vbo_requested(buffers.vbo.fdots_edituv_data) && !DRW_vbo_requested(buffers.vbo.uv) &&
166 !DRW_vbo_requested(buffers.vbo.edituv_stretch_area) &&
167 !DRW_vbo_requested(buffers.vbo.edituv_stretch_angle) &&
168 !DRW_vbo_requested(buffers.vbo.edituv_data) && !DRW_ibo_requested(buffers.ibo.edituv_tris) &&
169 !DRW_ibo_requested(buffers.ibo.edituv_lines) &&
170 !DRW_ibo_requested(buffers.ibo.edituv_points) &&
171 !DRW_ibo_requested(buffers.ibo.edituv_fdots) &&
172 !DRW_ibo_requested(buffers.ibo.lines_paint_mask) &&
173 !DRW_ibo_requested(buffers.ibo.lines_adjacency) &&
174 !DRW_vbo_requested(buffers.vbo.skin_roots) && !DRW_vbo_requested(buffers.vbo.sculpt_data) &&
175 !DRW_vbo_requested(buffers.vbo.orco) && !DRW_vbo_requested(buffers.vbo.mesh_analysis) &&
176 !DRW_vbo_requested(buffers.vbo.attr_viewer) && !attrs_requested)
177 {
178 return;
179 }
180
181#ifdef DEBUG_TIME
182 double rdata_start = BLI_time_now_seconds();
183#endif
184
185 std::unique_ptr<MeshRenderData> mr_ptr = mesh_render_data_create(object,
186 mesh,
187 is_editmode,
188 is_paint_mode,
189 edit_mode_active,
190 object_to_world,
191 do_final,
192 do_uvedit,
193 use_hide,
194 ts);
195 MeshRenderData *mr = mr_ptr.get();
196 mr->use_subsurf_fdots = mr->mesh && !mr->mesh->runtime->subsurf_face_dot_tags.is_empty();
197 mr->use_final_mesh = do_final;
198 mr->use_simplify_normals = (scene.r.mode & R_SIMPLIFY) && (scene.r.mode & R_SIMPLIFY_NORMALS);
199
200#ifdef DEBUG_TIME
201 double rdata_end = BLI_time_now_seconds();
202#endif
203
204 TaskNode *task_node_mesh_render_data = BLI_task_graph_node_create(
205 &task_graph,
207 new MeshRenderDataUpdateTaskData{std::move(mr_ptr), mbc},
208 [](void *task_data) { delete static_cast<MeshRenderDataUpdateTaskData *>(task_data); });
209
210 if (DRW_vbo_requested(buffers.vbo.pos)) {
211 struct TaskData {
212 MeshRenderData &mr;
213 MeshBufferCache &mbc;
214 };
216 &task_graph,
217 [](void *__restrict task_data) {
218 const TaskData &data = *static_cast<TaskData *>(task_data);
219 extract_positions(data.mr, *data.mbc.buff.vbo.pos);
220 },
221 new TaskData{*mr, mbc},
222 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
223 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
224 }
225 if (DRW_vbo_requested(buffers.vbo.fdots_pos)) {
226 struct TaskData {
227 MeshRenderData &mr;
228 MeshBufferCache &mbc;
229 };
231 &task_graph,
232 [](void *__restrict task_data) {
233 const TaskData &data = *static_cast<TaskData *>(task_data);
234 extract_face_dots_position(data.mr, *data.mbc.buff.vbo.fdots_pos);
235 },
236 new TaskData{*mr, mbc},
237 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
238 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
239 }
240 if (DRW_vbo_requested(buffers.vbo.nor)) {
241 struct TaskData {
242 MeshRenderData &mr;
243 MeshBufferCache &mbc;
244 bool do_hq_normals;
245 };
247 &task_graph,
248 [](void *__restrict task_data) {
249 const TaskData &data = *static_cast<TaskData *>(task_data);
250 extract_normals(data.mr, data.do_hq_normals, *data.mbc.buff.vbo.nor);
251 },
252 new TaskData{*mr, mbc, do_hq_normals},
253 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
254 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
255 }
256 if (DRW_vbo_requested(buffers.vbo.vnor)) {
257 struct TaskData {
258 MeshRenderData &mr;
260 };
262 &task_graph,
263 [](void *__restrict task_data) {
264 const TaskData &data = *static_cast<TaskData *>(task_data);
265 extract_vert_normals(data.mr, *data.buffers.vbo.vnor);
266 },
267 new TaskData{*mr, buffers},
268 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
269 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
270 }
271 if (DRW_vbo_requested(buffers.vbo.fdots_nor)) {
272 struct TaskData {
273 MeshRenderData &mr;
274 MeshBufferCache &mbc;
275 bool do_hq_normals;
276 };
278 &task_graph,
279 [](void *__restrict task_data) {
280 const TaskData &data = *static_cast<TaskData *>(task_data);
281 extract_face_dot_normals(data.mr, data.do_hq_normals, *data.mbc.buff.vbo.fdots_nor);
282 },
283 new TaskData{*mr, mbc, do_hq_normals},
284 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
285 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
286 }
287 if (DRW_vbo_requested(buffers.vbo.edge_fac)) {
288 struct TaskData {
289 MeshRenderData &mr;
290 MeshBufferCache &mbc;
291 };
293 &task_graph,
294 [](void *__restrict task_data) {
295 const TaskData &data = *static_cast<TaskData *>(task_data);
296 extract_edge_factor(data.mr, *data.mbc.buff.vbo.edge_fac);
297 },
298 new TaskData{*mr, mbc},
299 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
300 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
301 }
302 if (DRW_ibo_requested(buffers.ibo.tris)) {
303 struct TaskData {
304 MeshRenderData &mr;
305 MeshBufferCache &mbc;
306 MeshBatchCache &cache;
307 };
309 &task_graph,
310 [](void *__restrict task_data) {
311 const TaskData &data = *static_cast<TaskData *>(task_data);
312 const SortedFaceData &face_sorted = mesh_render_data_faces_sorted_ensure(data.mr,
313 data.mbc);
314 extract_tris(data.mr, face_sorted, data.cache, *data.mbc.buff.ibo.tris);
315 },
316 new TaskData{*mr, mbc, cache},
317 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
318 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
319 }
320 if (DRW_ibo_requested(buffers.ibo.lines) || DRW_ibo_requested(buffers.ibo.lines_loose)) {
321 struct TaskData {
322 MeshRenderData &mr;
324 MeshBatchCache &cache;
325 };
327 &task_graph,
328 [](void *__restrict task_data) {
329 const TaskData &data = *static_cast<TaskData *>(task_data);
330 extract_lines(data.mr,
331 data.buffers.ibo.lines,
332 data.buffers.ibo.lines_loose,
333 data.cache.no_loose_wire);
334 },
335 new TaskData{*mr, buffers, cache},
336 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
337 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
338 }
339 if (DRW_ibo_requested(buffers.ibo.points)) {
340 struct TaskData {
341 MeshRenderData &mr;
343 };
345 &task_graph,
346 [](void *__restrict task_data) {
347 const TaskData &data = *static_cast<TaskData *>(task_data);
348 extract_points(data.mr, *data.buffers.ibo.points);
349 },
350 new TaskData{*mr, buffers},
351 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
352 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
353 }
354 if (DRW_ibo_requested(buffers.ibo.fdots)) {
355 struct TaskData {
356 MeshRenderData &mr;
358 };
360 &task_graph,
361 [](void *__restrict task_data) {
362 const TaskData &data = *static_cast<TaskData *>(task_data);
363 extract_face_dots(data.mr, *data.buffers.ibo.fdots);
364 },
365 new TaskData{*mr, buffers},
366 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
367 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
368 }
369 if (DRW_vbo_requested(buffers.vbo.edit_data)) {
370 struct TaskData {
371 MeshRenderData &mr;
373 };
375 &task_graph,
376 [](void *__restrict task_data) {
377 const TaskData &data = *static_cast<TaskData *>(task_data);
378 extract_edit_data(data.mr, *data.buffers.vbo.edit_data);
379 },
380 new TaskData{*mr, buffers},
381 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
382 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
383 }
384 if (DRW_vbo_requested(buffers.vbo.tan)) {
385 struct TaskData {
386 MeshRenderData &mr;
388 MeshBatchCache &cache;
389 bool do_hq_normals;
390 };
392 &task_graph,
393 [](void *__restrict task_data) {
394 const TaskData &data = *static_cast<TaskData *>(task_data);
395 extract_tangents(data.mr, data.cache, data.do_hq_normals, *data.buffers.vbo.tan);
396 },
397 new TaskData{*mr, buffers, cache, do_hq_normals},
398 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
399 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
400 }
401 if (DRW_vbo_requested(buffers.vbo.face_idx) || DRW_vbo_requested(buffers.vbo.edge_idx) ||
402 DRW_vbo_requested(buffers.vbo.vert_idx) || DRW_vbo_requested(buffers.vbo.fdot_idx))
403 {
404 struct TaskData {
405 MeshRenderData &mr;
407 };
409 &task_graph,
410 [](void *__restrict task_data) {
411 const TaskData &data = *static_cast<TaskData *>(task_data);
412 if (DRW_vbo_requested(data.buffers.vbo.vert_idx)) {
413 extract_vert_index(data.mr, *data.buffers.vbo.vert_idx);
414 }
415 if (DRW_vbo_requested(data.buffers.vbo.edge_idx)) {
416 extract_edge_index(data.mr, *data.buffers.vbo.edge_idx);
417 }
418 if (DRW_vbo_requested(data.buffers.vbo.face_idx)) {
419 extract_face_index(data.mr, *data.buffers.vbo.face_idx);
420 }
421 if (DRW_vbo_requested(data.buffers.vbo.fdot_idx)) {
422 extract_face_dot_index(data.mr, *data.buffers.vbo.fdot_idx);
423 }
424 },
425 new TaskData{*mr, buffers},
426 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
427 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
428 }
429 if (DRW_vbo_requested(buffers.vbo.weights)) {
430 struct TaskData {
431 MeshRenderData &mr;
433 MeshBatchCache &cache;
434 };
436 &task_graph,
437 [](void *__restrict task_data) {
438 const TaskData &data = *static_cast<TaskData *>(task_data);
439 extract_weights(data.mr, data.cache, *data.buffers.vbo.weights);
440 },
441 new TaskData{*mr, buffers, cache},
442 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
443 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
444 }
445 if (DRW_vbo_requested(buffers.vbo.fdots_uv)) {
446 struct TaskData {
447 MeshRenderData &mr;
449 };
451 &task_graph,
452 [](void *__restrict task_data) {
453 const TaskData &data = *static_cast<TaskData *>(task_data);
454 extract_face_dots_uv(data.mr, *data.buffers.vbo.fdots_uv);
455 },
456 new TaskData{*mr, buffers},
457 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
458 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
459 }
460 if (DRW_vbo_requested(buffers.vbo.fdots_edituv_data)) {
461 struct TaskData {
462 MeshRenderData &mr;
464 };
466 &task_graph,
467 [](void *__restrict task_data) {
468 const TaskData &data = *static_cast<TaskData *>(task_data);
469 extract_face_dots_edituv_data(data.mr, *data.buffers.vbo.fdots_edituv_data);
470 },
471 new TaskData{*mr, buffers},
472 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
473 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
474 }
475 if (DRW_vbo_requested(buffers.vbo.uv)) {
476 struct TaskData {
477 MeshRenderData &mr;
479 MeshBatchCache &cache;
480 };
482 &task_graph,
483 [](void *__restrict task_data) {
484 const TaskData &data = *static_cast<TaskData *>(task_data);
485 extract_uv_maps(data.mr, data.cache, *data.buffers.vbo.uv);
486 },
487 new TaskData{*mr, buffers, cache},
488 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
489 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
490 }
491 if (DRW_vbo_requested(buffers.vbo.edituv_stretch_area)) {
492 struct TaskData {
493 MeshRenderData &mr;
495 MeshBatchCache &cache;
496 };
498 &task_graph,
499 [](void *__restrict task_data) {
500 const TaskData &data = *static_cast<TaskData *>(task_data);
502 *data.buffers.vbo.edituv_stretch_area,
503 data.cache.tot_area,
504 data.cache.tot_uv_area);
505 },
506 new TaskData{*mr, buffers, cache},
507 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
508 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
509 }
510 if (DRW_vbo_requested(buffers.vbo.edituv_stretch_angle)) {
511 struct TaskData {
512 MeshRenderData &mr;
514 };
516 &task_graph,
517 [](void *__restrict task_data) {
518 const TaskData &data = *static_cast<TaskData *>(task_data);
519 extract_edituv_stretch_angle(data.mr, *data.buffers.vbo.edituv_stretch_angle);
520 },
521 new TaskData{*mr, buffers},
522 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
523 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
524 }
525 if (DRW_vbo_requested(buffers.vbo.edituv_data)) {
526 struct TaskData {
527 MeshRenderData &mr;
529 };
531 &task_graph,
532 [](void *__restrict task_data) {
533 const TaskData &data = *static_cast<TaskData *>(task_data);
534 extract_edituv_data(data.mr, *data.buffers.vbo.edituv_data);
535 },
536 new TaskData{*mr, buffers},
537 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
538 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
539 }
540 if (DRW_ibo_requested(buffers.ibo.edituv_tris)) {
541 struct TaskData {
542 MeshRenderData &mr;
544 };
546 &task_graph,
547 [](void *__restrict task_data) {
548 const TaskData &data = *static_cast<TaskData *>(task_data);
549 extract_edituv_tris(data.mr, *data.buffers.ibo.edituv_tris);
550 },
551 new TaskData{*mr, buffers},
552 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
553 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
554 }
555 if (DRW_ibo_requested(buffers.ibo.edituv_lines)) {
556 struct TaskData {
557 MeshRenderData &mr;
559 };
561 &task_graph,
562 [](void *__restrict task_data) {
563 const TaskData &data = *static_cast<TaskData *>(task_data);
564 extract_edituv_lines(data.mr, *data.buffers.ibo.edituv_lines);
565 },
566 new TaskData{*mr, buffers},
567 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
568 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
569 }
570 if (DRW_ibo_requested(buffers.ibo.edituv_points)) {
571 struct TaskData {
572 MeshRenderData &mr;
574 };
576 &task_graph,
577 [](void *__restrict task_data) {
578 const TaskData &data = *static_cast<TaskData *>(task_data);
579 extract_edituv_points(data.mr, *data.buffers.ibo.edituv_points);
580 },
581 new TaskData{*mr, buffers},
582 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
583 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
584 }
585 if (DRW_ibo_requested(buffers.ibo.edituv_fdots)) {
586 struct TaskData {
587 MeshRenderData &mr;
589 };
591 &task_graph,
592 [](void *__restrict task_data) {
593 const TaskData &data = *static_cast<TaskData *>(task_data);
594 extract_edituv_face_dots(data.mr, *data.buffers.ibo.edituv_fdots);
595 },
596 new TaskData{*mr, buffers},
597 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
598 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
599 }
600 if (DRW_ibo_requested(buffers.ibo.lines_paint_mask)) {
601 struct TaskData {
602 MeshRenderData &mr;
604 };
606 &task_graph,
607 [](void *__restrict task_data) {
608 const TaskData &data = *static_cast<TaskData *>(task_data);
609 extract_lines_paint_mask(data.mr, *data.buffers.ibo.lines_paint_mask);
610 },
611 new TaskData{*mr, buffers},
612 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
613 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
614 }
615 if (DRW_ibo_requested(buffers.ibo.lines_adjacency)) {
616 struct TaskData {
617 MeshRenderData &mr;
619 MeshBatchCache &cache;
620 };
622 &task_graph,
623 [](void *__restrict task_data) {
624 const TaskData &data = *static_cast<TaskData *>(task_data);
626 data.mr, *data.buffers.ibo.lines_adjacency, data.cache.is_manifold);
627 },
628 new TaskData{*mr, buffers, cache},
629 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
630 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
631 }
632 if (DRW_vbo_requested(buffers.vbo.skin_roots)) {
633 struct TaskData {
634 MeshRenderData &mr;
636 };
638 &task_graph,
639 [](void *__restrict task_data) {
640 const TaskData &data = *static_cast<TaskData *>(task_data);
641 extract_skin_roots(data.mr, *data.buffers.vbo.skin_roots);
642 },
643 new TaskData{*mr, buffers},
644 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
645 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
646 }
647 if (DRW_vbo_requested(buffers.vbo.sculpt_data)) {
648 struct TaskData {
649 MeshRenderData &mr;
651 };
653 &task_graph,
654 [](void *__restrict task_data) {
655 const TaskData &data = *static_cast<TaskData *>(task_data);
656 extract_sculpt_data(data.mr, *data.buffers.vbo.sculpt_data);
657 },
658 new TaskData{*mr, buffers},
659 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
660 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
661 }
662 if (DRW_vbo_requested(buffers.vbo.orco)) {
663 struct TaskData {
664 MeshRenderData &mr;
666 };
668 &task_graph,
669 [](void *__restrict task_data) {
670 const TaskData &data = *static_cast<TaskData *>(task_data);
671 extract_orco(data.mr, *data.buffers.vbo.orco);
672 },
673 new TaskData{*mr, buffers},
674 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
675 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
676 }
677 if (DRW_vbo_requested(buffers.vbo.mesh_analysis)) {
678 struct TaskData {
679 MeshRenderData &mr;
681 };
683 &task_graph,
684 [](void *__restrict task_data) {
685 const TaskData &data = *static_cast<TaskData *>(task_data);
686 extract_mesh_analysis(data.mr, *data.buffers.vbo.mesh_analysis);
687 },
688 new TaskData{*mr, buffers},
689 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
690 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
691 }
692 if (attrs_requested) {
693 struct TaskData {
694 MeshRenderData &mr;
696 MeshBatchCache &cache;
697 };
699 &task_graph,
700 [](void *__restrict task_data) {
701 const TaskData &data = *static_cast<TaskData *>(task_data);
702 extract_attributes(data.mr,
703 {data.cache.attr_used.requests, GPU_MAX_ATTR},
704 {data.buffers.vbo.attr, GPU_MAX_ATTR});
705 },
706 new TaskData{*mr, buffers, cache},
707 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
708 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
709 }
710 if (DRW_vbo_requested(buffers.vbo.attr_viewer)) {
711 struct TaskData {
712 MeshRenderData &mr;
714 };
716 &task_graph,
717 [](void *__restrict task_data) {
718 const TaskData &data = *static_cast<TaskData *>(task_data);
719 extract_attr_viewer(data.mr, *data.buffers.vbo.attr_viewer);
720 },
721 new TaskData{*mr, buffers},
722 [](void *task_data) { delete static_cast<TaskData *>(task_data); });
723 BLI_task_graph_edge_create(task_node_mesh_render_data, task_node);
724 }
725
726 /* Trigger the sub-graph for this mesh. */
727 BLI_task_graph_node_push_work(task_node_mesh_render_data);
728
729#ifdef DEBUG_TIME
731 double end = BLI_time_now_seconds();
732
733 static double avg = 0;
734 static double avg_fps = 0;
735 static double avg_rdata = 0;
736 static double end_prev = 0;
737
738 if (end_prev == 0) {
739 end_prev = end;
740 }
741
742 avg = avg * 0.95 + (end - rdata_end) * 0.05;
743 avg_fps = avg_fps * 0.95 + (end - end_prev) * 0.05;
744 avg_rdata = avg_rdata * 0.95 + (rdata_end - rdata_start) * 0.05;
745
746 printf(
747 "rdata %.0fms iter %.0fms (frame %.0fms)\n", avg_rdata * 1000, avg * 1000, avg_fps * 1000);
748
749 end_prev = end;
750#endif
751}
752
755/* ---------------------------------------------------------------------- */
760 MeshBufferCache &mbc,
761 DRWSubdivCache &subdiv_cache,
762 MeshRenderData &mr)
763{
765 const bool attrs_requested = any_attr_requested(buffers);
766 if (!DRW_ibo_requested(buffers.ibo.lines) && !DRW_ibo_requested(buffers.ibo.lines_loose) &&
767 !DRW_ibo_requested(buffers.ibo.tris) && !DRW_ibo_requested(buffers.ibo.points) &&
768 !DRW_vbo_requested(buffers.vbo.pos) && !DRW_vbo_requested(buffers.vbo.orco) &&
769 !DRW_vbo_requested(buffers.vbo.nor) && !DRW_vbo_requested(buffers.vbo.edge_fac) &&
770 !DRW_vbo_requested(buffers.vbo.tan) && !DRW_vbo_requested(buffers.vbo.edit_data) &&
771 !DRW_vbo_requested(buffers.vbo.face_idx) && !DRW_vbo_requested(buffers.vbo.edge_idx) &&
772 !DRW_vbo_requested(buffers.vbo.vert_idx) && !DRW_vbo_requested(buffers.vbo.weights) &&
773 !DRW_vbo_requested(buffers.vbo.fdots_nor) && !DRW_vbo_requested(buffers.vbo.fdots_pos) &&
774 !DRW_ibo_requested(buffers.ibo.fdots) && !DRW_vbo_requested(buffers.vbo.uv) &&
775 !DRW_vbo_requested(buffers.vbo.edituv_stretch_area) &&
776 !DRW_vbo_requested(buffers.vbo.edituv_stretch_angle) &&
777 !DRW_vbo_requested(buffers.vbo.edituv_data) && !DRW_ibo_requested(buffers.ibo.edituv_tris) &&
778 !DRW_ibo_requested(buffers.ibo.edituv_lines) &&
779 !DRW_ibo_requested(buffers.ibo.edituv_points) &&
780 !DRW_ibo_requested(buffers.ibo.lines_paint_mask) &&
781 !DRW_ibo_requested(buffers.ibo.lines_adjacency) &&
782 !DRW_vbo_requested(buffers.vbo.sculpt_data) && !attrs_requested)
783 {
784 return;
785 }
786
789 DRW_subdivide_loose_geom(subdiv_cache, mbc);
790
791 if (DRW_vbo_requested(buffers.vbo.pos) || DRW_vbo_requested(buffers.vbo.orco)) {
792 extract_positions_subdiv(subdiv_cache, mr, *buffers.vbo.pos, buffers.vbo.orco);
793 }
794 if (DRW_vbo_requested(buffers.vbo.nor)) {
795 /* The corner normals calculation uses positions and normals stored in the `pos` VBO. */
796 extract_normals_subdiv(mr, subdiv_cache, *buffers.vbo.pos, *buffers.vbo.nor);
797 }
798 if (DRW_vbo_requested(buffers.vbo.edge_fac)) {
799 extract_edge_factor_subdiv(subdiv_cache, mr, *buffers.vbo.pos, *buffers.vbo.edge_fac);
800 }
801 if (DRW_ibo_requested(buffers.ibo.lines) || DRW_ibo_requested(buffers.ibo.lines_loose)) {
803 subdiv_cache, mr, buffers.ibo.lines, buffers.ibo.lines_loose, cache.no_loose_wire);
804 }
805 if (DRW_ibo_requested(buffers.ibo.tris)) {
806 extract_tris_subdiv(subdiv_cache, cache, *buffers.ibo.tris);
807 }
808 if (DRW_ibo_requested(buffers.ibo.points)) {
809 extract_points_subdiv(mr, subdiv_cache, *buffers.ibo.points);
810 }
811 if (DRW_vbo_requested(buffers.vbo.edit_data)) {
812 extract_edit_data_subdiv(mr, subdiv_cache, *buffers.vbo.edit_data);
813 }
814 if (DRW_vbo_requested(buffers.vbo.tan)) {
815 extract_tangents_subdiv(mr, subdiv_cache, cache, *buffers.vbo.tan);
816 }
817 if (DRW_vbo_requested(buffers.vbo.vert_idx)) {
818 extract_vert_index_subdiv(subdiv_cache, mr, *buffers.vbo.vert_idx);
819 }
820 if (DRW_vbo_requested(buffers.vbo.edge_idx)) {
821 extract_edge_index_subdiv(subdiv_cache, mr, *buffers.vbo.edge_idx);
822 }
823 if (DRW_vbo_requested(buffers.vbo.face_idx)) {
824 extract_face_index_subdiv(subdiv_cache, mr, *buffers.vbo.face_idx);
825 }
826 if (DRW_vbo_requested(buffers.vbo.weights)) {
827 extract_weights_subdiv(mr, subdiv_cache, cache, *buffers.vbo.weights);
828 }
829 if (DRW_vbo_requested(buffers.vbo.fdots_nor) || DRW_vbo_requested(buffers.vbo.fdots_pos) ||
830 DRW_ibo_requested(buffers.ibo.fdots))
831 {
832 /* We use only one extractor for face dots, as the work is done in a single compute shader. */
834 subdiv_cache, *buffers.vbo.fdots_pos, buffers.vbo.fdots_nor, *buffers.ibo.fdots);
835 }
836 if (DRW_ibo_requested(buffers.ibo.lines_paint_mask)) {
837 extract_lines_paint_mask_subdiv(mr, subdiv_cache, *buffers.ibo.lines_paint_mask);
838 }
839 if (DRW_ibo_requested(buffers.ibo.lines_adjacency)) {
840 extract_lines_adjacency_subdiv(subdiv_cache, *buffers.ibo.lines_adjacency, cache.is_manifold);
841 }
842 if (DRW_vbo_requested(buffers.vbo.sculpt_data)) {
843 extract_sculpt_data_subdiv(mr, subdiv_cache, *buffers.vbo.sculpt_data);
844 }
845 if (DRW_vbo_requested(buffers.vbo.uv)) {
846 /* Make sure UVs are computed before edituv stuffs. */
847 extract_uv_maps_subdiv(subdiv_cache, cache, *buffers.vbo.uv);
848 }
849 if (DRW_vbo_requested(buffers.vbo.edituv_stretch_area)) {
851 mr, subdiv_cache, *buffers.vbo.edituv_stretch_area, cache.tot_area, cache.tot_uv_area);
852 }
853 if (DRW_vbo_requested(buffers.vbo.edituv_stretch_area)) {
855 mr, subdiv_cache, cache, *buffers.vbo.edituv_stretch_angle);
856 }
857 if (DRW_vbo_requested(buffers.vbo.edituv_data)) {
858 extract_edituv_data_subdiv(mr, subdiv_cache, *buffers.vbo.edituv_data);
859 }
860 if (DRW_ibo_requested(buffers.ibo.edituv_tris)) {
861 extract_edituv_tris_subdiv(mr, subdiv_cache, *buffers.ibo.edituv_tris);
862 }
863 if (DRW_ibo_requested(buffers.ibo.edituv_lines)) {
864 extract_edituv_lines_subdiv(mr, subdiv_cache, *buffers.ibo.edituv_lines);
865 }
866 if (DRW_ibo_requested(buffers.ibo.edituv_points)) {
867 extract_edituv_points_subdiv(mr, subdiv_cache, *buffers.ibo.edituv_points);
868 }
869 if (attrs_requested) {
871 subdiv_cache,
873 {buffers.vbo.attr, GPU_MAX_ATTR});
874 }
875}
876
879} // namespace blender::draw
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
struct TaskNode * BLI_task_graph_node_create(struct TaskGraph *task_graph, TaskGraphNodeRunFunction run, void *user_data, TaskGraphNodeFreeFunction free_func)
void BLI_task_graph_edge_create(struct TaskNode *from_node, struct TaskNode *to_node)
bool BLI_task_graph_node_push_work(struct TaskNode *task_node)
void BLI_task_graph_work_and_wait(struct TaskGraph *task_graph)
double BLI_time_now_seconds(void)
Definition time.c:65
Utility defines for timing/benchmarks.
#define ARRAY_SIZE(arr)
@ SCE_PERF_HQ_NORMALS
@ R_SIMPLIFY
@ R_SIMPLIFY_NORMALS
bool GPU_use_hq_normals_workaround()
#define GPU_MAX_ATTR
Definition GPU_shader.hh:29
Read Guarded memory(de)allocation.
#define printf
bool DRW_vbo_requested(blender::gpu::VertBuf *vbo)
bool DRW_ibo_requested(blender::gpu::IndexBuf *ibo)
Extraction of Mesh data into VBO to feed to GPU.
void extract_edge_factor_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &pos_nor, gpu::VertBuf &vbo)
void extract_lines_paint_mask(const MeshRenderData &mr, gpu::IndexBuf &lines)
void extract_edge_index(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_face_dots_uv(const MeshRenderData &mr, gpu::VertBuf &vbo)
void mesh_render_data_update_face_normals(MeshRenderData &mr)
void extract_edituv_lines(const MeshRenderData &mr, gpu::IndexBuf &ibo)
void extract_edituv_lines_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo)
void extract_edituv_stretch_area_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &vbo, float &tot_area, float &tot_uv_area)
void extract_tris(const MeshRenderData &mr, const SortedFaceData &face_sorted, MeshBatchCache &cache, gpu::IndexBuf &ibo)
void extract_attributes_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const Span< DRW_AttributeRequest > requests, const Span< gpu::VertBuf * > vbos)
void extract_edituv_stretch_angle(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_positions_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &vbo, gpu::VertBuf *orco_vbo)
void extract_face_dots(const MeshRenderData &mr, gpu::IndexBuf &face_dots)
void extract_edituv_data(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_normals(const MeshRenderData &mr, bool use_hq, gpu::VertBuf &vbo)
void extract_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &points)
void DRW_subdivide_loose_geom(DRWSubdivCache &subdiv_cache, const MeshBufferCache &cache)
void extract_tris_subdiv(const DRWSubdivCache &subdiv_cache, MeshBatchCache &cache, gpu::IndexBuf &ibo)
void extract_face_dots_position(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_edge_factor(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_face_dot_normals(const MeshRenderData &mr, const bool use_hq, gpu::VertBuf &vbo)
void extract_lines_adjacency_subdiv(const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo, bool &r_is_manifold)
void extract_weights(const MeshRenderData &mr, const MeshBatchCache &cache, gpu::VertBuf &vbo)
void extract_normals_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &pos_nor, gpu::VertBuf &lnor)
void extract_uv_maps(const MeshRenderData &mr, const MeshBatchCache &cache, gpu::VertBuf &vbo)
void extract_edituv_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &vbo)
void extract_lines(const MeshRenderData &mr, gpu::IndexBuf *lines, gpu::IndexBuf *lines_loose, bool &no_loose_wire)
void extract_weights_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache, gpu::VertBuf &vbo)
void extract_face_dot_index(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_tangents(const MeshRenderData &mr, const MeshBatchCache &cache, const bool use_hq, gpu::VertBuf &vbo)
void extract_vert_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_face_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_edituv_tris(const MeshRenderData &mr, gpu::IndexBuf &ibo)
void extract_uv_maps_subdiv(const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache, gpu::VertBuf &vbo)
void extract_orco(const MeshRenderData &mr, gpu::VertBuf &vbo)
int mesh_render_mat_len_get(const Object &object, const Mesh &mesh)
static bool any_attr_requested(const MeshBufferList &buffers)
void mesh_buffer_cache_create_requested(TaskGraph &task_graph, MeshBatchCache &cache, MeshBufferCache &mbc, Object &object, Mesh &mesh, bool is_editmode, bool is_paint_mode, bool edit_mode_active, const float4x4 &object_to_world, bool do_final, bool do_uvedit, const Scene &scene, const ToolSettings *ts, bool use_hide)
void extract_edituv_stretch_angle_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache, gpu::VertBuf &vbo)
void extract_face_dots_edituv_data(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_edituv_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo)
void extract_lines_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::IndexBuf *lines, gpu::IndexBuf *lines_loose, bool &no_loose_wire)
void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, MeshBufferCache &mbc, DRWSubdivCache &subdiv_cache, MeshRenderData &mr)
void extract_tangents_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache, gpu::VertBuf &vbo)
std::unique_ptr< MeshRenderData > mesh_render_data_create(Object &object, Mesh &mesh, const bool is_editmode, const bool is_paint_mode, const bool edit_mode_active, const float4x4 &object_to_world, const bool do_final, const bool do_uvedit, const bool use_hide, const ToolSettings *ts)
void mesh_render_data_update_corner_normals(MeshRenderData &mr)
void extract_points(const MeshRenderData &mr, gpu::IndexBuf &points)
void extract_vert_index(const MeshRenderData &mr, gpu::VertBuf &vbo)
static void mesh_extract_render_data_node_exec(void *__restrict task_data)
const SortedFaceData & mesh_render_data_faces_sorted_ensure(const MeshRenderData &mr, MeshBufferCache &cache)
void extract_face_index(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_sculpt_data(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_edit_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &vbo)
void extract_lines_paint_mask_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &lines)
void extract_positions(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_vert_normals(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_lines_adjacency(const MeshRenderData &mr, gpu::IndexBuf &ibo, bool &r_is_manifold)
void mesh_render_data_update_loose_geom(MeshRenderData &mr, MeshBufferCache &cache)
void extract_sculpt_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &vbo)
void extract_mesh_analysis(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_skin_roots(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_attr_viewer(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_attributes(const MeshRenderData &mr, const Span< DRW_AttributeRequest > requests, const Span< gpu::VertBuf * > vbos)
void extract_edituv_tris_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::IndexBuf &ibo)
void extract_edituv_face_dots(const MeshRenderData &mr, gpu::IndexBuf &ibo)
void extract_edit_data(const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_edituv_stretch_area(const MeshRenderData &mr, gpu::VertBuf &vbo, float &tot_area, float &tot_uv_area)
void extract_edituv_points(const MeshRenderData &mr, gpu::IndexBuf &ibo)
void extract_edge_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &vbo)
void extract_face_dots_subdiv(const DRWSubdivCache &subdiv_cache, gpu::VertBuf &fdots_pos, gpu::VertBuf *fdots_nor, gpu::IndexBuf &fdots)
MeshRuntimeHandle * runtime
short totcol
DRW_AttributeRequest requests[GPU_MAX_ATTR]
char * buffers[2]