summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward O'Callaghan <funfunctor@folklore1984.net>2017-03-06 13:02:40 +1100
committerEdward O'Callaghan <funfunctor@folklore1984.net>2017-03-06 13:02:40 +1100
commit4f0abcd290c226e3572e35b1b826640699f33f4e (patch)
tree5aaacffd0f911cd29e11177d4b8a9938b3c71f34
parentd76af6a2fccc296e74a870ad1f21d63b6d5e95f9 (diff)
src/fb: cleanup gbm init logic
Signed-off-by: Edward O'Callaghan <funfunctor@folklore1984.net>
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/common.c56
-rw-r--r--src/common.h14
-rw-r--r--src/framebuffer.c160
-rw-r--r--src/framebuffer.h9
-rw-r--r--src/modesetting.c12
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);