diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2016-03-30 16:17:07 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2016-03-30 16:17:07 +0200 |
commit | 6b54359f371edab9f6165757aabcfe823b77ccd4 (patch) | |
tree | 8902d2d3adc9b8bcc1cd52b4c82d36b9ab0667a2 | |
parent | 23c102eb5272d3c2199cb5d952c3ad4b15a03cf6 (diff) | |
download | fbida-6b54359f371edab9f6165757aabcfe823b77ccd4.tar.gz |
fbpdf: pageflip
-rw-r--r-- | drmtools.c | 61 | ||||
-rw-r--r-- | drmtools.h | 2 | ||||
-rw-r--r-- | fb-gui.c | 2 | ||||
-rw-r--r-- | fbi.c | 4 | ||||
-rw-r--r-- | fbpdf.c | 21 | ||||
-rw-r--r-- | gfx.h | 4 |
6 files changed, 59 insertions, 35 deletions
@@ -25,11 +25,12 @@ static drmModeConnector *conn = NULL; static drmModeEncoder *enc = NULL; static drmModeModeInfo *mode = NULL; static drmModeCrtc *scrtc = NULL; -static uint32_t fb_id; -/* dumb fb */ -static struct drm_mode_create_dumb creq; -static uint8_t *fbmem; +struct drmfb { + uint32_t id; + struct drm_mode_create_dumb creq; + uint8_t *mem; +} fb1, fb2, *fbc; /* ------------------------------------------------------------------ */ @@ -141,23 +142,24 @@ static int drm_init_dev(const char *dev, const char *output) return 0; } -static int drm_init_fb(void) +static int drm_init_fb(struct drmfb *fb) { struct drm_mode_map_dumb mreq; int rc; /* create framebuffer */ - memset(&creq, 0, sizeof(creq)); - creq.width = mode->hdisplay; - creq.height = mode->vdisplay; - creq.bpp = 32; - rc = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq); + memset(&fb->creq, 0, sizeof(fb->creq)); + fb->creq.width = mode->hdisplay; + fb->creq.height = mode->vdisplay; + fb->creq.bpp = 32; + rc = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &fb->creq); if (rc < 0) { fprintf(stderr, "drm: DRM_IOCTL_MODE_CREATE_DUMB: %s\n", strerror(errno)); return -1; } - rc = drmModeAddFB(fd, creq.width, creq.height, 24, 32, creq.pitch, - creq.handle, &fb_id); + rc = drmModeAddFB(fd, fb->creq.width, fb->creq.height, + 24, 32, fb->creq.pitch, + fb->creq.handle, &fb->id); if (rc < 0) { fprintf(stderr, "drm: drmModeAddFB() failed\n"); return -1; @@ -165,25 +167,26 @@ static int drm_init_fb(void) /* map framebuffer */ memset(&mreq, 0, sizeof(mreq)); - mreq.handle = creq.handle; + mreq.handle = fb->creq.handle; rc = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); if (rc < 0) { fprintf(stderr, "drm: DRM_IOCTL_MODE_MAP_DUMB: %s\n", strerror(errno)); return -1; } - fbmem = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset); - if (fbmem == MAP_FAILED) { + fb->mem = mmap(0, fb->creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, mreq.offset); + if (fb->mem == MAP_FAILED) { fprintf(stderr, "drm: framebuffer mmap: %s\n", strerror(errno)); return -1; } return 0; } -static int drm_show_fb(void) +static int drm_show_fb(struct drmfb *fb) { int rc; - rc = drmModeSetCrtc(fd, enc->crtc_id, fb_id, 0, 0, + rc = drmModeSetCrtc(fd, enc->crtc_id, fb->id, 0, 0, &conn->connector_id, 1, &conn->modes[0]); if (rc < 0) { @@ -197,15 +200,17 @@ static int drm_show_fb(void) static void drm_restore_display(void) { - drm_show_fb(); + drm_show_fb(fbc); } -static void drm_flush_display(void) +static void drm_flush_display(bool second) { - drmModeDirtyFB(fd, fb_id, 0, 0); + fbc = second ? &fb2 : &fb1; + drm_show_fb(fbc); + drmModeDirtyFB(fd, fbc->id, 0, 0); } -gfxstate *drm_init(const char *device, const char *output) +gfxstate *drm_init(const char *device, const char *output, bool pageflip) { gfxstate *gfx; char dev[64]; @@ -219,9 +224,9 @@ gfxstate *drm_init(const char *device, const char *output) if (drm_init_dev(dev, output) < 0) return NULL; - if (drm_init_fb() < 0) + if (drm_init_fb(&fb1) < 0) return NULL; - if (drm_show_fb() < 0) + if (drm_show_fb(&fb1) < 0) return NULL; /* prepare gfx */ @@ -230,8 +235,8 @@ gfxstate *drm_init(const char *device, const char *output) gfx->hdisplay = mode->hdisplay; gfx->vdisplay = mode->vdisplay; - gfx->stride = creq.pitch; - gfx->mem = fbmem; + gfx->stride = fb1.creq.pitch; + gfx->mem = fb1.mem; gfx->rlen = 8; gfx->glen = 8; @@ -246,6 +251,12 @@ gfxstate *drm_init(const char *device, const char *output) gfx->restore_display = drm_restore_display; gfx->cleanup_display = drm_cleanup_display; gfx->flush_display = drm_flush_display; + + if (pageflip) { + if (drm_init_fb(&fb2) == 0) { + gfx->mem2 = fb2.mem; + } + } return gfx; } @@ -1,2 +1,2 @@ -gfxstate *drm_init(const char *device, const char *output); +gfxstate *drm_init(const char *device, const char *output, bool pageflip); void drm_info(const char *device); @@ -102,7 +102,7 @@ void shadow_render(gfxstate *gfx) sdirty[i] = 0; } if (gfx->flush_display) - gfx->flush_display(); + gfx->flush_display(false); } void shadow_clear_lines(int first, int last) @@ -1478,14 +1478,14 @@ int main(int argc, char *argv[]) if (device) { /* device specified */ if (strncmp(device, "/dev/d", 6) == 0) { - gfx = drm_init(device, output); + gfx = drm_init(device, output, false); } else { framebuffer = true; gfx = fb_init(device, mode, GET_VT()); } } else { /* try drm first, failing that fb */ - gfx = drm_init(NULL, output); + gfx = drm_init(NULL, output, false); if (!gfx) { framebuffer = true; gfx = fb_init(NULL, mode, GET_VT()); @@ -42,7 +42,8 @@ gfxstate *gfx; int debug; PopplerDocument *doc; -cairo_surface_t *surface; +cairo_surface_t *surface1; +cairo_surface_t *surface2; PopplerPage *page; double pw, ph; /* pdf page size */ @@ -119,9 +120,12 @@ static void page_fit_width(void) static void page_render(void) { + static bool second; cairo_t *context; - context = cairo_create(surface); + if (surface2) + second = !second; + context = cairo_create(second ? surface2 : surface1); cairo_set_source_rgb(context, 1, 1, 1); cairo_paint(context); @@ -133,7 +137,7 @@ static void page_render(void) cairo_destroy(context); if (gfx->flush_display) - gfx->flush_display(); + gfx->flush_display(second); } /* ---------------------------------------------------------------------- */ @@ -210,7 +214,7 @@ int main(int argc, char *argv[]) } /* gfx init */ - gfx = drm_init(NULL, NULL); + gfx = drm_init(NULL, NULL, true); if (!gfx) { framebuffer = true; gfx = fb_init(NULL, NULL, 0); @@ -231,11 +235,18 @@ int main(int argc, char *argv[]) } } - surface = cairo_image_surface_create_for_data(gfx->mem, + surface1 = cairo_image_surface_create_for_data(gfx->mem, CAIRO_FORMAT_ARGB32, gfx->hdisplay, gfx->vdisplay, gfx->stride); + if (gfx->mem2) { + surface2 = cairo_image_surface_create_for_data(gfx->mem2, + CAIRO_FORMAT_ARGB32, + gfx->hdisplay, + gfx->vdisplay, + gfx->stride); + } tty_raw(); @@ -1,3 +1,4 @@ +#include <stdbool.h> #include <inttypes.h> typedef struct gfxstate gfxstate; @@ -8,6 +9,7 @@ struct gfxstate { uint32_t vdisplay; uint32_t stride; uint8_t *mem; + uint8_t *mem2; uint32_t bits_per_pixel; uint32_t rlen, glen, blen, tlen; @@ -16,5 +18,5 @@ struct gfxstate { /* calls */ void (*restore_display)(void); void (*cleanup_display)(void); - void (*flush_display)(void); + void (*flush_display)(bool second); }; |