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) { ListBase threads; PrefetchQueue queue; PrefetchThread *handles; int tot_thread = BLI_system_thread_count(); int i; /* reserve one thread for the interface */ if (tot_thread > 1) tot_thread--; /* 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.direction = 1; queue.stop = stop; queue.do_update = do_update; queue.progress = progress; /* fill in thread handles */ handles = MEM_callocN(sizeof(PrefetchThread) * tot_thread, "prefetch threaded handles"); if (tot_thread > 1) BLI_init_threads(&threads, do_prefetch_thread, tot_thread); for (i = 0; i < tot_thread; i++) { PrefetchThread *handle = &handles[i]; handle->clip = clip; handle->queue = &queue; if (tot_thread > 1) BLI_insert_thread(&threads, handle); } /* run the threads */ if (tot_thread > 1) BLI_end_threads(&threads); else do_prefetch_thread(handles); MEM_freeN(handles); }
TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size) { TracksMap *map = MEM_callocN(sizeof(TracksMap), "TrackingsMap"); BLI_strncpy(map->object_name, object_name, sizeof(map->object_name)); map->is_camera = is_camera; map->num_tracks = num_tracks; map->customdata_size = customdata_size; map->tracks = MEM_callocN(sizeof(MovieTrackingTrack) * num_tracks, "TrackingsMap tracks"); if (customdata_size) map->customdata = MEM_callocN(customdata_size * num_tracks, "TracksMap customdata"); map->hash = BLI_ghash_ptr_new("TracksMap hash"); BLI_spin_init(&map->spin_lock); return map; }
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); }
void image_undo_init_locks(void) { BLI_spin_init(&undolock); }
int blf_font_init(void) { BLI_spin_init(&ft_lib_mutex); return FT_Init_FreeType(&ft_lib); }
void imb_refcounter_lock_init(void) { BLI_spin_init(&refcounter_spin); }
static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_tangent, MPassKnownData passKnownData, MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData) { DerivedMesh *dm = bkr->lores_dm; const int lvl = bkr->lvl; const int tot_face = dm->getNumTessFaces(dm); if (tot_face > 0) { MultiresBakeThread *handles; MultiresBakeQueue queue; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); MVert *mvert = dm->getVertArray(dm); MFace *mface = dm->getTessFaceArray(dm); MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); float *precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL); float *pvtangent = NULL; ListBase threads; int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count(); void *bake_data = NULL; if (require_tangent) { if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) DM_add_tangent_layer(dm); pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT); } /* all threads shares the same custom bake data */ if (initBakeData) bake_data = initBakeData(bkr, ima); if (tot_thread > 1) BLI_init_threads(&threads, do_multires_bake_thread, tot_thread); handles = MEM_callocN(tot_thread * sizeof(MultiresBakeThread), "do_multires_bake handles"); /* faces queue */ queue.cur_face = 0; queue.tot_face = tot_face; BLI_spin_init(&queue.spin); /* fill in threads handles */ for (i = 0; i < tot_thread; i++) { MultiresBakeThread *handle = &handles[i]; handle->bkr = bkr; handle->image = ima; handle->queue = &queue; handle->data.mface = mface; handle->data.mvert = mvert; handle->data.mtface = mtface; handle->data.pvtangent = pvtangent; handle->data.precomputed_normals = precomputed_normals; /* don't strictly need this */ handle->data.w = ibuf->x; handle->data.h = ibuf->y; handle->data.lores_dm = dm; handle->data.hires_dm = bkr->hires_dm; handle->data.lvl = lvl; handle->data.pass_data = passKnownData; handle->data.bake_data = bake_data; handle->data.ibuf = ibuf; init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel); if (tot_thread > 1) BLI_insert_thread(&threads, handle); } /* run threads */ if (tot_thread > 1) BLI_end_threads(&threads); else do_multires_bake_thread(&handles[0]); BLI_spin_end(&queue.spin); /* finalize baking */ if (applyBakeData) applyBakeData(bake_data); if (freeBakeData) freeBakeData(bake_data); BKE_image_release_ibuf(ima, ibuf, NULL); } }
void BKE_cachefiles_init(void) { BLI_spin_init(&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; int sfra = SFRA, efra = EFRA; ProxyThread *handles; ListBase threads; int i, tot_thread = BLI_system_thread_count(); ProxyQueue queue; 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; handles = MEM_callocN(sizeof(ProxyThread) * tot_thread, "proxy threaded handles"); if (tot_thread > 1) BLI_init_threads(&threads, do_proxy_thread, tot_thread); for (i = 0; i < tot_thread; i++) { ProxyThread *handle = &handles[i]; handle->clip = clip; handle->queue = &queue; 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(); if (tot_thread > 1) BLI_insert_thread(&threads, handle); } if (tot_thread > 1) BLI_end_threads(&threads); else do_proxy_thread(handles); MEM_freeN(handles); if (build_undistort_count) { for (i = 0; i < tot_thread; i++) { ProxyThread *handle = &handles[i]; BKE_tracking_distortion_free(handle->distortion); } } }
void imb_mmap_lock_init(void) { BLI_spin_init(&mmap_spin); }
void BLI_threadapi_init(void) { mainid = pthread_self(); BLI_spin_init(&_malloc_lock); }
static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize) { /* * x1 is the starting x value to draw the wave, * x2 the end x value, same for y1 and y2 * stepsize is width of a pixel. */ if ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)) { int i, j, pos; int length = floor((x2 - x1) / stepsize) + 1; float ymid = (y1 + y2) / 2; float yscale = (y2 - y1) / 2; float samplestep; float startsample, endsample; float value1, value2; bSound *sound = seq->sound; SoundWaveform *waveform; if (!sound->spinlock) { sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock"); BLI_spin_init(sound->spinlock); } BLI_spin_lock(sound->spinlock); if (!seq->sound->waveform) { if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) { /* prevent sounds from reloading */ seq->sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING; BLI_spin_unlock(sound->spinlock); sequencer_preview_add_sound(C, seq); } else { BLI_spin_unlock(sound->spinlock); } return; /* nothing to draw */ } BLI_spin_unlock(sound->spinlock); waveform = seq->sound->waveform; if (waveform->length == 0) { /* BKE_sound_read_waveform() set an empty SoundWaveform data in case it cannot generate a valid one... * See T45726. */ return; } startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND); endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND); samplestep = (endsample - startsample) * stepsize / (x2 - x1); if (length > floor((waveform->length - startsample) / samplestep)) length = floor((waveform->length - startsample) / samplestep); glColor4f(1.0f, 1.0f, 1.0f, 0.5); glEnable(GL_BLEND); glBegin(GL_TRIANGLE_STRIP); for (i = 0; i < length; i++) { float sampleoffset = startsample + i * samplestep; pos = sampleoffset; value1 = waveform->data[pos * 3]; value2 = waveform->data[pos * 3 + 1]; if (samplestep > 1.0f) { for (j = pos + 1; (j < waveform->length) && (j < pos + samplestep); j++) { if (value1 > waveform->data[j * 3]) value1 = waveform->data[j * 3]; if (value2 < waveform->data[j * 3 + 1]) value2 = waveform->data[j * 3 + 1]; } } else { /* use simple linear interpolation */ float f = sampleoffset - pos; value1 = (1.0f - f) * value1 + f * waveform->data[pos * 3 + 3]; value2 = (1.0f - f) * value2 + f * waveform->data[pos * 3 + 4]; } glVertex2f(x1 + i * stepsize, ymid + value1 * yscale); glVertex2f(x1 + i * stepsize, ymid + value2 * yscale); } glEnd(); glDisable(GL_BLEND); } }
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; }