summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward O'Callaghan <funfunctor@folklore1984.net>2017-03-07 00:24:22 +1100
committerEdward O'Callaghan <funfunctor@folklore1984.net>2017-03-07 00:24:22 +1100
commit3e6766934a80e658d78c9dd031abde952b71141c (patch)
tree043fdcca8b1cb8c664c5e2c2fd36e55176f2974f
parent4f0abcd290c226e3572e35b1b826640699f33f4e (diff)
src: Essentially rewrite the thing
Now we have a proper render loop where all the draw calls are within a function pointer passed in. All the crtc+conn logic was reworked to allow for redraws and pageflips. Signed-off-by: Edward O'Callaghan <funfunctor@folklore1984.net>
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/common.h56
-rw-r--r--src/drm.c233
-rw-r--r--src/drm.h21
-rw-r--r--src/egl.c51
-rw-r--r--src/egl.h17
-rw-r--r--src/gl_minimal.c45
-rw-r--r--src/main.c71
-rw-r--r--src/modesetting.c244
-rw-r--r--src/modesetting.h11
10 files changed, 327 insertions, 423 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9418530..ebfc85a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,7 +3,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/)
add_library(baregl_lib SHARED
- modesetting.c
common.c
egl.c
drm.c
diff --git a/src/common.h b/src/common.h
index 30fde55..3726032 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,21 +1,9 @@
#ifndef COMMON_H
#define COMMON_H
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <epoxy/egl.h>
#include <gbm.h>
/**
- * https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html
- */
-struct render_node {
- int fd;
- drmModeRes *res;
- drmModeConnector *conn;
-};
-
-/**
* setup a backing gbm device and surface from a
* render node file descriptor and the expected
* width and height.
@@ -29,48 +17,4 @@ struct gbm {
const struct gbm * init_gbm(int drm_fd, int w, int h);
void deinit_gbm();
-/**
- * ..
- */
-struct drm_fb {
- struct drm_fb *next;
-
- uint32_t width, height; /** w,h of our buffer object */
- uint32_t stride; /** stride value of our buffer object */
- uint32_t size; /** size o fthe memory mapped buffer */
- uint32_t handle; /** a DRM handle to the buffer object that we can draw into */
-
- /* Used by gbm fbs */
- struct gbm_device *gbm_dev;
- struct gbm_surface *gbm_surface;
- /* Used by dumb fbs */
- uint32_t *map; /** pointer to the memory mapped buffer */
-
- drmModeModeInfo mode; /** display mode that we want to use */
- uint32_t fb; /** framebuffer handle with our buffer object as scanout buffer */
- uint32_t conn; /** the connector ID that we want to use with this buffer */
- uint32_t crtc; /** the crtc ID that we want to use with this connector */
- drmModeCrtc *saved_crtc; /** the conf of the crtc before we changed it as to restore on exit */
-};
-
-struct egl {
- EGLDisplay display;
- EGLConfig config;
- EGLContext context;
- EGLSurface surface;
-};
-
-/**
- * struct drm_output {}
- * drmModeCrtc *saved_crtc;
- * drmModeConnector *connector;
- * struct gbm_surface *gbm_surface;
- * struct drm_fb *current, *next;
- */
-struct display {
- struct render_node rnode;
- struct drm_fb * dev;
- struct egl egl;
-};
-
#endif /* COMMON_H */
diff --git a/src/drm.c b/src/drm.c
index b70c6fd..18c2dae 100644
--- a/src/drm.c
+++ b/src/drm.c
@@ -2,11 +2,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "drm.h"
+#include "egl.h"
static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
{
@@ -51,3 +54,233 @@ struct drm_fb_xxx * drm_fb_get_from_bo(struct gbm_bo *bo)
return fb;
}
+
+static uint32_t find_crtc_for_encoder(const drmModeRes *resources,
+ const drmModeEncoder *encoder) {
+ int i;
+
+ fprintf(stderr, "%s: not impl\n", __func__);
+
+ return -1; /* no match found */
+}
+static uint32_t find_crtc_for_connector(const struct drm *drm, const drmModeRes *resources,
+ const drmModeConnector *connector) {
+ int i;
+
+ fprintf(stderr, "%s: not impl\n", __func__);
+
+ return -1; /* no match found */
+}
+
+// call init_egl() after this.
+static int init_drm(struct drm * drm, const char *device)
+{
+ drmModeRes *resources;
+ drmModeConnector *connector = NULL;
+ drmModeEncoder *encoder = NULL;
+ unsigned i, area;
+ uint64_t has_dumb;
+
+ printf("using card '%s'\n", device);
+
+ /* open the DRM device */
+ drm->fd = open(device, O_RDWR | O_CLOEXEC);
+ if (drm->fd < 0) {
+ fprintf(stderr, "cannot open card\n");
+ return -1;
+ }
+ if (drmGetCap(drm->fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 ||
+ !has_dumb) {
+ fprintf(stderr, "drm device '%s' does not support dumb buffers\n", device);
+ close(drm->fd);
+ return -EOPNOTSUPP;
+ }
+
+ resources = drmModeGetResources(drm->fd);
+ if (!resources) {
+ fprintf(stderr, "connot retrieve DRM resources (%d): %m\n", errno);
+ return -errno;
+ }
+
+ /* find a connected connector: */
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(drm->fd, resources->connectors[i]);
+ if (connector->connection == DRM_MODE_CONNECTED)
+ break; /* it's connected, let's use this! */
+ else
+ printf("ignoring unused connector %u\n", connector->connector_id);
+
+ drmModeFreeConnector(connector);
+ connector = NULL;
+ }
+
+ if (!connector) {
+ /* we could be fancy and listen for hotplug events and wait for
+ * a connector..
+ */
+ fprintf(stderr, "no connected connector!\n");
+ return -1;
+ }
+
+ /* find prefered mode or the highest resolution mode: */
+ for (i = 0, area = 0; i < connector->count_modes; i++) {
+ drmModeModeInfo *current_mode = &connector->modes[i];
+ if (current_mode->type & DRM_MODE_TYPE_PREFERRED)
+ drm->mode = current_mode;
+
+ int current_area = current_mode->hdisplay * current_mode->vdisplay;
+ if (current_area > area) {
+ drm->mode = current_mode;
+ area = current_area;
+ }
+ }
+
+ /* is there atleast one valid mode? */
+ if (!drm->mode) {
+ fprintf(stderr, "no valid mode for connector %u\n", connector->connector_id);
+ drmModeFreeConnector(connector);
+ return -1;
+ }
+
+ /* find encoder: */
+ for (i = 0; i < resources->count_encoders; i++) {
+ encoder = drmModeGetEncoder(drm->fd, resources->encoders[i]);
+ if (encoder->encoder_id == connector->encoder_id)
+ break;
+ drmModeFreeEncoder(encoder);
+ encoder = NULL;
+ }
+
+ if (encoder) {
+ drm->crtc_id = encoder->crtc_id;
+ } else {
+ uint32_t crtc_id = find_crtc_for_connector(drm,resources,connector);
+ if (crtc_id == 0) {
+ fprintf(stderr, "no crtc found!\n");
+ return -1;
+ }
+ drm->crtc_id = crtc_id;
+ }
+
+ /* find the crtc_id index and store it */
+ for (i = 0; i < resources->count_crtcs; i++)
+ if (resources->crtcs[i] == drm->crtc_id) {
+ drm->crtc_index = i;
+ break;
+ }
+
+ drmModeFreeResources(resources);
+ drm->connector_id = connector->connector_id;
+
+ return 0;
+}
+
+void deinit_drm(const struct drm * drm)
+{
+#if 0
+ /* restore saved CRTC */
+ drmModeSetCrtc(fd,
+ iter->saved_crtc->crtc_id,
+ iter->saved_crtc->buffer_id,
+ iter->saved_crtc->x,
+ iter->saved_crtc->y,
+ &iter->conn,
+ 1,
+ &iter->saved_crtc->mode);
+ drmModeFreeCrtc(iter->saved_crtc);
+#endif
+ close(drm->fd);
+}
+
+/*********************************************************************/
+
+/** global state machine */
+static struct drm g_drm;
+
+static void page_flip_handler(int fd, unsigned int frame,
+ unsigned int sec, unsigned int usec, void *data)
+{
+ int *waiting_for_flip = data;
+ *waiting_for_flip = 0;
+}
+
+static int drm_run_flip_thingy(const struct gbm *gbm, const struct egl *egl)
+{
+ struct gbm_bo * bo;
+ struct drm_fb_xxx * fb;
+ int ret;
+
+ drmEventContext evctx = {
+ .version = DRM_EVENT_CONTEXT_VERSION,
+ .page_flip_handler = page_flip_handler,
+ };
+
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ FD_SET(g_drm.fd, &fds);
+
+ eglSwapBuffers(egl->display, egl->surface);
+ bo = gbm_surface_lock_front_buffer(gbm->surface);
+ fb = drm_fb_get_from_bo(bo);
+
+ /* set mode: */
+ ret = drmModeSetCrtc(g_drm.fd, g_drm.crtc_id, fb->fb_id, 0, 0,
+ &g_drm.connector_id, 1, g_drm.mode);
+ if (ret) {
+ fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
+ return ret;
+ }
+
+ while (1) {
+ int waiting_for_flip = 1;
+ struct gbm_bo *next_bo;
+
+ /* lets do our draw calls. */
+ egl->draw();
+
+ eglSwapBuffers(egl->display, egl->surface);
+ next_bo = gbm_surface_lock_front_buffer(gbm->surface);
+ fb = drm_fb_get_from_bo(next_bo);
+
+ /*
+ * Here you could also update drm plane layers if you want
+ * hw composition
+ */
+ ret = drmModePageFlip(g_drm.fd, g_drm.crtc_id, fb->fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
+ if (ret) {
+ fprintf(stderr, "failed to queue page flip: %s\n", strerror(errno));
+ return -1;
+ }
+ while (waiting_for_flip) {
+ ret = select(g_drm.fd + 1, &fds, NULL, NULL, NULL);
+ if (ret < 0)
+ return ret;
+ else if (ret == 0)
+ return -1;
+ else if (FD_ISSET(0, &fds))
+ break;
+ drmHandleEvent(g_drm.fd, &evctx);
+ }
+
+ /* release last buffer to render on again: */
+ gbm_surface_release_buffer(gbm->surface, bo);
+ bo = next_bo;
+ }
+
+ return 0;
+}
+
+const struct drm * init_drm_runner(const char *device)
+{
+ int ret;
+
+ ret = init_drm(&g_drm, device);
+ if (ret)
+ return NULL;
+
+ g_drm.run = drm_run_flip_thingy;
+
+ return &g_drm;
+}
diff --git a/src/drm.h b/src/drm.h
index d15cd34..61c5f7f 100644
--- a/src/drm.h
+++ b/src/drm.h
@@ -1,8 +1,12 @@
#ifndef XXX_DRM_H
#define XXX_DRM_H
+#include <xf86drm.h>
+#include <xf86drmMode.h>
#include <gbm.h>
+#include "egl.h"
+
/**
* ..
*/
@@ -19,4 +23,21 @@ struct drm_fb_xxx {
*/
struct drm_fb_xxx * drm_fb_get_from_bo(struct gbm_bo *bo);
+
+struct drm {
+ int fd;
+
+ int crtc_index;
+
+ drmModeModeInfo *mode;
+ uint32_t crtc_id;
+ uint32_t connector_id;
+
+ /* deal with swapping front and back render buffers */
+ int (*run)(const struct gbm *gbm, const struct egl *egl);
+};
+
+const struct drm * init_drm_runner(const char *device);
+void deinit_drm(const struct drm * drm);
+
#endif /* XXX_DRM_H */
diff --git a/src/egl.c b/src/egl.c
index 0986ff6..eec2ced 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -15,9 +15,14 @@
#include <epoxy/glx.h>
#include <gbm.h>
+#include "egl.h"
+void setup_egl_draw_loop(struct egl *egl, void (*draw_func)())
+{
+ egl->draw = draw_func;
+}
-void init_egl(struct display * d)
+void init_egl(struct egl *egl, const struct gbm *gbm)
{
EGLBoolean b;
EGLint major, minor, n;
@@ -38,63 +43,57 @@ void init_egl(struct display * d)
EGL_NONE
};
- /* sanity checking */
- assert(d);
-
if (eglGetPlatformDisplayEXT)
- d->egl.display = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, d->dev->gbm_dev, NULL);
+ egl->display = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, gbm->dev, NULL);
else
- d->egl.display = eglGetDisplay((void *) d->dev->gbm_dev);
+ egl->display = eglGetDisplay((void *) gbm->dev);
- if (!d->egl.display)
+ if (!egl->display)
fprintf(stderr, "cannot create EGL display\n");
- b = eglInitialize(d->egl.display, &major, &minor);
+ b = eglInitialize(egl->display, &major, &minor);
if (!b)
fprintf(stderr, "Cannot initialise EGL\n");
fprintf(stderr, "EGL major/minor: %d.%d\n", major, minor);
fprintf(stderr, "EGL version: %s\n",
- eglQueryString(d->egl.display, EGL_VERSION));
+ eglQueryString(egl->display, EGL_VERSION));
fprintf(stderr, "EGL vendor: %s\n",
- eglQueryString(d->egl.display, EGL_VENDOR));
+ eglQueryString(egl->display, EGL_VENDOR));
fprintf(stderr, "EGL extensions: %s\n",
- eglQueryString(d->egl.display, EGL_EXTENSIONS));
+ eglQueryString(egl->display, EGL_EXTENSIONS));
if (!eglBindAPI(EGL_OPENGL_API))
fprintf(stderr, "cannot bind OpenGL API\n");
- b = eglChooseConfig(d->egl.display, conf_att, &d->egl.config, 1, &n);
+ b = eglChooseConfig(egl->display, conf_att, &egl->config, 1, &n);
if (!b || n != 1) {
fprintf(stderr, "cannot find suitable EGL config\n");
abort();
}
- d->egl.context = eglCreateContext(d->egl.display, d->egl.config,
+ egl->context = eglCreateContext(egl->display, egl->config,
EGL_NO_CONTEXT, ctx_att);
- if (!d->egl.context)
+ if (!egl->context)
fprintf(stderr, "cannot create EGL context\n");
- assert(d->dev->gbm_surface);
- EGLNativeWindowType native_surface = (EGLNativeWindowType) d->dev->gbm_surface;
- d->egl.surface = eglCreateWindowSurface(d->egl.display, d->egl.config, native_surface, NULL);
- if (d->egl.surface == EGL_NO_SURFACE) {
+ assert(gbm->surface);
+ EGLNativeWindowType native_surface = (EGLNativeWindowType) gbm->surface;
+ egl->surface = eglCreateWindowSurface(egl->display, egl->config, native_surface, NULL);
+ if (egl->surface == EGL_NO_SURFACE) {
fprintf(stderr, "cannot create EGL surface\n");
assert(0);
}
/* connect the context to the surface */
- eglMakeCurrent(d->egl.display, d->egl.surface, d->egl.surface, d->egl.context);
+ eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context);
printf("GL Extensions: \"%s\"\n", glGetString(GL_EXTENSIONS));
}
-void deinit_egl(struct display * d)
+void deinit_egl(struct egl * egl)
{
- /* sanity checks */
- assert(d);
-
- eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(d->egl.display, d->egl.context);
- eglTerminate(d->egl.display);
+ eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroyContext(egl->display, egl->context);
+ eglTerminate(egl->display);
}
diff --git a/src/egl.h b/src/egl.h
index f7856cd..18a3de4 100644
--- a/src/egl.h
+++ b/src/egl.h
@@ -1,9 +1,22 @@
#ifndef MY_EGL_H
#define MY_EGL_H
+#include <epoxy/egl.h>
+
#include "common.h"
-void init_egl(struct display * d);
-void deinit_egl(struct display * d);
+struct egl {
+ EGLDisplay display;
+ EGLConfig config;
+ EGLContext context;
+ EGLSurface surface;
+
+ void (*draw)();
+};
+
+void init_egl(struct egl *egl, const struct gbm *gbm);
+void deinit_egl(struct egl *egl);
+
+void setup_egl_draw_loop(struct egl *egl, void (*draw_func)());
#endif /* MY_EGL_H */
diff --git a/src/gl_minimal.c b/src/gl_minimal.c
index db63d72..ff0d919 100644
--- a/src/gl_minimal.c
+++ b/src/gl_minimal.c
@@ -1,31 +1,12 @@
-#include <epoxy/gl.h>
-#include <epoxy/glx.h>
-
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
-#include "egl.h"
-#include "common.h"
-#include "drm.h"
+#include <epoxy/gl.h>
+#include <epoxy/glx.h>
-void run_gl_example(struct display * d)
+void run_gl_example()
{
-#if 0
- // wipe the drawing surface clear
- for (unsigned i = 0; i < 3; i++) {
- GLfloat r =0.0,g = 0.0,b = 0.0;
- if (i == 0) r = 1.0;
- if (i == 1) g = 1.0;
- if (i == 2) b = 1.0;
- printf("r,g,b = (%f,%f,%f)\n", r,g,b);
- glClearColor(r, g, b, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
- glFlush();
- sleep(3);
- }
-#endif
-
const GLfloat vertices[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
@@ -90,7 +71,16 @@ void run_gl_example(struct display * d)
glDeleteShader(vs);
glDeleteShader(fs);
- glClearColor(0.3,0.3,0.3, 1.0);
+ static int my_delay = 0;
+ if (my_delay) {
+ glClearColor(0.3,0.3,0.3, 1.0);
+ sleep(1);
+ my_delay = 0;
+ } else {
+ glClearColor(1.3,0.3,0.3, 1.0);
+ sleep(1);
+ my_delay = 1;
+ }
// wipe the drawing surface clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -102,13 +92,4 @@ void run_gl_example(struct display * d)
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
-
- eglSwapBuffers(d->egl.display, d->egl.surface);
-
- /* this must be _after_ calling eglSwapBuffers */
- struct gbm_bo * bo;
- bo = gbm_surface_lock_front_buffer(d->dev->gbm_surface);
- assert(bo);
- struct drm_fb_xxx * fb_xxx = drm_fb_get_from_bo(bo);
- d->dev->fb = fb_xxx->fb_id; // XXX modeset_crtc() needs this state later...
}
diff --git a/src/main.c b/src/main.c
index a6b36f1..60909f3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,7 @@
#include <unistd.h>
#include <string.h>
-#include "modesetting.h"
+#include "drm.h"
#include "egl.h"
/**
@@ -27,72 +27,41 @@
* create simple memory-mapped buffers without any driver-dependent
* code, as want to avoid any vendor specifics.
*/
-static int modeset_open(int *out, const char *node)
-{
- int fd;
- uint64_t has_dumb;
- fd = open(node, O_RDWR | O_CLOEXEC);
- if (fd < 0) {
- fprintf(stderr, "cannot open '%s': %m\n", node);
- return -errno;
- }
+struct egl egl;
+static const struct gbm *gbm;
+static const struct drm *drm;
- if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 ||
- !has_dumb) {
- fprintf(stderr, "drm device '%s' does not support dumb buffers\n", node);
- close(fd);
- return -EOPNOTSUPP;
- }
-
- *out = fd;
- return 0;
-}
+extern void run_gl_example();// XX move to header.
-static int init_render_node(struct display * d)
+int main()
{
- int fd;
const char * card = "/dev/dri/card0";
- /* sanity checking */
- assert(d);
-
- printf("using card '%s'\n", card);
-
- /* open the DRM device */
- if (modeset_open(&fd, card) < 0) {
- fprintf(stderr, "cannot open card\n");
- return -1;
+ drm = init_drm_runner(card);
+ if (!drm) {
+ fprintf(stderr, "failed to initialize DRM\n");
+ exit(1);
}
- d->rnode.fd = fd;
-
- return 0;
-}
-
-extern void run_gl_example(struct display *);// XX move to header.
-
-int main()
-{
- struct display d;
-
- if (init_render_node(&d) < 0)
+ gbm = init_gbm(drm->fd, drm->mode->hdisplay, drm->mode->vdisplay);
+ if (!gbm) {
+ printf("failed to initialize GBM\n");
exit(1);
+ }
- modeset(&d);
+ init_egl(&egl, gbm);
/* ...... */
/* draw here?? */
- run_gl_example(&d);
+ setup_egl_draw_loop(&egl, run_gl_example);
+ drm->run(gbm, &egl); // main render loop
/* ...... */
- modeset_crtc(d.rnode.fd);
- sleep(3); // XXX keep rendered scene on screen for a bit
-
/* cleanups */
- deinit_egl(&d);
- modeset_cleanup(&d);
- close(d.rnode.fd);
+ deinit_egl(&egl);
+ deinit_gbm(gbm);
+ deinit_drm(drm);
return 0;
}
diff --git a/src/modesetting.c b/src/modesetting.c
deleted file mode 100644
index 61eb6bb..0000000
--- a/src/modesetting.c
+++ /dev/null
@@ -1,244 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <sys/mman.h>
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include "modesetting.h"
-#include "egl.h"
-#include "common.h"
-
-
-/** global state ! */
-static struct drm_fb * modeset_list = NULL;
-
-
-/**
- * find a suitable CRTC for a given connector.
- */
-static int modeset_find_crtc(
- int fd,
- drmModeRes *res,
- drmModeConnector *conn,
- struct drm_fb *dev)
-{
- drmModeEncoder *enc = NULL;
- struct drm_fb *iter;
- int32_t crtc;
-
- /* try the currently connected encoder+crtc */
- if (conn->encoder_id)
- enc = drmModeGetEncoder(fd, conn->encoder_id);
- if (enc) {
- if (enc->crtc_id) {
- crtc = enc->crtc_id;
- for (iter = modeset_list; iter; iter = iter->next) {
- if (iter->crtc == crtc) {
- crtc = -1;
- break;
- }
- }
- if (crtc >= 0) {
- drmModeFreeEncoder(enc);
- dev->crtc = crtc;
- return 0;
- }
- }
-
- drmModeFreeEncoder(enc);
- }
-
- // TODO handle if the connector is not currently bound to an encoder
- // or if the encoder+crtc is already used by another connector.
-
- fprintf(stderr, "connot find suitable CRTC for connector %u\n", conn->connector_id);
- return -ENOENT;
-}
-
-/**
- * Perform actual modesetting on each found connector+CRTC,
- * saving the previous CRTC mode and modeset the CRTC with ours.
- */
-void modeset_crtc(int fd)
-{
- struct drm_fb *iter;
- int ret;
-
- /* perform actual modesetting on each found connector+CRTC */
- for (iter = modeset_list; iter; iter = iter->next) {
- iter->saved_crtc = drmModeGetCrtc(fd, iter->crtc);
- ret = drmModeSetCrtc(fd, iter->crtc, iter->fb, 0, 0,
- &iter->conn, 1, &iter->mode);
- if (ret)
- fprintf(stderr, "cannot set CRTC for connector %u (%d): %m\n", iter->conn, errno);
- }
-}
-
-/**
- * Hook up a connector with a CRTC.
- */
-static int modeset_setup_dev(
- int fd,
- drmModeRes *res,
- drmModeConnector *conn,
- struct drm_fb *dev,
- bool is_accelerated)
-{
- int ret;
-
- /* is monitor connected? */
- if (conn->connection != DRM_MODE_CONNECTED) {
- fprintf(stderr, "ignoring unused connector %u\n", conn->connector_id);
- return -ENOENT;
- }
-
- /* is there atleast one valid mode? */
- if (conn->count_modes == 0) {
- fprintf(stderr, "no valid mode for connector %u\n", conn->connector_id);
- return -EFAULT;
- }
-
- /* copy the mode information into our device structure */
- memcpy(&dev->mode, &conn->modes[0], sizeof(dev->mode));
- dev->width = conn->modes[0].hdisplay;
- dev->height = conn->modes[0].vdisplay;
- printf("mode for connector %u is %ux%u\n", conn->connector_id, dev->width, dev->height);
-
- /* find crtc for this connector */
- ret = modeset_find_crtc(fd,res,conn,dev);
- if (ret) {
- fprintf(stderr, "no valid crtc for connector %u\n", conn->connector_id);
- return ret;
- }
-
- /* create a framebuffer for this CRTC */
- 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 -1;
- }
- dev->gbm_dev = gbm->dev;
- dev->gbm_surface = gbm->surface;
-
- return 0;
-}
-
-static bool check_extensions(EGLDisplay egl_display)
-{
- bool has_accelerated = false;
- const char * client_extensions = eglQueryString(egl_display, EGL_EXTENSIONS);
-
- if (!client_extensions || !strstr(client_extensions, "EGL_MESA_platform_gbm"))
- has_accelerated = true;
-
- assert((has_accelerated == true));
-
- return has_accelerated;
-}
-
-/**
- * prepare all the connectors we find.
- *
- * Consume the DRM fd and then retrieves the resource-info from the device.
- * We then iterates through all connectors and calls other helper functions
- * to initialize this connector. If the initialization was successful, we
- * add this object as new device into the global modeset device list.
- */
-int modeset(struct display * d)
-{
- drmModeRes *res;
- drmModeConnector *conn;
- int ret;
- unsigned i;
-
- // XXX
- assert(d);
- int fd = d->rnode.fd;
-
- res = drmModeGetResources(fd);
- if (!res) {
- fprintf(stderr, "connot retrieve DRM resources (%d): %m\n", errno);
- return -errno;
- }
-
- for (i = 0; i < res->count_connectors; i++) {
- conn = drmModeGetConnector(fd, res->connectors[i]);
- if (!conn) {
- fprintf(stderr, "connot retrieve DRM connector %u:%u (%d): %m\n",
- i, res->connectors[i], errno);
- continue;
- }
-
- struct drm_fb * dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->conn = conn->connector_id;
-
- /*
- * modeset_setup_dev() returns -ENOENT if the connector is currently
- * unused and no monitor is plugged in. So we can ignore this connector.
- */
- bool is_accelerated = check_extensions(d->egl.display);
- ret = modeset_setup_dev(fd, res, conn, dev, is_accelerated);
- if (ret) {
- if (ret != -ENOENT) {
- errno = -ret;
- fprintf(stderr, "cannot setup device for connector ..\n");
- }
- free(dev);
- drmModeFreeConnector(conn);
- continue;
- }
-
- drmModeFreeConnector(conn);
- /* insert into global state */
- dev->next = modeset_list;
- modeset_list = dev;
- d->dev = dev; // XXX
- init_egl(d);
- break; //FIXME: HACK ! first connector works fine for me
- }
-
- drmModeFreeResources(res);
-
- return 0;
-}
-
-void modeset_cleanup(struct display * d)
-{
- struct drm_fb *iter;
-
- assert(d);
-
- int fd = d->rnode.fd;
-
- while (modeset_list) {
- /* remove from global state ! */
- iter = modeset_list;
- modeset_list = iter->next;
-
- /* restore saved CRTC */
- drmModeSetCrtc(fd,
- iter->saved_crtc->crtc_id,
- iter->saved_crtc->buffer_id,
- iter->saved_crtc->x,
- iter->saved_crtc->y,
- &iter->conn,
- 1,
- &iter->saved_crtc->mode);
- drmModeFreeCrtc(iter->saved_crtc);
-
- /* unmap buffer */
- /* remove framebuffer */
- /* delete dumb buffer */
- bool is_accelerated = check_extensions(d->egl.display);
- deinit_gbm();
-
- /* free the removed resource */
- free(iter);
- }
-}
diff --git a/src/modesetting.h b/src/modesetting.h
deleted file mode 100644
index e050526..0000000
--- a/src/modesetting.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef MODESETTING_H
-#define MODESETTING_H
-
-#include "common.h"
-
-int modeset(struct display * d);
-void modeset_cleanup(struct display * d);
-
-void modeset_crtc(int fd);
-
-#endif /* MODESETTING_H */