src/raytracer.cc
branchpyrit
changeset 52 a6413a3d741d
parent 51 89fec8668768
child 53 228cb8bfdd54
equal deleted inserted replaced
51:89fec8668768 52:a6413a3d741d
    22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    24  * THE SOFTWARE.
    24  * THE SOFTWARE.
    25  */
    25  */
    26 
    26 
    27 #ifdef PTHREADS
       
    28 #include <pthread.h>
    27 #include <pthread.h>
    29 #endif
       
    30 
       
    31 #include <stdio.h>
    28 #include <stdio.h>
    32 #include <malloc.h>
    29 #include <malloc.h>
    33 #include "raytracer.h"
    30 #include "raytracer.h"
    34 
    31 
    35 int pyrit_verbosity = 2;
    32 int pyrit_verbosity = 4;
    36 
    33 
    37 // Hammersley spherical point distribution
    34 // Hammersley spherical point distribution
    38 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
    35 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
    39 Vector3 Raytracer::SphereDistribute(int i, int n, Float extent, Vector3 &normal)
    36 Vector3 Raytracer::SphereDistribute(int i, int n, Float extent, Vector3 &normal)
    40 {
    37 {
   405 	for (;;)
   402 	for (;;)
   406 	{
   403 	{
   407 		pthread_mutex_lock(&rt->sample_queue_mutex);
   404 		pthread_mutex_lock(&rt->sample_queue_mutex);
   408 		pthread_cond_signal(&rt->worker_ready_cond);
   405 		pthread_cond_signal(&rt->worker_ready_cond);
   409 
   406 
   410 		while (rt->sample_queue.empty()) {
   407 		while (rt->sample_queue_count == 0)
       
   408 		{
   411 			if (rt->sample_queue_end)
   409 			if (rt->sample_queue_end)
   412 			{
   410 			{
       
   411 				dbgmsg(4, "T thread [%d] exiting\n", pthread_self());
   413 				pthread_mutex_unlock(&rt->sample_queue_mutex);
   412 				pthread_mutex_unlock(&rt->sample_queue_mutex);
   414 				pthread_exit(NULL);
   413 				pthread_exit(NULL);
   415 			}
   414 			}
   416 			pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
   415 			pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
   417 		}
   416 		}
   418 
   417 
   419 		sample = rt->sample_queue.front();
   418 		sample = rt->sample_queue[rt->sample_queue_pos++];
   420 		rt->sample_queue.pop();
   419 		rt->sample_queue_count--;
       
   420 		if (rt->sample_queue_pos > rt->sample_queue_max)
       
   421 			rt->sample_queue_pos = 0;
   421 
   422 
   422 		pthread_mutex_unlock(&rt->sample_queue_mutex);
   423 		pthread_mutex_unlock(&rt->sample_queue_mutex);
   423 
   424 
   424 		// do the work
   425 		// do the work
   425 		pthread_mutex_lock(&rt->sampler_mutex);
   426 		pthread_mutex_lock(&rt->sampler_mutex);
   441 {
   442 {
   442 	if (!sampler || !camera || !top)
   443 	if (!sampler || !camera || !top)
   443 		return;
   444 		return;
   444 
   445 
   445 	sample_queue_end = false;
   446 	sample_queue_end = false;
       
   447 	sample_queue_max = 2000;
       
   448 	sample_queue = new Sample* [sample_queue_max+1];
       
   449 	sample_queue_pos = 0;
       
   450 	sample_queue_count = 0;
   446 
   451 
   447 	// create workers
   452 	// create workers
   448 	dbgmsg(1, "* running %d threads\n", num_threads);
   453 	dbgmsg(1, "* running %d threads\n", num_threads);
   449 	pthread_t threads[num_threads];
   454 	pthread_t threads[num_threads];
   450 	for (int t = 0; t < num_threads; t++)
   455 	for (int t = 0; t < num_threads; t++)
   458 
   463 
   459 	dbgmsg(1, "* raytracing...\n");
   464 	dbgmsg(1, "* raytracing...\n");
   460 	dbgmsg(2, "-  0%% done");
   465 	dbgmsg(2, "-  0%% done");
   461 
   466 
   462 	sampler->init();
   467 	sampler->init();
       
   468 	Sample *sample;
   463 	int sampnum = 0, sampdone;
   469 	int sampnum = 0, sampdone;
   464 	Sample *sample;
   470 	int my_pos = 0, my_count;
   465 
   471 
   466 	pthread_mutex_lock(&sampler_mutex);
   472 	pthread_mutex_lock(&sampler_mutex);
   467 	while ( (sampnum = sampler->initSampleSet()) > 0 )
   473 	while ( (sampnum = sampler->initSampleSet()) > 0 )
   468 	{
   474 	{
   469 		sampdone = 0;
   475 		sampdone = 0;
   470 		while ( (sample = sampler->nextSample()) != NULL )
   476 		for (;;)
   471 		{
   477 		{
       
   478 			my_count = 0;
       
   479 			while ( (sample = sampler->nextSample()) != NULL )
       
   480 			{
       
   481 				sample_queue[my_pos++] = sample;
       
   482 				my_count++;
       
   483 				if (my_count >= 1000)
       
   484 					break;
       
   485 				if (my_pos > sample_queue_max)
       
   486 					my_pos = 0;
       
   487 			}
       
   488 			if (sample == NULL)
       
   489 				break;
       
   490 
   472 			pthread_mutex_unlock(&sampler_mutex);
   491 			pthread_mutex_unlock(&sampler_mutex);
   473 			pthread_mutex_lock(&sample_queue_mutex);
   492 			pthread_mutex_lock(&sample_queue_mutex);
   474 			sample_queue.push(sample);
   493 			sample_queue_count += my_count;
   475 
   494 
   476 			// wait for workers if there is enough samples ready on queue
   495 			// wait for workers if there is enough samples ready on queue
   477 			if (sample_queue.size() > 1000)
   496 			while (sample_queue_count > 1000)
   478 			{
   497 			{
   479 				while (sample_queue.size() > 100)
   498 				pthread_cond_signal(&sample_queue_cond);
   480 				{
   499 				pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
   481 					pthread_cond_signal(&sample_queue_cond);
   500 			}
   482 					pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
   501 
   483 				}
   502 			sampdone += my_count;
   484 			}
   503 			dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue_count)*100/sampnum);
   485 
       
   486 			sampdone++;
       
   487 			if ((sampdone & 0xfff) == 0)
       
   488 				dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue.size())*100/sampnum);
       
   489 
   504 
   490 			pthread_cond_signal(&sample_queue_cond);
   505 			pthread_cond_signal(&sample_queue_cond);
   491 			pthread_mutex_unlock(&sample_queue_mutex);
   506 			pthread_mutex_unlock(&sample_queue_mutex);
   492 			pthread_mutex_lock(&sampler_mutex);
   507 			pthread_mutex_lock(&sampler_mutex);
   493 		}
   508 		}
   498 	// wait for workers
   513 	// wait for workers
   499 	dbgmsg(2, "- waiting for threads to finish\n");
   514 	dbgmsg(2, "- waiting for threads to finish\n");
   500 
   515 
   501 	pthread_mutex_lock(&sample_queue_mutex);
   516 	pthread_mutex_lock(&sample_queue_mutex);
   502 	sample_queue_end = true;
   517 	sample_queue_end = true;
   503 	while (!sample_queue.empty())
   518 	while (sample_queue_count)
   504 	{
   519 	{
   505 		pthread_cond_broadcast(&sample_queue_cond);
   520 		pthread_cond_broadcast(&sample_queue_cond);
   506 		pthread_mutex_unlock(&sample_queue_mutex);
   521 		pthread_mutex_unlock(&sample_queue_mutex);
   507 		pthread_mutex_lock(&sample_queue_mutex);
   522 		pthread_mutex_lock(&sample_queue_mutex);
   508 	}
   523 	}
   510 	pthread_mutex_unlock(&sample_queue_mutex);
   525 	pthread_mutex_unlock(&sample_queue_mutex);
   511 
   526 
   512 	for (int t = 0; t < num_threads; t++)
   527 	for (int t = 0; t < num_threads; t++)
   513 		pthread_join(threads[t], NULL);
   528 		pthread_join(threads[t], NULL);
   514 
   529 
       
   530 	delete[] sample_queue;
       
   531 
   515 #if 0
   532 #if 0
   516 
       
   517 	RenderrowData *d;
   533 	RenderrowData *d;
   518 
   534 
   519 	Float S = 0.5/w;
   535 	Float S = 0.5/w;
   520 	Vector3 dfix = camera->u*(-w/2.0*S/camera->f)
   536 	Vector3 dfix = camera->u*(-w/2.0*S/camera->f)
   521 		+ camera->v*(h/2.0*S/camera->f) + camera->p;
   537 		+ camera->v*(h/2.0*S/camera->f) + camera->p;