shithub: libgraphics

Download patch

ref: 2c286986893435895528d59c7db624261ac5571b
parent: 8b5ba54275a75b71cb5a7c523cf089e4f6ed7fff
author: rodri <rgl@antares-labs.eu>
date: Fri Apr 5 04:36:24 EDT 2024

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.

--- a/camera.c
+++ b/camera.c
@@ -86,15 +86,17 @@
 
 	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);
--- a/fb.c
+++ b/fb.c
@@ -46,6 +46,18 @@
 	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 @@
 	fc->memdraw = framebufctl_memdraw;
 	fc->swap = framebufctl_swap;
 	fc->reset = framebufctl_reset;
+	fc->getfb = framebufctl_getfb;
+	fc->getbb = framebufctl_getbb;
 	return fc;
 }
 
--- a/graphics.h
+++ b/graphics.h
@@ -79,6 +79,7 @@
 	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 @@
 {
 	RFrame3;
 	Model *mdl;
+
 	Entity *prev, *next;
 };
 
@@ -150,9 +152,7 @@
 struct SUparams
 {
 	Framebuf *fb;
-	int id;
 	Memimage *frag;
-	Channel *donec;
 	Renderjob *job;
 
 	Entity *entity;
@@ -177,14 +177,11 @@
 
 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 @@
 	void (*memdraw)(Framebufctl*, Memimage*);
 	void (*swap)(Framebufctl*);
 	void (*reset)(Framebufctl*);
+	Framebuf *(*getfb)(Framebufctl*);
+	Framebuf *(*getbb)(Framebufctl*);
 };
 
 struct Viewport
@@ -217,7 +216,6 @@
 	void (*draw)(Viewport*, Image*);
 	void (*memdraw)(Viewport*, Memimage*);
 	Framebuf *(*getfb)(Viewport*);
-	Framebuf *(*getbb)(Viewport*);
 };
 
 struct Camera
--- 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);
--- a/render.c
+++ b/render.c
@@ -358,6 +358,7 @@
 {
 	Channel *paramsc;
 	SUparams *params;
+	Memimage *frag;
 	VSparams vsp;
 	OBJVertex *verts, *tverts, *nverts;	/* geometric, texture and normals vertices */
 	OBJIndexArray *idxtab;
@@ -369,9 +370,11 @@
 	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 @@
 				delvattrs(&t[nt][2]);
 			}
 		}
-		sendp(params->donec, params);
+
+		if(--params->job->nrem < 1)
+			nbsend(params->job->donec, nil);
+		free(params);
 	}
 }
 
@@ -478,86 +484,37 @@
 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);
+	while((job = recvp(jobc)) != nil){
+		sc = job->scene;
+		job->nrem = sc->nents;
+		time = nanosec();
 
-			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;
+		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 *
--- a/viewport.c
+++ b/viewport.c
@@ -23,15 +23,9 @@
 static Framebuf *
 viewport_getfb(Viewport *v)
 {
-	return v->fbctl->fb[v->fbctl->idx];	/* front buffer */
+	return v->fbctl->getfb(v->fbctl);
 }
 
-static Framebuf *
-viewport_getbb(Viewport *v)
-{
-	return v->fbctl->fb[v->fbctl->idx^1];	/* back buffer */
-}
-
 Viewport *
 mkviewport(Rectangle r)
 {
@@ -45,7 +39,6 @@
 	v->draw = viewport_draw;
 	v->memdraw = viewport_memdraw;
 	v->getfb = viewport_getfb;
-	v->getbb = viewport_getbb;
 	return v;
 }