Beispiel #1
0
void BLI_task_pool_free(TaskPool *pool)
{
	BLI_task_pool_stop(pool);

	BLI_mutex_end(&pool->num_mutex);
	BLI_condition_end(&pool->num_cond);

	BLI_mutex_end(&pool->user_mutex);

	/* Free local memory pool, those pointers are lost forever. */
	if (pool->task_mempool == &pool->task_mempool_local) {
		for (int i = 0; i < pool->task_mempool_local.num_tasks; i++) {
			MEM_freeN(pool->task_mempool_local.tasks[i]);
		}
	}

#ifdef DEBUG_STATS
	printf("Thread ID    Allocated   Reused   Discarded\n");
	for (int i = 0; i < pool->scheduler->num_threads + 1; ++i) {
		printf("%02d           %05d       %05d    %05d\n",
		       i,
		       pool->mempool_stats[i].num_alloc,
		       pool->mempool_stats[i].num_reuse,
		       pool->mempool_stats[i].num_discard);
	}
	MEM_freeN(pool->mempool_stats);
#endif

	MEM_freeN(pool);

	BLI_end_threaded_malloc();
}
Beispiel #2
0
void BLI_task_pool_free(TaskPool *pool)
{
	BLI_task_pool_stop(pool);

	BLI_mutex_end(&pool->num_mutex);
	BLI_condition_end(&pool->num_cond);

	BLI_mutex_end(&pool->user_mutex);

	MEM_freeN(pool);

	BLI_end_threaded_malloc();
}
Beispiel #3
0
void BLI_task_scheduler_free(TaskScheduler *scheduler)
{
	Task *task;

	/* stop all waiting threads */
	BLI_mutex_lock(&scheduler->queue_mutex);
	scheduler->do_exit = true;
	BLI_condition_notify_all(&scheduler->queue_cond);
	BLI_mutex_unlock(&scheduler->queue_mutex);

	/* delete threads */
	if (scheduler->threads) {
		int i;

		for (i = 0; i < scheduler->num_threads; i++) {
			if (pthread_join(scheduler->threads[i], NULL) != 0)
				fprintf(stderr, "TaskScheduler failed to join thread %d/%d\n", i, scheduler->num_threads);
		}

		MEM_freeN(scheduler->threads);
	}

	/* Delete task thread data */
	if (scheduler->task_threads) {
		MEM_freeN(scheduler->task_threads);
	}

	/* Delete task memory pool */
	if (scheduler->task_mempool) {
		for (int i = 0; i <= scheduler->num_threads; ++i) {
			for (int j = 0; j < scheduler->task_mempool[i].num_tasks; ++j) {
				MEM_freeN(scheduler->task_mempool[i].tasks[j]);
			}
		}
		MEM_freeN(scheduler->task_mempool);
	}

	/* delete leftover tasks */
	for (task = scheduler->queue.first; task; task = task->next) {
		task_data_free(task, 0);
	}
	BLI_freelistN(&scheduler->queue);

	/* delete mutex/condition */
	BLI_mutex_end(&scheduler->queue_mutex);
	BLI_condition_end(&scheduler->queue_cond);

	MEM_freeN(scheduler);
}
Beispiel #4
0
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);
}