mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-22 06:47:12 -04:00
Merge upstream
This commit is contained in:
commit
c673b684a0
203 changed files with 6752 additions and 4861 deletions
|
|
@ -133,12 +133,15 @@ static void handle_dev_change(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: add and handle lease uevents
|
||||
switch (change->type) {
|
||||
case WLR_DEVICE_HOTPLUG:;
|
||||
case WLR_DEVICE_HOTPLUG:
|
||||
wlr_log(WLR_DEBUG, "Received hotplug event for %s", drm->name);
|
||||
scan_drm_connectors(drm, &change->hotplug);
|
||||
break;
|
||||
case WLR_DEVICE_LEASE:
|
||||
wlr_log(WLR_DEBUG, "Received lease event for %s", drm->name);
|
||||
scan_drm_leases(drm);
|
||||
break;
|
||||
default:
|
||||
wlr_log(WLR_DEBUG, "Received unknown change event for %s", drm->name);
|
||||
}
|
||||
|
|
@ -232,10 +235,6 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
|||
}
|
||||
|
||||
if (drm->parent) {
|
||||
// Ensure we use the same renderer as the parent backend
|
||||
drm->backend.renderer = wlr_backend_get_renderer(&drm->parent->backend);
|
||||
assert(drm->backend.renderer != NULL);
|
||||
|
||||
if (!init_drm_renderer(drm, &drm->mgpu_renderer)) {
|
||||
wlr_log(WLR_ERROR, "Failed to initialize renderer");
|
||||
goto error_resources;
|
||||
|
|
|
|||
|
|
@ -118,9 +118,15 @@ static bool add_plane(struct wlr_drm_backend *drm,
|
|||
p->id = drm_plane->plane_id;
|
||||
p->props = *props;
|
||||
|
||||
for (size_t j = 0; j < drm_plane->count_formats; ++j) {
|
||||
wlr_drm_format_set_add(&p->formats, drm_plane->formats[j],
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
for (size_t i = 0; i < drm_plane->count_formats; ++i) {
|
||||
// Force a LINEAR layout for the cursor if the driver doesn't support
|
||||
// modifiers
|
||||
wlr_drm_format_set_add(&p->formats, drm_plane->formats[i],
|
||||
DRM_FORMAT_MOD_LINEAR);
|
||||
if (type != DRM_PLANE_TYPE_CURSOR) {
|
||||
wlr_drm_format_set_add(&p->formats, drm_plane->formats[i],
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->props.in_formats && drm->addfb2_modifiers) {
|
||||
|
|
@ -136,27 +142,12 @@ static bool add_plane(struct wlr_drm_backend *drm,
|
|||
goto error;
|
||||
}
|
||||
|
||||
struct drm_format_modifier_blob *data = blob->data;
|
||||
uint32_t *fmts = (uint32_t *)((char *)data + data->formats_offset);
|
||||
struct drm_format_modifier *mods = (struct drm_format_modifier *)
|
||||
((char *)data + data->modifiers_offset);
|
||||
for (uint32_t i = 0; i < data->count_modifiers; ++i) {
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (mods[i].formats & ((uint64_t)1 << j)) {
|
||||
wlr_drm_format_set_add(&p->formats,
|
||||
fmts[j + mods[i].offset], mods[i].modifier);
|
||||
}
|
||||
}
|
||||
drmModeFormatModifierIterator iter = {0};
|
||||
while (drmModeFormatModifierBlobIterNext(blob, &iter)) {
|
||||
wlr_drm_format_set_add(&p->formats, iter.fmt, iter.mod);
|
||||
}
|
||||
|
||||
drmModeFreePropertyBlob(blob);
|
||||
} else if (type == DRM_PLANE_TYPE_CURSOR) {
|
||||
// Force a LINEAR layout for the cursor if the driver doesn't support
|
||||
// modifiers
|
||||
for (size_t i = 0; i < p->formats.len; ++i) {
|
||||
wlr_drm_format_set_add(&p->formats, p->formats.formats[i]->format,
|
||||
DRM_FORMAT_MOD_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
|
@ -1300,8 +1291,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
|||
wlr_output_init(&wlr_conn->output, &drm->backend, &output_impl,
|
||||
drm->display);
|
||||
|
||||
memcpy(wlr_conn->output.name, wlr_conn->name,
|
||||
sizeof(wlr_conn->output.name));
|
||||
wlr_output_set_name(&wlr_conn->output, wlr_conn->name);
|
||||
|
||||
wlr_conn->output.phys_width = drm_conn->mmWidth;
|
||||
wlr_conn->output.phys_height = drm_conn->mmHeight;
|
||||
|
|
@ -1431,6 +1421,36 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
|||
}
|
||||
}
|
||||
|
||||
void scan_drm_leases(struct wlr_drm_backend *drm) {
|
||||
drmModeLesseeListRes *list = drmModeListLessees(drm->fd);
|
||||
if (list == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "drmModeListLessees failed");
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_drm_connector *conn;
|
||||
wl_list_for_each(conn, &drm->outputs, link) {
|
||||
if (conn->lease == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < list->count; i++) {
|
||||
if (list->lessees[i] == conn->lease->lessee_id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
wlr_log(WLR_DEBUG, "DRM lease %"PRIu32" has been terminated",
|
||||
conn->lease->lessee_id);
|
||||
drm_lease_destroy(conn->lease);
|
||||
}
|
||||
}
|
||||
|
||||
drmFree(list);
|
||||
}
|
||||
|
||||
static int mhz_to_nsec(int mhz) {
|
||||
return 1000000000000LL / mhz;
|
||||
}
|
||||
|
|
@ -1560,17 +1580,13 @@ int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* TODO: make the function return a `wlr_drm_lease` to provide a destroy event
|
||||
* that can be fired when the kernel notifies us through uevent that the lease
|
||||
* has been destroyed
|
||||
*/
|
||||
int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
||||
uint32_t *lessee_id) {
|
||||
struct wlr_drm_lease *wlr_drm_create_lease(struct wlr_output **outputs,
|
||||
size_t n_outputs, int *lease_fd_ptr) {
|
||||
assert(outputs);
|
||||
|
||||
if (n_outputs == 0) {
|
||||
wlr_log(WLR_ERROR, "Can't lease 0 outputs");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_drm_backend *drm =
|
||||
|
|
@ -1581,11 +1597,11 @@ int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
|||
for (size_t i = 0; i < n_outputs; ++i) {
|
||||
struct wlr_drm_connector *conn =
|
||||
get_drm_connector_from_output(outputs[i]);
|
||||
assert(conn->lessee_id == 0);
|
||||
assert(conn->lease == NULL);
|
||||
|
||||
if (conn->backend != drm) {
|
||||
wlr_log(WLR_ERROR, "Can't lease output from different backends");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
objects[n_objects++] = conn->id;
|
||||
|
|
@ -1593,7 +1609,7 @@ int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
|||
|
||||
if (!conn->crtc) {
|
||||
wlr_log(WLR_ERROR, "Connector has no CRTC");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
objects[n_objects++] = conn->crtc->id;
|
||||
|
|
@ -1610,50 +1626,63 @@ int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
|||
|
||||
assert(n_objects != 0);
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issuing DRM lease with the %d objects", n_objects);
|
||||
int lease_fd = drmModeCreateLease(drm->fd, objects, n_objects, 0,
|
||||
lessee_id);
|
||||
if (lease_fd < 0) {
|
||||
return lease_fd;
|
||||
struct wlr_drm_lease *lease = calloc(1, sizeof(*lease));
|
||||
if (lease == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issued DRM lease %"PRIu32, *lessee_id);
|
||||
lease->backend = drm;
|
||||
wl_signal_init(&lease->events.destroy);
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issuing DRM lease with %d objects", n_objects);
|
||||
int lease_fd = drmModeCreateLease(drm->fd, objects, n_objects, 0,
|
||||
&lease->lessee_id);
|
||||
if (lease_fd < 0) {
|
||||
free(lease);
|
||||
return NULL;
|
||||
}
|
||||
*lease_fd_ptr = lease_fd;
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issued DRM lease %"PRIu32, lease->lessee_id);
|
||||
for (size_t i = 0; i < n_outputs; ++i) {
|
||||
struct wlr_drm_connector *conn =
|
||||
get_drm_connector_from_output(outputs[i]);
|
||||
conn->lessee_id = *lessee_id;
|
||||
conn->crtc->lessee_id = *lessee_id;
|
||||
conn->lease = lease;
|
||||
conn->crtc->lease = lease;
|
||||
}
|
||||
|
||||
return lease_fd;
|
||||
return lease;
|
||||
}
|
||||
|
||||
bool wlr_drm_backend_terminate_lease(struct wlr_backend *backend,
|
||||
uint32_t lessee_id) {
|
||||
wlr_log(WLR_DEBUG, "Terminating DRM lease %d", lessee_id);
|
||||
void wlr_drm_lease_terminate(struct wlr_drm_lease *lease) {
|
||||
struct wlr_drm_backend *drm = lease->backend;
|
||||
|
||||
assert(backend);
|
||||
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
|
||||
|
||||
int r = drmModeRevokeLease(drm->fd, lessee_id);
|
||||
if (r < 0) {
|
||||
wlr_log_errno(WLR_DEBUG, "Failed to terminate lease");
|
||||
wlr_log(WLR_DEBUG, "Terminating DRM lease %d", lease->lessee_id);
|
||||
int ret = drmModeRevokeLease(drm->fd, lease->lessee_id);
|
||||
if (ret < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to terminate lease");
|
||||
}
|
||||
|
||||
drm_lease_destroy(lease);
|
||||
}
|
||||
|
||||
void drm_lease_destroy(struct wlr_drm_lease *lease) {
|
||||
struct wlr_drm_backend *drm = lease->backend;
|
||||
|
||||
wlr_signal_emit_safe(&lease->events.destroy, NULL);
|
||||
|
||||
struct wlr_drm_connector *conn;
|
||||
wl_list_for_each(conn, &drm->outputs, link) {
|
||||
if (conn->lessee_id == lessee_id) {
|
||||
conn->lessee_id = 0;
|
||||
/* Will be re-initialized in scan_drm_connectors */
|
||||
if (conn->lease == lease) {
|
||||
conn->lease = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < drm->num_crtcs; ++i) {
|
||||
if (drm->crtcs[i].lessee_id == lessee_id) {
|
||||
drm->crtcs[i].lessee_id = 0;
|
||||
if (drm->crtcs[i].lease == lease) {
|
||||
drm->crtcs[i].lease = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return r >= 0;
|
||||
free(lease);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,9 +151,13 @@ static bool legacy_crtc_commit(struct wlr_drm_connector *conn,
|
|||
|
||||
int ret = drmModeSetCursor(drm->fd, crtc->id, cursor_handle,
|
||||
cursor_width, cursor_height);
|
||||
close_bo_handle(drm->fd, cursor_handle);
|
||||
int set_cursor_errno = errno;
|
||||
if (drmCloseBufferHandle(drm->fd, cursor_handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmCloseBufferHandle failed");
|
||||
}
|
||||
if (ret != 0) {
|
||||
wlr_drm_conn_log_errno(conn, WLR_DEBUG, "drmModeSetCursor failed");
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG, "drmModeSetCursor failed: %s",
|
||||
strerror(set_cursor_errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ wlr_files += files(
|
|||
'cvt.c',
|
||||
'drm.c',
|
||||
'legacy.c',
|
||||
'monitor.c',
|
||||
'properties.c',
|
||||
'renderer.c',
|
||||
'util.c',
|
||||
|
|
|
|||
94
backend/drm/monitor.c
Normal file
94
backend/drm/monitor.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include <wlr/util/log.h>
|
||||
#include <stdlib.h>
|
||||
#include "backend/drm/monitor.h"
|
||||
#include "backend/multi.h"
|
||||
#include "backend/session/session.h"
|
||||
|
||||
static void drm_backend_monitor_destroy(struct wlr_drm_backend_monitor* monitor) {
|
||||
wl_list_remove(&monitor->session_add_drm_card.link);
|
||||
wl_list_remove(&monitor->session_destroy.link);
|
||||
wl_list_remove(&monitor->primary_drm_destroy.link);
|
||||
wl_list_remove(&monitor->multi_destroy.link);
|
||||
free(monitor);
|
||||
}
|
||||
|
||||
static void handle_add_drm_card(struct wl_listener *listener, void *data) {
|
||||
struct wlr_session_add_event *event = data;
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, session_add_drm_card);
|
||||
|
||||
struct wlr_device *dev =
|
||||
session_open_if_kms(backend_monitor->session, event->path);
|
||||
if (!dev) {
|
||||
wlr_log(WLR_ERROR, "Unable to open %s as DRM device", event->path);
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Creating DRM backend for %s after hotplug", event->path);
|
||||
struct wlr_backend *child_drm = wlr_drm_backend_create(
|
||||
backend_monitor->session->display, backend_monitor->session,
|
||||
dev, backend_monitor->primary_drm);
|
||||
if (!child_drm) {
|
||||
wlr_log(WLR_ERROR, "Failed to create DRM backend after hotplug");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wlr_multi_backend_add(backend_monitor->multi, child_drm)) {
|
||||
wlr_log(WLR_ERROR, "Failed to add new drm backend to multi backend");
|
||||
wlr_backend_destroy(child_drm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wlr_backend_start(child_drm)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start new child DRM backend");
|
||||
wlr_backend_destroy(child_drm);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_session_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, session_destroy);
|
||||
drm_backend_monitor_destroy(backend_monitor);
|
||||
}
|
||||
|
||||
static void handle_primary_drm_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, primary_drm_destroy);
|
||||
drm_backend_monitor_destroy(backend_monitor);
|
||||
}
|
||||
|
||||
static void handle_multi_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, multi_destroy);
|
||||
drm_backend_monitor_destroy(backend_monitor);
|
||||
}
|
||||
|
||||
struct wlr_drm_backend_monitor *drm_backend_monitor_create(
|
||||
struct wlr_backend *multi,
|
||||
struct wlr_backend *primary_drm,
|
||||
struct wlr_session *session) {
|
||||
struct wlr_drm_backend_monitor *monitor =
|
||||
calloc(1, sizeof(struct wlr_drm_backend_monitor));
|
||||
if (!monitor) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
monitor->multi = multi;
|
||||
monitor->primary_drm = primary_drm;
|
||||
monitor->session = session;
|
||||
|
||||
monitor->session_add_drm_card.notify = handle_add_drm_card;
|
||||
wl_signal_add(&session->events.add_drm_card, &monitor->session_add_drm_card);
|
||||
|
||||
monitor->session_destroy.notify = handle_session_destroy;
|
||||
wl_signal_add(&session->events.destroy, &monitor->session_destroy);
|
||||
|
||||
monitor->primary_drm_destroy.notify = handle_primary_drm_destroy;
|
||||
wl_signal_add(&primary_drm->events.destroy, &monitor->primary_drm_destroy);
|
||||
|
||||
monitor->multi_destroy.notify = handle_multi_destroy;
|
||||
wl_signal_add(&multi->events.destroy, &monitor->multi_destroy);
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ struct wlr_drm_format *drm_plane_pick_render_format(
|
|||
const struct wlr_drm_format_set *plane_formats = &plane->formats;
|
||||
|
||||
uint32_t fmt = DRM_FORMAT_ARGB8888;
|
||||
if (!wlr_drm_format_set_has(&plane->formats, fmt, DRM_FORMAT_MOD_INVALID)) {
|
||||
if (!wlr_drm_format_set_get(&plane->formats, fmt)) {
|
||||
const struct wlr_pixel_format_info *format_info =
|
||||
drm_get_pixel_format_info(fmt);
|
||||
assert(format_info != NULL &&
|
||||
|
|
@ -220,6 +220,13 @@ static uint32_t get_fb_for_bo(struct wlr_drm_backend *drm,
|
|||
wlr_log_errno(WLR_DEBUG, "drmModeAddFB2WithModifiers failed");
|
||||
}
|
||||
} else {
|
||||
if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID &&
|
||||
dmabuf->modifier != DRM_FORMAT_MOD_LINEAR) {
|
||||
wlr_log(WLR_ERROR, "Cannot import DRM framebuffer with explicit "
|
||||
"modifier 0x%"PRIX64, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = drmModeAddFB2(drm->fd, dmabuf->width, dmabuf->height,
|
||||
dmabuf->format, handles, dmabuf->stride, dmabuf->offset, &id, 0);
|
||||
if (ret != 0 && dmabuf->format == DRM_FORMAT_ARGB8888 &&
|
||||
|
|
@ -264,30 +271,62 @@ static void close_all_bo_handles(struct wlr_drm_backend *drm,
|
|||
continue;
|
||||
}
|
||||
|
||||
close_bo_handle(drm->fd, handles[i]);
|
||||
if (drmCloseBufferHandle(drm->fd, handles[i]) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmCloseBufferHandle failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void drm_poisoned_fb_handle_destroy(struct wlr_addon *addon) {
|
||||
wlr_addon_finish(addon);
|
||||
free(addon);
|
||||
}
|
||||
|
||||
static const struct wlr_addon_interface poisoned_fb_addon_impl = {
|
||||
.name = "wlr_drm_poisoned_fb",
|
||||
.destroy = drm_poisoned_fb_handle_destroy,
|
||||
};
|
||||
|
||||
static bool is_buffer_poisoned(struct wlr_drm_backend *drm,
|
||||
struct wlr_buffer *buf) {
|
||||
return wlr_addon_find(&buf->addons, drm, &poisoned_fb_addon_impl) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the buffer as "poisoned", ie. it cannot be imported into KMS. This
|
||||
* allows us to avoid repeatedly trying to import it when it's not
|
||||
* scanout-capable.
|
||||
*/
|
||||
static void poison_buffer(struct wlr_drm_backend *drm,
|
||||
struct wlr_buffer *buf) {
|
||||
struct wlr_addon *addon = calloc(1, sizeof(*addon));
|
||||
if (addon == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
wlr_addon_init(addon, &buf->addons, drm, &poisoned_fb_addon_impl);
|
||||
wlr_log(WLR_DEBUG, "Poisoning buffer");
|
||||
}
|
||||
|
||||
static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
||||
struct wlr_buffer *buf, const struct wlr_drm_format_set *formats) {
|
||||
struct wlr_dmabuf_attributes attribs;
|
||||
if (!wlr_buffer_get_dmabuf(buf, &attribs)) {
|
||||
wlr_log(WLR_DEBUG, "Failed to get DMA-BUF from buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_buffer_poisoned(drm, buf)) {
|
||||
wlr_log(WLR_DEBUG, "Buffer is poisoned");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_drm_fb *fb = calloc(1, sizeof(*fb));
|
||||
if (!fb) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_dmabuf_attributes attribs;
|
||||
if (!wlr_buffer_get_dmabuf(buf, &attribs)) {
|
||||
wlr_log(WLR_DEBUG, "Failed to get DMA-BUF from buffer");
|
||||
goto error_get_dmabuf;
|
||||
}
|
||||
|
||||
if (attribs.flags != 0) {
|
||||
wlr_log(WLR_DEBUG, "Buffer with DMA-BUF flags 0x%"PRIX32" cannot be "
|
||||
"scanned out", attribs.flags);
|
||||
goto error_get_dmabuf;
|
||||
}
|
||||
|
||||
if (formats && !wlr_drm_format_set_has(formats, attribs.format,
|
||||
attribs.modifier)) {
|
||||
// The format isn't supported by the plane. Try stripping the alpha
|
||||
|
|
@ -301,7 +340,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
|||
wlr_log(WLR_DEBUG, "Buffer format 0x%"PRIX32" with modifier "
|
||||
"0x%"PRIX64" cannot be scanned out",
|
||||
attribs.format, attribs.modifier);
|
||||
goto error_get_dmabuf;
|
||||
goto error_fb;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +356,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
|||
fb->id = get_fb_for_bo(drm, &attribs, handles);
|
||||
if (!fb->id) {
|
||||
wlr_log(WLR_DEBUG, "Failed to import BO in KMS");
|
||||
poison_buffer(drm, buf);
|
||||
goto error_bo_handle;
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +372,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
|||
|
||||
error_bo_handle:
|
||||
close_all_bo_handles(drm, handles);
|
||||
error_get_dmabuf:
|
||||
error_fb:
|
||||
free(fb);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,14 +355,3 @@ size_t match_obj(size_t num_objs, const uint32_t objs[static restrict num_objs],
|
|||
match_obj_(&st, 0, 0, 0, 0);
|
||||
return st.score;
|
||||
}
|
||||
|
||||
void close_bo_handle(int drm_fd, uint32_t handle) {
|
||||
if (handle == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct drm_gem_close args = { .handle = handle };
|
||||
if (drmIoctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &args) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmIoctl(GEM_CLOSE) failed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue