summaryrefslogtreecommitdiff
path: root/render.c
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-09-20 21:44:07 +0000
committerrodri <rgl@antares-labs.eu>2024-09-20 21:44:07 +0000
commitd8f71404ffd54af08bc84dbb04e60cb07e83a021 (patch)
tree51eea850a374f92569332ddb3bca7fcc021f6142 /render.c
parent2fd16cbf190d5c37fc627f79bf586f66129fea46 (diff)
downloadlibgraphics-d8f71404ffd54af08bc84dbb04e60cb07e83a021.tar.gz
libgraphics-d8f71404ffd54af08bc84dbb04e60cb07e83a021.tar.bz2
libgraphics-d8f71404ffd54af08bc84dbb04e60cb07e83a021.zip
implement clipped drawing. take branching out of the upscaler loop.
the rasterizers now produce a bbox of used fragments/pixels that are unified at the end of every job/frame. we use that when drawing so only the part that was rasterized gets sent to devdraw.
Diffstat (limited to 'render.c')
-rw-r--r--render.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/render.c b/render.c
index 84893ba..5a4f5b6 100644
--- a/render.c
+++ b/render.c
@@ -212,6 +212,14 @@ rasterize(Rastertask *task)
pushtoAbuf(params->fb, p, c, z);
else
pixel(cr, p, c, ropts & ROBlend);
+
+ if(task->clipr->min.x < 0){
+ task->clipr->min = p;
+ task->clipr->max = addpt(p, Pt(1,1));
+ }else{
+ task->clipr->min = minpt(task->clipr->min, p);
+ task->clipr->max = maxpt(task->clipr->max, addpt(p, Pt(1,1)));
+ }
delvattrs(fsp.v);
break;
case PLine:
@@ -270,6 +278,14 @@ rasterize(Rastertask *task)
pushtoAbuf(params->fb, p, c, z);
else
pixel(cr, p, c, ropts & ROBlend);
+
+ if(task->clipr->min.x < 0){
+ task->clipr->min = p;
+ task->clipr->max = addpt(p, Pt(1,1));
+ }else{
+ task->clipr->min = minpt(task->clipr->min, p);
+ task->clipr->max = maxpt(task->clipr->max, addpt(p, Pt(1,1)));
+ }
discard:
if(steep) SWAP(int, &p.x, &p.y);
@@ -316,6 +332,14 @@ discard:
pushtoAbuf(params->fb, p, c, z);
else
pixel(cr, p, c, ropts & ROBlend);
+
+ if(task->clipr->min.x < 0){
+ task->clipr->min = p;
+ task->clipr->max = addpt(p, Pt(1,1));
+ }else{
+ task->clipr->min = minpt(task->clipr->min, p);
+ task->clipr->max = maxpt(task->clipr->max, addpt(p, Pt(1,1)));
+ }
}
delvattrs(fsp.v);
break;
@@ -349,8 +373,23 @@ rasterizer(void *arg)
if(decref(job) < 1){
if(job->camera->rendopts & ROAbuff)
squashAbuf(job->fb, job->camera->rendopts & ROBlend);
+
+ /* set the clipr to the union of bboxes from the rasterizers */
+ for(i = 1; i < job->ncliprects; i++){
+ if(job->cliprects[i].min.x < 0)
+ continue;
+ job->cliprects[0].min = job->cliprects[0].min.x < 0?
+ job->cliprects[i].min:
+ minpt(job->cliprects[0].min, job->cliprects[i].min);
+ job->cliprects[0].max = job->cliprects[0].max.x < 0?
+ job->cliprects[i].max:
+ maxpt(job->cliprects[0].max, job->cliprects[i].max);
+ }
+ job->fb->clipr = job->cliprects[0];
+
if(job->rctl->doprof)
job->times.Rn[rp->id].t1 = nanosec();
+
nbsend(job->donec, nil);
free(params);
}else if(job->rctl->doprof)
@@ -458,6 +497,7 @@ tiler(void *arg)
*newparams = *params;
task = emalloc(sizeof *task);
task->params = newparams;
+ task->clipr = &params->job->cliprects[i];
task->p = *p;
task->p.v[0] = dupvertex(&p->v[0]);
sendp(taskchans[i], task);
@@ -501,6 +541,7 @@ tiler(void *arg)
task = emalloc(sizeof *task);
task->params = newparams;
task->wr = wr[i];
+ task->clipr = &params->job->cliprects[i];
task->p = *p;
task->p.v[0] = dupvertex(&p->v[0]);
task->p.v[1] = dupvertex(&p->v[1]);
@@ -554,6 +595,7 @@ tiler(void *arg)
task->params = newparams;
task->wr = bbox;
rectclip(&task->wr, wr[i]);
+ task->clipr = &params->job->cliprects[i];
task->p = *p;
task->p.v[0] = dupvertex(&p->v[0]);
task->p.v[1] = dupvertex(&p->v[1]);
@@ -637,6 +679,15 @@ entityproc(void *arg)
continue;
}
+ if(params->job->cliprects == nil){
+ params->job->cliprects = emalloc(nproc*sizeof(Rectangle));
+ params->job->ncliprects = nproc;
+ for(i = 0; i < nproc; i++){
+ params->job->cliprects[i].min = Pt(-1,-1);
+ params->job->cliprects[i].max = Pt(-1,-1);
+ }
+ }
+
eb = params->entity->mdl->prims;
nprims = params->entity->mdl->nprims;
ee = eb + nprims;