Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_extract_mesh.c
| Show First 20 Lines • Show All 4,503 Lines • ▼ Show 20 Lines | case MR_EXTRACT_MESH: | ||||
| for (int v = start; v < lv_end; v++) { | for (int v = start; v < lv_end; v++) { | ||||
| extract->iter_lvert(mr, v, &mr->mvert[mr->lverts[v]], user_data); | extract->iter_lvert(mr, v, &mr->mvert[mr->lverts[v]], user_data); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| static void extract_run(TaskPool *__restrict UNUSED(pool), void *taskdata, int UNUSED(threadid)) | static void extract_run(TaskPool *__restrict UNUSED(pool), void *taskdata) | ||||
| { | { | ||||
| ExtractTaskData *data = taskdata; | ExtractTaskData *data = taskdata; | ||||
| mesh_extract_iter( | mesh_extract_iter( | ||||
| data->mr, data->iter_type, data->start, data->end, data->extract, data->user_data); | data->mr, data->iter_type, data->start, data->end, data->extract, data->user_data); | ||||
| /* If this is the last task, we do the finish function. */ | /* If this is the last task, we do the finish function. */ | ||||
| int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1); | int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1); | ||||
| if (remainin_tasks == 0 && data->extract->finish != NULL) { | if (remainin_tasks == 0 && data->extract->finish != NULL) { | ||||
| data->extract->finish(data->mr, data->buf, data->user_data); | data->extract->finish(data->mr, data->buf, data->user_data); | ||||
| } | } | ||||
| } | } | ||||
| static void extract_range_task_create( | static void extract_range_task_create( | ||||
| TaskPool *task_pool, ExtractTaskData *taskdata, const eMRIterType type, int start, int length) | TaskPool *task_pool, ExtractTaskData *taskdata, const eMRIterType type, int start, int length) | ||||
| { | { | ||||
| taskdata = MEM_dupallocN(taskdata); | taskdata = MEM_dupallocN(taskdata); | ||||
| atomic_add_and_fetch_int32(taskdata->task_counter, 1); | atomic_add_and_fetch_int32(taskdata->task_counter, 1); | ||||
| taskdata->iter_type = type; | taskdata->iter_type = type; | ||||
| taskdata->start = start; | taskdata->start = start; | ||||
| taskdata->end = start + length; | taskdata->end = start + length; | ||||
| BLI_task_pool_push(task_pool, extract_run, taskdata, true, NULL); | BLI_task_pool_legacy_push(task_pool, extract_run, taskdata, true, NULL); | ||||
| } | } | ||||
| static void extract_task_create(TaskPool *task_pool, | static void extract_task_create(TaskPool *task_pool, | ||||
| const Scene *scene, | const Scene *scene, | ||||
| const MeshRenderData *mr, | const MeshRenderData *mr, | ||||
| const MeshExtract *extract, | const MeshExtract *extract, | ||||
| void *buf, | void *buf, | ||||
| int32_t *task_counter) | int32_t *task_counter) | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (taskdata->iter_type & MR_ITER_LVERT) { | ||||
| extract_range_task_create(task_pool, taskdata, MR_ITER_LVERT, i, chunk_size); | extract_range_task_create(task_pool, taskdata, MR_ITER_LVERT, i, chunk_size); | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(taskdata); | MEM_freeN(taskdata); | ||||
| } | } | ||||
| else if (use_thread) { | else if (use_thread) { | ||||
| /* One task for the whole VBO. */ | /* One task for the whole VBO. */ | ||||
| (*task_counter)++; | (*task_counter)++; | ||||
| BLI_task_pool_push(task_pool, extract_run, taskdata, true, NULL); | BLI_task_pool_legacy_push(task_pool, extract_run, taskdata, true, NULL); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Single threaded extraction. */ | /* Single threaded extraction. */ | ||||
| (*task_counter)++; | (*task_counter)++; | ||||
| extract_run(NULL, taskdata, -1); | extract_run(NULL, taskdata); | ||||
| MEM_freeN(taskdata); | MEM_freeN(taskdata); | ||||
| } | } | ||||
| } | } | ||||
| void mesh_buffer_cache_create_requested(MeshBatchCache *cache, | void mesh_buffer_cache_create_requested(MeshBatchCache *cache, | ||||
| MeshBufferCache mbc, | MeshBufferCache mbc, | ||||
| Mesh *me, | Mesh *me, | ||||
| const bool is_editmode, | const bool is_editmode, | ||||
| ▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | |||||
| #ifdef DEBUG_TIME | #ifdef DEBUG_TIME | ||||
| double rdata_end = PIL_check_seconds_timer(); | double rdata_end = PIL_check_seconds_timer(); | ||||
| #endif | #endif | ||||
| TaskScheduler *task_scheduler; | TaskScheduler *task_scheduler; | ||||
| TaskPool *task_pool; | TaskPool *task_pool; | ||||
| task_scheduler = BLI_task_scheduler_get(); | task_scheduler = BLI_task_scheduler_legacy_get(); | ||||
| task_pool = BLI_task_pool_create_suspended(task_scheduler, NULL, TASK_PRIORITY_HIGH); | task_pool = BLI_task_pool_legacy_create_suspended(task_scheduler, NULL, TASK_PRIORITY_HIGH); | ||||
brecht: See {rB05721cd} for why this must be a suspended task pool.
I'm not sure about the other… | |||||
| size_t counters_size = (sizeof(mbc) / sizeof(void *)) * sizeof(int32_t); | size_t counters_size = (sizeof(mbc) / sizeof(void *)) * sizeof(int32_t); | ||||
| int32_t *task_counters = MEM_callocN(counters_size, __func__); | int32_t *task_counters = MEM_callocN(counters_size, __func__); | ||||
| int counter_used = 0; | int counter_used = 0; | ||||
| #define EXTRACT(buf, name) \ | #define EXTRACT(buf, name) \ | ||||
| if (mbc.buf.name) { \ | if (mbc.buf.name) { \ | ||||
| extract_task_create( \ | extract_task_create( \ | ||||
| Show All 33 Lines | #define EXTRACT(buf, name) \ | ||||
| EXTRACT(ibo, edituv_tris); | EXTRACT(ibo, edituv_tris); | ||||
| EXTRACT(ibo, edituv_lines); | EXTRACT(ibo, edituv_lines); | ||||
| EXTRACT(ibo, edituv_points); | EXTRACT(ibo, edituv_points); | ||||
| EXTRACT(ibo, edituv_fdots); | EXTRACT(ibo, edituv_fdots); | ||||
| /* TODO(fclem) Ideally, we should have one global pool for all | /* TODO(fclem) Ideally, we should have one global pool for all | ||||
| * objects and wait for finish only before drawing when buffers | * objects and wait for finish only before drawing when buffers | ||||
| * need to be ready. */ | * need to be ready. */ | ||||
| BLI_task_pool_work_and_wait(task_pool); | BLI_task_pool_legacy_work_and_wait(task_pool); | ||||
| /* The next task(s) rely on the result of the tasks above. */ | /* The next task(s) rely on the result of the tasks above. */ | ||||
| /* The `lines_loose` is a sub buffer from `ibo.lines`. | /* The `lines_loose` is a sub buffer from `ibo.lines`. | ||||
| * We schedule it here due to potential synchronization issues.*/ | * We schedule it here due to potential synchronization issues.*/ | ||||
| EXTRACT(ibo, lines_loose); | EXTRACT(ibo, lines_loose); | ||||
| BLI_task_pool_work_and_wait(task_pool); | BLI_task_pool_legacy_work_and_wait(task_pool); | ||||
| #undef EXTRACT | #undef EXTRACT | ||||
| BLI_task_pool_free(task_pool); | BLI_task_pool_legacy_free(task_pool); | ||||
| MEM_freeN(task_counters); | MEM_freeN(task_counters); | ||||
| mesh_render_data_free(mr); | mesh_render_data_free(mr); | ||||
| #ifdef DEBUG_TIME | #ifdef DEBUG_TIME | ||||
| double end = PIL_check_seconds_timer(); | double end = PIL_check_seconds_timer(); | ||||
| static double avg = 0; | static double avg = 0; | ||||
| Show All 20 Lines | |||||
See rB05721cd00ad1: Mesh Batch Cache: Fix threading issue for why this must be a suspended task pool.
I'm not sure about the other places that use suspended pools. It should be slightly faster not to suspend, but it might not be safe.