slighly optimized raytrace_worker pyrit
authorRadek Brich <radek.brich@devl.cz>
Sat, 29 Mar 2008 02:17:22 +0100
branchpyrit
changeset 53 228cb8bfdd54
parent 52 a6413a3d741d
child 54 dbe3c7a4e0f0
slighly optimized raytrace_worker
include/raytracer.h
include/sampler.h
include/scene.h
src/raytracer.cc
src/sampler.cc
src/scene.cc
--- a/include/raytracer.h	Fri Mar 28 23:30:04 2008 +0100
+++ b/include/raytracer.h	Sat Mar 29 02:17:22 2008 +0100
@@ -62,7 +62,7 @@
 
 	Vector3 SphereDistribute(int i, int n, Float extent, Vector3 &normal);
 
-	Sample **sample_queue;
+	Sample *sample_queue;
 	int sample_queue_max, sample_queue_pos, sample_queue_count;
 	bool sample_queue_end;
 	pthread_mutex_t sample_queue_mutex, sampler_mutex;
--- a/include/sampler.h	Fri Mar 28 23:30:04 2008 +0100
+++ b/include/sampler.h	Sat Mar 29 02:17:22 2008 +0100
@@ -37,8 +37,10 @@
  */
 class Sample
 {
+	friend class Sampler;
 public:
 	Float x,y;
+	int sx,sy,osa_samp;
 };
 
 /**
@@ -62,17 +64,8 @@
 	void resetBuffer(Float *abuffer, int &aw, int &ah) { buffer = abuffer; w = aw; h = ah; };
 	virtual void init() = 0;
 	virtual int initSampleSet() = 0;
-	virtual Sample *nextSample() = 0;
-	virtual void saveSample(Sample *samp, Colour &col) = 0;
-};
-
-/**
- * default sample
- */
-class DefaultSample: public Sample
-{
-	friend class DefaultSampler;
-	int sx,sy,osa_samp;
+	virtual bool nextSample(Sample *s) = 0;
+	virtual void saveSample(Sample &samp, Colour &col) = 0;
 };
 
 /**
@@ -90,8 +83,8 @@
 		Sampler(abuffer, aw, ah), phase(-1), subsample(8), oversample(0) {};
 	void init();
 	int initSampleSet();
-	Sample *nextSample();
-	void saveSample(Sample *samp, Colour &col);
+	bool nextSample(Sample *s);
+	void saveSample(Sample &samp, Colour &col);
 
 	void setSubsample(int sub) { subsample = sub; };
 	int getSubsample() { return subsample; };
--- a/include/scene.h	Fri Mar 28 23:30:04 2008 +0100
+++ b/include/scene.h	Sat Mar 29 02:17:22 2008 +0100
@@ -74,7 +74,12 @@
 	void rotate(const Quaternion &q);
 	void move(const Float fw, const Float left, const Float up);
 
-	Ray makeRay(Sample *samp);
+	Ray makeRay(Sample &samp)
+	{
+		Vector3 dir = p + (u*samp.x - v*samp.y)*F;
+		dir.normalize();
+		return Ray(eye, dir);
+	};
 };
 
 /**
--- a/src/raytracer.cc	Fri Mar 28 23:30:04 2008 +0100
+++ b/src/raytracer.cc	Sat Mar 29 02:17:22 2008 +0100
@@ -29,7 +29,7 @@
 #include <malloc.h>
 #include "raytracer.h"
 
-int pyrit_verbosity = 4;
+int pyrit_verbosity = 2;
 
 // Hammersley spherical point distribution
 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
@@ -396,8 +396,9 @@
 void *Raytracer::raytrace_worker(void *d)
 {
 	Raytracer *rt = (Raytracer*)d;
-	Sample *sample;
-	Colour col;
+	Sample my_queue[80];
+	Colour my_colours[80];
+	int my_count;
 	Ray ray;
 	for (;;)
 	{
@@ -415,26 +416,33 @@
 			pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
 		}
 
-		sample = rt->sample_queue[rt->sample_queue_pos++];
-		rt->sample_queue_count--;
-		if (rt->sample_queue_pos > rt->sample_queue_max)
-			rt->sample_queue_pos = 0;
+		if (rt->sample_queue_count >= 80)
+			my_count = 80;
+		else
+			my_count = rt->sample_queue_count;
+		rt->sample_queue_count -= my_count;
+
+		for (int i = 0; i < my_count; i++)
+		{
+			my_queue[i] = rt->sample_queue[rt->sample_queue_pos++];
+			if (rt->sample_queue_pos > rt->sample_queue_max)
+				rt->sample_queue_pos = 0;
+		}
 
 		pthread_mutex_unlock(&rt->sample_queue_mutex);
 
 		// do the work
-		pthread_mutex_lock(&rt->sampler_mutex);
-		ray = rt->camera->makeRay(sample);
-		pthread_mutex_unlock(&rt->sampler_mutex);
-
-		col = rt->raytrace(ray, 0, NULL);
+		for (int i = 0; i < my_count; i++)
+		{
+			ray = rt->camera->makeRay(my_queue[i]);
+			my_colours[i] = rt->raytrace(ray, 0, NULL);
+		}
 
-		// save the result
+		// save the results
 		pthread_mutex_lock(&rt->sampler_mutex);
-		rt->sampler->saveSample(sample, col);
+		for (int i = 0; i < my_count; i++)
+			rt->sampler->saveSample(my_queue[i], my_colours[i]);
 		pthread_mutex_unlock(&rt->sampler_mutex);
-
-		delete sample;
 	}
 }
 
@@ -445,7 +453,7 @@
 
 	sample_queue_end = false;
 	sample_queue_max = 2000;
-	sample_queue = new Sample* [sample_queue_max+1];
+	sample_queue = new Sample [sample_queue_max+1];
 	sample_queue_pos = 0;
 	sample_queue_count = 0;
 
@@ -465,9 +473,9 @@
 	dbgmsg(2, "-  0%% done");
 
 	sampler->init();
-	Sample *sample;
 	int sampnum = 0, sampdone;
 	int my_pos = 0, my_count;
+	bool more_samples;
 
 	pthread_mutex_lock(&sampler_mutex);
 	while ( (sampnum = sampler->initSampleSet()) > 0 )
@@ -476,16 +484,15 @@
 		for (;;)
 		{
 			my_count = 0;
-			while ( (sample = sampler->nextSample()) != NULL )
+			while ( more_samples = sampler->nextSample(&sample_queue[my_pos++]) )
 			{
-				sample_queue[my_pos++] = sample;
 				my_count++;
 				if (my_count >= 1000)
 					break;
 				if (my_pos > sample_queue_max)
 					my_pos = 0;
 			}
-			if (sample == NULL)
+			if (!more_samples)
 				break;
 
 			pthread_mutex_unlock(&sampler_mutex);
@@ -528,69 +535,6 @@
 		pthread_join(threads[t], NULL);
 
 	delete[] sample_queue;
-
-#if 0
-	RenderrowData *d;
-
-	Float S = 0.5/w;
-	Vector3 dfix = camera->u*(-w/2.0*S/camera->f)
-		+ camera->v*(h/2.0*S/camera->f) + camera->p;
-	Vector3 dx = camera->u * (S/camera->f);
-	Vector3 dy = camera->v * (-S/camera->f);
-
-#ifdef PTHREADS
-	dbgmsg(1, "* pthreads enabled, using %d threads\n", num_threads);
-	pthread_t threads[num_threads];
-	for (int t = 0; t < num_threads; t++)
-		threads[t] = pthread_self();
-	int t = 0;
-#endif
-
-	/* for each pixel... */
-	dbgmsg(1, "* raytracing...\n");
-	dbgmsg(2, "- row   0 (  0%% done)");
-	for (int y = 0; y < h; y += subsample)
-	{
-		d = (RenderrowData*) malloc(sizeof(RenderrowData));
-		d->rt = this;
-		d->w = w;
-		d->eye = camera->eye;
-		d->dfix = dfix;
-		d->dx = dx;
-		d->dy = dy;
-		d->iter = buffer + y*3*w;
-#ifdef PTHREADS
-		/* create new thread and increase 't' */
-		int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d);
-		if (rc) {
-			dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc);
-			exit(1);
-		}
-		/* when 't' overflows, reset it */
-		if (t >= num_threads)
-			t = 0;
-		/* wait for next thread in fifo queue, so the descriptor can be reused;
-		   this also limits number of running threads */
-		if (!pthread_equal(threads[t], pthread_self()))
-			if (pthread_join(threads[t], (void**)&d) == 0)
-				free(d);
-#else
-		renderrow((void *)d);
-		free(d);
-#endif
-		dfix += dy*subsample;
-		dbgmsg(2, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1));
-	}
-	dbgmsg(2, "\n");
-
-#ifdef PTHREADS
-	dbgmsg(2, "- waiting for threads to finish\n");
-	for (t = 0; t < num_threads; t++)
-		if (pthread_join(threads[t], (void**)&d) == 0)
-			free(d);
-#endif
-
-#endif
 }
 
 void Raytracer::addlight(Light *light)
