summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--camera.c4
-rw-r--r--fb.c14
-rw-r--r--graphics.h12
-rw-r--r--internal.h7
-rw-r--r--render.c95
-rw-r--r--viewport.c9
6 files changed, 49 insertions, 92 deletions
diff --git a/camera.c b/camera.c
index a6bf601..123db32 100644
--- a/camera.c
+++ b/camera.c
@@ -86,15 +86,17 @@ shootcamera(Camera *c, Shadertab *s)
job = emalloc(sizeof *job);
memset(job, 0, sizeof *job);
- job->v = c->vp;
+ job->fb = c->vp->fbctl->getbb(c->vp->fbctl);
job->scene = c->s;
job->shaders = s;
job->donec = chancreate(sizeof(void*), 0);
+ c->vp->fbctl->reset(c->vp->fbctl);
t0 = nanosec();
sendp(c->rctl->c, job);
recvp(job->donec);
t1 = nanosec();
+ c->vp->fbctl->swap(c->vp->fbctl);
chanfree(job->donec);
free(job);
diff --git a/fb.c b/fb.c
index 17496ac..02c984d 100644
--- a/fb.c
+++ b/fb.c
@@ -46,6 +46,18 @@ framebufctl_reset(Framebufctl *ctl)
memfillcolor(fb->cb, DTransparent);
}
+static Framebuf *
+framebufctl_getfb(Framebufctl *ctl)
+{
+ return ctl->fb[ctl->idx]; /* front buffer */
+}
+
+static Framebuf *
+framebufctl_getbb(Framebufctl *ctl)
+{
+ return ctl->fb[ctl->idx^1]; /* back buffer */
+}
+
Framebuf *
mkfb(Rectangle r)
{
@@ -81,6 +93,8 @@ mkfbctl(Rectangle r)
fc->memdraw = framebufctl_memdraw;
fc->swap = framebufctl_swap;
fc->reset = framebufctl_reset;
+ fc->getfb = framebufctl_getfb;
+ fc->getbb = framebufctl_getbb;
return fc;
}
diff --git a/graphics.h b/graphics.h
index 7dcc7ff..9a46914 100644
--- a/graphics.h
+++ b/graphics.h
@@ -79,6 +79,7 @@ struct Vertex
Color c; /* shading color */
Point2 uv; /* texture coordinate */
OBJMaterial *mtl;
+
/* TODO it'd be neat to use a dynamic hash table instead */
Vertexattr *attrs; /* attributes (aka varyings) */
ulong nattrs;
@@ -118,6 +119,7 @@ struct Entity
{
RFrame3;
Model *mdl;
+
Entity *prev, *next;
};
@@ -150,9 +152,7 @@ struct FSparams
struct SUparams
{
Framebuf *fb;
- int id;
Memimage *frag;
- Channel *donec;
Renderjob *job;
Entity *entity;
@@ -177,14 +177,11 @@ struct Renderer
struct Renderjob
{
- Viewport *v;
+ Framebuf *fb;
Scene *scene;
Shadertab *shaders;
Channel *donec;
-
ulong nrem; /* remaining entities to process */
- ulong lastid;
- uvlong time0;
Renderjob *next;
};
@@ -207,6 +204,8 @@ struct Framebufctl
void (*memdraw)(Framebufctl*, Memimage*);
void (*swap)(Framebufctl*);
void (*reset)(Framebufctl*);
+ Framebuf *(*getfb)(Framebufctl*);
+ Framebuf *(*getbb)(Framebufctl*);
};
struct Viewport
@@ -217,7 +216,6 @@ struct Viewport
void (*draw)(Viewport*, Image*);
void (*memdraw)(Viewport*, Memimage*);
Framebuf *(*getfb)(Viewport*);
- Framebuf *(*getbb)(Viewport*);
};
struct Camera
diff --git a/internal.h b/internal.h
index 7f0d648..a145585 100644
--- a/internal.h
+++ b/internal.h
@@ -1,10 +1,3 @@
-typedef struct Jobqueue Jobqueue;
-
-struct Jobqueue
-{
- Renderjob *hd, *tl;
-};
-
/* alloc */
void *emalloc(ulong);
void *erealloc(void*, ulong);
diff --git a/render.c b/render.c
index bef319e..96cc3a3 100644
--- a/render.c
+++ b/render.c
@@ -358,6 +358,7 @@ entityproc(void *arg)
{
Channel *paramsc;
SUparams *params;
+ Memimage *frag;
VSparams vsp;
OBJVertex *verts, *tverts, *nverts; /* geometric, texture and normals vertices */
OBJIndexArray *idxtab;
@@ -369,9 +370,11 @@ entityproc(void *arg)
threadsetname("entityproc");
paramsc = arg;
+ frag = rgb(DBlack);
t = emalloc(sizeof(*t)*16);
while((params = recvp(paramsc)) != nil){
+ params->frag = frag;
vsp.su = params;
verts = params->entity->mdl->obj->vertdata[OBJVGeometric].verts;
@@ -470,7 +473,10 @@ entityproc(void *arg)
delvattrs(&t[nt][2]);
}
}
- sendp(params->donec, params);
+
+ if(--params->job->nrem < 1)
+ nbsend(params->job->donec, nil);
+ free(params);
}
}
@@ -478,86 +484,37 @@ static void
renderer(void *arg)
{
Channel *jobc;
- Jobqueue jobq;
Renderjob *job;
Scene *sc;
Entity *ent;
- SUparams *params, *params2;
- Channel *paramsc, *donec;
+ SUparams *params;
+ Channel *paramsc;
+ uvlong time;
threadsetname("renderer");
jobc = arg;
- jobq.tl = jobq.hd = nil;
- ent = nil;
paramsc = chancreate(sizeof(SUparams*), 8);
- donec = chancreate(sizeof(SUparams*), 0);
proccreate(entityproc, paramsc, mainstacksize);
- enum { JOB, PARM, DONE };
- Alt a[] = {
- [JOB] {jobc, &job, CHANRCV},
- [PARM] {paramsc, &params, CHANNOP},
- [DONE] {donec, &params2, CHANRCV},
- {nil, nil, CHANEND}
- };
- for(;;)
- switch(alt(a)){
- case JOB:
- sc = job->scene;
- job->nrem = sc->nents;
- job->lastid = 0;
- job->time0 = nanosec();
- job->v->fbctl->reset(job->v->fbctl);
-
- if(jobq.tl == nil){
- jobq.tl = jobq.hd = job;
- ent = sc->ents.next;
- a[PARM].op = CHANSND;
- goto sendparams;
- }else
- jobq.tl = jobq.tl->next = job;
- break;
- case PARM:
-sendparams:
- job = jobq.hd;
- sc = job->scene;
-
- if(ent != nil && ent != &sc->ents){
- params = emalloc(sizeof *params);
- memset(params, 0, sizeof *params);
- params->fb = job->v->getbb(job->v);
- params->id = job->lastid++;
- params->frag = rgb(DBlack);
- params->donec = donec;
- params->job = job;
- params->entity = ent;
- params->uni_time = job->time0;
- params->vshader = job->shaders->vshader;
- params->fshader = job->shaders->fshader;
- ent = ent->next;
- }else{
- jobq.hd = job->next;
- if((job = jobq.hd) != nil){
- ent = job->scene->ents.next;
- goto sendparams;
- }
-
- jobq.tl = jobq.hd;
- a[PARM].op = CHANNOP;
- }
- break;
- case DONE:
- if(--params2->job->nrem < 1){
- params2->job->v->fbctl->swap(params2->job->v->fbctl);
- send(params2->job->donec, nil);
- }
-
- freememimage(params2->frag);
- free(params2);
- break;
+ while((job = recvp(jobc)) != nil){
+ sc = job->scene;
+ job->nrem = sc->nents;
+ time = nanosec();
+
+ for(ent = sc->ents.next; ent != &sc->ents; ent = ent->next){
+ params = emalloc(sizeof *params);
+ memset(params, 0, sizeof *params);
+ params->fb = job->fb;
+ params->job = job;
+ params->entity = ent;
+ params->uni_time = time;
+ params->vshader = job->shaders->vshader;
+ params->fshader = job->shaders->fshader;
+ sendp(paramsc, params);
}
+ }
}
Renderer *
diff --git a/viewport.c b/viewport.c
index 9feffaa..8a18b44 100644
--- a/viewport.c
+++ b/viewport.c
@@ -23,13 +23,7 @@ viewport_memdraw(Viewport *v, Memimage *dst)
static Framebuf *
viewport_getfb(Viewport *v)
{
- return v->fbctl->fb[v->fbctl->idx]; /* front buffer */
-}
-
-static Framebuf *
-viewport_getbb(Viewport *v)
-{
- return v->fbctl->fb[v->fbctl->idx^1]; /* back buffer */
+ return v->fbctl->getfb(v->fbctl);
}
Viewport *
@@ -45,7 +39,6 @@ mkviewport(Rectangle r)
v->draw = viewport_draw;
v->memdraw = viewport_memdraw;
v->getfb = viewport_getfb;
- v->getbb = viewport_getbb;
return v;
}