TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata) { TaskPool *pool = MEM_callocN(sizeof(TaskPool), "TaskPool"); pool->scheduler = scheduler; pool->num = 0; pool->num_threads = 0; pool->currently_running_tasks = 0; pool->do_cancel = false; BLI_mutex_init(&pool->num_mutex); BLI_condition_init(&pool->num_cond); pool->userdata = userdata; BLI_mutex_init(&pool->user_mutex); /* Ensure malloc will go fine from threads, * * This is needed because we could be in main thread here * and malloc could be non-threda safe at this point because * no other jobs are running. */ BLI_begin_threaded_malloc(); return pool; }
/* executes blocking render */ static int screen_render_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); SceneRenderLayer *srl = NULL; Render *re; Image *ima; View3D *v3d = CTX_wm_view3d(C); Main *mainp = CTX_data_main(C); unsigned int lay_override; const bool is_animation = RNA_boolean_get(op->ptr, "animation"); const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; /* custom scene and single layer re-render */ screen_render_scene_layer_set(op, mainp, &scene, &srl); 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 OPERATOR_CANCELLED; } re = RE_NewRender(scene->id.name); lay_override = (v3d && v3d->lay != scene->lay) ? v3d->lay : 0; G.is_break = false; RE_test_break_cb(re, NULL, render_break); ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); BKE_image_backup_render(scene, ima); /* cleanup sequencer caches before starting user triggered render. * otherwise, invalidated cache entries can make their way into * the output rendering. We can't put that into RE_BlenderFrame, * since sequence rendering can call that recursively... (peter) */ BKE_sequencer_cache_cleanup(); RE_SetReports(re, op->reports); BLI_begin_threaded_malloc(); if (is_animation) RE_BlenderAnim(re, mainp, scene, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step); else RE_BlenderFrame(re, mainp, scene, srl, camera_override, lay_override, scene->r.cfra, is_write_still); BLI_end_threaded_malloc(); RE_SetReports(re, NULL); // no redraw needed, we leave state as we entered it ED_update_for_newframe(mainp, scene, 1); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); return OPERATOR_FINISHED; }
static TaskPool *task_pool_create_ex(TaskScheduler *scheduler, void *userdata, const bool is_background) { TaskPool *pool = MEM_mallocN(sizeof(TaskPool), "TaskPool"); #ifndef NDEBUG /* Assert we do not try to create a background pool from some parent task - those only work OK from main thread. */ if (is_background) { const pthread_t thread_id = pthread_self(); int i = scheduler->num_threads; while (i--) { BLI_assert(!pthread_equal(scheduler->threads[i], thread_id)); } } #endif pool->scheduler = scheduler; pool->num = 0; pool->done = 0; pool->num_threads = 0; pool->currently_running_tasks = 0; pool->do_cancel = false; pool->run_in_background = is_background; BLI_mutex_init(&pool->num_mutex); BLI_condition_init(&pool->num_cond); pool->userdata = userdata; BLI_mutex_init(&pool->user_mutex); if (BLI_thread_is_main()) { pool->task_mempool = scheduler->task_mempool; } else { pool->task_mempool = &pool->task_mempool_local; pool->task_mempool_local.num_tasks = 0; } #ifdef DEBUG_STATS pool->mempool_stats = MEM_callocN(sizeof(*pool->mempool_stats) * (scheduler->num_threads + 1), "per-taskpool mempool stats"); #endif /* Ensure malloc will go fine from threads, * * This is needed because we could be in main thread here * and malloc could be non-threda safe at this point because * no other jobs are running. */ BLI_begin_threaded_malloc(); return pool; }
RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport) { RenderEngine *engine = MEM_callocN(sizeof(RenderEngine), "RenderEngine"); engine->type = type; if (use_for_viewport) { engine->flag |= RE_ENGINE_USED_FOR_VIEWPORT; BLI_begin_threaded_malloc(); } return engine; }
static int render_frame(int argc, const char **argv, void *data) { bContext *C = data; Scene *scene = CTX_data_scene(C); if (scene) { Main *bmain = CTX_data_main(C); if (argc > 1) { Render *re = RE_NewRender(scene->id.name); int frame; ReportList reports; switch (*argv[1]) { case '+': frame = scene->r.sfra + atoi(argv[1] + 1); break; case '-': frame = (scene->r.efra - atoi(argv[1] + 1)) + 1; break; default: frame = atoi(argv[1]); break; } BLI_begin_threaded_malloc(); BKE_reports_init(&reports, RPT_PRINT); frame = CLAMPIS(frame, MINAFRAME, MAXFRAME); RE_SetReports(re, &reports); RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step); RE_SetReports(re, NULL); BLI_end_threaded_malloc(); return 1; } else { printf("\nError: frame number must follow '-f / --render-frame'.\n"); return 0; } } else { printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n"); return 0; } }
static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data) { bContext *C = data; Scene *scene = CTX_data_scene(C); if (scene) { Main *bmain = CTX_data_main(C); Render *re = RE_NewRender(scene->id.name); ReportList reports; BLI_begin_threaded_malloc(); BKE_reports_init(&reports, RPT_PRINT); RE_SetReports(re, &reports); RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step); RE_SetReports(re, NULL); BLI_end_threaded_malloc(); } else { printf("\nError: no blend loaded. cannot use '-a'.\n"); } return 0; }