diff -r 3b60fd0bea64 -r dbe8438d5dca src/raytracer.cc --- 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; }