diff options
-rw-r--r-- | camera.c | 4 | ||||
-rw-r--r-- | fb.c | 14 | ||||
-rw-r--r-- | graphics.h | 12 | ||||
-rw-r--r-- | internal.h | 7 | ||||
-rw-r--r-- | render.c | 95 | ||||
-rw-r--r-- | viewport.c | 9 |
6 files changed, 49 insertions, 92 deletions
@@ -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); @@ -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; } @@ -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 @@ -1,10 +1,3 @@ -typedef struct Jobqueue Jobqueue; - -struct Jobqueue -{ - Renderjob *hd, *tl; -}; - /* alloc */ void *emalloc(ulong); void *erealloc(void*, ulong); @@ -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, ¶ms, CHANNOP}, - [DONE] {donec, ¶ms2, 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 * @@ -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; } |