diff options
author | Edward O'Callaghan <funfunctor@folklore1984.net> | 2017-03-07 00:24:22 +1100 |
---|---|---|
committer | Edward O'Callaghan <funfunctor@folklore1984.net> | 2017-03-07 00:24:22 +1100 |
commit | 3e6766934a80e658d78c9dd031abde952b71141c (patch) | |
tree | 043fdcca8b1cb8c664c5e2c2fd36e55176f2974f | |
parent | 4f0abcd290c226e3572e35b1b826640699f33f4e (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.txt | 1 | ||||
-rw-r--r-- | src/common.h | 56 | ||||
-rw-r--r-- | src/drm.c | 233 | ||||
-rw-r--r-- | src/drm.h | 21 | ||||
-rw-r--r-- | src/egl.c | 51 | ||||
-rw-r--r-- | src/egl.h | 17 | ||||
-rw-r--r-- | src/gl_minimal.c | 45 | ||||
-rw-r--r-- | src/main.c | 71 | ||||
-rw-r--r-- | src/modesetting.c | 244 | ||||
-rw-r--r-- | src/modesetting.h | 11 |
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 */ @@ -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; +} @@ -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 */ @@ -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); } @@ -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... } @@ -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 */ |