switched to freeglut for now. seems to work slightly better with all the
[erebus2020] / liberebus / src / erebus.c
index dbc253b..8ad4a88 100644 (file)
@@ -5,16 +5,21 @@
 
 struct render_job {
        struct erb_rend *erb;
-       int x, y, width, height;
+       unsigned int id;
+       struct erb_rect rect;
        struct render_job *next;
 };
 
 struct erb_rend {
        int fb_width, fb_height, fb_size;
        float *fb_pixels;
+
+       erb_done_func donecb;
+       void *donecls;
 };
 
 static void proc_render_job(void *cls);
+static void done_render_job(void *cls);
 static struct render_job *alloc_job(void);
 static void free_job(struct render_job *job);
 
@@ -100,12 +105,19 @@ float *erb_end(struct erb_rend *erb)
        return erb->fb_pixels;
 }
 
-void erb_queue_frame(struct erb_rend *erb)
+void erb_set_done_callback(struct erb_rend *erb, erb_done_func donecb, void *cls)
+{
+       erb->donecb = donecb;
+       erb->donecls = cls;
+}
+
+void erb_queue_frame(struct erb_rend *erb, unsigned int job_id)
 {
-       erb_queue_block(erb, 0, 0, erb->fb_width, erb->fb_height);
+       erb_queue_block(erb, job_id, 0, 0, erb->fb_width, erb->fb_height);
 }
 
-void erb_queue_block(struct erb_rend *erb, int x, int y, int width, int height)
+void erb_queue_block(struct erb_rend *erb, unsigned int job_id, int x, int y,
+               int width, int height)
 {
        struct render_job *job;
 
@@ -115,12 +127,13 @@ void erb_queue_block(struct erb_rend *erb, int x, int y, int width, int height)
        }
 
        job->erb = erb;
-       job->x = x;
-       job->y = y;
-       job->width = width;
-       job->height = height;
+       job->id = job_id;
+       job->rect.x = x;
+       job->rect.y = y;
+       job->rect.w = width;
+       job->rect.h = height;
 
-       tpool_enqueue(tpool, job, proc_render_job, 0);
+       tpool_enqueue(tpool, job, proc_render_job, done_render_job);
 }
 
 void erb_wait(struct erb_rend *erb)
@@ -150,17 +163,29 @@ static void proc_render_job(void *cls)
        struct erb_ray ray;
 
        erb = job->erb;
-       fboffs = job->y * erb->fb_width + job->x;
+       fboffs = job->rect.y * erb->fb_width + job->rect.x;
        fbptr = erb->fb_pixels + fboffs * 4;
 
-       for(i=0; i<job->height; i++) {
-               for(j=0; j<job->width; j++) {
+       for(i=0; i<job->rect.h; i++) {
+               for(j=0; j<job->rect.w; j++) {
                        erb_primary_ray(erb, &ray, (int)fbptr[3]);
                        erb_sample_ray(erb, &ray, fbptr);
                        fbptr += 4;
                }
-               fbptr += (erb->fb_width - job->width) * 4;
+               fbptr += (erb->fb_width - job->rect.w) * 4;
        }
+}
+
+static void done_render_job(void *cls)
+{
+       struct erb_rend *erb;
+       struct render_job *job = cls;
+
+       erb = job->erb;
+       if(erb->donecb) {
+               erb->donecb(job->id, &job->rect, erb->donecls);
+       }
+
        free_job(job);
 }