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 }
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); }
KX_BlenderSceneConverter::KX_BlenderSceneConverter( Main *maggie, KX_KetsjiEngine *engine) :m_maggie(maggie), m_ketsjiEngine(engine), m_alwaysUseExpandFraming(false), m_usemat(false), m_useglslmat(false), m_use_mat_cache(true) { BKE_main_id_tag_all(maggie, LIB_TAG_DOIT, false); /* avoid re-tagging later on */ m_newfilename = ""; m_threadinfo = new ThreadInfo(); m_threadinfo->m_pool = BLI_task_pool_create(engine->GetTaskScheduler(), NULL); BLI_mutex_init(&m_threadinfo->m_mutex); }
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 bool screen_opengl_render_init(bContext *C, wmOperator *op) { /* new render clears all callbacks */ wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); ScrArea *prevsa = CTX_wm_area(C); ARegion *prevar = CTX_wm_region(C); GPUOffScreen *ofs; OGLRender *oglrender; int sizex, sizey; const int samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0; const bool full_samples = (samples != 0) && (scene->r.scemode & R_FULL_SAMPLE); bool is_view_context = RNA_boolean_get(op->ptr, "view_context"); const bool is_animation = RNA_boolean_get(op->ptr, "animation"); const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer"); const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); char err_out[256] = "unknown"; if (G.background) { BKE_report(op->reports, RPT_ERROR, "Cannot use OpenGL render in background mode (no opengl context)"); return false; } /* only one render job at a time */ if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) return false; if (is_sequencer) { is_view_context = false; } else { /* ensure we have a 3d view */ if (!ED_view3d_context_activate(C)) { RNA_boolean_set(op->ptr, "view_context", false); is_view_context = false; } if (!is_view_context && scene->camera == NULL) { BKE_report(op->reports, RPT_ERROR, "Scene has no camera"); return false; } } if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); return false; } /* stop all running jobs, except screen one. currently previews frustrate Render */ WM_jobs_kill_all_except(wm, CTX_wm_screen(C)); /* create offscreen buffer */ sizex = (scene->r.size * scene->r.xsch) / 100; sizey = (scene->r.size * scene->r.ysch) / 100; /* corrects render size with actual size, not every card supports non-power-of-two dimensions */ ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, GPU_HDR_NONE, GPU_OFFSCREEN_DEPTH_COMPARE, err_out); if (!ofs) { BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); return false; } /* allocate opengl render */ oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender"); op->customdata = oglrender; oglrender->ofs = ofs; oglrender->ofs_samples = samples; oglrender->ofs_full_samples = full_samples; oglrender->sizex = sizex; oglrender->sizey = sizey; oglrender->bmain = CTX_data_main(C); oglrender->scene = scene; oglrender->cfrao = scene->r.cfra; oglrender->write_still = is_write_still && !is_animation; oglrender->is_animation = is_animation; oglrender->views_len = BKE_scene_multiview_num_views_get(&scene->r); oglrender->is_sequencer = is_sequencer; if (is_sequencer) { oglrender->sseq = CTX_wm_space_seq(C); ImBuf **ibufs_arr = MEM_callocN(sizeof(*ibufs_arr) * oglrender->views_len, __func__); oglrender->seq_data.ibufs_arr = ibufs_arr; } oglrender->prevsa = prevsa; oglrender->prevar = prevar; if (is_view_context) { ED_view3d_context_user_region(C, &oglrender->v3d, &oglrender->ar); /* so quad view renders camera */ oglrender->rv3d = oglrender->ar->regiondata; /* MUST be cleared on exit */ oglrender->scene->customdata_mask_modal = ED_view3d_datamask(oglrender->scene, oglrender->v3d); /* apply immediately in case we're rendering from a script, * running notifiers again will overwrite */ oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal; if (oglrender->v3d->fx_settings.fx_flag & (GPU_FX_FLAG_DOF | GPU_FX_FLAG_SSAO)) { oglrender->fx = GPU_fx_compositor_create(); } } /* create render */ oglrender->re = RE_NewRender(scene->id.name); /* create image and image user */ oglrender->ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(oglrender->ima, NULL, IMA_SIGNAL_FREE); BKE_image_backup_render(oglrender->scene, oglrender->ima, true); oglrender->iuser.scene = scene; oglrender->iuser.ok = 1; /* create render result */ RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL); /* create render views */ screen_opengl_views_setup(oglrender); /* wm vars */ oglrender->wm = wm; oglrender->win = win; oglrender->totvideos = 0; oglrender->mh = NULL; oglrender->movie_ctx_arr = NULL; if (is_animation) { TaskScheduler *task_scheduler = BLI_task_scheduler_get(); if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { task_scheduler = BLI_task_scheduler_create(1); oglrender->task_scheduler = task_scheduler; oglrender->task_pool = BLI_task_pool_create_background(task_scheduler, oglrender); BLI_pool_set_num_threads(oglrender->task_pool, 1); } else { oglrender->task_scheduler = NULL; oglrender->task_pool = BLI_task_pool_create(task_scheduler, oglrender); } oglrender->pool_ok = true; BLI_spin_init(&oglrender->reports_lock); } else { oglrender->task_scheduler = NULL; oglrender->task_pool = NULL; } oglrender->num_scheduled_frames = 0; BLI_mutex_init(&oglrender->task_mutex); BLI_condition_init(&oglrender->task_condition); #ifdef DEBUG_TIME oglrender->time_start = PIL_check_seconds_timer(); #endif return true; }