Skip to content

Commit 17cd0d5

Browse files
committed
kms: split drmdev into drm_resources and drmdev
drmdev: (mostly) non-stateful part. Basically a better wrapper around a drm fd. Fully mt-safe. Also properly separate kms_req from drmdev. kms_req now mostly accesses public drmdev API, instead of having access to hidden drmdev state. drm_resources: the DRM state / resources. Is stateful, but does not update itself. To keep it in sync with kernel state, one needs to listen to kernel events with drm_monitor and call drm_resources_update. drm_resources is not mt-safe and only supposed to be used on a single thread. Also add a bunch of QoL stuff to drm_resources.
1 parent 086b5ce commit 17cd0d5

File tree

14 files changed

+4043
-3534
lines changed

14 files changed

+4043
-3534
lines changed

CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,12 @@ add_library(
127127
src/platformchannel.c
128128
src/pluginregistry.c
129129
src/texture_registry.c
130-
src/modesetting.c
131-
src/util/collection.c
130+
src/kms/drmdev.c
131+
src/kms/req_builder.c
132+
src/kms/resources.c
132133
src/util/bitscan.c
133134
src/util/vector.c
135+
src/util/collection.c
134136
src/cursor.c
135137
src/keyboard.c
136138
src/user_input.c

src/compositor_ng.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
#include "dummy_render_surface.h"
2828
#include "flutter-pi.h"
2929
#include "frame_scheduler.h"
30-
#include "modesetting.h"
30+
#include "kms/drmdev.h"
31+
#include "kms/req_builder.h"
32+
#include "kms/resources.h"
3133
#include "notifier_listener.h"
3234
#include "pixel_format.h"
3335
#include "render_surface.h"

src/compositor_ng.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#include "cursor.h"
1616
#include "flutter-pi.h"
1717
#include "frame_scheduler.h"
18-
#include "modesetting.h"
18+
#include "kms/drmdev.h"
19+
#include "kms/resources.h"
20+
#include "kms/req_builder.h"
1921
#include "pixel_format.h"
2022
#include "util/collection.h"
2123
#include "util/refcounting.h"

src/egl_gbm_render_surface.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
#include "egl.h"
1717
#include "gl_renderer.h"
1818
#include "gles.h"
19-
#include "modesetting.h"
19+
#include "kms/req_builder.h"
20+
#include "kms/resources.h"
2021
#include "pixel_format.h"
2122
#include "render_surface.h"
2223
#include "render_surface_private.h"
@@ -428,7 +429,7 @@ static int egl_gbm_render_surface_present_kms(struct surface *s, const struct fl
428429
struct drm_crtc *crtc = kms_req_builder_get_crtc(builder);
429430
ASSERT_NOT_NULL(crtc);
430431

431-
if (drm_crtc_any_plane_supports_format(meta->drmdev, crtc, egl_surface->pixel_format)) {
432+
if (drm_resources_any_crtc_plane_supports_format(kms_req_builder_peek_resources(builder), crtc->id, egl_surface->pixel_format)) {
432433
TRACER_BEGIN(egl_surface->surface.tracer, "drmdev_add_fb (non-opaque)");
433434
uint32_t fb_id = drmdev_add_fb_from_gbm_bo(
434435
meta->drmdev,
@@ -453,7 +454,7 @@ static int egl_gbm_render_surface_present_kms(struct surface *s, const struct fl
453454
// if this EGL surface is non-opaque and has an opaque equivalent
454455
if (!get_pixfmt_info(egl_surface->pixel_format)->is_opaque &&
455456
pixfmt_opaque(egl_surface->pixel_format) != egl_surface->pixel_format &&
456-
drm_crtc_any_plane_supports_format(meta->drmdev, crtc, pixfmt_opaque(egl_surface->pixel_format))) {
457+
drm_resources_any_crtc_plane_supports_format(kms_req_builder_peek_resources(builder), crtc->id, pixfmt_opaque(egl_surface->pixel_format))) {
457458
uint32_t opaque_fb_id = drmdev_add_fb_from_gbm_bo(
458459
meta->drmdev,
459460
bo,

src/flutter-pi.c

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#include "frame_scheduler.h"
4646
#include "keyboard.h"
4747
#include "locales.h"
48-
#include "modesetting.h"
48+
#include "kms/drmdev.h"
4949
#include "pixel_format.h"
5050
#include "platformchannel.h"
5151
#include "pluginregistry.h"
@@ -1097,7 +1097,8 @@ static int on_drmdev_ready(sd_event_source *s, int fd, uint32_t revents, void *u
10971097
ASSERT_NOT_NULL(userdata);
10981098
drmdev = userdata;
10991099

1100-
return drmdev_on_event_fd_ready(drmdev);
1100+
drmdev_dispatch_modesetting(drmdev);
1101+
return 0;
11011102
}
11021103

11031104
static const FlutterLocale *on_compute_platform_resolved_locales(const FlutterLocale **locales, size_t n_locales) {
@@ -2120,74 +2121,7 @@ static void on_drmdev_close(int fd, void *fd_metadata, void *userdata) {
21202121
}
21212122
}
21222123

2123-
static const struct drmdev_interface drmdev_interface = { .open = on_drmdev_open, .close = on_drmdev_close };
2124-
2125-
static struct drmdev *find_drmdev(struct libseat *libseat) {
2126-
struct drm_connector *connector;
2127-
struct drmdev *drmdev;
2128-
drmDevicePtr devices[64];
2129-
int ok, n_devices;
2130-
2131-
#ifndef HAVE_LIBSEAT
2132-
ASSERT_EQUALS(libseat, NULL);
2133-
#endif
2134-
2135-
ok = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
2136-
if (ok < 0) {
2137-
LOG_ERROR("Could not query DRM device list: %s\n", strerror(-ok));
2138-
return NULL;
2139-
}
2140-
2141-
n_devices = ok;
2142-
2143-
// find a GPU that has a primary node
2144-
drmdev = NULL;
2145-
for (int i = 0; i < n_devices; i++) {
2146-
drmDevicePtr device;
2147-
2148-
device = devices[i];
2149-
2150-
if (!(device->available_nodes & (1 << DRM_NODE_PRIMARY))) {
2151-
// We need a primary node.
2152-
continue;
2153-
}
2154-
2155-
drmdev = drmdev_new_from_path(device->nodes[DRM_NODE_PRIMARY], &drmdev_interface, libseat);
2156-
if (drmdev == NULL) {
2157-
LOG_ERROR("Could not create drmdev from device at \"%s\". Continuing.\n", device->nodes[DRM_NODE_PRIMARY]);
2158-
continue;
2159-
}
2160-
2161-
for_each_connector_in_drmdev(drmdev, connector) {
2162-
if (connector->variable_state.connection_state == kConnected_DrmConnectionState) {
2163-
goto found_connected_connector;
2164-
}
2165-
}
2166-
LOG_ERROR("Device \"%s\" doesn't have a display connected. Skipping.\n", device->nodes[DRM_NODE_PRIMARY]);
2167-
drmdev_unref(drmdev);
2168-
continue;
2169-
2170-
found_connected_connector:
2171-
break;
2172-
}
2173-
2174-
drmFreeDevices(devices, n_devices);
2175-
2176-
if (drmdev == NULL) {
2177-
LOG_ERROR(
2178-
"flutter-pi couldn't find a usable DRM device.\n"
2179-
"Please make sure you've enabled the Fake-KMS driver in raspi-config.\n"
2180-
"If you're not using a Raspberry Pi, please make sure there's KMS support for your graphics chip.\n"
2181-
);
2182-
goto fail_free_devices;
2183-
}
2184-
2185-
return drmdev;
2186-
2187-
fail_free_devices:
2188-
drmFreeDevices(devices, n_devices);
2189-
return NULL;
2190-
}
2124+
static const struct drmdev_file_interface drmdev_interface = { .open = on_drmdev_open, .close = on_drmdev_close };
21912125

21922126
static struct gbm_device *open_rendernode_as_gbm_device(void) {
21932127
struct gbm_device *gbm;
@@ -2338,7 +2272,6 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
23382272
struct flutterpi_cmdline_args cmd_args;
23392273
struct libseat *libseat;
23402274
struct locales *locales;
2341-
struct drmdev *drmdev;
23422275
struct tracer *tracer;
23432276
struct window *window;
23442277
void *engine_handle;
@@ -2455,6 +2388,8 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
24552388

24562389
locales_print(locales);
24572390

2391+
struct drmdev *drmdev = NULL;
2392+
struct drm_resources *resources = NULL;
24582393
if (cmd_args.dummy_display) {
24592394
drmdev = NULL;
24602395

@@ -2467,11 +2402,16 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
24672402
goto fail_destroy_locales;
24682403
}
24692404
} else {
2470-
drmdev = find_drmdev(libseat);
2405+
// TODO: Share this udev instance with the one the user input uses.
2406+
struct udev *udev = udev_new();
2407+
2408+
drmdev = drmdev_new_from_udev_primary(udev, "seat0", &drmdev_interface, NULL);
24712409
if (drmdev == NULL) {
24722410
goto fail_destroy_locales;
24732411
}
24742412

2413+
udev_unref(udev);
2414+
24752415
gbm_device = drmdev_get_gbm_device(drmdev);
24762416
if (gbm_device == NULL) {
24772417
LOG_ERROR("Couldn't create GBM device.\n");
@@ -2563,6 +2503,7 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
25632503
cmd_args.has_physical_dimensions, cmd_args.physical_dimensions.x, cmd_args.physical_dimensions.y,
25642504
cmd_args.has_pixel_format, cmd_args.pixel_format,
25652505
drmdev,
2506+
resources,
25662507
desired_videomode
25672508
// clang-format on
25682509
);
@@ -2572,6 +2513,8 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
25722513
}
25732514
}
25742515

2516+
drm_resources_unrefp(&resources);
2517+
25752518
compositor = compositor_new(tracer, window);
25762519
if (compositor == NULL) {
25772520
LOG_ERROR("Couldn't create compositor.\n");
@@ -2580,7 +2523,7 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
25802523

25812524
/// TODO: Do we really need the window after this?
25822525
if (drmdev != NULL) {
2583-
ok = sd_event_add_io(event_loop, NULL, drmdev_get_event_fd(drmdev), EPOLLIN | EPOLLHUP | EPOLLPRI, on_drmdev_ready, drmdev);
2526+
ok = sd_event_add_io(event_loop, NULL, drmdev_get_modesetting_fd(drmdev), EPOLLIN | EPOLLHUP | EPOLLPRI, on_drmdev_ready, drmdev);
25842527
if (ok < 0) {
25852528
LOG_ERROR("Could not add DRM pageflip event listener. sd_event_add_io: %s\n", strerror(-ok));
25862529
goto fail_unref_compositor;
@@ -2778,6 +2721,9 @@ struct flutterpi *flutterpi_new_from_args(int argc, char **argv) {
27782721
tracer_unref(tracer);
27792722

27802723
fail_destroy_drmdev:
2724+
if (resources != NULL) {
2725+
drm_resources_unref(resources);
2726+
}
27812727
drmdev_unref(drmdev);
27822728

27832729
fail_destroy_locales:

0 commit comments

Comments
 (0)