uterm: video: add support for immediate buffer-swaps

Internally, we already support immediate buffer-swaps but this hasn't been
exported in the API. This patch adds an "immediate" argument that causes
the flip to be immediate and not synchronized with vertical-blanks.

Please note that this might block if there is a pending page-flip.
However, this is mostly a delay of 16ms so we can ignore it as this is
acceptable if you want immediate swaps while there is still a
pending-buffer.
You can listen for the UTERM_PAGE_FLIP event if you don't want this
behavior.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2013-01-13 16:06:00 +01:00
parent df2d153e39
commit 80e5a3b4a6
9 changed files with 19 additions and 23 deletions

View File

@ -58,7 +58,7 @@ static void dummy_redraw(struct kmscon_dummy *dummy, struct display *d)
h = uterm_mode_get_height(mode);
uterm_display_fill(d->disp, 0, 0, 0, 0, 0, w, h);
uterm_display_swap(d->disp);
uterm_display_swap(d->disp, false);
}
static int dummy_session_event(struct kmscon_session *session,

View File

@ -93,7 +93,7 @@ static void do_redraw_screen(struct screen *scr)
scr->pending = false;
tsm_screen_draw(scr->term->console, kmscon_text_prepare_cb,
kmscon_text_draw_cb, kmscon_text_render_cb, scr->txt);
ret = uterm_display_swap(scr->disp);
ret = uterm_display_swap(scr->disp, false);
if (ret) {
log_warning("cannot swap display %p", scr->disp);
return;

View File

@ -425,17 +425,23 @@ static int display_set_dpms(struct uterm_display *disp, int state)
return 0;
}
static int display_swap(struct uterm_display *disp)
static int display_swap(struct uterm_display *disp, bool immediate)
{
struct fbdev_display *dfb = disp->data;
struct fb_var_screeninfo *vinfo;
int ret;
if (!(disp->flags & DISPLAY_DBUF))
if (!(disp->flags & DISPLAY_DBUF)) {
if (immediate)
return 0;
return display_schedule_vblank_timer(disp);
}
vinfo = &dfb->vinfo;
vinfo->activate = FB_ACTIVATE_VBL;
if (immediate)
vinfo->activate = FB_ACTIVATE_NOW;
else
vinfo->activate = FB_ACTIVATE_VBL;
if (!dfb->bufid)
vinfo->yoffset = dfb->yres;

View File

@ -423,12 +423,12 @@ int uterm_display_use(struct uterm_display *disp)
return VIDEO_CALL(disp->ops->use, -EOPNOTSUPP, disp);
}
int uterm_display_swap(struct uterm_display *disp)
int uterm_display_swap(struct uterm_display *disp, bool immediate)
{
if (!disp || !display_is_online(disp) || !video_is_awake(disp->video))
return -EINVAL;
return VIDEO_CALL(disp->ops->swap, 0, disp);
return VIDEO_CALL(disp->ops->swap, 0, disp, immediate);
}
bool uterm_display_is_swapping(struct uterm_display *disp)

View File

@ -164,7 +164,7 @@ int uterm_display_set_dpms(struct uterm_display *disp, int state);
int uterm_display_get_dpms(const struct uterm_display *disp);
int uterm_display_use(struct uterm_display *disp);
int uterm_display_swap(struct uterm_display *disp);
int uterm_display_swap(struct uterm_display *disp, bool immediate);
bool uterm_display_is_swapping(struct uterm_display *disp);
int uterm_display_fill(struct uterm_display *disp,

View File

@ -320,7 +320,7 @@ static int display_use(struct uterm_display *disp)
return 0;
}
static int swap_display(struct uterm_display *disp, bool immediate)
static int display_swap(struct uterm_display *disp, bool immediate)
{
int ret;
struct gbm_bo *bo;
@ -372,11 +372,6 @@ static int swap_display(struct uterm_display *disp, bool immediate)
return 0;
}
static int display_swap(struct uterm_display *disp)
{
return swap_display(disp, false);
}
extern const char *gl_static_fill_vert;
extern const char *gl_static_fill_frag;
extern const char *gl_static_blend_vert;
@ -853,7 +848,7 @@ static void show_displays(struct uterm_video *video)
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
swap_display(iter, true);
display_swap(iter, true);
}
}

View File

@ -240,7 +240,7 @@ static void display_deactivate(struct uterm_display *disp)
disp->current_mode = NULL;
}
static int swap_display(struct uterm_display *disp, bool immediate)
static int display_swap(struct uterm_display *disp, bool immediate)
{
int ret, rb;
struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp);
@ -254,11 +254,6 @@ static int swap_display(struct uterm_display *disp, bool immediate)
return 0;
}
static int display_swap(struct uterm_display *disp)
{
return swap_display(disp, false);
}
static int display_blit(struct uterm_display *disp,
const struct uterm_video_buffer *buf,
unsigned int x, unsigned int y)

View File

@ -54,7 +54,7 @@ struct display_ops {
void (*deactivate) (struct uterm_display *disp);
int (*set_dpms) (struct uterm_display *disp, int state);
int (*use) (struct uterm_display *disp);
int (*swap) (struct uterm_display *disp);
int (*swap) (struct uterm_display *disp, bool immediate);
int (*blit) (struct uterm_display *disp,
const struct uterm_video_buffer *buf,
unsigned int x, unsigned int y);

View File

@ -97,7 +97,7 @@ static int blit_outputs(struct uterm_video *video)
continue;
}
ret = uterm_display_swap(iter);
ret = uterm_display_swap(iter, true);
if (ret) {
log_err("Cannot swap screen: %d", ret);
continue;