src/raytracer.cc
branchpyrit
changeset 50 14a727b70d07
parent 49 558fde7da82a
child 51 89fec8668768
equal deleted inserted replaced
49:558fde7da82a 50:14a727b70d07
   394 #endif
   394 #endif
   395 	return (void *)d;
   395 	return (void *)d;
   396 }
   396 }
   397 #endif
   397 #endif
   398 
   398 
       
   399 void *Raytracer::raytrace_worker(void *d)
       
   400 {
       
   401 	Raytracer *rt = (Raytracer*)d;
       
   402 	Sample *sample;
       
   403 	Colour col;
       
   404 	Ray ray;
       
   405 	for (;;)
       
   406 	{
       
   407 		cout<<"#worker "<<pthread_self()<<" locking queue"<<endl;
       
   408 		pthread_mutex_lock(&rt->sample_queue_mutex);
       
   409 		pthread_cond_signal(&rt->worker_ready_cond);
       
   410 
       
   411 		// if queue is empty, wait for samples
       
   412 		while (rt->sample_queue.empty()) {
       
   413 			if (rt->sample_queue_end)
       
   414 			{
       
   415 				cout<<"#worker "<<pthread_self()<<" end of queue, unlocking queue and exiting..."<<endl;
       
   416 				pthread_mutex_unlock(&rt->sample_queue_mutex);
       
   417 				pthread_exit(NULL);
       
   418 			}
       
   419 			cout<<"#worker "<<pthread_self()<<" waiting for cond"<<endl;
       
   420 			pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
       
   421 		}
       
   422 
       
   423 
       
   424 		sample = rt->sample_queue.front();
       
   425 		rt->sample_queue.pop();
       
   426 		cout<<"#worker "<<pthread_self()<<" unlocking queue"<<endl;
       
   427 		pthread_mutex_unlock(&rt->sample_queue_mutex);
       
   428 
       
   429 		// do the work
       
   430 		cout<<"#worker "<<pthread_self()<<" locking sampler (camera)"<<endl;
       
   431 		pthread_mutex_lock(&rt->sampler_mutex);
       
   432 		ray = rt->camera->makeRay(sample);
       
   433 		cout<<"#worker "<<pthread_self()<<" unlocking sampler (camera)"<<endl;
       
   434 		pthread_mutex_unlock(&rt->sampler_mutex);
       
   435 
       
   436 		cout<<"#worker "<<pthread_self()<<" ray tracing..."<<endl;
       
   437 		col = rt->raytrace(ray, 0, NULL);
       
   438 		
       
   439 		// save the result
       
   440 		cout<<"#worker "<<pthread_self()<<" locking sampler"<<endl;
       
   441 		pthread_mutex_lock(&rt->sampler_mutex);
       
   442 		rt->sampler->saveSample(sample, col);
       
   443 		cout<<"#worker "<<pthread_self()<<" unlocking sampler"<<endl;
       
   444 		pthread_mutex_unlock(&rt->sampler_mutex);
       
   445 
       
   446 		delete sample;
       
   447 	}
       
   448 }
       
   449 
   399 void Raytracer::render()
   450 void Raytracer::render()
   400 {
   451 {
   401 	if (!sampler || !camera || !top)
   452 	if (!sampler || !camera || !top)
   402 		return;
   453 		return;
   403 
   454 
       
   455 	sample_queue_end = false;
       
   456 
   404 	// create workers
   457 	// create workers
   405 	// ...
   458 	dbgmsg(1, "* using %d threads\n", num_threads);
       
   459 	pthread_t threads[num_threads];
       
   460 	for (int t = 0; t < num_threads; t++)
       
   461 	{
       
   462 		int rc = pthread_create(&threads[t], NULL, raytrace_worker, (void*)this);
       
   463 		if (rc) {
       
   464 			dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc);
       
   465 			exit(1);
       
   466 		}
       
   467 	}
   406 
   468 
   407 	sampler->init();
   469 	sampler->init();
   408 	int sampnum = 0;
   470 	int sampnum = 0;
       
   471 	cout<<"locking sampler"<<endl;
       
   472 	pthread_mutex_lock(&sampler_mutex);
   409 	while ( (sampnum = sampler->initSampleSet()) > 0 )
   473 	while ( (sampnum = sampler->initSampleSet()) > 0 )
   410 	{
   474 	{
   411 		Sample *sample, *prev = NULL;
   475 		Sample *sample;
   412 		while ( (sample = sampler->nextSample(prev)) != NULL )
   476 		while ( (sample = sampler->nextSample()) != NULL )
   413 		{
   477 		{
   414 			Ray ray = camera->makeRay(sample);
   478 			cout<<"unlocking sampler and locking queue"<<endl;
   415 			//raystack->push(ray);
   479 			pthread_mutex_unlock(&sampler_mutex);
   416 
   480 			pthread_mutex_lock(&sample_queue_mutex);
   417 			// in worker:
   481 			sample_queue.push(sample);
   418 			Colour col = raytrace(ray, 0, NULL);
   482 
   419 			sampler->saveSample(sample, col);
   483 			if (sample_queue.size() > 1000)
   420 
   484 			{
   421 			delete prev;
   485 			    while (sample_queue.size() > 100)
   422 			prev = sample;
   486 			    {
       
   487 				pthread_cond_signal(&sample_queue_cond);
       
   488 				pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
       
   489 			    }
       
   490 			}
       
   491 
       
   492 			cout<<"sending signal and unlocking queue"<<endl;
       
   493 			pthread_cond_signal(&sample_queue_cond);
       
   494 			pthread_mutex_unlock(&sample_queue_mutex);
       
   495 
   423 			sampnum--;
   496 			sampnum--;
   424 			if ((sampnum % 1000) == 0)
   497 			if ((sampnum % 1000) == 0)
   425 				dbgmsg(2, "\b\b\b\b\b\b\b\b%8d", sampnum);
   498 				dbgmsg(2, "\b\b\b\b\b\b\b\b%8d", sampnum);
       
   499 
       
   500 
       
   501 			cout<<"locking sampler"<<endl;
       
   502 			pthread_mutex_lock(&sampler_mutex);
   426 		}
   503 		}
   427 		dbgmsg(2, "\n");
   504 		dbgmsg(2, "\n");
   428 	}
   505 	}
       
   506 	cout<<"unlocking sampler"<<endl;
       
   507 	pthread_mutex_unlock(&sampler_mutex);
   429 
   508 
   430 	// wait for workers
   509 	// wait for workers
   431 	// ...
   510 	dbgmsg(2, "- waiting for threads to finish\n");
       
   511 
       
   512 	cout<<"locking queue"<<endl;
       
   513 	pthread_mutex_lock(&sample_queue_mutex);
       
   514 	sample_queue_end = true;
       
   515 	while (!sample_queue.empty())
       
   516 	{
       
   517 		cout<<"broadcasting signal and unlocking queue"<<endl;
       
   518 		pthread_cond_broadcast(&sample_queue_cond);
       
   519 		pthread_mutex_unlock(&sample_queue_mutex);
       
   520 		cout<<"locking queue"<<endl;
       
   521 		pthread_mutex_lock(&sample_queue_mutex);
       
   522 	}
       
   523 	cout<<"broadcasting signal and unlocking queue"<<endl;
       
   524 	pthread_cond_broadcast(&sample_queue_cond);
       
   525 	pthread_mutex_unlock(&sample_queue_mutex);
       
   526 
       
   527 	cout<<"joining threads"<<endl;
       
   528 	for (int t = 0; t < num_threads; t++)
       
   529 		pthread_join(threads[t], NULL);
       
   530 
       
   531 	cout<<"done!"<<endl;
   432 
   532 
   433 #if 0
   533 #if 0
   434 
   534 
   435 	RenderrowData *d;
   535 	RenderrowData *d;
   436 
   536