summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-07-14 21:49:43 +0000
committerrodri <rgl@antares-labs.eu>2024-07-14 21:49:43 +0000
commit5f10c82aad318fc9091c9bd612e89fda1a77009f (patch)
tree821cd9dfd0fcea21fdb720805666c77a63d2819c
parent78bf838d0c45fbe6e282450e127446de5888fa11 (diff)
downloadlibgraphics-5f10c82aad318fc9091c9bd612e89fda1a77009f.tar.gz
libgraphics-5f10c82aad318fc9091c9bd612e89fda1a77009f.tar.bz2
libgraphics-5f10c82aad318fc9091c9bd612e89fda1a77009f.zip
initial viewport upscaling support.
-rw-r--r--fb.c50
-rw-r--r--graphics.h2
-rw-r--r--viewport.c26
3 files changed, 76 insertions, 2 deletions
diff --git a/fb.c b/fb.c
index e0fa2cd..a23e305 100644
--- a/fb.c
+++ b/fb.c
@@ -20,6 +20,30 @@ framebufctl_draw(Framebufctl *ctl, Image *dst)
}
static void
+framebufctl_upscaledraw(Framebufctl *ctl, Image *dst, Point scale)
+{
+ Framebuf *fb;
+ Rectangle blkr;
+ Point sp, dp;
+ ulong *blk;
+ int i;
+
+ blk = emalloc(scale.x*scale.y*4);
+ blkr = Rect(0,0,scale.x,scale.y);
+
+ qlock(ctl);
+ fb = ctl->getfb(ctl);
+ for(sp.y = fb->r.min.y, dp.y = dst->r.min.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; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){
+ for(i = 0; i < scale.x*scale.y; i++)
+ blk[i] = fb->cb[Dx(fb->r)*sp.y + sp.x];
+ loadimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4);
+ }
+ qunlock(ctl);
+ free(blk);
+}
+
+static void
framebufctl_memdraw(Framebufctl *ctl, Memimage *dst)
{
Framebuf *fb;
@@ -31,6 +55,30 @@ framebufctl_memdraw(Framebufctl *ctl, Memimage *dst)
}
static void
+framebufctl_upscalememdraw(Framebufctl *ctl, Memimage *dst, Point scale)
+{
+ Framebuf *fb;
+ Rectangle blkr;
+ Point sp, dp;
+ ulong *blk;
+ int i;
+
+ blk = emalloc(scale.x*scale.y*4);
+ blkr = Rect(0,0,scale.x,scale.y);
+
+ qlock(ctl);
+ fb = ctl->getfb(ctl);
+ for(sp.y = fb->r.min.y, dp.y = dst->r.min.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; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){
+ for(i = 0; i < scale.x*scale.y; i++)
+ blk[i] = fb->cb[Dx(fb->r)*sp.y + sp.x];
+ loadmemimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4);
+ }
+ qunlock(ctl);
+ free(blk);
+}
+
+static void
framebufctl_drawnormals(Framebufctl *ctl, Image *dst)
{
Framebuf *fb;
@@ -106,7 +154,9 @@ mkfbctl(Rectangle r)
fc->fb[0] = mkfb(r);
fc->fb[1] = mkfb(r);
fc->draw = framebufctl_draw;
+ fc->upscaledraw = framebufctl_upscaledraw;
fc->memdraw = framebufctl_memdraw;
+ fc->upscalememdraw = framebufctl_upscalememdraw;
fc->drawnormals = framebufctl_drawnormals;
fc->swap = framebufctl_swap;
fc->reset = framebufctl_reset;
diff --git a/graphics.h b/graphics.h
index 3c170f7..511564e 100644
--- a/graphics.h
+++ b/graphics.h
@@ -255,7 +255,9 @@ struct Framebufctl
uint idx; /* front buffer index */
void (*draw)(Framebufctl*, Image*);
+ void (*upscaledraw)(Framebufctl*, Image*, Point);
void (*memdraw)(Framebufctl*, Memimage*);
+ void (*upscalememdraw)(Framebufctl*, Memimage*, Point);
void (*drawnormals)(Framebufctl*, Image*);
void (*swap)(Framebufctl*);
void (*reset)(Framebufctl*);
diff --git a/viewport.c b/viewport.c
index 0336353..d37a12c 100644
--- a/viewport.c
+++ b/viewport.c
@@ -11,13 +11,35 @@
static void
viewport_draw(Viewport *v, Image *dst)
{
- v->fbctl->draw(v->fbctl, dst);
+ Point scale;
+
+ scale.x = Dx(dst->r)/Dx(v->r);
+ scale.y = Dy(dst->r)/Dy(v->r);
+
+ /* no downsampling support yet */
+ assert(scale.x > 0 && scale.y > 0);
+
+ if(scale.x > 1 || scale.y > 1)
+ v->fbctl->upscaledraw(v->fbctl, dst, scale);
+ else
+ v->fbctl->draw(v->fbctl, dst);
}
static void
viewport_memdraw(Viewport *v, Memimage *dst)
{
- v->fbctl->memdraw(v->fbctl, dst);
+ Point scale;
+
+ scale.x = Dx(dst->r)/Dx(v->r);
+ scale.y = Dy(dst->r)/Dy(v->r);
+
+ /* no downsampling support yet */
+ assert(scale.x > 0 && scale.y > 0);
+
+ if(scale.x > 1 || scale.y > 1)
+ v->fbctl->upscalememdraw(v->fbctl, dst, scale);
+ else
+ v->fbctl->memdraw(v->fbctl, dst);
}
static Framebuf *