@@ -605,5 +549,5 @@
 	ao_angle = angle;
 	if (ao_distance == 0)
 		/* 0 ==> Inf */
-		ao_distance = FLT_MAX;
+		ao_distance = Inf;
 }
--- a/src/sampler.cc	Fri Mar 28 23:30:04 2008 +0100
+++ b/src/sampler.cc	Sat Mar 29 02:17:22 2008 +0100
@@ -59,10 +59,8 @@
 	}
 }
 
-Sample* DefaultSampler::nextSample()
+bool DefaultSampler::nextSample(Sample* s)
 {
-	DefaultSample *s = new DefaultSample;
-
 	/* grid oversampling */
 	static const int gridsamples[] = {1,5,9,16};
 	static const Float osa5x[] = {0.0, -0.4, +0.4, +0.4, -0.4};
@@ -109,11 +107,10 @@
 				sx = 0;
 				sy++;
 			}
+
 			if (sy >= h)
-			{
-				delete s;
-				return NULL;
-			}
+				return false;
+
 			s->x = (Float)sx/h - (Float)w/h/2.0;
 			s->y = (Float)sy/h - 0.5;
 			osa_samp = 0;
@@ -133,13 +130,13 @@
 	s->sx = sx;
 	s->sy = sy;
 	s->osa_samp = osa_samp;
-	return s;
+
+	return true;
 }
 
-void DefaultSampler::saveSample(Sample *samp, Colour &col)
+void DefaultSampler::saveSample(Sample &samp, Colour &col)
 {
-	DefaultSample *sp = static_cast<DefaultSample*>(samp);
-	Float *buf = buffer + 3*(sp->sy*w + sp->sx);
+	Float *buf = buffer + 3*(samp.sy * w + samp.sx);
 	if (oversample)
 	{
 		*(buf+0) += col.r;
--- a/src/scene.cc	Fri Mar 28 23:30:04 2008 +0100
+++ b/src/scene.cc	Sat Mar 29 02:17:22 2008 +0100
@@ -75,13 +75,6 @@
 	eye = eye + fw*p + left*u + up*v;
 }
 
-Ray Camera::makeRay(Sample *samp)
-{
-	Vector3 dir = p + (u*samp->x - v*samp->y)*F;
-	dir.normalize();
-	return Ray(eye, dir);
-}
-
 /* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */
 bool BBox::intersect(const Ray &ray, Float &a, Float &b)
 {