uterm: video: add support for immediate buffer-swaps
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 13 Jan 2013 15:06:00 +0000 (16:06 +0100)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 13 Jan 2013 15:06:00 +0000 (16:06 +0100)
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>
src/kmscon_dummy.c
src/kmscon_terminal.c
src/uterm_fbdev_video.c
src/uterm_video.c
src/uterm_video.h
src/uterm_video_drm.c
src/uterm_video_dumb.c
src/uterm_video_internal.h
tests/test_output.c

index a45a0c4..38432ce 100644 (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,
index 4e9cf80..12829d6 100644 (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;
index f1b1c06..2467cf8 100644 (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;
index 1b76d68..266de71 100644 (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)
index 9e3412b..8d36c3d 100644 (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,
index 758883c..8cb2e1d 100644 (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);
        }
 }
 
index c4b69e5..dafe56b 100644 (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)
index d52c0cd..c86b704 100644 (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);
index b087886..ff523cf 100644 (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;