aboutsummaryrefslogtreecommitdiff
path: root/backend/drm/drm.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/drm/drm.c')
-rw-r--r--backend/drm/drm.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 619664d6..e0eed4c2 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -632,13 +632,25 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_HEIGHT, &h);
h = ret ? 64 : h;
- struct wlr_drm_renderer *renderer =
- drm->parent ? &drm->parent->renderer : &drm->renderer;
- if (!init_drm_surface(&plane->surf, renderer, w, h,
- renderer->gbm_format, GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT)) {
- wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
- return false;
+ if (!drm->parent) {
+ if (!init_drm_surface(&plane->surf, &drm->renderer, w, h,
+ drm->renderer.gbm_format, GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT)) {
+ wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
+ return false;
+ }
+ } else {
+ if (!init_drm_surface(&plane->surf, &drm->parent->renderer, w, h,
+ drm->parent->renderer.gbm_format, GBM_BO_USE_LINEAR)) {
+ wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
+ return false;
+ }
+
+ if (!init_drm_surface(&plane->mgpu_surf, &drm->renderer, w, h,
+ drm->renderer.gbm_format, GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT)) {
+ wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
+ return false;
+ }
}
}
@@ -708,6 +720,19 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
}
struct gbm_bo *bo = plane->cursor_enabled ? plane->surf.back : NULL;
+ if (bo && drm->parent) {
+ bo = copy_drm_surface_mgpu(&plane->mgpu_surf, bo);
+ }
+
+ if (bo) {
+ // workaround for nouveau
+ // Buffers created with GBM_BO_USER_LINEAR are placed in NOUVEAU_GEM_DOMAIN_GART.
+ // When the bo is attached to the cursor plane it is moved to NOUVEAU_GEM_DOMAIN_VRAM.
+ // However, this does not wait for the render operations to complete, leaving an empty surface.
+ // see https://bugs.freedesktop.org/show_bug.cgi?id=109631
+ // The render operations can be waited for using:
+ glFinish();
+ }
bool ok = drm->iface->crtc_set_cursor(drm, crtc, bo);
if (ok) {
wlr_output_update_needs_swap(output);