uterm: video_fbdev: make double-buffering optional
This makes double-buffering optional as not all drivers provide this. In fact, only very few drivers implement this. Furthermore, this also adds a fake display-mode that is used instead of NULL. Otherwise, the screen object might not work as expected. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
749f653e66
commit
66b7cce2cf
@ -46,17 +46,17 @@
|
|||||||
|
|
||||||
static const char *mode_get_name(const struct uterm_mode *mode)
|
static const char *mode_get_name(const struct uterm_mode *mode)
|
||||||
{
|
{
|
||||||
return NULL;
|
return "<default>";
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int mode_get_width(const struct uterm_mode *mode)
|
static unsigned int mode_get_width(const struct uterm_mode *mode)
|
||||||
{
|
{
|
||||||
return 0;
|
return mode->fbdev.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int mode_get_height(const struct uterm_mode *mode)
|
static unsigned int mode_get_height(const struct uterm_mode *mode)
|
||||||
{
|
{
|
||||||
return 0;
|
return mode->fbdev.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int refresh_info(struct uterm_display *disp)
|
static int refresh_info(struct uterm_display *disp)
|
||||||
@ -120,8 +120,17 @@ static int display_activate_force(struct uterm_display *disp,
|
|||||||
|
|
||||||
ret = ioctl(disp->fbdev.fd, FBIOPUT_VSCREENINFO, vinfo);
|
ret = ioctl(disp->fbdev.fd, FBIOPUT_VSCREENINFO, vinfo);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_err("video_fbdev: cannot set vinfo (%d): %m", errno);
|
disp->flags &= ~DISPLAY_DBUF;
|
||||||
return -EFAULT;
|
vinfo->yres_virtual = vinfo->yres;
|
||||||
|
ret = ioctl(disp->fbdev.fd, FBIOPUT_VSCREENINFO, vinfo);
|
||||||
|
if (ret) {
|
||||||
|
log_err("cannot set vinfo (%d): %m",
|
||||||
|
errno);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
disp->flags |= DISPLAY_DBUF;
|
||||||
|
log_debug("enabling double buffering");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = refresh_info(disp);
|
ret = refresh_info(disp);
|
||||||
@ -152,9 +161,11 @@ static int display_activate_force(struct uterm_display *disp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo->yres_virtual < vinfo->yres * 2 ||
|
if (vinfo->xres_virtual < vinfo->xres ||
|
||||||
vinfo->xres_virtual < vinfo->xres) {
|
(disp->flags & DISPLAY_DBUF &&
|
||||||
log_error("device %s does no double-buffering",
|
vinfo->yres_virtual < vinfo->yres * 2) ||
|
||||||
|
vinfo->yres_virtual < vinfo->yres) {
|
||||||
|
log_error("device %s does not support out buffer sizes",
|
||||||
disp->fbdev.node);
|
disp->fbdev.node);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@ -194,7 +205,10 @@ static int display_activate_force(struct uterm_display *disp,
|
|||||||
else
|
else
|
||||||
disp->fbdev.rate = 60 * 1000;
|
disp->fbdev.rate = 60 * 1000;
|
||||||
|
|
||||||
len = finfo->line_length * (vinfo->yres * 2);
|
len = finfo->line_length * vinfo->yres;
|
||||||
|
if (disp->flags & DISPLAY_DBUF)
|
||||||
|
len *= 2;
|
||||||
|
|
||||||
disp->fbdev.map = mmap(0, len, PROT_WRITE, MAP_SHARED,
|
disp->fbdev.map = mmap(0, len, PROT_WRITE, MAP_SHARED,
|
||||||
disp->fbdev.fd, 0);
|
disp->fbdev.fd, 0);
|
||||||
if (disp->fbdev.map == MAP_FAILED) {
|
if (disp->fbdev.map == MAP_FAILED) {
|
||||||
@ -211,8 +225,16 @@ static int display_activate_force(struct uterm_display *disp,
|
|||||||
disp->fbdev.stride = finfo->line_length;
|
disp->fbdev.stride = finfo->line_length;
|
||||||
disp->fbdev.bufid = 0;
|
disp->fbdev.bufid = 0;
|
||||||
|
|
||||||
disp->flags |= DISPLAY_ONLINE;
|
ret = mode_new(&disp->modes, &fbdev_mode_ops);
|
||||||
|
if (ret) {
|
||||||
|
munmap(disp->fbdev.map, disp->fbdev.len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
disp->modes->fbdev.width = disp->fbdev.xres;
|
||||||
|
disp->modes->fbdev.height = disp->fbdev.yres;
|
||||||
|
disp->current_mode = disp->modes;
|
||||||
|
|
||||||
|
disp->flags |= DISPLAY_ONLINE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +249,9 @@ static void display_deactivate_force(struct uterm_display *disp, bool force)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
log_info("deactivating device %s", disp->fbdev.node);
|
log_info("deactivating device %s", disp->fbdev.node);
|
||||||
|
uterm_mode_unref(disp->modes);
|
||||||
|
disp->modes = NULL;
|
||||||
|
disp->current_mode = NULL;
|
||||||
munmap(disp->fbdev.map, disp->fbdev.len);
|
munmap(disp->fbdev.map, disp->fbdev.len);
|
||||||
|
|
||||||
if (!force)
|
if (!force)
|
||||||
@ -300,6 +325,9 @@ static int display_swap(struct uterm_display *disp)
|
|||||||
if (!(disp->flags & DISPLAY_ONLINE))
|
if (!(disp->flags & DISPLAY_ONLINE))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!(disp->flags & DISPLAY_DBUF))
|
||||||
|
return 0;
|
||||||
|
|
||||||
vinfo = &disp->fbdev.vinfo;
|
vinfo = &disp->fbdev.vinfo;
|
||||||
vinfo->activate = FB_ACTIVATE_VBL;
|
vinfo->activate = FB_ACTIVATE_VBL;
|
||||||
|
|
||||||
@ -346,7 +374,7 @@ static int display_blit(struct uterm_display *disp,
|
|||||||
if (tmp > buf->height)
|
if (tmp > buf->height)
|
||||||
height = buf->height - y;
|
height = buf->height - y;
|
||||||
|
|
||||||
if (disp->fbdev.bufid)
|
if (!(disp->flags & DISPLAY_DBUF) || disp->fbdev.bufid)
|
||||||
dst = disp->fbdev.map;
|
dst = disp->fbdev.map;
|
||||||
else
|
else
|
||||||
dst = &disp->fbdev.map[disp->fbdev.yres * disp->fbdev.stride];
|
dst = &disp->fbdev.map[disp->fbdev.yres * disp->fbdev.stride];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user