summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-09-10 14:26:35 +0000
committerrodri <rgl@antares-labs.eu>2024-09-10 14:26:35 +0000
commit8806aad87f7be2d2e82c7db2b9f0978246e5a747 (patch)
treeec1e040177c0e352331911664bba862bd50fddf3
parent6d137698282ca2c04eff4b52ac8e69ac10164a90 (diff)
downloadlibgraphics-8806aad87f7be2d2e82c7db2b9f0978246e5a747.tar.gz
libgraphics-8806aad87f7be2d2e82c7db2b9f0978246e5a747.tar.bz2
libgraphics-8806aad87f7be2d2e82c7db2b9f0978246e5a747.zip
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.
-rw-r--r--fb.c67
-rw-r--r--internal.h27
-rw-r--r--mkfile1
-rw-r--r--render.c8
4 files changed, 99 insertions, 4 deletions
diff --git a/fb.c b/fb.c
index c23678d..ec1c056 100644
--- a/fb.c
+++ b/fb.c
@@ -163,6 +163,23 @@ upscaledraw(Raster *fb, Image *dst, Point off, Point scale, uint filter)
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 @@ framebufctl_draw(Framebufctl *ctl, Image *dst, char *name, Point off, Point scal
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 */
diff --git a/internal.h b/internal.h
index 3173f75..e1c81ca 100644
--- a/internal.h
+++ b/internal.h
@@ -39,6 +39,27 @@ struct Rastertask
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);
@@ -79,6 +100,12 @@ void memsetl(void*, ulong, usize);
/* 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)
#define getdepth(fb, p) rastergetfloat(fb, p)
diff --git a/mkfile b/mkfile
index 558ca9c..7a5c535 100644
--- a/mkfile
+++ b/mkfile
@@ -17,6 +17,7 @@ OFILES=\
color.$O\
util.$O\
nanosec.$O\
+ procpool.$O\
HFILES=\
graphics.h\
diff --git a/render.c b/render.c
index 1a858e4..c86c3d8 100644
--- 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 @@ rasterizer(void *arg)
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;
@@ -749,6 +751,8 @@ initgraphics(void)
nproc = 1;
free(nprocs);
+// turbodrawingpool = mkprocpool(nproc);
+
r = emalloc(sizeof *r);
memset(r, 0, sizeof *r);
r->jobq = chancreate(sizeof(Renderjob*), 8);