Added example.
This commit is contained in:
parent
e9d716fc0c
commit
e446a5300b
|
@ -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)
|
|
@ -48,10 +48,11 @@ find_package(WaylandProtocols REQUIRED)
|
||||||
find_package(EGL REQUIRED)
|
find_package(EGL REQUIRED)
|
||||||
find_package(GLESv2 REQUIRED)
|
find_package(GLESv2 REQUIRED)
|
||||||
find_package(DRM REQUIRED)
|
find_package(DRM REQUIRED)
|
||||||
|
find_package(GBM REQUIRED)
|
||||||
find_package(LibInput REQUIRED)
|
find_package(LibInput REQUIRED)
|
||||||
find_package(Udev)
|
find_package(Udev REQUIRED)
|
||||||
find_package(Dbus)
|
find_package(Dbus)
|
||||||
find_package(Systemd)
|
find_package(Systemd REQUIRED)
|
||||||
|
|
||||||
include(Wayland)
|
include(Wayland)
|
||||||
include(Manpage)
|
include(Manpage)
|
||||||
|
|
|
@ -19,4 +19,11 @@ target_link_libraries(wlr-backend
|
||||||
wlr-common
|
wlr-common
|
||||||
wlr-wayland
|
wlr-wayland
|
||||||
${WAYLAND_LIBRARIES}
|
${WAYLAND_LIBRARIES}
|
||||||
|
${DRM_LIBRARIES}
|
||||||
|
${GBM_LIBRARIES}
|
||||||
|
${GLESv2_LIBRARIES}
|
||||||
|
${EGL_LIBRARIES}
|
||||||
|
${SYSTEMD_LIBRARIES}
|
||||||
|
${UDEV_LIBRARIES}
|
||||||
|
${GBM_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
#include "backend/drm/udev.h"
|
#include "backend/drm/udev.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
|
||||||
struct wlr_drm_backend *wlr_drm_backend_init(void)
|
struct wlr_drm_backend *wlr_drm_backend_init(struct wl_listener *add,
|
||||||
|
struct wl_listener *rem,
|
||||||
|
struct wl_listener *render)
|
||||||
{
|
{
|
||||||
struct wlr_drm_backend *backend = calloc(1, sizeof *backend);
|
struct wlr_drm_backend *backend = calloc(1, sizeof *backend);
|
||||||
if (!backend) {
|
if (!backend) {
|
||||||
|
@ -57,6 +59,13 @@ struct wlr_drm_backend *wlr_drm_backend_init(void)
|
||||||
wl_signal_init(&backend->signals.display_rem);
|
wl_signal_init(&backend->signals.display_rem);
|
||||||
wl_signal_init(&backend->signals.display_render);
|
wl_signal_init(&backend->signals.display_render);
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
wl_signal_add(&backend->signals.display_add, add);
|
||||||
|
if (rem)
|
||||||
|
wl_signal_add(&backend->signals.display_rem, rem);
|
||||||
|
if (render)
|
||||||
|
wl_signal_add(&backend->signals.display_render, render);
|
||||||
|
|
||||||
wlr_drm_scan_connectors(backend);
|
wlr_drm_scan_connectors(backend);
|
||||||
|
|
||||||
return backend;
|
return backend;
|
||||||
|
@ -80,6 +89,7 @@ static void free_display(void *item)
|
||||||
{
|
{
|
||||||
struct wlr_drm_display *disp = item;
|
struct wlr_drm_display *disp = item;
|
||||||
wlr_drm_display_free(disp, true);
|
wlr_drm_display_free(disp, true);
|
||||||
|
free(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_drm_backend_free(struct wlr_drm_backend *backend)
|
void wlr_drm_backend_free(struct wlr_drm_backend *backend)
|
||||||
|
@ -95,9 +105,14 @@ void wlr_drm_backend_free(struct wlr_drm_backend *backend)
|
||||||
wlr_session_end(&backend->session);
|
wlr_session_end(&backend->session);
|
||||||
|
|
||||||
wl_event_source_remove(backend->event_src.drm);
|
wl_event_source_remove(backend->event_src.drm);
|
||||||
|
wl_event_source_remove(backend->event_src.udev);
|
||||||
wl_event_loop_destroy(backend->event_loop);
|
wl_event_loop_destroy(backend->event_loop);
|
||||||
|
|
||||||
list_free(backend->displays);
|
list_free(backend->displays);
|
||||||
free(backend);
|
free(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wl_event_loop *wlr_drm_backend_get_event_loop(struct wlr_drm_backend *backend)
|
||||||
|
{
|
||||||
|
return backend->event_loop;
|
||||||
|
}
|
||||||
|
|
|
@ -281,6 +281,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disp->renderer = &backend->renderer;
|
||||||
disp->state = DRM_DISP_DISCONNECTED;
|
disp->state = DRM_DISP_DISCONNECTED;
|
||||||
disp->connector = res->connectors[i];
|
disp->connector = res->connectors[i];
|
||||||
snprintf(disp->name, sizeof disp->name, "%s-%"PRIu32,
|
snprintf(disp->name, sizeof disp->name, "%s-%"PRIu32,
|
||||||
|
@ -288,6 +289,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend)
|
||||||
conn->connector_type_id);
|
conn->connector_type_id);
|
||||||
|
|
||||||
list_add(backend->displays, disp);
|
list_add(backend->displays, disp);
|
||||||
|
wlr_log(L_INFO, "Found display '%s'", disp->name);
|
||||||
} else {
|
} else {
|
||||||
disp = backend->displays->items[index];
|
disp = backend->displays->items[index];
|
||||||
}
|
}
|
||||||
|
@ -295,12 +297,14 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend)
|
||||||
if (disp->state == DRM_DISP_DISCONNECTED &&
|
if (disp->state == DRM_DISP_DISCONNECTED &&
|
||||||
conn->connection == DRM_MODE_CONNECTED) {
|
conn->connection == DRM_MODE_CONNECTED) {
|
||||||
disp->state = DRM_DISP_NEEDS_MODESET;
|
disp->state = DRM_DISP_NEEDS_MODESET;
|
||||||
|
wlr_log(L_INFO, "Sending modesetting signal for '%s'", disp->name);
|
||||||
wl_signal_emit(&backend->signals.display_add, disp);
|
wl_signal_emit(&backend->signals.display_add, disp);
|
||||||
|
|
||||||
} else if (disp->state == DRM_DISP_CONNECTED &&
|
} else if (disp->state == DRM_DISP_CONNECTED &&
|
||||||
conn->connection != DRM_MODE_CONNECTED) {
|
conn->connection != DRM_MODE_CONNECTED) {
|
||||||
disp->state = DRM_DISP_DISCONNECTED;
|
disp->state = DRM_DISP_DISCONNECTED;
|
||||||
wlr_drm_display_free(disp, false);
|
wlr_drm_display_free(disp, false);
|
||||||
|
wlr_log(L_INFO, "Sending destruction signal for '%s'", disp->name);
|
||||||
wl_signal_emit(&backend->signals.display_rem, disp);
|
wl_signal_emit(&backend->signals.display_rem, disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,9 +434,9 @@ static drmModeModeInfo *select_mode(size_t num_modes,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_drm_display_modeset(struct wlr_drm_backend *backend,
|
bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str)
|
||||||
struct wlr_drm_display *disp, const char *str)
|
|
||||||
{
|
{
|
||||||
|
struct wlr_drm_backend *backend = disp->renderer->backend;
|
||||||
wlr_log(L_INFO, "Modesetting %s with '%s'", disp->name, str);
|
wlr_log(L_INFO, "Modesetting %s with '%s'", disp->name, str);
|
||||||
|
|
||||||
drmModeConnector *conn = drmModeGetConnector(backend->fd, disp->connector);
|
drmModeConnector *conn = drmModeGetConnector(backend->fd, disp->connector);
|
||||||
|
@ -519,7 +523,7 @@ bool wlr_drm_display_modeset(struct wlr_drm_backend *backend,
|
||||||
|
|
||||||
drmModeFreeConnector(conn);
|
drmModeFreeConnector(conn);
|
||||||
|
|
||||||
wlr_log(L_INFO, "Configuring %s with mode %"PRIu16"x%"PRIu16"@%"PRIu32"\n",
|
wlr_log(L_INFO, "Configuring %s with mode %"PRIu16"x%"PRIu16"@%"PRIu32"",
|
||||||
disp->name, disp->active_mode->hdisplay, disp->active_mode->vdisplay,
|
disp->name, disp->active_mode->hdisplay, disp->active_mode->vdisplay,
|
||||||
disp->active_mode->vrefresh);
|
disp->active_mode->vrefresh);
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ bool wlr_session_start(struct wlr_session *session)
|
||||||
|
|
||||||
sprintf(session->path, fmt, session->id);
|
sprintf(session->path, fmt, session->id);
|
||||||
|
|
||||||
ret = sd_bus_open_system(&session->bus);
|
ret = sd_bus_default_system(&session->bus);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
wlr_log(L_ERROR, "Failed to open DBus connection: %s", strerror(-ret));
|
wlr_log(L_ERROR, "Failed to open DBus connection: %s", strerror(-ret));
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -94,9 +94,10 @@ int wlr_udev_find_gpu(struct wlr_udev *udev, struct wlr_session *session)
|
||||||
const char *id = udev_device_get_sysattr_value(pci, "boot_vga");
|
const char *id = udev_device_get_sysattr_value(pci, "boot_vga");
|
||||||
if (id && strcmp(id, "1") == 0)
|
if (id && strcmp(id, "1") == 0)
|
||||||
is_boot_vga = true;
|
is_boot_vga = true;
|
||||||
udev_device_unref(pci);
|
//udev_device_unref(pci);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We already have a valid GPU
|
||||||
if (!is_boot_vga && fd >= 0) {
|
if (!is_boot_vga && fd >= 0) {
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
continue;
|
continue;
|
||||||
|
@ -107,9 +108,10 @@ int wlr_udev_find_gpu(struct wlr_udev *udev, struct wlr_session *session)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_boot_vga) {
|
udev_device_unref(dev);
|
||||||
|
|
||||||
|
if (is_boot_vga)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_enumerate_unref(en);
|
udev_enumerate_unref(en);
|
||||||
|
|
|
@ -5,3 +5,11 @@ add_executable(example
|
||||||
target_link_libraries(example
|
target_link_libraries(example
|
||||||
wlr-backend
|
wlr-backend
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_executable(example-drm
|
||||||
|
example-drm.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(example-drm
|
||||||
|
wlr-backend
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
|
||||||
|
#include <wlr/backend/drm.h>
|
||||||
|
|
||||||
|
struct state {
|
||||||
|
float color[3];
|
||||||
|
int dec;
|
||||||
|
|
||||||
|
struct timespec last_frame;
|
||||||
|
|
||||||
|
struct wl_listener add;
|
||||||
|
struct wl_listener rem;
|
||||||
|
struct wl_listener render;
|
||||||
|
};
|
||||||
|
|
||||||
|
void display_add(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_drm_display *disp = data;
|
||||||
|
|
||||||
|
fprintf(stderr, "Display added\n");
|
||||||
|
wlr_drm_display_modeset(disp, "preferred");
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_rem(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Display removed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_render(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_drm_display *disp = data;
|
||||||
|
struct state *s = wl_container_of(listener, s, render);
|
||||||
|
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
|
long ms = (now.tv_sec - s->last_frame.tv_sec) * 1000 +
|
||||||
|
(now.tv_nsec - s->last_frame.tv_nsec) / 1000000;
|
||||||
|
int inc = (s->dec + 1) % 3;
|
||||||
|
|
||||||
|
s->color[inc] += ms / 2000.0f;
|
||||||
|
s->color[s->dec] -= ms / 2000.0f;
|
||||||
|
|
||||||
|
if (s->color[s->dec] < 0.0f) {
|
||||||
|
s->color[inc] = 1.0f;
|
||||||
|
s->color[s->dec] = 0.0f;
|
||||||
|
|
||||||
|
s->dec = inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->last_frame = now;
|
||||||
|
|
||||||
|
wlr_drm_display_begin(disp);
|
||||||
|
|
||||||
|
glClearColor(s->color[0], s->color[1], s->color[2], 1.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
wlr_drm_display_end(disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int timer_done(void *data)
|
||||||
|
{
|
||||||
|
*(bool *)data = true;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (getenv("DISPLAY")) {
|
||||||
|
fprintf(stderr, "Detected that X is running. Run this in its own virtual terminal.\n");
|
||||||
|
return 1;
|
||||||
|
} else if (getenv("WAYLAND_DISPLAY")) {
|
||||||
|
fprintf(stderr, "Detected that Wayland is running. Run this in its own virtual terminal.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct state state = {
|
||||||
|
.color = { 1.0, 0.0, 0.0 },
|
||||||
|
.dec = 0,
|
||||||
|
.add = { .notify = display_add },
|
||||||
|
.rem = { .notify = display_rem },
|
||||||
|
.render = { .notify = display_render },
|
||||||
|
};
|
||||||
|
|
||||||
|
wl_list_init(&state.add.link);
|
||||||
|
wl_list_init(&state.rem.link);
|
||||||
|
wl_list_init(&state.render.link);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &state.last_frame);
|
||||||
|
|
||||||
|
struct wlr_drm_backend *wlr = wlr_drm_backend_init(&state.add, &state.rem, &state.render);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
struct wl_event_loop *event_loop = wlr_drm_backend_get_event_loop(wlr);
|
||||||
|
struct wl_event_source *timer = wl_event_loop_add_timer(event_loop,
|
||||||
|
timer_done, &done);
|
||||||
|
|
||||||
|
wl_event_source_timer_update(timer, 10000);
|
||||||
|
|
||||||
|
while (!done)
|
||||||
|
wl_event_loop_dispatch(event_loop, 0);
|
||||||
|
|
||||||
|
wl_event_source_remove(timer);
|
||||||
|
wlr_drm_backend_free(wlr);
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
|
||||||
#include <wlr/common/list.h>
|
#include <wlr/common/list.h>
|
||||||
|
#include <wlr/backend/drm.h>
|
||||||
|
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "udev.h"
|
#include "udev.h"
|
||||||
|
@ -41,7 +42,9 @@ struct wlr_drm_backend {
|
||||||
struct wlr_udev udev;
|
struct wlr_udev udev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_backend *wlr_drm_backend_init(void);
|
struct wlr_drm_backend *wlr_drm_backend_init(struct wl_listener *add,
|
||||||
|
struct wl_listener *rem,
|
||||||
|
struct wl_listener *render);
|
||||||
void wlr_drm_backend_free(struct wlr_drm_backend *backend);
|
void wlr_drm_backend_free(struct wlr_drm_backend *backend);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,8 +57,7 @@ struct wlr_drm_display {
|
||||||
bool cleanup;
|
bool cleanup;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool wlr_drm_display_modeset(struct wlr_drm_backend *backend,
|
bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str);
|
||||||
struct wlr_drm_display *disp, const char *str);
|
|
||||||
void wlr_drm_display_free(struct wlr_drm_display *disp, bool restore);
|
void wlr_drm_display_free(struct wlr_drm_display *disp, bool restore);
|
||||||
|
|
||||||
void wlr_drm_display_begin(struct wlr_drm_display *disp);
|
void wlr_drm_display_begin(struct wlr_drm_display *disp);
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef WLR_BACKEND_DRM_H
|
||||||
|
#define WLR_BACKEND_DRM_H
|
||||||
|
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
struct wlr_drm_backend;
|
||||||
|
struct wlr_drm_display;
|
||||||
|
|
||||||
|
struct wlr_drm_backend *wlr_drm_backend_init(struct wl_listener *add,
|
||||||
|
struct wl_listener *rem,
|
||||||
|
struct wl_listener *render);
|
||||||
|
void wlr_drm_backend_free(struct wlr_drm_backend *backend);
|
||||||
|
|
||||||
|
struct wl_event_loop *wlr_drm_backend_get_event_loop(struct wlr_drm_backend *backend);
|
||||||
|
|
||||||
|
bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str);
|
||||||
|
void wlr_drm_display_begin(struct wlr_drm_display *disp);
|
||||||
|
void wlr_drm_display_end(struct wlr_drm_display *disp);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue