uterm: video: add blitting support
All backends that do not provide OpenGL contexts can not implement buffer blitting so we can at least draw rectangular areas to the framebuffer. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
eec3f2ad85
commit
749f653e66
12
src/uterm.h
12
src/uterm.h
@ -157,6 +157,14 @@ struct uterm_video_hotplug {
|
|||||||
int action;
|
int action;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct uterm_video_buffer {
|
||||||
|
uint8_t *data;
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
unsigned int stride;
|
||||||
|
unsigned int bpp;
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*uterm_video_cb) (struct uterm_video *video,
|
typedef void (*uterm_video_cb) (struct uterm_video *video,
|
||||||
struct uterm_video_hotplug *arg,
|
struct uterm_video_hotplug *arg,
|
||||||
void *data);
|
void *data);
|
||||||
@ -177,6 +185,10 @@ unsigned int uterm_screen_height(struct uterm_screen *screen);
|
|||||||
|
|
||||||
int uterm_screen_use(struct uterm_screen *screen);
|
int uterm_screen_use(struct uterm_screen *screen);
|
||||||
int uterm_screen_swap(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);
|
||||||
|
|
||||||
/* display modes interface */
|
/* display modes interface */
|
||||||
|
|
||||||
|
@ -134,6 +134,18 @@ int uterm_screen_swap(struct uterm_screen *screen)
|
|||||||
return VIDEO_CALL(screen->disp->ops->swap, 0, screen->disp);
|
return VIDEO_CALL(screen->disp->ops->swap, 0, screen->disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (!screen)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return VIDEO_CALL(screen->disp->ops->blit, -EOPNOTSUPP, screen->disp,
|
||||||
|
buf, x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
int mode_new(struct uterm_mode **out, const struct mode_ops *ops)
|
int mode_new(struct uterm_mode **out, const struct mode_ops *ops)
|
||||||
{
|
{
|
||||||
struct uterm_mode *mode;
|
struct uterm_mode *mode;
|
||||||
|
@ -319,6 +319,51 @@ static int display_swap(struct uterm_display *disp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 tmp;
|
||||||
|
uint8_t *dst, *src;
|
||||||
|
|
||||||
|
log_debug("blit start");
|
||||||
|
if (!disp->video || !(disp->flags & DISPLAY_ONLINE))
|
||||||
|
return -EINVAL;
|
||||||
|
if (!buf || !video_is_awake(disp->video))
|
||||||
|
return -EINVAL;
|
||||||
|
if (buf->bpp != disp->fbdev.bpp)
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (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 * buf->bpp];
|
||||||
|
|
||||||
|
log_debug("blitting %u %u %u %u %u %u", buf->width, buf->height,
|
||||||
|
x, y, width, height);
|
||||||
|
while (--height) {
|
||||||
|
memcpy(dst, src, buf->bpp * width);
|
||||||
|
dst += disp->fbdev.stride;
|
||||||
|
src += buf->stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int video_init(struct uterm_video *video, const char *node)
|
static int video_init(struct uterm_video *video, const char *node)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -405,6 +450,7 @@ const struct display_ops fbdev_display_ops = {
|
|||||||
.set_dpms = display_set_dpms,
|
.set_dpms = display_set_dpms,
|
||||||
.use = NULL,
|
.use = NULL,
|
||||||
.swap = display_swap,
|
.swap = display_swap,
|
||||||
|
.blit = display_blit,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct video_ops fbdev_video_ops = {
|
const struct video_ops fbdev_video_ops = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user