uterm: video: add uterm_display_get_buffer()
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 13 Jan 2013 15:58:31 +0000 (16:58 +0100)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 13 Jan 2013 15:58:31 +0000 (16:58 +0100)
Until now we required external renderers to use the blit/blend helpers.
However, this seems hardly reasonable now so we provide a way to retrieve
the 2D buffer via the public API.

This is limited to xrgb32 and rgb16, other formats are not exported for
now (and probably not used, yet?). The 3D backends do not support that so
use the blit/blend helpers or OpenGL.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
src/uterm_fbdev_internal.h
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

index b0ac72e..722d1f5 100644 (file)
@@ -55,6 +55,7 @@ struct fbdev_display {
        unsigned int stride;
 
        bool xrgb32;
+       bool rgb16;
        unsigned int Bpp;
        unsigned int off_r;
        unsigned int off_g;
index 2467cf8..b4cae9e 100644 (file)
@@ -323,10 +323,15 @@ static int display_activate_force(struct uterm_display *disp,
        dfb->dither_g = 0;
        dfb->dither_b = 0;
        dfb->xrgb32 = false;
+       dfb->rgb16 = false;
        if (dfb->len_r == 8 && dfb->len_g == 8 && dfb->len_b == 8 &&
            dfb->off_r == 16 && dfb->off_g ==  8 && dfb->off_b ==  0 &&
            dfb->Bpp == 4)
                dfb->xrgb32 = true;
+       else if (dfb->len_r == 5 && dfb->len_g == 6 && dfb->len_b == 5 &&
+                dfb->off_r == 11 && dfb->off_g == 5 && dfb->off_b == 0 &&
+                dfb->Bpp == 2)
+               dfb->rgb16 = true;
 
        /* TODO: make dithering configurable */
        disp->flags |= DISPLAY_DITHERING;
@@ -425,6 +430,30 @@ static int display_set_dpms(struct uterm_display *disp, int state)
        return 0;
 }
 
+static int display_get_buffer(struct uterm_display *disp,
+                             struct uterm_video_buffer *buffer,
+                             unsigned int formats)
+{
+       struct fbdev_display *dfb = disp->data;
+       unsigned int f = 0;
+
+       if (dfb->xrgb32)
+               f = UTERM_FORMAT_XRGB32;
+       else if (dfb->rgb16)
+               f = UTERM_FORMAT_RGB16;
+
+       if (!(formats & f))
+               return -EOPNOTSUPP;
+
+       buffer->width = dfb->xres;
+       buffer->height = dfb->yres;
+       buffer->stride = dfb->stride;
+       buffer->format = f;
+       buffer->data = dfb->map;
+
+       return 0;
+}
+
 static int display_swap(struct uterm_display *disp, bool immediate)
 {
        struct fbdev_display *dfb = disp->data;
@@ -466,6 +495,7 @@ static const struct display_ops fbdev_display_ops = {
        .deactivate = display_deactivate,
        .set_dpms = display_set_dpms,
        .use = NULL,
+       .get_buffer = display_get_buffer,
        .swap = display_swap,
        .blit = uterm_fbdev_display_blit,
        .fake_blendv = uterm_fbdev_display_fake_blendv,
index 266de71..60455b6 100644 (file)
@@ -423,6 +423,17 @@ int uterm_display_use(struct uterm_display *disp)
        return VIDEO_CALL(disp->ops->use, -EOPNOTSUPP, disp);
 }
 
+int uterm_display_get_buffer(struct uterm_display *disp,
+                            struct uterm_video_buffer *buffer,
+                            unsigned int formats)
+{
+       if (!disp || !display_is_online(disp) || !buffer)
+               return -EINVAL;
+
+       return VIDEO_CALL(disp->ops->get_buffer, -EOPNOTSUPP, disp, buffer,
+                         formats);
+}
+
 int uterm_display_swap(struct uterm_display *disp, bool immediate)
 {
        if (!disp || !display_is_online(disp) || !video_is_awake(disp->video))
index 8d36c3d..2170b89 100644 (file)
@@ -96,8 +96,9 @@ struct uterm_display_event {
 };
 
 enum uterm_video_format {
-       UTERM_FORMAT_GREY,
-       UTERM_FORMAT_XRGB32,
+       UTERM_FORMAT_GREY       = 0x01,
+       UTERM_FORMAT_XRGB32     = 0x02,
+       UTERM_FORMAT_RGB16      = 0x04,
 };
 
 struct uterm_video_buffer {
@@ -164,6 +165,9 @@ 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_get_buffer(struct uterm_display *disp,
+                            struct uterm_video_buffer *buffer,
+                            unsigned int formats);
 int uterm_display_swap(struct uterm_display *disp, bool immediate);
 bool uterm_display_is_swapping(struct uterm_display *disp);
 
index 8cb2e1d..e72e258 100644 (file)
@@ -819,6 +819,7 @@ static const struct display_ops drm_display_ops = {
        .deactivate = display_deactivate,
        .set_dpms = uterm_drm_display_set_dpms,
        .use = display_use,
+       .get_buffer = NULL,
        .swap = display_swap,
        .blit = display_blit,
        .fake_blendv = display_fake_blendv,
index dafe56b..130f5e3 100644 (file)
@@ -240,6 +240,27 @@ static void display_deactivate(struct uterm_display *disp)
        disp->current_mode = NULL;
 }
 
+static int display_get_buffer(struct uterm_display *disp,
+                             struct uterm_video_buffer *buffer,
+                             unsigned int formats)
+{
+       struct uterm_drm2d_display *d2d = uterm_drm_display_get_data(disp);
+       struct uterm_drm2d_rb *rb;
+
+       if (!(formats & UTERM_FORMAT_XRGB32))
+               return -EOPNOTSUPP;
+
+       rb = &d2d->rb[d2d->current_rb ^ 1];
+
+       buffer->width = uterm_drm_mode_get_width(disp->current_mode);
+       buffer->height = uterm_drm_mode_get_height(disp->current_mode);
+       buffer->stride = rb->stride;
+       buffer->format = UTERM_FORMAT_XRGB32;
+       buffer->data = rb->map;
+
+       return 0;
+}
+
 static int display_swap(struct uterm_display *disp, bool immediate)
 {
        int ret, rb;
@@ -427,6 +448,7 @@ static const struct display_ops dumb_display_ops = {
        .deactivate = display_deactivate,
        .set_dpms = uterm_drm_display_set_dpms,
        .use = NULL,
+       .get_buffer = display_get_buffer,
        .swap = display_swap,
        .blit = display_blit,
        .fake_blendv = display_fake_blendv,
index c86b704..18725be 100644 (file)
@@ -54,6 +54,9 @@ 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 (*get_buffer) (struct uterm_display *disp,
+                          struct uterm_video_buffer *buffer,
+                          unsigned int formats);
        int (*swap) (struct uterm_display *disp, bool immediate);
        int (*blit) (struct uterm_display *disp,
                     const struct uterm_video_buffer *buf,