diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-05-10 10:37:29 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-10 10:37:29 -0400 |
commit | c436e76240ab190a07afcd961ca2dd279af72968 (patch) | |
tree | aab4f835e5341cd44b5937e0cd0dbb012c2369e8 /backend/drm/backend.c | |
parent | 1aed98730194aa80b5954ae1d6370162041b56e2 (diff) | |
parent | 42878b45a1dba582feb5ec75762d66ede51fdc98 (diff) |
Merge pull request #2 from ascent12/master
DRM backend + Session interface + EGL
Diffstat (limited to 'backend/drm/backend.c')
-rw-r--r-- | backend/drm/backend.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/backend/drm/backend.c b/backend/drm/backend.c new file mode 100644 index 00000000..0da84745 --- /dev/null +++ b/backend/drm/backend.c @@ -0,0 +1,103 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <wayland-server.h> + +#include <wlr/session.h> +#include <wlr/common/list.h> + +#include "backend.h" +#include "backend/drm/backend.h" +#include "backend/drm/drm.h" +#include "backend/drm/udev.h" +#include "common/log.h" + +static bool wlr_drm_backend_init(struct wlr_backend_state *state) { + wlr_drm_scan_connectors(state); + return true; +} + +static void wlr_drm_backend_destroy(struct wlr_backend_state *state) { + if (!state) { + return; + } + // TODO: free outputs in shared backend code + wlr_drm_renderer_free(&state->renderer); + wlr_udev_free(&state->udev); + wlr_session_close_file(state->session, state->fd); + wlr_session_finish(state->session); + wl_event_source_remove(state->drm_event); + free(state); +} + +static struct wlr_backend_impl backend_impl = { + .init = wlr_drm_backend_init, + .destroy = wlr_drm_backend_destroy +}; + +struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, + struct wlr_session *session) { + struct wlr_backend_state *state = calloc(1, sizeof(struct wlr_backend_state)); + if (!state) { + wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); + return NULL; + } + + struct wlr_backend *backend = wlr_backend_create(&backend_impl, state); + if (!backend) { + wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); + return NULL; + } + + state->backend = backend; + state->session = session; + state->outputs = list_create(); + if (!state->outputs) { + wlr_log(L_ERROR, "Failed to allocate list"); + goto error_backend; + } + + if (!wlr_udev_init(display, &state->udev)) { + wlr_log(L_ERROR, "Failed to start udev"); + goto error_list; + } + + state->fd = wlr_udev_find_gpu(&state->udev, state->session); + if (state->fd == -1) { + wlr_log(L_ERROR, "Failed to open DRM device"); + goto error_udev; + } + + struct wl_event_loop *event_loop = wl_display_get_event_loop(display); + + state->drm_event = wl_event_loop_add_fd(event_loop, state->fd, + WL_EVENT_READABLE, wlr_drm_event, NULL); + if (!state->drm_event) { + wlr_log(L_ERROR, "Failed to create DRM event source"); + goto error_fd; + } + + // TODO: what is the difference between the per-output renderer and this + // one? + if (!wlr_drm_renderer_init(&state->renderer, state->fd)) { + wlr_log(L_ERROR, "Failed to initialize renderer"); + goto error_event; + } + + return backend; + +error_event: + wl_event_source_remove(state->drm_event); +error_fd: + wlr_session_close_file(state->session, state->fd); +error_udev: + wlr_udev_free(&state->udev); +error_list: + list_free(state->outputs); +error_backend: + free(state); + free(backend); + return NULL; +} |