--- a/src/raytracer.cc Mon Apr 21 19:35:27 2008 +0200
+++ b/src/raytracer.cc Tue Apr 22 13:33:12 2008 +0200
@@ -235,164 +235,6 @@
}
}
-#if 0
-static void *renderrow(void *data)
-{
- RenderrowData *d = (RenderrowData*) data;
- const int subsample = d->rt->getSubsample();
- const Float subsample2 = 1.0/(subsample*subsample);
- const int oversample = d->rt->getOversample();
- const int ww = d->w*3;
- Vector3 dir = d->dfix;
- for (int x = 0; x < d->w; x += subsample) {
- // generate a ray from eye passing through this pixel
- if (subsample > 1)
- {
- Colour ic;
- // top-left
- dir.normalize();
- Ray ray(d->eye, dir);
- Colour c1 = d->rt->raytrace(ray, 0, NULL);
- // top-right
- Vector3 tmpdir = dir + (subsample-1)*d->dx;
- tmpdir.normalize();
- ray.dir = tmpdir;
- Colour c2 = d->rt->raytrace(ray, 0, NULL);
- // bottom right
- tmpdir += (subsample-1)*d->dy;
- tmpdir.normalize();
- ray.dir = tmpdir;
- Colour c4 = d->rt->raytrace(ray, 0, NULL);
- // bottom left
- tmpdir = dir + (subsample-1)*d->dy;
- tmpdir.normalize();
- ray.dir = tmpdir;
- Colour c3 = d->rt->raytrace(ray, 0, NULL);
- // are the colors similar?
- Float m = (c1-c2).mag2();
- m = max(m, (c2-c3).mag2());
- m = max(m, (c3-c4).mag2());
- m = max(m, (c4-c1).mag2());
- if (m < 0.001)
- {
- // interpolate
- Float *i = d->iter;
- for (int x = 0; x < subsample; x++)
- {
- for (int y = 0; y < subsample; y++)
- {
- ic = c1*(subsample-x)*(subsample-y)*subsample2
- + c2*(x)*(subsample-y)*subsample2
- + c3*(subsample-x)*(y)*subsample2
- + c4*(x)*(y)*subsample2;
- *(i + ww*y) = ic.r;
- *(i + ww*y + 1) = ic.g;
- *(i + ww*y + 2) = ic.b;
- }
- i += 3;
- }
- d->iter = i;
- }
- else
- {
- // render all pixels
- Vector3 tmpdir = dir;
-
- if (oversample)
- {
- for (int x = 0; x < subsample; x++)
- {
- for (int y = 0; y < subsample; y++)
- {
- Vector3 tmp2dir = tmpdir + y*d->dy;
- samplepixel(ic, tmp2dir, d, oversample);
- *(d->iter + ww*y) = ic.r;
- *(d->iter + ww*y + 1) = ic.g;
- *(d->iter + ww*y + 2) = ic.b;
- }
- d->iter += 3;
- tmpdir += d->dx;
- }
- }
- else
- {
- /* this is so complex because it tries to reuse
- already computed corner pixels
- though, above code will also work for non-oversampling... */
- // first column
- *(d->iter) = c1.r;
- *(d->iter + 1) = c1.g;
- *(d->iter + 2) = c1.b;
- for (int y = 1; y < subsample-1; y++)
- {
- Vector3 tmp2dir = tmpdir + y*d->dy;
- tmp2dir.normalize();
- ray.dir = tmp2dir;
- ic = d->rt->raytrace(ray, 0, NULL);
- *(d->iter + ww*y) = ic.r;
- *(d->iter + ww*y + 1) = ic.g;
- *(d->iter + ww*y + 2) = ic.b;
- }
- *(d->iter + ww*(subsample-1)) = c3.r;
- *(d->iter + ww*(subsample-1) + 1) = c3.g;
- *(d->iter + ww*(subsample-1) + 2) = c3.b;
- d->iter += 3;
- tmpdir += d->dx;
- // middle
- for (int x = 1; x < subsample-1; x++)
- {
- for (int y = 0; y < subsample; y++)
- {
- Vector3 tmp2dir = tmpdir + y*d->dy;
- tmp2dir.normalize();
- ray.dir = tmp2dir;
- ic = d->rt->raytrace(ray, 0, NULL);
- *(d->iter + ww*y) = ic.r;
- *(d->iter + ww*y + 1) = ic.g;
- *(d->iter + ww*y + 2) = ic.b;
- }
- d->iter += 3;
- tmpdir += d->dx;
- }
- // last column
- *(d->iter) = c2.r;
- *(d->iter + 1) = c2.g;
- *(d->iter + 2) = c2.b;
- for (int y = 1; y < subsample-1; y++)
- {
- Vector3 tmp2dir = tmpdir + y*d->dy;
- tmp2dir.normalize();
- ray.dir = tmp2dir;
- ic = d->rt->raytrace(ray, 0, NULL);
- *(d->iter + ww*y) = ic.r;
- *(d->iter + ww*y + 1) = ic.g;
- *(d->iter + ww*y + 2) = ic.b;
- }
- *(d->iter + ww*(subsample-1)) = c4.r;
- *(d->iter + ww*(subsample-1) + 1) = c4.g;
- *(d->iter + ww*(subsample-1) + 2) = c4.b;
- d->iter += 3;
- }
- }
- }
- else // subsample <= 1
- {
- Colour c;
- samplepixel(c, dir, d, oversample);
- // write color to buffer
- *d->iter++ = c.r;
- *d->iter++ = c.g;
- *d->iter++ = c.b;
- }
- dir += d->dx*subsample;
- }
-#ifdef PTHREADS
- pthread_exit((void *)d);
-#endif
- return (void *)d;
-}
-#endif
-
void *Raytracer::raytrace_worker(void *d)
{
static const int my_queue_size = 256;
@@ -462,34 +304,40 @@
static const int my_count_max = 256;
sample_queue_size = my_count_max*2*num_threads;
sample_queue = new Sample [sample_queue_size];
- sample_queue_pos = 0;
sample_queue_count = 0;
- end_of_samples = false;
- int my_count, my_pos = 0;
+ int my_count, my_pos;
int sampnum = 0, sampdone;
+ int phase = 1;
bool more_samples;
sampler->init();
// create workers
- dbgmsg(1, "* running %d threads\n", num_threads);
+ dbgmsg(1, "* using %d threads\n", num_threads);
pthread_t threads[num_threads];
- for (int t = 0; t < num_threads; t++)
- {
- int rc = pthread_create(&threads[t], NULL, raytrace_worker, (void*)this);
- if (rc) {
- dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc);
- exit(1);
- }
- }
dbgmsg(1, "* raytracing...\n");
- dbgmsg(2, "- 0%% done");
- pthread_mutex_lock(&sampler_mutex);
while ( (sampnum = sampler->initSampleSet()) > 0 )
{
+ my_pos = 0;
+ sample_queue_pos = 0;
sampdone = 0;
+ end_of_samples = false;
+
+ for (int t = 0; t < num_threads; t++)
+ {
+ int rc = pthread_create(&threads[t], NULL, raytrace_worker, (void*)this);
+ if (rc) {
+ dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc);
+ exit(1);
+ }
+ }
+
+ dbgmsg(2, "phase %d: 0%% done", phase);
+
+ pthread_mutex_lock(&sampler_mutex);
+
for (;;)
{
my_count = 0;
@@ -519,27 +367,33 @@
dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue_count)*100/sampnum);
pthread_mutex_lock(&sampler_mutex);
+
+ if (!more_samples)
+ break;
}
dbgmsg(2, "\b\b\b\b\b\b\b\b100%% done\n");
- }
- pthread_mutex_unlock(&sampler_mutex);
+
+ pthread_mutex_unlock(&sampler_mutex);
+
+ // wait for workers
+ dbgmsg(2, "- waiting for threads to finish\n");
- // wait for workers
- dbgmsg(2, "- waiting for threads to finish\n");
-
- pthread_mutex_lock(&sample_queue_mutex);
- end_of_samples = true;
- while (sample_queue_count)
- {
+ pthread_mutex_lock(&sample_queue_mutex);
+ end_of_samples = true;
+ while (sample_queue_count)
+ {
+ pthread_cond_broadcast(&sample_queue_cond);
+ pthread_mutex_unlock(&sample_queue_mutex);
+ pthread_mutex_lock(&sample_queue_mutex);
+ }
pthread_cond_broadcast(&sample_queue_cond);
pthread_mutex_unlock(&sample_queue_mutex);
- pthread_mutex_lock(&sample_queue_mutex);
+
+ for (int t = 0; t < num_threads; t++)
+ pthread_join(threads[t], NULL);
+
+ phase ++;
}
- pthread_cond_broadcast(&sample_queue_cond);
- pthread_mutex_unlock(&sample_queue_mutex);
-
- for (int t = 0; t < num_threads; t++)
- pthread_join(threads[t], NULL);
delete[] sample_queue;
}