aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-04-05 08:36:24 +0000
committerrodri <rgl@antares-labs.eu>2024-04-05 08:36:24 +0000
commit2c286986893435895528d59c7db624261ac5571b (patch)
tree5d3a47ce5e05f0c4a08da7a35865b3a56f9aaae0
parent8b5ba54275a75b71cb5a7c523cf089e4f6ed7fff (diff)
downloadlibgraphics-2c286986893435895528d59c7db624261ac5571b.tar.gz
libgraphics-2c286986893435895528d59c7db624261ac5571b.tar.bz2
libgraphics-2c286986893435895528d59c7db624261ac5571b.zip
simplify the job scheduler. correct two mistakes regarding the Viewport.
> They made two mistakes. they hanged the wrong man and they didn't finish the job. so Clint Eastwood came back to kick my ass. the mistakes in question were that the Viewport shouldn't know about double buffering, conceptually it has a framebuffer and that's it. the second one was passing it to the renderer, when the renderer couldn't care less about what a viewport is.
-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;
}