diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index fe67244f0..3e2047e43 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -135,12 +135,7 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm, uint32_t id = plane->id; const union wlr_drm_plane_props *props = &plane->props; struct wlr_drm_fb *fb = plane_get_next_fb(plane); - struct gbm_bo *bo = drm_fb_acquire(fb, drm, &plane->mgpu_surf); - if (!bo) { - goto error; - } - - uint32_t fb_id = get_fb_for_bo(bo, drm->addfb2_modifiers); + uint32_t fb_id = drm_fb_acquire(fb, drm, &plane->mgpu_surf); if (!fb_id) { goto error; } diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index fc3158e16..7a7e36f77 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -17,12 +17,7 @@ static bool legacy_crtc_commit(struct wlr_drm_backend *drm, uint32_t fb_id = 0; if (crtc->pending.active) { struct wlr_drm_fb *fb = plane_get_next_fb(crtc->primary); - struct gbm_bo *bo = drm_fb_acquire(fb, drm, &crtc->primary->mgpu_surf); - if (!bo) { - return false; - } - - fb_id = get_fb_for_bo(bo, drm->addfb2_modifiers); + uint32_t fb_id = drm_fb_acquire(fb, drm, &crtc->primary->mgpu_surf); if (!fb_id) { return false; } @@ -79,14 +74,17 @@ static bool legacy_crtc_commit(struct wlr_drm_backend *drm, if (cursor != NULL && drm_connector_is_cursor_visible(conn)) { struct wlr_drm_fb *cursor_fb = plane_get_next_fb(cursor); - struct gbm_bo *cursor_bo = - drm_fb_acquire(cursor_fb, drm, &cursor->mgpu_surf); - if (!cursor_bo) { + if (drm_fb_acquire(cursor_fb, drm, &cursor->mgpu_surf) == 0) { wlr_drm_conn_log_errno(conn, WLR_DEBUG, "Failed to acquire cursor FB"); return false; } + struct gbm_bo *cursor_bo = cursor_fb->bo; + if (cursor_fb->mgpu_bo) { + cursor_bo = cursor_fb->mgpu_bo; + } + if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(cursor_bo).u32, cursor->surf.width, cursor->surf.height)) { diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 52ef7700a..27ad70c8c 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -14,6 +14,7 @@ #include #include #include "backend/drm/drm.h" +#include "backend/drm/util.h" #include "render/drm_format_set.h" #include "render/gbm_allocator.h" #include "render/swapchain.h" @@ -248,6 +249,14 @@ void drm_fb_clear(struct wlr_drm_fb *fb) { return; } + struct gbm_device *gbm = gbm_bo_get_device(fb->bo); + if (fb->mgpu_bo) { + gbm = gbm_bo_get_device(fb->mgpu_bo); + } + if (drmModeRmFB(gbm_device_get_fd(gbm), fb->id) != 0) { + wlr_log(WLR_ERROR, "drmModeRmFB failed"); + } + gbm_bo_destroy(fb->bo); wlr_buffer_unlock(fb->wlr_buf); @@ -362,19 +371,20 @@ bool drm_surface_render_black_frame(struct wlr_drm_surface *surf) { return true; } -struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm, +uint32_t drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm, struct wlr_drm_surface *mgpu) { + if (fb->id) { + return fb->id; + } + if (!fb->bo) { wlr_log(WLR_ERROR, "Tried to acquire an FB with a NULL BO"); - return NULL; + return 0; } if (!drm->parent) { - return fb->bo; - } - - if (fb->mgpu_bo) { - return fb->mgpu_bo; + fb->id = get_fb_for_bo(fb->bo, drm->addfb2_modifiers); + return fb->id; } /* Perform copy across GPUs */ @@ -383,17 +393,17 @@ struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm struct wlr_dmabuf_attributes attribs = {0}; if (!wlr_buffer_get_dmabuf(fb->wlr_buf, &attribs)) { - return NULL; + return 0; } struct wlr_texture *tex = wlr_texture_from_dmabuf(renderer, &attribs); if (tex == NULL) { - return NULL; + return 0; } if (!drm_surface_make_current(mgpu, NULL)) { wlr_texture_destroy(tex); - return NULL; + return 0; } float mat[9]; @@ -410,7 +420,7 @@ struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm }; if (!drm_fb_lock_surface(&mgpu_fb, mgpu)) { wlr_texture_destroy(tex); - return false; + return 0; } wlr_texture_destroy(tex); @@ -418,5 +428,7 @@ struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm fb->mgpu_bo = mgpu_fb.bo; fb->mgpu_wlr_buf = mgpu_fb.wlr_buf; fb->mgpu_surf = mgpu; - return fb->mgpu_bo; + + fb->id = get_fb_for_bo(fb->mgpu_bo, drm->addfb2_modifiers); + return fb->id; } diff --git a/backend/drm/util.c b/backend/drm/util.c index b926e1187..b7ee50da4 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -170,21 +170,7 @@ const char *conn_get_name(uint32_t type_id) { } } -static void free_fb(struct gbm_bo *bo, void *data) { - uint32_t id = (uintptr_t)data; - - if (id) { - struct gbm_device *gbm = gbm_bo_get_device(bo); - drmModeRmFB(gbm_device_get_fd(gbm), id); - } -} - uint32_t get_fb_for_bo(struct gbm_bo *bo, bool with_modifiers) { - uint32_t id = (uintptr_t)gbm_bo_get_user_data(bo); - if (id) { - return id; - } - struct gbm_device *gbm = gbm_bo_get_device(bo); int fd = gbm_device_get_fd(gbm); @@ -204,6 +190,7 @@ uint32_t get_fb_for_bo(struct gbm_bo *bo, bool with_modifiers) { modifiers[i] = gbm_bo_get_modifier(bo); } + uint32_t id = 0; if (with_modifiers && gbm_bo_get_modifier(bo) != DRM_FORMAT_MOD_INVALID) { if (drmModeAddFB2WithModifiers(fd, width, height, format, handles, strides, offsets, modifiers, &id, DRM_MODE_FB_MODIFIERS)) { @@ -216,8 +203,6 @@ uint32_t get_fb_for_bo(struct gbm_bo *bo, bool with_modifiers) { } } - gbm_bo_set_user_data(bo, (void *)(uintptr_t)id, free_fb); - return id; } diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index 9171edc03..a6d75a906 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -38,6 +38,8 @@ struct wlr_drm_fb { struct wlr_drm_surface *mgpu_surf; struct gbm_bo *mgpu_bo; struct wlr_buffer *mgpu_wlr_buf; + + uint32_t id; }; bool init_drm_renderer(struct wlr_drm_backend *drm, @@ -55,7 +57,7 @@ bool drm_fb_import_wlr(struct wlr_drm_fb *fb, struct wlr_drm_renderer *renderer, void drm_fb_move(struct wlr_drm_fb *new, struct wlr_drm_fb *old); bool drm_surface_render_black_frame(struct wlr_drm_surface *surf); -struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm, +uint32_t drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm, struct wlr_drm_surface *mgpu); bool drm_plane_init_surface(struct wlr_drm_plane *plane,