Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

DRM backend + Session interface + EGL #2

Merged
merged 21 commits into from
May 10, 2017
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CMake/FindGBM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#.rst:
# FindGBM
# -------
#
# Find GBM library
#
# Try to find GBM library on UNIX systems. The following values are defined
#
# ::
#
# GBM_FOUND - True if gbm is available
# GBM_INCLUDE_DIRS - Include directories for gbm
# GBM_LIBRARIES - List of libraries for gbm
# GBM_DEFINITIONS - List of definitions for gbm
#
#=============================================================================
# Copyright (c) 2015 Jari Vetoniemi
#
# Distributed under the OSI-approved BSD License (the "License");
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================

set_package_properties(GBM PROPERTIES
URL "http://www.mesa3d.org/"
DESCRIPTION "Generic buffer manager")

find_package(PkgConfig)
pkg_check_modules(PC_GBM QUIET gbm)
find_library(GBM_LIBRARIES NAMES gbm HINTS ${PC_GBM_LIBRARY_DIRS})
find_path(GBM_INCLUDE_DIRS gbm.h HINTS ${PC_GBM_INCLUDE_DIRS})

set(GBM_DEFINITIONS ${PC_GBM_CFLAGS_OTHER})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GBM DEFAULT_MSG GBM_INCLUDE_DIRS GBM_LIBRARIES)
mark_as_advanced(GBM_INCLUDE_DIRS GBM_LIBRARIES GBM_DEFINITIONS)
40 changes: 40 additions & 0 deletions CMake/FindSystemd.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#.rst:
# FindSystemd
# -------
#
# Find Systemd library
#
# Try to find Systemd library on UNIX systems. The following values are defined
#
# ::
#
# SYSTEMD_FOUND - True if Systemd is available
# SYSTEMD_INCLUDE_DIRS - Include directories for Systemd
# SYSTEMD_LIBRARIES - List of libraries for Systemd
# SYSTEMD_DEFINITIONS - List of definitions for Systemd
#
#=============================================================================
# Copyright (c) 2015 Jari Vetoniemi
#
# Distributed under the OSI-approved BSD License (the "License");
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================

include(FeatureSummary)
set_package_properties(Systemd PROPERTIES
URL "http://freedesktop.org/wiki/Software/systemd/"
DESCRIPTION "System and Service Manager")

find_package(PkgConfig)
pkg_check_modules(PC_SYSTEMD QUIET libsystemd)
find_library(SYSTEMD_LIBRARIES NAMES systemd ${PC_SYSTEMD_LIBRARY_DIRS})
find_path(SYSTEMD_INCLUDE_DIRS systemd/sd-login.h HINTS ${PC_SYSTEMD_INCLUDE_DIRS})

set(SYSTEMD_DEFINITIONS ${PC_SYSTEMD_CFLAGS_OTHER})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SYSTEMD DEFAULT_MSG SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES)
mark_as_advanced(SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES SYSTEMD_DEFINITIONS)
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ find_package(WaylandProtocols REQUIRED)
find_package(EGL REQUIRED)
find_package(GLESv2 REQUIRED)
find_package(DRM REQUIRED)
find_package(GBM REQUIRED)
find_package(LibInput REQUIRED)
find_package(Udev)
find_package(Dbus)
find_package(Udev REQUIRED)
find_package(Systemd)

include(Wayland)
include(Manpage)
Expand All @@ -60,5 +61,6 @@ include_directories(include)
add_subdirectory(backend)
add_subdirectory(common)
add_subdirectory(wayland)
add_subdirectory(session)

add_subdirectory(example)
21 changes: 17 additions & 4 deletions backend/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
include_directories(
${PROTOCOLS_INCLUDE_DIRS}
${WAYLAND_INCLUDE_DIR}
${DRM_INCLUDE_DIRS}
)

add_library(wlr-backend
wayland/backend.c
wayland/registry.c
wayland/wl_seat.c
wayland/wl_output.c
#wayland/backend.c
#wayland/registry.c
#wayland/wl_seat.c
#wayland/wl_output.c
drm/backend.c
drm/drm.c
drm/udev.c
backend.c
egl.c
)

target_link_libraries(wlr-backend
wlr-common
wlr-wayland
${WAYLAND_LIBRARIES}
${DRM_LIBRARIES}
${GBM_LIBRARIES}
${GLESv2_LIBRARIES}
${EGL_LIBRARIES}
${SYSTEMD_LIBRARIES}
${UDEV_LIBRARIES}
${GBM_LIBRARIES}
)
36 changes: 36 additions & 0 deletions backend/backend.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <wayland-server.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "common/log.h"
#include "backend.h"

struct wlr_backend *wlr_backend_create(const struct wlr_backend_impl *impl,
struct wlr_backend_state *state) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note wlr_backend_autocreate will eventually be made to automatically create the most appropriate backend. It will handle udev and logind and things like that, and will invoke the most appropriate backend's wlr_*_backend_create function. This function, wlr_backend_create, is an internal function used by the backends to create the user-facing backend object.

struct wlr_backend *backend = calloc(1, sizeof(struct wlr_backend));
if (!backend) {
wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno));
return NULL;
}
backend->state = state;
backend->impl = impl;
wl_signal_init(&backend->events.output_add);
wl_signal_init(&backend->events.output_remove);
wl_signal_init(&backend->events.keyboard_add);
wl_signal_init(&backend->events.keyboard_remove);
wl_signal_init(&backend->events.pointer_add);
wl_signal_init(&backend->events.pointer_remove);
wl_signal_init(&backend->events.touch_add);
wl_signal_init(&backend->events.touch_remove);
return backend;
}

bool wlr_backend_init(struct wlr_backend *backend) {
return backend->impl->init(backend->state);
}

void wlr_backend_destroy(struct wlr_backend *backend) {
backend->impl->destroy(backend->state);
// TODO: free outputs
free(backend);
}
103 changes: 103 additions & 0 deletions backend/drm/backend.c
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this fail?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I wonder if it's a good idea to move the EGL init stuff into here

}

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

udev and session code will be removed from this file shortly

error_list:
list_free(state->outputs);
error_backend:
free(state);
free(backend);
return NULL;
}
Loading