From 80e5a3b4a68c3e6757b61b49413ee2788adcce0e Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 13 Jan 2013 16:06:00 +0100 Subject: [PATCH] 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 --- src/kmscon_dummy.c | 2 +- src/kmscon_terminal.c | 2 +- src/uterm_fbdev_video.c | 12 +++++++++--- src/uterm_video.c | 4 ++-- src/uterm_video.h | 2 +- src/uterm_video_drm.c | 9 ++------- src/uterm_video_dumb.c | 7 +------ src/uterm_video_internal.h | 2 +- tests/test_output.c | 2 +- 9 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/kmscon_dummy.c b/src/kmscon_dummy.c index a45a0c4..38432ce 100644 --- a/src/kmscon_dummy.c +++ b/src/kmscon_dummy.c @@ -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, diff --git a/src/kmscon_terminal.c b/src/kmscon_terminal.c index 4e9cf80..12829d6 100644 --- a/src/kmscon_terminal.c +++ b/src/kmscon_terminal.c @@ -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; diff --git a/src/uterm_fbdev_video.c b/src/uterm_fbdev_video.c index f1b1c06..2467cf8 100644 --- a/src/uterm_fbdev_video.c +++ b/src/uterm_fbdev_video.c @@ -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; diff --git a/src/uterm_video.c b/src/uterm_video.c index 1b76d68..266de71 100644 --- a/src/uterm_video.c +++ b/src/uterm_video.c @@ -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) diff --git a/src/uterm_video.h b/src/uterm_video.h index 9e3412b..8d36c3d 100644 --- a/src/uterm_video.h +++ b/src/uterm_video.h @@ -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, diff --git a/src/uterm_video_drm.c b/src/uterm_video_drm.c index 758883c..8cb2e1d 100644 --- a/src/uterm_video_drm.c +++ b/src/uterm_video_drm.c @@ -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); } } diff --git a/src/uterm_video_dumb.c b/src/uterm_video_dumb.c index c4b69e5..dafe56b 100644 --- a/src/uterm_video_dumb.c +++ b/src/uterm_video_dumb.c @@ -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) diff --git a/src/uterm_video_internal.h b/src/uterm_video_internal.h index d52c0cd..c86b704 100644 --- a/src/uterm_video_internal.h +++ b/src/uterm_video_internal.h @@ -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); diff --git a/tests/test_output.c b/tests/test_output.c index b087886..ff523cf 100644 --- a/tests/test_output.c +++ b/tests/test_output.c @@ -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;