diff options
author | Edward O'Callaghan <funfunctor@folklore1984.net> | 2017-03-06 13:02:40 +1100 |
---|---|---|
committer | Edward O'Callaghan <funfunctor@folklore1984.net> | 2017-03-06 13:02:40 +1100 |
commit | 4f0abcd290c226e3572e35b1b826640699f33f4e (patch) | |
tree | 5aaacffd0f911cd29e11177d4b8a9938b3c71f34 | |
parent | d76af6a2fccc296e74a870ad1f21d63b6d5e95f9 (diff) |
src/fb: cleanup gbm init logic
Signed-off-by: Edward O'Callaghan <funfunctor@folklore1984.net>
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/common.c | 56 | ||||
-rw-r--r-- | src/common.h | 14 | ||||
-rw-r--r-- | src/framebuffer.c | 160 | ||||
-rw-r--r-- | src/framebuffer.h | 9 | ||||
-rw-r--r-- | src/modesetting.c | 12 |
6 files changed, 77 insertions, 176 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index adc42f3..9418530 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/) add_library(baregl_lib SHARED modesetting.c - framebuffer.c + common.c egl.c drm.c ) diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..03bae20 --- /dev/null +++ b/src/common.c @@ -0,0 +1,56 @@ +#include <assert.h> +#include <stdio.h> + +#include <gbm.h> + +#include "common.h" + +static struct gbm g_gbm; + +/** + * After we have found a crtc+connector+mode combination, + * we need to actually create a suitable framebuffer that + * we can use with it. There are two ways to do that: + * + * - We create a so-called "dumb buffer" + * This is a buffer that we can mmap() and every driver + * supports this. We can use it for unaccelerated software + * rendering on the CPU. + * + * - We use libgbm to create buffers available for hardware + * accelerated rendering. libgbm is an abstraction layer + * that creates these buffers for each available DRM driver. + * As there is no generic API for this, each driver provides + * its own mechanism to create these buffers. We can then + * use such buffers to create OpenGL contexts with the Mesa3D + * library. (We do this here). + */ +const struct gbm * init_gbm(int drm_fd, int w, int h) +{ + unsigned flags = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT; + int format = GBM_FORMAT_XRGB8888; + + g_gbm.dev = gbm_create_device(drm_fd); + if (!g_gbm.dev) { + fprintf(stderr, "cannot create gbm device\n"); + return NULL; + } + + g_gbm.surface = gbm_surface_create(g_gbm.dev, w, h, format, flags); + if (!g_gbm.surface) { + fprintf(stderr, "failed to create gbm surface\n"); + gbm_device_destroy(g_gbm.dev); + g_gbm.dev = NULL; + return NULL; + } + g_gbm.width = w; + g_gbm.height = h; + return &g_gbm; +} + +void deinit_gbm() +{ + assert(g_gbm.surface && g_gbm.dev); + gbm_surface_destroy(g_gbm.surface); + gbm_device_destroy(g_gbm.dev); +} diff --git a/src/common.h b/src/common.h index 6c168f1..30fde55 100644 --- a/src/common.h +++ b/src/common.h @@ -16,6 +16,20 @@ struct render_node { }; /** + * setup a backing gbm device and surface from a + * render node file descriptor and the expected + * width and height. + */ +struct gbm { + struct gbm_device *dev; + struct gbm_surface *surface; + uint32_t width, height; +}; + +const struct gbm * init_gbm(int drm_fd, int w, int h); +void deinit_gbm(); + +/** * .. */ struct drm_fb { diff --git a/src/framebuffer.c b/src/framebuffer.c deleted file mode 100644 index 3f8ae2b..0000000 --- a/src/framebuffer.c +++ /dev/null @@ -1,160 +0,0 @@ -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdbool.h> -#include <unistd.h> - -#include <sys/mman.h> - -#include <gbm.h> -#include <xf86drm.h> -#include <xf86drmMode.h> - -#include "common.h" - - -/** - * After we have found a crtc+connector+mode combination, - * we need to actually create a suitable framebuffer that - * we can use with it. There are two ways to do that: - * - * - We create a so-called "dumb buffer" (We do this here). - * This is a buffer that we can mmap() and every driver - * supports this. We can use it for unaccelerated software - * rendering on the CPU. - * - * - We use libgbm to create buffers available for hardware - * accelerated rendering. libgbm is an abstraction layer - * that creates these buffers for each available DRM driver. - * As there is no generic API for this, each driver provides - * its own mechanism to create these buffers. We can then - * use such buffers to create OpenGL contexts with the Mesa3D - * library. - */ -static int modeset_create_dumb_fb(struct drm_fb *dev, int fd) -{ - struct drm_mode_create_dumb creq; - struct drm_mode_destroy_dumb dreq; - struct drm_mode_map_dumb mreq; - int ret; - - /* create dumb buffer */ - memset(&creq, 0, sizeof(creq)); - creq.width = dev->width; - creq.height = dev->height; - creq.bpp = 32; - ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq); - if (ret < 0) { - fprintf(stderr, "cannot create dumb buffer (%d): %m\n", errno); - return -errno; - } - dev->stride = creq.pitch; - dev->size = creq.size; - dev->handle = creq.handle; - - /* create framebuffer object for the dumb-buffer */ - ret = drmModeAddFB(fd, dev->width, dev->height, 24, 32, dev->stride, dev->handle, &dev->fb); - if (ret) { - fprintf(stderr, "cannot create framebuffer (%d): %m\n", errno); - ret = -errno; - goto err_destroy; - } - - /* prepare buffer for memory mapping */ - memset(&mreq, 0, sizeof(mreq)); - mreq.handle = dev->handle; - ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); - if (ret) { - fprintf(stderr, "cannot map dumb buffer (%d): %m\n", errno); - ret = -errno; - goto err_fb; - } - - /* preform the actual memory mapping */ - dev->map = mmap(0, dev->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset); - if (dev->map == MAP_FAILED) { - fprintf(stderr, "cannot mmap dumb buffer (%d): %m\n", errno); - ret = -errno; - goto err_fb; - } - - memset(dev->map, 0, dev->size); - - return 0; - -err_fb: - drmModeRmFB(fd, dev->fb); -err_destroy: - memset(&dreq, 0, sizeof(dreq)); - dreq.handle = dev->handle; - drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); - return ret; -} - -static int modeset_cleanup_dumb_fb(struct drm_fb *dev, int fd) -{ - struct drm_mode_destroy_dumb dreq = {0}; - - /* unmap buffer */ - munmap(dev->map, dev->size); - /* remove framebuffer */ - drmModeRmFB(fd, dev->fb); - /* delete dumb buffer */ - dreq.handle = dev->handle; - drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); -} - -static int modeset_create_gbm_fb(struct drm_fb *dev, int fd) -{ - unsigned flags = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT; - - int format = GBM_FORMAT_XRGB8888; - uint32_t bpp = 32, depth = 24; - - int ret; - - struct gbm_device * gbm_dev = gbm_create_device(fd); - if (!gbm_dev) { - fprintf(stderr, "cannot create gbm device\n"); - return -1; - } - dev->gbm_dev = gbm_dev; - - dev->gbm_surface = gbm_surface_create(gbm_dev, dev->width, dev->height, format, flags); - if (!dev->gbm_surface) { - fprintf(stderr, "failed to create gbm surface\n"); - gbm_device_destroy(gbm_dev); - dev->gbm_dev = NULL; - return -1; - } - - return 0; -} - -static int modeset_cleanup_gbm_fb(struct drm_fb *dev, int fd) -{ - gbm_surface_destroy(dev->gbm_surface); - gbm_device_destroy(dev->gbm_dev); -} - -int modeset_create_fb(struct drm_fb *dev, int fd, bool is_accelerated) -{ - int ret; - - if (is_accelerated) // do accel path - ret = modeset_create_gbm_fb(dev, fd); - else // fallback - ret = modeset_create_dumb_fb(dev, fd); - - return ret; -} - -void modeset_cleanup_fb(struct drm_fb *dev, int fd, bool is_accelerated) -{ - if (is_accelerated) // do accel path - modeset_cleanup_gbm_fb(dev, fd); - else // fallback - modeset_cleanup_dumb_fb(dev, fd); -} diff --git a/src/framebuffer.h b/src/framebuffer.h deleted file mode 100644 index 3051290..0000000 --- a/src/framebuffer.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef FRAMEBUFFER_H -#define FRAMEBUFFER_H - -#include "common.h" - -int modeset_create_fb(struct drm_fb *dev, int fd, bool is_accelerated); -void modeset_cleanup_fb(struct drm_fb *dev, int fd, bool is_accelerated); - -#endif /* FRAMEBUFFER_H */ diff --git a/src/modesetting.c b/src/modesetting.c index 7860a25..61eb6bb 100644 --- a/src/modesetting.c +++ b/src/modesetting.c @@ -9,7 +9,6 @@ #include <xf86drm.h> #include <xf86drmMode.h> -#include "framebuffer.h" #include "modesetting.h" #include "egl.h" #include "common.h" @@ -118,12 +117,13 @@ static int modeset_setup_dev( } /* create a framebuffer for this CRTC */ - ret = modeset_create_fb(dev, fd, is_accelerated); - assert(dev->gbm_surface); - if (ret) { + struct gbm * gbm = init_gbm(fd, dev->width, dev->height); + if (!gbm) { fprintf(stderr, "connot create framebuffer for connector %u\n", conn->connector_id); - return ret; + return -1; } + dev->gbm_dev = gbm->dev; + dev->gbm_surface = gbm->surface; return 0; } @@ -236,7 +236,7 @@ void modeset_cleanup(struct display * d) /* remove framebuffer */ /* delete dumb buffer */ bool is_accelerated = check_extensions(d->egl.display); - modeset_cleanup_fb(iter, fd, is_accelerated); + deinit_gbm(); /* free the removed resource */ free(iter); |