Пример #1
0
void BLI_insert_work(ThreadedWorker *worker, void *param)
{
	WorkParam *p = MEM_callocN(sizeof(WorkParam), "workparam");
	int index;
	
	if (BLI_available_threads(&worker->threadbase) == 0)
	{
		index = worker->total;
		while(index == worker->total)
		{
			PIL_sleep_ms(worker->sleep_time);
			
			for (index = 0; index < worker->total; index++)
			{
				if (worker->busy[index] == 0)
				{
					BLI_remove_thread_index(&worker->threadbase, index);
					break;
				}
			}
		}
	}
	else
	{
		index = BLI_available_thread_index(&worker->threadbase);
	}
	
	worker->busy[index] = 1;
	
	p->param = param;
	p->index = index;
	p->worker = worker;
	
	BLI_insert_thread(&worker->threadbase, p);
}
Пример #2
0
/* optimized tree execute test for compositing */
static void ntreeCompositExecTreeOld(bNodeTree *ntree, RenderData *rd, int do_preview)
{
	bNodeExec *nodeexec;
	bNode *node;
	ListBase threads;
	ThreadData thdata;
	int totnode, curnode, rendering = TRUE, n;
	bNodeTreeExec *exec = ntree->execdata;

	if (do_preview)
		ntreeInitPreview(ntree, 0, 0);
	
	if (!ntree->execdata) {
		/* XXX this is the top-level tree, so we use the ntree->execdata pointer. */
		exec = ntreeCompositBeginExecTree(ntree, 1);
	}
	ntree_composite_texnode(ntree, 1);
	
	/* prevent unlucky accidents */
	if (G.background)
		rd->scemode &= ~R_COMP_CROP;
	
	/* setup callerdata for thread callback */
	thdata.rd= rd;
	thdata.stack= exec->stack;
	
	/* fixed seed, for example noise texture */
	BLI_srandom(rd->cfra);

	/* sets need_exec tags in nodes */
	curnode = totnode= setExecutableNodes(exec, &thdata);

	BLI_init_threads(&threads, exec_composite_node, rd->threads);
	
	while (rendering) {
		
		if (BLI_available_threads(&threads)) {
			nodeexec= getExecutableNode(exec);
			if (nodeexec) {
				node = nodeexec->node;
				if (ntree->progress && totnode)
					ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode));
				if (ntree->stats_draw) {
					char str[128];
					BLI_snprintf(str, sizeof(str), "Compositing %d %s", curnode, node->name);
					ntree->stats_draw(ntree->sdh, str);
				}
				curnode--;
				
				node->threaddata = &thdata;
				node->exec= NODE_PROCESSING;
				BLI_insert_thread(&threads, nodeexec);
			}
			else
				PIL_sleep_ms(50);
		}
		else
			PIL_sleep_ms(50);
		
		rendering= 0;
		/* test for ESC */
		if (ntree->test_break && ntree->test_break(ntree->tbh)) {
			for (node= ntree->nodes.first; node; node= node->next)
				node->exec |= NODE_READY;
		}
		
		/* check for ready ones, and if we need to continue */
		for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
			node = nodeexec->node;
			if (node->exec & NODE_READY) {
				if ((node->exec & NODE_FINISHED)==0) {
					BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */
					node->exec |= NODE_FINISHED;
					
					/* freeing unused buffers */
					if (rd->scemode & R_COMP_FREE)
						freeExecutableNode(exec);
				}
			}
			else rendering= 1;
		}
	}
	
	BLI_end_threads(&threads);
	
	/* XXX top-level tree uses the ntree->execdata pointer */
	ntreeCompositEndExecTree(exec, 1);
}
Пример #3
0
/* Precache a volume into a 3D voxel grid.
 * The voxel grid is stored in the ObjectInstanceRen, 
 * in camera space, aligned with the ObjectRen's bounding box.
 * Resolution is defined by the user.
 */
void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma)
{
	VolumePrecache *vp;
	VolPrecachePart *nextpa, *pa;
	RayObject *tree;
	ShadeInput shi;
	ListBase threads;
	float *bbmin=obi->obr->boundbox[0], *bbmax=obi->obr->boundbox[1];
	int parts[3] = {1, 1, 1}, totparts;
	
	int caching=1, counter=0;
	int totthread = re->r.threads;
	
	double time, lasttime= PIL_check_seconds_timer();
	
	R = *re;

	/* create a raytree with just the faces of the instanced ObjectRen, 
	 * used for checking if the cached point is inside or outside. */
	//tree = create_raytree_obi(obi, bbmin, bbmax);
	tree = makeraytree_object(&R, obi);
	if (!tree) return;
	INIT_MINMAX(bbmin, bbmax);
	RE_rayobject_merge_bb( tree, bbmin, bbmax);

	vp = MEM_callocN(sizeof(VolumePrecache), "volume light cache");
	
	if (!precache_resolution(vp, bbmin, bbmax, ma->vol.precache_resolution)) {
		MEM_freeN(vp);
		vp = NULL;
		return;
	}

	vp->data_r = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data red channel");
	vp->data_g = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data green channel");
	vp->data_b = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data blue channel");
	obi->volume_precache = vp;

	/* Need a shadeinput to calculate scattering */
	precache_setup_shadeinput(re, obi, ma, &shi);
	
	precache_init_parts(re, tree, &shi, obi, totthread, parts);
	totparts = parts[0] * parts[1] * parts[2];
	
	BLI_init_threads(&threads, vol_precache_part, totthread);
	
	while(caching) {

		if(BLI_available_threads(&threads) && !(re->test_break(re->tbh))) {
			nextpa = precache_get_new_part(re);
			if (nextpa) {
				nextpa->working = 1;
				BLI_insert_thread(&threads, nextpa);
			}
		}
		else PIL_sleep_ms(50);

		caching=0;
		counter=0;
		for(pa= re->volume_precache_parts.first; pa; pa= pa->next) {
			
			if(pa->done) {
				counter++;
				BLI_remove_thread(&threads, pa);
			} else
				caching = 1;
		}
		
		if (re->test_break(re->tbh) && BLI_available_threads(&threads)==totthread)
			caching=0;
		
		time= PIL_check_seconds_timer();
		if(time-lasttime>1.0f) {
			char str[64];
			sprintf(str, "Precaching volume: %d%%", (int)(100.0f * ((float)counter / (float)totparts)));
			re->i.infostr= str;
			re->stats_draw(re->sdh, &re->i);
			re->i.infostr= NULL;
			lasttime= time;
		}
	}
	
	BLI_end_threads(&threads);
	BLI_freelistN(&re->volume_precache_parts);
	
	if(tree) {
		//TODO: makeraytree_object creates a tree and saves it on OBI, if we free this tree we should also clear other pointers to it
		//RE_rayobject_free(tree);
		//tree= NULL;
	}
	
	lightcache_filter(obi->volume_precache);
	
	if (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE))
	{
		multiple_scattering_diffusion(re, vp, ma);
	}
}