wl-drm: don't store wlr_renderer

Query the formats at init time, then forget about the renderer.
This will allow wl_drm to be created with a list of formats instead
of a renderer, and will behave better after a GPU reset.
This commit is contained in:
Simon Ser 2022-12-02 14:33:02 +01:00 committed by Simon Zeni
parent c9b378d21a
commit f36a5915da
2 changed files with 26 additions and 24 deletions

View file

@ -10,6 +10,7 @@
#define WLR_TYPES_WLR_DRM_H #define WLR_TYPES_WLR_DRM_H
#include <wayland-server-protocol.h> #include <wayland-server-protocol.h>
#include <wlr/render/drm_format_set.h>
struct wlr_renderer; struct wlr_renderer;
@ -30,15 +31,17 @@ struct wlr_drm_buffer {
*/ */
struct wlr_drm { struct wlr_drm {
struct wl_global *global; struct wl_global *global;
struct wlr_renderer *renderer;
char *node_name;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;
} events; } events;
// private state
char *node_name;
struct wlr_drm_format_set formats;
struct wl_listener display_destroy; struct wl_listener display_destroy;
struct wl_listener renderer_destroy;
}; };
bool wlr_drm_buffer_is_resource(struct wl_resource *resource); bool wlr_drm_buffer_is_resource(struct wl_resource *resource);

View file

@ -11,6 +11,7 @@
#include <wlr/types/wlr_drm.h> #include <wlr/types/wlr_drm.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "drm-protocol.h" #include "drm-protocol.h"
#include "render/drm_format_set.h"
#define WLR_DRM_VERSION 2 #define WLR_DRM_VERSION 2
@ -159,14 +160,8 @@ static void drm_bind(struct wl_client *client, void *data,
wl_drm_send_device(resource, drm->node_name); wl_drm_send_device(resource, drm->node_name);
wl_drm_send_capabilities(resource, WL_DRM_CAPABILITY_PRIME); wl_drm_send_capabilities(resource, WL_DRM_CAPABILITY_PRIME);
const struct wlr_drm_format_set *formats = for (size_t i = 0; i < drm->formats.len; i++) {
wlr_renderer_get_dmabuf_texture_formats(drm->renderer); wl_drm_send_format(resource, drm->formats.formats[i]->format);
if (formats == NULL) {
return;
}
for (size_t i = 0; i < formats->len; i++) {
wl_drm_send_format(resource, formats->formats[i]->format);
} }
} }
@ -185,8 +180,8 @@ static void drm_destroy(struct wlr_drm *drm) {
wl_signal_emit_mutable(&drm->events.destroy, NULL); wl_signal_emit_mutable(&drm->events.destroy, NULL);
wl_list_remove(&drm->display_destroy.link); wl_list_remove(&drm->display_destroy.link);
wl_list_remove(&drm->renderer_destroy.link);
wlr_drm_format_set_finish(&drm->formats);
free(drm->node_name); free(drm->node_name);
wl_global_destroy(drm->global); wl_global_destroy(drm->global);
free(drm); free(drm);
@ -197,11 +192,6 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
drm_destroy(drm); drm_destroy(drm);
} }
static void handle_renderer_destroy(struct wl_listener *listener, void *data) {
struct wlr_drm *drm = wl_container_of(listener, drm, renderer_destroy);
drm_destroy(drm);
}
struct wlr_drm *wlr_drm_create(struct wl_display *display, struct wlr_drm *wlr_drm_create(struct wl_display *display,
struct wlr_renderer *renderer) { struct wlr_renderer *renderer) {
int drm_fd = wlr_renderer_get_drm_fd(renderer); int drm_fd = wlr_renderer_get_drm_fd(renderer);
@ -237,24 +227,33 @@ struct wlr_drm *wlr_drm_create(struct wl_display *display,
} }
drm->node_name = node_name; drm->node_name = node_name;
drm->renderer = renderer;
wl_signal_init(&drm->events.destroy); wl_signal_init(&drm->events.destroy);
const struct wlr_drm_format_set *formats = wlr_renderer_get_dmabuf_texture_formats(renderer);
if (formats == NULL) {
goto error;
}
if (!wlr_drm_format_set_copy(&drm->formats, formats)) {
goto error;
}
drm->global = wl_global_create(display, &wl_drm_interface, WLR_DRM_VERSION, drm->global = wl_global_create(display, &wl_drm_interface, WLR_DRM_VERSION,
drm, drm_bind); drm, drm_bind);
if (drm->global == NULL) { if (drm->global == NULL) {
free(drm->node_name); goto error;
free(drm);
return NULL;
} }
drm->display_destroy.notify = handle_display_destroy; drm->display_destroy.notify = handle_display_destroy;
wl_display_add_destroy_listener(display, &drm->display_destroy); wl_display_add_destroy_listener(display, &drm->display_destroy);
drm->renderer_destroy.notify = handle_renderer_destroy;
wl_signal_add(&renderer->events.destroy, &drm->renderer_destroy);
wlr_buffer_register_resource_interface(&buffer_resource_interface); wlr_buffer_register_resource_interface(&buffer_resource_interface);
return drm; return drm;
error:
wlr_drm_format_set_finish(&drm->formats);
free(drm->node_name);
free(drm);
return NULL;
} }