From 361177fe972c0be63adb369ab1a3b3fea2286f2b Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 31 Jul 2012 10:22:39 +0200 Subject: [PATCH] uterm: video: change blit'ting logic Instead of passing width/height separately, we now use the values from the buffer object. The caller has to manipulate the buffer object to change these values. In fact, they can simply create a buffer object on the stack with the same values copied from the real buffer and just adjust the offset, width, height and stride. With the help of the stride value, it is possible to even shrink the buffer horizontally. Signed-off-by: David Herrmann --- src/font_pango.c | 3 +-- src/uterm.h | 3 +-- src/uterm_internal.h | 3 +-- src/uterm_video.c | 5 ++--- src/uterm_video_dumb.c | 38 +++++++++++++++++++++++--------------- src/uterm_video_fbdev.c | 27 ++++++++++++++++----------- 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/font_pango.c b/src/font_pango.c index 871b04c..8d4ece2 100644 --- a/src/font_pango.c +++ b/src/font_pango.c @@ -787,8 +787,7 @@ int font_screen_draw_perform(struct font_screen *screen, float *m) screen->buf->data); gl_shader_draw_tex(screen->shader, ver, tex, 6, screen->tex, m); } else { - uterm_screen_blit(screen->scr, &buf, 0, 0, - buf.width, buf.height); + uterm_screen_blit(screen->scr, &buf, 0, 0); } cairo_restore(screen->cr); diff --git a/src/uterm.h b/src/uterm.h index 24caf14..4d93404 100644 --- a/src/uterm.h +++ b/src/uterm.h @@ -194,8 +194,7 @@ int uterm_screen_use(struct uterm_screen *screen); int uterm_screen_swap(struct uterm_screen *screen); int uterm_screen_blit(struct uterm_screen *screen, const struct uterm_video_buffer *buf, - unsigned int x, unsigned int y, - unsigned int width, unsigned int height); + unsigned int x, unsigned int y); /* display modes interface */ diff --git a/src/uterm_internal.h b/src/uterm_internal.h index 6637666..c34b6f6 100644 --- a/src/uterm_internal.h +++ b/src/uterm_internal.h @@ -57,8 +57,7 @@ struct display_ops { int (*swap) (struct uterm_display *disp); int (*blit) (struct uterm_display *disp, const struct uterm_video_buffer *buf, - unsigned int x, unsigned int y, - unsigned int width, unsigned int height); + unsigned int x, unsigned int y); }; struct video_ops { diff --git a/src/uterm_video.c b/src/uterm_video.c index 502495c..1008668 100644 --- a/src/uterm_video.c +++ b/src/uterm_video.c @@ -135,14 +135,13 @@ int uterm_screen_swap(struct uterm_screen *screen) int uterm_screen_blit(struct uterm_screen *screen, const struct uterm_video_buffer *buf, - unsigned int x, unsigned int y, - unsigned int width, unsigned int height) + unsigned int x, unsigned int y) { if (!screen) return -EINVAL; return VIDEO_CALL(screen->disp->ops->blit, -EOPNOTSUPP, screen->disp, - buf, x, y, width, height); + buf, x, y); } int mode_new(struct uterm_mode **out, const struct mode_ops *ops) diff --git a/src/uterm_video_dumb.c b/src/uterm_video_dumb.c index 44f9e67..214ae67 100644 --- a/src/uterm_video_dumb.c +++ b/src/uterm_video_dumb.c @@ -365,12 +365,13 @@ static int display_swap(struct uterm_display *disp) static int display_blit(struct uterm_display *disp, const struct uterm_video_buffer *buf, - unsigned int x, unsigned int y, - unsigned int width, unsigned int height) + unsigned int x, unsigned int y) { unsigned int tmp; uint8_t *dst, *src; struct dumb_rb *rb; + unsigned int width, height; + unsigned int sw, sh; if (!disp->video || !display_is_online(disp)) return -EINVAL; @@ -379,22 +380,29 @@ static int display_blit(struct uterm_display *disp, if (buf->format != UTERM_FORMAT_XRGB32) return -EINVAL; - tmp = x + width; - if (tmp < x || x >= buf->width) - return -EINVAL; - if (tmp > buf->width) - width = buf->width - x; - tmp = y + height; - if (tmp < y || y >= buf->height) - return -EINVAL; - if (tmp > buf->height) - height = buf->height - y; - rb = &disp->dumb.rb[disp->dumb.current_rb ^ 1]; - dst = rb->map; + sw = disp->current_mode->dumb.info.hdisplay; + sh = disp->current_mode->dumb.info.vdisplay; + tmp = x + buf->width; + if (tmp < x || x >= sw) + return -EINVAL; + if (tmp > sw) + width = sw - x; + else + width = buf->width; + + tmp = y + buf->height; + if (tmp < y || y >= sh) + return -EINVAL; + if (tmp > sh) + height = sh - y; + else + height = buf->height; + + dst = rb->map; dst = &dst[y * rb->stride + x * 4]; - src = &buf->data[y * buf->stride + x * 4]; + src = buf->data; while (--height) { memcpy(dst, src, 4 * width); diff --git a/src/uterm_video_fbdev.c b/src/uterm_video_fbdev.c index 16785ec..bbe8052 100644 --- a/src/uterm_video_fbdev.c +++ b/src/uterm_video_fbdev.c @@ -349,11 +349,11 @@ static int display_swap(struct uterm_display *disp) static int display_blit(struct uterm_display *disp, const struct uterm_video_buffer *buf, - unsigned int x, unsigned int y, - unsigned int width, unsigned int height) + unsigned int x, unsigned int y) { unsigned int tmp; uint8_t *dst, *src; + unsigned int width, height; if (!disp->video || !(disp->flags & DISPLAY_ONLINE)) return -EINVAL; @@ -362,23 +362,28 @@ static int display_blit(struct uterm_display *disp, if (buf->format != UTERM_FORMAT_XRGB32) return -EINVAL; - tmp = x + width; - if (tmp < x || x >= buf->width) + tmp = x + buf->width; + if (tmp < x || x >= disp->fbdev.xres) return -EINVAL; - if (tmp > buf->width) - width = buf->width - x; - tmp = y + height; - if (tmp < y || y >= buf->height) + if (tmp > disp->fbdev.xres) + width = disp->fbdev.xres - x; + else + width = buf->width; + + tmp = y + buf->height; + if (tmp < y || y >= disp->fbdev.yres) return -EINVAL; - if (tmp > buf->height) - height = buf->height - y; + if (tmp > disp->fbdev.yres) + height = disp->fbdev.yres - y; + else + height = buf->height; if (!(disp->flags & DISPLAY_DBUF) || disp->fbdev.bufid) dst = disp->fbdev.map; else dst = &disp->fbdev.map[disp->fbdev.yres * disp->fbdev.stride]; dst = &dst[y * disp->fbdev.stride + x * disp->fbdev.bpp]; - src = &buf->data[y * buf->stride + x * 4]; + src = buf->data; while (--height) { memcpy(dst, src, 4 * width);