ref: 8806aad87f7be2d2e82c7db2b9f0978246e5a747
parent: 6d137698282ca2c04eff4b52ac8e69ac10164a90
author: rodri <rgl@antares-labs.eu>
date: Tue Sep 10 10:26:35 EDT 2024
fix a use-after-free when profiling rasterizer times. this commit also includes the turbo drawing pool. the experiment was successful in getting reasonable drawing times to a fullhd image, but the process causes glitches when moving the objects around, which is unacceptable. it's been commented out for now.
--- a/fb.c
+++ b/fb.c
@@ -163,6 +163,23 @@
free(blk);
}
+//typedef struct Ldimgtask Ldimgtask;
+//struct Ldimgtask
+//{
+// Image *dst;
+// Rectangle dr;
+// uchar *src;
+// ulong len;
+//};
+//static void
+//ldimgtask(void *arg)
+//{
+// Ldimgtask *t;
+//
+// t = arg;
+// loadimage(t->dst, t->dr, t->src, t->len);
+//}
+
static void
framebufctl_draw(Framebufctl *ctl, Image *dst, char *name, Point off, Point scale)
{
@@ -195,9 +212,55 @@
sr = rectaddpt(fb->r, off);
dr = rectsubpt(dst->r, dst->r.min);
- if(rectinrect(sr, dr))
+ if(rectinrect(sr, dr)){
+// Ldimgtask *tasks;
+// Rectangle blkr;
+// ulong len, stride;
+// int Δy, i;
+// static Display **disps;
+// static Image **imgs;
+// static int loaded;
+//
+// assert(turbodrawingpool != nil);
+//
+// if(!loaded){
+// disps = emalloc(turbodrawingpool->nprocs * sizeof(*disps));
+// imgs = emalloc(turbodrawingpool->nprocs * sizeof(*imgs));
+// for(i = 0; i < turbodrawingpool->nprocs; i++){
+// disps[i] = initdisplay(nil, nil, nil);
+// if(disps[i] == nil)
+// sysfatal("initdisplay: %r");
+// imgs[i] = namedimage(disps[i], "screenb");
+// if(imgs[i] == nil)
+// sysfatal("namedimage: %r");
+////fprint(2, "d %#p i %#p → %#p\n", disps[i], imgs[i], imgs[i]->display);
+// }
+// loaded++;
+// }
+//
+// len = Dx(r->r)*Dy(r->r)*4;
+// Δy = Dy(sr)/turbodrawingpool->nprocs;
+// dr = rectaddpt(sr, dst->r.min);
+// blkr = dr;
+// blkr.max.y = blkr.min.y + Δy;
+// stride = Dx(blkr)*Dy(blkr)*4;
+// tasks = emalloc(turbodrawingpool->nprocs * sizeof(*tasks));
+//
+// for(i = 0; i < turbodrawingpool->nprocs; i++){
+// tasks[i].dst = imgs[i];
+// tasks[i].dr = rectaddpt(blkr, Pt(0, i*Δy));
+// tasks[i].src = (uchar*)r->data + i*stride;
+// tasks[i].len = stride;
+// if(i == turbodrawingpool->nprocs-1){
+// tasks[i].dr.max.y = dr.max.y;
+// tasks[i].len = len - i*stride;
+// }
+// procpoolexec(turbodrawingpool, ldimgtask, &tasks[i]);
+// }
+// procpoolwait(turbodrawingpool);
+// free(tasks);
loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)r->data, Dx(fb->r)*Dy(r->r)*4);
- else if(rectclip(&sr, dr)){
+ }else if(rectclip(&sr, dr)){
dr = sr;
dr.max.y = dr.min.y + 1;
/* remove offset to get the actual rect within the framebuffer */
--- a/internal.h
+++ b/internal.h
@@ -39,6 +39,27 @@
Primitive p;
};
+typedef struct Proctask Proctask;
+typedef struct Procpool Procpool;
+
+struct Proctask
+{
+ void (*fn)(void*);
+ void *arg;
+};
+
+struct Procpool
+{
+ ulong nprocs;
+ Ref issued;
+ Ref complete;
+
+ Channel *subq; /* task submission queue */
+ Channel *done; /* task completion signal */
+};
+
+extern Procpool *turbodrawingpool;
+
/* alloc */
void *emalloc(ulong);
void *erealloc(void*, ulong);
@@ -78,6 +99,12 @@
/* nanosec */
uvlong nanosec(void);
+
+/* procpool */
+Procpool *mkprocpool(ulong);
+void procpoolexec(Procpool*, void(*)(void*), void*);
+void procpoolwait(Procpool*);
+void rmprocpool(Procpool*);
#define getpixel(fb, p) rastergetcolor(fb, p)
#define putpixel(fb, p, c) rasterputcolor(fb, p, c)
--- a/mkfile
+++ b/mkfile
@@ -17,6 +17,7 @@
color.$O\
util.$O\
nanosec.$O\
+ procpool.$O\
HFILES=\
graphics.h\
--- a/render.c
+++ b/render.c
@@ -9,6 +9,7 @@
#include "internal.h"
Rectangle UR = {0,0,1,1};
+//Procpool *turbodrawingpool;
static ulong col2ul(Color);
@@ -368,10 +369,11 @@
if(decref(job) < 1){
if(job->camera->enableAbuff)
squashAbuf(job->fb, job->camera->enableblend);
+ if(job->rctl->doprof)
+ job->times.Rn[rp->id].t1 = nanosec();
nbsend(job->donec, nil);
free(params);
- }
- if(job->rctl->doprof)
+ }else if(job->rctl->doprof)
job->times.Rn[rp->id].t1 = nanosec();
free(task);
continue;
@@ -748,6 +750,8 @@
if(nprocs == nil || (nproc = strtoul(nprocs, nil, 10)) < 2)
nproc = 1;
free(nprocs);
+
+// turbodrawingpool = mkprocpool(nproc);
r = emalloc(sizeof *r);
memset(r, 0, sizeof *r);