static void scene_update_objects(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent) { TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; ThreadedObjectUpdateState state; state.eval_ctx = eval_ctx; state.scene = scene; state.scene_parent = scene_parent; memset(state.statistics, 0, sizeof(state.statistics)); state.has_updated_objects = false; state.base_time = PIL_check_seconds_timer(); #ifdef MBALL_SINGLETHREAD_HACK state.has_mballs = false; #endif task_pool = BLI_task_pool_create(task_scheduler, &state); DAG_threaded_update_begin(scene, scene_update_object_add_task, task_pool); BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); if (G.debug & G_DEBUG) { print_threads_statistics(&state); } #ifdef MBALL_SINGLETHREAD_HACK if (state.has_mballs) { scene_update_all_bases(eval_ctx, scene, scene_parent); } #endif }
KX_BlenderSceneConverter::~KX_BlenderSceneConverter() { // clears meshes, and hashmaps from blender to gameengine data // delete sumoshapes int numAdtLists = m_map_blender_to_gameAdtList.size(); for (int i = 0; i < numAdtLists; i++) { BL_InterpolatorList *adtList = *m_map_blender_to_gameAdtList.at(i); delete (adtList); } vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator itw = m_worldinfos.begin(); while (itw != m_worldinfos.end()) { delete itw->second; itw++; } m_worldinfos.clear(); vector<pair<KX_Scene *,RAS_IPolyMaterial *> >::iterator itp = m_polymaterials.begin(); while (itp != m_polymaterials.end()) { delete itp->second; itp++; } m_polymaterials.clear(); // delete after RAS_IPolyMaterial vector<pair<KX_Scene *,BL_Material *> >::iterator itmat = m_materials.begin(); while (itmat != m_materials.end()) { delete itmat->second; itmat++; } m_materials.clear(); vector<pair<KX_Scene *,RAS_MeshObject *> >::iterator itm = m_meshobjects.begin(); while (itm != m_meshobjects.end()) { delete itm->second; itm++; } m_meshobjects.clear(); /* free any data that was dynamically loaded */ while (m_DynamicMaggie.size() != 0) { FreeBlendFile(m_DynamicMaggie[0]); } m_DynamicMaggie.clear(); if (m_threadinfo) { /* Thread infos like mutex must be freed after FreeBlendFile function. Because it needs to lock the mutex, even if there's no active task when it's in the scene converter destructor. */ BLI_task_pool_free(m_threadinfo->m_pool); BLI_mutex_end(&m_threadinfo->m_mutex); delete m_threadinfo; } }
static float *threaded_mask_rasterize(Mask *mask, const int width, const int height) { TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; MaskRasterHandle *handle; ThreadedMaskRasterizeState state; float *buffer; int i, num_threads = BLI_task_scheduler_num_threads(task_scheduler), scanlines_per_thread; buffer = MEM_mallocN(sizeof(float) * height * width, "rasterized mask buffer"); /* Initialize rasterization handle. */ handle = BKE_maskrasterize_handle_new(); BKE_maskrasterize_handle_init(handle, mask, width, height, true, true, true); state.handle = handle; state.buffer = buffer; state.width = width; state.height = height; task_pool = BLI_task_pool_create(task_scheduler, &state); scanlines_per_thread = height / num_threads; for (i = 0; i < num_threads; i++) { ThreadedMaskRasterizeData *data = MEM_mallocN(sizeof(ThreadedMaskRasterizeData), "threaded mask rasterize data"); data->start_scanline = i * scanlines_per_thread; if (i < num_threads - 1) { data->num_scanlines = scanlines_per_thread; } else { data->num_scanlines = height - data->start_scanline; } BLI_task_pool_push(task_pool, mask_rasterize_func, data, true, TASK_PRIORITY_LOW); } /* work and wait until tasks are done */ BLI_task_pool_work_and_wait(task_pool); /* Free memory. */ BLI_task_pool_free(task_pool); BKE_maskrasterize_handle_free(handle); return buffer; }
void KX_Scene::UpdateAnimations(double curtime) { TaskPool *pool = BLI_task_pool_create(KX_GetActiveEngine()->GetTaskScheduler(), &curtime); for (int i=0; i<m_animatedlist->GetCount(); ++i) { BLI_task_pool_push(pool, update_anim_thread_func, m_animatedlist->GetValue(i), false, TASK_PRIORITY_LOW); } BLI_task_pool_work_and_wait(pool); BLI_task_pool_free(pool); }
static void um_arraystore_free(UndoMesh *um) { Mesh *me = &um->me; um_arraystore_cd_free(um->store.vdata); um_arraystore_cd_free(um->store.edata); um_arraystore_cd_free(um->store.ldata); um_arraystore_cd_free(um->store.pdata); if (um->store.keyblocks) { const size_t stride = me->key->elemsize; BArrayStore *bs = BLI_array_store_at_size_get(&um_arraystore.bs_stride, stride); for (int i = 0; i < me->key->totkey; i++) { BArrayState *state = um->store.keyblocks[i]; BLI_array_store_state_remove(bs, state); } MEM_freeN(um->store.keyblocks); um->store.keyblocks = NULL; } if (um->store.mselect) { const size_t stride = sizeof(*me->mselect); BArrayStore *bs = BLI_array_store_at_size_get(&um_arraystore.bs_stride, stride); BArrayState *state = um->store.mselect; BLI_array_store_state_remove(bs, state); um->store.mselect = NULL; } um_arraystore.users -= 1; BLI_assert(um_arraystore.users >= 0); if (um_arraystore.users == 0) { #ifdef DEBUG_PRINT printf("mesh undo store: freeing all data!\n"); #endif BLI_array_store_at_size_clear(&um_arraystore.bs_stride); #ifdef USE_ARRAY_STORE_THREAD BLI_task_pool_free(um_arraystore.task_pool); um_arraystore.task_pool = NULL; #endif } }
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata, void (init_handle) (void *handle, int start_line, int tot_line, void *customdata), void *(do_thread) (void *)) { const int lines_per_task = 64; TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; void *handles; int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task; int i, start_line; task_pool = BLI_task_pool_create(task_scheduler, do_thread); handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles"); start_line = 0; for (i = 0; i < total_tasks; i++) { int lines_per_current_task; void *handle = ((char *) handles) + handle_size * i; if (i < total_tasks - 1) lines_per_current_task = lines_per_task; else lines_per_current_task = buffer_lines - start_line; init_handle(handle, start_line, lines_per_current_task, init_customdata); BLI_task_pool_push(task_pool, processor_apply_func, handle, false, TASK_PRIORITY_LOW); start_line += lines_per_task; } /* work and wait until tasks are done */ BLI_task_pool_work_and_wait(task_pool); /* Free memory. */ MEM_freeN(handles); BLI_task_pool_free(task_pool); }
static void start_prefetch_threads(MovieClip *clip, int start_frame, int current_frame, int end_frame, short render_size, short render_flag, short *stop, short *do_update, float *progress) { PrefetchQueue queue; TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; int i, tot_thread = BLI_task_scheduler_num_threads(task_scheduler); /* initialize queue */ BLI_spin_init(&queue.spin); queue.current_frame = current_frame; queue.initial_frame = current_frame; queue.start_frame = start_frame; queue.end_frame = end_frame; queue.render_size = render_size; queue.render_flag = render_flag; queue.forward = 1; queue.stop = stop; queue.do_update = do_update; queue.progress = progress; task_pool = BLI_task_pool_create(task_scheduler, &queue); for (i = 0; i < tot_thread; i++) { BLI_task_pool_push(task_pool, prefetch_task_func, clip, false, TASK_PRIORITY_LOW); } BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); BLI_spin_end(&queue.spin); }
static void do_sequence_proxy(void *pjv, int *build_sizes, int build_count, int *build_undistort_sizes, int build_undistort_count, short *stop, short *do_update, float *progress) { ProxyJob *pj = pjv; MovieClip *clip = pj->clip; Scene *scene = pj->scene; TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; int sfra = SFRA, efra = EFRA; ProxyThread *handles; int i, tot_thread = BLI_task_scheduler_num_threads(task_scheduler); int width, height; ProxyQueue queue; if (build_undistort_count) { BKE_movieclip_get_size(clip, NULL, &width, &height); } BLI_spin_init(&queue.spin); queue.cfra = sfra; queue.sfra = sfra; queue.efra = efra; queue.stop = stop; queue.do_update = do_update; queue.progress = progress; task_pool = BLI_task_pool_create(task_scheduler, &queue); handles = MEM_callocN(sizeof(ProxyThread) * tot_thread, "proxy threaded handles"); for (i = 0; i < tot_thread; i++) { ProxyThread *handle = &handles[i]; handle->clip = clip; handle->build_count = build_count; handle->build_sizes = build_sizes; handle->build_undistort_count = build_undistort_count; handle->build_undistort_sizes = build_undistort_sizes; if (build_undistort_count) { handle->distortion = BKE_tracking_distortion_new(&clip->tracking, width, height); } BLI_task_pool_push(task_pool, proxy_task_func, handle, false, TASK_PRIORITY_LOW); } BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); if (build_undistort_count) { for (i = 0; i < tot_thread; i++) { ProxyThread *handle = &handles[i]; BKE_tracking_distortion_free(handle->distortion); } } BLI_spin_end(&queue.spin); MEM_freeN(handles); }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; if (oglrender->is_animation) { BLI_task_pool_work_and_wait(oglrender->task_pool); BLI_task_pool_free(oglrender->task_pool); /* Depending on various things we might or might not use global scheduler. */ if (oglrender->task_scheduler != NULL) { BLI_task_scheduler_free(oglrender->task_scheduler); } BLI_spin_end(&oglrender->reports_lock); } BLI_mutex_end(&oglrender->task_mutex); BLI_condition_end(&oglrender->task_condition); #ifdef DEBUG_TIME printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start); #endif if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); if (oglrender->is_sequencer) { MEM_freeN(oglrender->seq_data.ibufs_arr); } oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }