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 <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-07-31 10:22:39 +02:00
parent 20e0e69253
commit 361177fe97
6 changed files with 44 additions and 35 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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 {

View File

@ -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)

View File

@ -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);

View File

@ -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);