Example #1
0
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;
}
Example #3
0
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);
}
Example #4
0
void image_undo_init_locks(void)
{
	BLI_spin_init(&undolock);
}
Example #5
0
int blf_font_init(void)
{
	BLI_spin_init(&ft_lib_mutex);
	return FT_Init_FreeType(&ft_lib);
}
Example #6
0
void imb_refcounter_lock_init(void)
{
    BLI_spin_init(&refcounter_spin);
}
Example #7
0
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);
	}
}
Example #8
0
void BKE_cachefiles_init(void)
{
	BLI_spin_init(&spin);
}
Example #9
0
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);
		}
	}
}
Example #10
0
void imb_mmap_lock_init(void)
{
	BLI_spin_init(&mmap_spin);
}
Example #11
0
void BLI_threadapi_init(void)
{
	mainid = pthread_self();

	BLI_spin_init(&_malloc_lock);
}
Example #12
0
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);
	}
}
Example #13
0
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);
}
Example #14
0
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;
}