diff options
-rw-r--r-- | fb.c | 295 | ||||
-rw-r--r-- | graphics.h | 40 | ||||
-rw-r--r-- | internal.h | 19 | ||||
-rw-r--r-- | render.c | 63 | ||||
-rw-r--r-- | util.c | 14 | ||||
-rw-r--r-- | viewport.c | 22 |
6 files changed, 345 insertions, 108 deletions
@@ -14,7 +14,7 @@ * see https://www.scale2x.it/algorithm */ static void -scale2x_filter(ulong *dst, Framebuf *fb, Point sp) +scale2x_filter(ulong *dst, Raster *fb, Point sp) { ulong B, D, E, F, H; @@ -34,7 +34,7 @@ scale2x_filter(ulong *dst, Framebuf *fb, Point sp) } static void -scale3x_filter(ulong *dst, Framebuf *fb, Point sp) +scale3x_filter(ulong *dst, Raster *fb, Point sp) { ulong A, B, C, D, E, F, G, H, I; @@ -93,153 +93,187 @@ scale3x_filter(ulong *dst, Framebuf *fb, Point sp) //} static void -upscaledraw(Framebufctl *ctl, Image *dst, Point off, Point scale) +fb_createraster(Framebuf *fb, char *name, ulong chan) { - void (*filter)(ulong*, Framebuf*, Point); - Framebuf *fb; + Raster *r; + + assert(name != nil); + + /* + * TODO might be better to keep a tail so it's O(1) + * + * in practice though, most users won't ever create + * more than ten extra rasters. + */ + r = fb->rasters; + while(r->next != nil) + r = r->next; + r->next = allocraster(name, fb->r, chan); +} + +static Raster * +fb_fetchraster(Framebuf *fb, char *name) +{ + Raster *r; + + r = fb->rasters; + if(name == nil) + return r; + + while((r = r->next) != nil) + if(strcmp(name, r->name) == 0) + return r; + return nil; + +} + +static void +upscaledraw(Raster *fb, Image *dst, Point off, Point scale, uint filter) +{ + void (*filterfn)(ulong*, Raster*, Point); Rectangle blkr; Point sp, dp; ulong *blk; - filter = nil; + filterfn = nil; blk = emalloc(scale.x*scale.y*4); blkr = Rect(0,0,scale.x,scale.y); - qlock(ctl); - fb = ctl->getfb(ctl); - - switch(ctl->upfilter){ + switch(filter){ case UFScale2x: if(scale.x == scale.y && scale.y == 2) - filter = scale2x_filter; + filterfn = scale2x_filter; break; case UFScale3x: if(scale.x == scale.y && scale.y == 3) - filter = scale3x_filter; + filterfn = scale3x_filter; break; } for(sp.y = fb->r.min.y, dp.y = dst->r.min.y+off.y; sp.y < fb->r.max.y; sp.y++, dp.y += scale.y) for(sp.x = fb->r.min.x, dp.x = dst->r.min.x+off.x; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){ - if(filter != nil) - filter(blk, fb, sp); + if(filterfn != nil) + filterfn(blk, fb, sp); else memsetl(blk, getpixel(fb, sp), scale.x*scale.y); loadimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4); } - qunlock(ctl); free(blk); } static void -framebufctl_draw(Framebufctl *ctl, Image *dst, Point off, Point scale) +framebufctl_draw(Framebufctl *ctl, Image *dst, char *name, Point off, Point scale) { Framebuf *fb; + Raster *r; Rectangle sr, dr; - int y; + + qlock(ctl); + fb = ctl->getfb(ctl); + + r = fb->rasters; + if(name != nil) + do r = r->next; while(r != nil && strcmp(name, r->name) != 0); + if(r == nil){ + qunlock(ctl); + return; + } if(scale.x > 1 || scale.y > 1){ - upscaledraw(ctl, dst, off, scale); + upscaledraw(r, dst, off, scale, ctl->upfilter); + qunlock(ctl); return; } - qlock(ctl); - fb = ctl->getfb(ctl); sr = rectaddpt(fb->r, off); dr = rectsubpt(dst->r, dst->r.min); if(rectinrect(sr, dr)) - loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4); + loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)r->data, Dx(fb->r)*Dy(r->r)*4); else if(rectclip(&sr, dr)){ dr = sr; dr.max.y = dr.min.y + 1; /* remove offset to get the actual rect within the framebuffer */ sr = rectsubpt(sr, off); - for(y = sr.min.y; y < sr.max.y; y++, dr.min.y++, dr.max.y++) - loadimage(dst, rectaddpt(dr, dst->r.min), (uchar*)&fb->cb[y*Dx(fb->r) + sr.min.x], Dx(dr)*4); + for(; sr.min.y < sr.max.y; sr.min.y++, dr.min.y++, dr.max.y++) + loadimage(dst, rectaddpt(dr, dst->r.min), rasterbyteaddr(r, sr.min), Dx(dr)*4); } qunlock(ctl); } static void -upscalememdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale) +upscalememdraw(Raster *fb, Memimage *dst, Point off, Point scale, uint filter) { - void (*filter)(ulong*, Framebuf*, Point); - Framebuf *fb; + void (*filterfn)(ulong*, Raster*, Point); Rectangle blkr; Point sp, dp; ulong *blk; - filter = nil; + filterfn = nil; blk = emalloc(scale.x*scale.y*4); blkr = Rect(0,0,scale.x,scale.y); - qlock(ctl); - fb = ctl->getfb(ctl); - - switch(ctl->upfilter){ + switch(filter){ case UFScale2x: if(scale.x == scale.y && scale.y == 2) - filter = scale2x_filter; + filterfn = scale2x_filter; break; case UFScale3x: if(scale.x == scale.y && scale.y == 3) - filter = scale3x_filter; + filterfn = scale3x_filter; break; } for(sp.y = fb->r.min.y, dp.y = dst->r.min.y+off.y; sp.y < fb->r.max.y; sp.y++, dp.y += scale.y) for(sp.x = fb->r.min.x, dp.x = dst->r.min.x+off.x; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){ - if(filter != nil) - filter(blk, fb, sp); + if(filterfn != nil) + filterfn(blk, fb, sp); else memsetl(blk, getpixel(fb, sp), scale.x*scale.y); loadmemimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4); } - qunlock(ctl); free(blk); } static void -framebufctl_memdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale) +framebufctl_memdraw(Framebufctl *ctl, Memimage *dst, char *name, Point off, Point scale) { Framebuf *fb; + Raster *r; Rectangle sr, dr; - int y; + + qlock(ctl); + fb = ctl->getfb(ctl); + + r = fb->rasters; + if(name != nil) + do r = r->next; while(r != nil && strcmp(name, r->name) != 0); + if(r == nil){ + qunlock(ctl); + return; + } if(scale.x > 1 || scale.y > 1){ - upscalememdraw(ctl, dst, off, scale); + upscalememdraw(r, dst, off, scale, ctl->upfilter); + qunlock(ctl); return; } - qlock(ctl); - fb = ctl->getfb(ctl); sr = rectaddpt(fb->r, off); dr = rectsubpt(dst->r, dst->r.min); if(rectinrect(sr, dr)) - loadmemimage(dst, rectaddpt(sr, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4); + loadmemimage(dst, rectaddpt(sr, dst->r.min), (uchar*)r->data, Dx(fb->r)*Dy(r->r)*4); else if(rectclip(&sr, dr)){ dr = sr; dr.max.y = dr.min.y + 1; /* remove offset to get the actual rect within the framebuffer */ sr = rectsubpt(sr, off); - for(y = sr.min.y; y < sr.max.y; y++, dr.min.y++, dr.max.y++) - loadmemimage(dst, rectaddpt(dr, dst->r.min), (uchar*)&fb->cb[y*Dx(fb->r) + sr.min.x], Dx(dr)*4); + for(; sr.min.y < sr.max.y; sr.min.y++, dr.min.y++, dr.max.y++) + loadmemimage(dst, rectaddpt(dr, dst->r.min), rasterbyteaddr(r, sr.min), Dx(dr)*4); } qunlock(ctl); } static void -framebufctl_drawnormals(Framebufctl *ctl, Image *dst) -{ - Framebuf *fb; - - qlock(ctl); - fb = ctl->getfb(ctl); - loadimage(dst, rectaddpt(fb->r, dst->r.min), (uchar*)fb->nb, Dx(fb->r)*Dy(fb->r)*4); - qunlock(ctl); -} - -static void framebufctl_swap(Framebufctl *ctl) { qlock(ctl); @@ -261,13 +295,18 @@ static void framebufctl_reset(Framebufctl *ctl, ulong clr) { Framebuf *fb; + Raster *r; /* address the back buffer—resetting the front buffer is VERBOTEN */ fb = ctl->getbb(ctl); resetAbuf(&fb->abuf); - memsetl(fb->nb, 0, Dx(fb->r)*Dy(fb->r)); - memsetf(fb->zb, Inf(-1), Dx(fb->r)*Dy(fb->r)); - memsetl(fb->cb, rgba2xrgb(clr), Dx(fb->r)*Dy(fb->r)); + + r = fb->rasters; /* color buffer */ + clearraster(r, rgba2xrgb(clr)); + r = r->next; /* z-buffer */ + fclearraster(r, Inf(-1)); + while((r = r->next) != nil) + clearraster(r, 0); /* every other raster */ } static Framebuf * @@ -282,6 +321,126 @@ framebufctl_getbb(Framebufctl *ctl) return ctl->fb[ctl->idx^1]; /* back buffer */ } +static void +framebufctl_createraster(Framebufctl *ctl, char *name, ulong chan) +{ + Framebuf *fb; + int i; + + for(i = 0; i < 2; i++){ + fb = ctl->fb[i]; + fb->createraster(fb, name, chan); + } +} + +static Raster * +framebufctl_fetchraster(Framebufctl *ctl, char *name) +{ + Framebuf *fb; + + fb = ctl->getfb(ctl); + return fb->fetchraster(fb, name); +} + +Raster * +allocraster(char *name, Rectangle rr, ulong chan) +{ + Raster *r; + + assert(chan <= FLOAT32); + + r = emalloc(sizeof *r); + memset(r, 0, sizeof *r); + if(name != nil && (r->name = strdup(name)) == nil) + sysfatal("strdup: %r"); + r->chan = chan; + r->r = rr; + r->data = emalloc(Dx(rr)*Dy(rr)*sizeof(*r->data)); + return r; +} + +void +clearraster(Raster *r, ulong v) +{ + memsetl(r->data, v, Dx(r->r)*Dy(r->r)); +} + +void +fclearraster(Raster *r, float v) +{ + memsetf(r->data, v, Dx(r->r)*Dy(r->r)); +} + +uchar * +rasterbyteaddr(Raster *r, Point p) +{ + return (uchar*)&r->data[p.y*Dx(r->r) + p.x]; +} + +void +rasterput(Raster *r, Point p, void *v) +{ + switch(r->chan){ + case COLOR32: + *(ulong*)rasterbyteaddr(r, p) = *(ulong*)v; + break; + case FLOAT32: + *(float*)rasterbyteaddr(r, p) = *(float*)v; + break; + } +} + +void +rasterget(Raster *r, Point p, void *v) +{ + switch(r->chan){ + case COLOR32: + *(ulong*)v = *(ulong*)rasterbyteaddr(r, p); + break; + case FLOAT32: + *(float*)v = *(float*)rasterbyteaddr(r, p); + break; + } +} + +void +rasterputcolor(Raster *r, Point p, ulong c) +{ + rasterput(r, p, &c); +} + +ulong +rastergetcolor(Raster *r, Point p) +{ + ulong c; + + rasterget(r, p, &c); + return c; +} + +void +rasterputfloat(Raster *r, Point p, float v) +{ + rasterput(r, p, &v); +} + +float +rastergetfloat(Raster *r, Point p) +{ + float v; + + rasterget(r, p, &v); + return v; +} + +void +freeraster(Raster *r) +{ + free(r->data); + free(r->name); + free(r); +} + Framebuf * mkfb(Rectangle r) { @@ -289,20 +448,23 @@ mkfb(Rectangle r) fb = emalloc(sizeof *fb); memset(fb, 0, sizeof *fb); - fb->cb = emalloc(Dx(r)*Dy(r)*4); - fb->zb = emalloc(Dx(r)*Dy(r)*sizeof(*fb->zb)); - memsetf(fb->zb, Inf(-1), Dx(r)*Dy(r)); - fb->nb = emalloc(Dx(r)*Dy(r)*4); + fb->rasters = allocraster(nil, r, COLOR32); + fb->rasters->next = allocraster("z-buffer", r, FLOAT32); fb->r = r; + fb->createraster = fb_createraster; + fb->fetchraster = fb_fetchraster; return fb; } void rmfb(Framebuf *fb) { - free(fb->nb); - free(fb->zb); - free(fb->cb); + Raster *r, *nr; + + for(r = fb->rasters; r != nil; r = nr){ + nr = r->next; + freeraster(r); + } free(fb); } @@ -317,9 +479,10 @@ mkfbctl(Rectangle r) fc->fb[1] = mkfb(r); fc->draw = framebufctl_draw; fc->memdraw = framebufctl_memdraw; - fc->drawnormals = framebufctl_drawnormals; fc->swap = framebufctl_swap; fc->reset = framebufctl_reset; + fc->createraster = framebufctl_createraster; + fc->fetchraster = framebufctl_fetchraster; fc->getfb = framebufctl_getfb; fc->getbb = framebufctl_getbb; return fc; @@ -23,6 +23,10 @@ enum { LightDirectional, LightSpot, + /* raster formats */ + COLOR32 = 0, + FLOAT32, + /* texture formats */ RAWTexture = 0, /* unmanaged */ sRGBTexture, @@ -50,6 +54,7 @@ typedef struct Model Model; typedef struct Entity Entity; typedef struct Scene Scene; typedef struct VSparams VSparams; +typedef struct FSoutput FSoutput; typedef struct FSparams FSparams; typedef struct SUparams SUparams; typedef struct Shadertab Shadertab; @@ -59,6 +64,7 @@ typedef struct Renderjob Renderjob; typedef struct Fragment Fragment; typedef struct Astk Astk; typedef struct Abuf Abuf; +typedef struct Raster Raster; typedef struct Framebuf Framebuf; typedef struct Framebufctl Framebufctl; typedef struct Viewport Viewport; @@ -205,6 +211,8 @@ struct FSparams SUparams *su; Point p; Vertex v; /* only for the attributes (varyings) */ + + void (*toraster)(FSparams*, char*, void*); }; /* shader unit params */ @@ -278,13 +286,24 @@ struct Abuf ulong nact; }; +struct Raster +{ + Rectangle r; + char *name; + ulong chan; + ulong *data; + + Raster *next; +}; + struct Framebuf { - ulong *cb; /* color buffer */ - float *zb; /* z/depth buffer */ - ulong *nb; /* normals buffer (DBG only) */ - Abuf abuf; /* A-buffer */ Rectangle r; + Raster *rasters; /* [0] color, [1] depth, [n] user-defined */ + Abuf abuf; /* A-buffer */ + + void (*createraster)(Framebuf*, char*, ulong); + Raster *(*fetchraster)(Framebuf*, char*); }; struct Framebufctl @@ -294,11 +313,12 @@ struct Framebufctl uint idx; /* front buffer index */ uint upfilter; /* upscaling filter */ - void (*draw)(Framebufctl*, Image*, Point, Point); - void (*memdraw)(Framebufctl*, Memimage*, Point, Point); - void (*drawnormals)(Framebufctl*, Image*); + void (*draw)(Framebufctl*, Image*, char*, Point, Point); + void (*memdraw)(Framebufctl*, Memimage*, char*, Point, Point); void (*swap)(Framebufctl*); void (*reset)(Framebufctl*, ulong); + void (*createraster)(Framebufctl*, char*, ulong); + Raster *(*fetchraster)(Framebufctl*, char*); Framebuf *(*getfb)(Framebufctl*); Framebuf *(*getbb)(Framebufctl*); }; @@ -309,13 +329,15 @@ struct Viewport Framebufctl *fbctl; Rectangle r; - void (*draw)(Viewport*, Image*); - void (*memdraw)(Viewport*, Memimage*); + void (*draw)(Viewport*, Image*, char*); + void (*memdraw)(Viewport*, Memimage*, char*); void (*setscale)(Viewport*, double, double); void (*setscalefilter)(Viewport*, int); Framebuf *(*getfb)(Viewport*); int (*getwidth)(Viewport*); int (*getheight)(Viewport*); + void (*createraster)(Viewport*, char*, ulong); + Raster *(*fetchraster)(Viewport*, char*); }; struct Camera @@ -38,6 +38,17 @@ void *erealloc(void*, ulong); Memimage *eallocmemimage(Rectangle, ulong); /* fb */ +Raster *allocraster(char*, Rectangle, ulong); +void clearraster(Raster*, ulong); +void fclearraster(Raster*, float); +uchar *rasterbyteaddr(Raster*, Point); +void rasterput(Raster*, Point, void*); +void rasterget(Raster*, Point, void*); +void rasterputcolor(Raster*, Point, ulong); +ulong rastergetcolor(Raster*, Point); +void rasterputfloat(Raster*, Point, float); +float rastergetfloat(Raster*, Point); +void freeraster(Raster*); Framebuf *mkfb(Rectangle); void rmfb(Framebuf*); Framebufctl *mkfbctl(Rectangle); @@ -61,10 +72,10 @@ void memsetl(void*, ulong, usize); /* nanosec */ uvlong nanosec(void); -/* ulong getpixel(Framebuf *fb, Point p) */ -#define getpixel(fb, p) (((fb)->cb)[Dx((fb)->r)*(p).y + (p).x]) -/* void putpixel(Framebuf *fb, Point p, ulong c) */ -#define putpixel(fb, p, c) (((fb)->cb)[Dx((fb)->r)*(p).y + (p).x] = (c)) +#define getpixel(fb, p) rastergetcolor(fb, p) +#define putpixel(fb, p, c) rasterputcolor(fb, p, c) +#define getdepth(fb, p) rastergetfloat(fb, p) +#define putdepth(fb, p, z) rasterputfloat(fb, p, z) /* void SWAP(type t, type *a, type *b) */ #define SWAP(t, a, b) {t tmp; tmp = *(a); *(a) = *(b); *(b) = tmp;} @@ -35,7 +35,7 @@ ul2col(ulong l) } static void -pixel(Framebuf *fb, Point p, Color c, int blend) +pixel(Raster *fb, Point p, Color c, int blend) { Color dc; @@ -50,13 +50,31 @@ pixel(Framebuf *fb, Point p, Color c, int blend) } static void -pixeln(Framebuf *fb, Point p, Color c) +fsparams_toraster(FSparams *sp, char *rname, void *v) { - ulong *dst; - - dst = fb->nb; - c.a = 1; - dst[Dx(fb->r)*p.y + p.x] = col2ul(c); + Framebuf *fb; + Raster *r; + ulong c, z; + + /* keep the user away from the color buffer */ + if(rname == nil || v == nil) + return; + + fb = sp->su->fb; + r = fb->fetchraster(fb, rname); + if(r == nil) + return; + + switch(r->chan){ + case COLOR32: + c = col2ul(*(Color*)v); + rasterput(r, sp->p, &c); + break; + case FLOAT32: + z = *(float*)v; + rasterput(r, sp->p, &z); + break; + } } static int @@ -117,16 +135,19 @@ squashAbuf(Framebuf *fb, int blend) { Abuf *buf; Astk *stk; + Raster *cr, *zr; int i, j; buf = &fb->abuf; + cr = fb->rasters; + zr = cr->next; for(i = 0; i < buf->nact; i++){ stk = buf->act[i]; j = stk->size; while(j--) - pixel(fb, stk->p, stk->items[j].c, blend); + pixel(cr, stk->p, stk->items[j].c, blend); /* write to the depth buffer as well */ - fb->zb[stk->p.x + stk->p.y*Dx(fb->r)] = stk->items[0].z; + putdepth(zr, stk->p, stk->items[0].z); } } @@ -149,6 +170,7 @@ static void rasterize(Rastertask *task) { SUparams *params; + Raster *cr, *zr; Primitive prim; FSparams fsp; Triangle2 t; @@ -164,6 +186,10 @@ rasterize(Rastertask *task) prim = task->p; fsp.su = params; memset(&fsp.v, 0, sizeof fsp.v); + fsp.toraster = fsparams_toraster; + + cr = params->fb->rasters; + zr = cr->next; switch(prim.type){ case PPoint: @@ -171,9 +197,9 @@ rasterize(Rastertask *task) z = fclamp(prim.v[0].p.z, 0, 1); if(params->camera->enabledepth){ - if(z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)]) + if(z <= getdepth(zr, p)) break; - params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z; + putdepth(zr, p, z); } fsp.v = dupvertex(&prim.v[0]); @@ -182,7 +208,7 @@ rasterize(Rastertask *task) if(params->camera->enableAbuff) pushtoAbuf(params->fb, p, c, z); else - pixel(params->fb, p, c, params->camera->enableblend); + pixel(cr, p, c, params->camera->enableblend); delvattrs(&fsp.v); break; case PLine: @@ -220,9 +246,9 @@ rasterize(Rastertask *task) z = flerp(prim.v[0].p.z, prim.v[1].p.z, perc); /* TODO get rid of the bounds check and make sure the clipping doesn't overflow */ if(params->camera->enabledepth){ - if(!ptinrect(p, params->fb->r) || z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)]) + if(!ptinrect(p, params->fb->r) || z <= getdepth(zr, p)) goto discard; - params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z; + putdepth(zr, p, z); } /* interpolate z⁻¹ and get actual z */ @@ -238,7 +264,7 @@ rasterize(Rastertask *task) if(params->camera->enableAbuff) pushtoAbuf(params->fb, p, c, z); else - pixel(params->fb, p, c, params->camera->enableblend); + pixel(cr, p, c, params->camera->enableblend); delvattrs(&fsp.v); discard: if(steep) SWAP(int, &p.x, &p.y); @@ -272,9 +298,9 @@ discard: z = fberp(prim.v[0].p.z, prim.v[1].p.z, prim.v[2].p.z, bc); if(params->camera->enabledepth){ - if(z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)]) + if(z <= getdepth(zr, p)) continue; - params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z; + putdepth(zr, p, z); } /* interpolate z⁻¹ and get actual z */ @@ -292,8 +318,7 @@ discard: if(params->camera->enableAbuff) pushtoAbuf(params->fb, p, c, z); else - pixel(params->fb, p, c, params->camera->enableblend); - pixeln(params->fb, p, fsp.v.n); + pixel(cr, p, c, params->camera->enableblend); delvattrs(&fsp.v); } break; @@ -23,19 +23,21 @@ modulapt3(Point3 a, Point3 b) void memsetf(void *dp, float v, usize len) { - float *p, *ep; + float *p; - for(p = dp, ep = p+len; p < ep; p++) - *p = v; + p = dp; + while(len--) + *p++ = v; } void memsetl(void *dp, ulong v, usize len) { - ulong *p, *ep; + ulong *p; - for(p = dp, ep = p+len; p < ep; p++) - *p = v; + p = dp; + while(len--) + *p++ = v; } Memimage * @@ -9,7 +9,7 @@ #include "internal.h" static void -viewport_draw(Viewport *v, Image *dst) +viewport_draw(Viewport *v, Image *dst, char *rname) { Point off, scale; @@ -18,11 +18,11 @@ viewport_draw(Viewport *v, Image *dst) scale.x = max(v->bx.x, 1); scale.y = max(v->by.y, 1); - v->fbctl->draw(v->fbctl, dst, off, scale); + v->fbctl->draw(v->fbctl, dst, rname, off, scale); } static void -viewport_memdraw(Viewport *v, Memimage *dst) +viewport_memdraw(Viewport *v, Memimage *dst, char *rname) { Point off, scale; @@ -31,7 +31,7 @@ viewport_memdraw(Viewport *v, Memimage *dst) scale.x = max(v->bx.x, 1); scale.y = max(v->by.y, 1); - v->fbctl->memdraw(v->fbctl, dst, off, scale); + v->fbctl->memdraw(v->fbctl, dst, rname, off, scale); } static void @@ -67,6 +67,18 @@ viewport_getheight(Viewport *v) return Dy(v->r)*v->by.y; } +static void +viewport_createraster(Viewport *v, char *name, ulong chan) +{ + v->fbctl->createraster(v->fbctl, name, chan); +} + +static Raster * +viewport_fetchraster(Viewport *v, char *name) +{ + return v->fbctl->fetchraster(v->fbctl, name); +} + Viewport * mkviewport(Rectangle r) { @@ -90,6 +102,8 @@ mkviewport(Rectangle r) v->getfb = viewport_getfb; v->getwidth = viewport_getwidth; v->getheight = viewport_getheight; + v->createraster = viewport_createraster; + v->fetchraster = viewport_fetchraster; return v; } |