aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/atomic.c101
-rw-r--r--backend/drm/drm.c11
-rw-r--r--backend/drm/legacy.c16
-rw-r--r--include/backend/drm/iface.h3
4 files changed, 66 insertions, 65 deletions
diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c
index cedc687b..d6149539 100644
--- a/backend/drm/atomic.c
+++ b/backend/drm/atomic.c
@@ -69,10 +69,27 @@ static void atomic_add(struct atomic *atom, uint32_t id, uint32_t prop, uint64_t
}
}
-static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane,
- uint32_t crtc_id, uint32_t fb_id, bool set_crtc_xy) {
+static void plane_disable(struct atomic *atom, struct wlr_drm_plane *plane) {
uint32_t id = plane->id;
const union wlr_drm_plane_props *props = &plane->props;
+ atomic_add(atom, id, props->fb_id, 0);
+ atomic_add(atom, id, props->crtc_id, 0);
+}
+
+static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm,
+ struct wlr_drm_plane *plane, uint32_t crtc_id, int32_t x, int32_t y) {
+ 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);
+ if (!fb_id) {
+ goto error;
+ }
// The src_* properties are in 16.16 fixed point
atomic_add(atom, id, props->src_x, 0);
@@ -83,16 +100,19 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_plane *plane,
atomic_add(atom, id, props->crtc_h, plane->surf.height);
atomic_add(atom, id, props->fb_id, fb_id);
atomic_add(atom, id, props->crtc_id, crtc_id);
- if (set_crtc_xy) {
- atomic_add(atom, id, props->crtc_x, 0);
- atomic_add(atom, id, props->crtc_y, 0);
- }
+ atomic_add(atom, id, props->crtc_x, (uint64_t)x);
+ atomic_add(atom, id, props->crtc_y, (uint64_t)y);
+
+ return;
+
+error:
+ atom->failed = true;
}
static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm,
- struct wlr_drm_connector *conn,
- struct wlr_drm_crtc *crtc,
- uint32_t fb_id, drmModeModeInfo *mode) {
+ struct wlr_drm_connector *conn, drmModeModeInfo *mode) {
+ struct wlr_drm_crtc *crtc = conn->crtc;
+
if (mode != NULL) {
if (crtc->mode_id != 0) {
drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id);
@@ -121,14 +141,29 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm,
}
atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id);
atomic_add(&atom, crtc->id, crtc->props.active, 1);
- set_plane_props(&atom, crtc->primary, crtc->id, fb_id, true);
+ set_plane_props(&atom, drm, crtc->primary, crtc->id, 0, 0);
+ if (crtc->cursor) {
+ if (crtc->cursor->cursor_enabled) {
+ set_plane_props(&atom, drm, crtc->cursor, crtc->id,
+ conn->cursor_x, conn->cursor_y);
+ } else {
+ plane_disable(&atom, crtc->cursor);
+ }
+ }
if (!atomic_end(drm->fd, mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : 0, &atom)) {
drmModeAtomicSetCursor(atom.req, 0);
return false;
}
- return atomic_commit(drm->fd, &atom, conn, flags, mode);
+ if (!atomic_commit(drm->fd, &atom, conn, flags, mode)) {
+ return false;
+ }
+
+ if (crtc->cursor) {
+ drm_fb_move(&crtc->cursor->queued_fb, &crtc->cursor->pending_fb);
+ }
+ return true;
}
static bool atomic_conn_enable(struct wlr_drm_backend *drm,
@@ -154,50 +189,14 @@ static bool atomic_conn_enable(struct wlr_drm_backend *drm,
static bool atomic_crtc_set_cursor(struct wlr_drm_backend *drm,
struct wlr_drm_crtc *crtc, struct gbm_bo *bo) {
- if (!crtc || !crtc->cursor) {
- return true;
- }
-
- struct wlr_drm_plane *plane = crtc->cursor;
- // We can't use atomic operations on fake planes
- if (plane->id == 0) {
- return legacy_crtc_set_cursor(drm, crtc, bo);
- }
-
- struct atomic atom;
-
- atomic_begin(crtc, &atom);
-
- if (bo) {
- uint32_t fb_id =
- get_fb_for_bo(bo, drm->addfb2_modifiers);
- set_plane_props(&atom, plane, crtc->id, fb_id, false);
- } else {
- atomic_add(&atom, plane->id, plane->props.fb_id, 0);
- atomic_add(&atom, plane->id, plane->props.crtc_id, 0);
- }
-
- return atomic_end(drm->fd, &atom);
+ /* Cursor updates happen when we pageflip */
+ return true;
}
static bool atomic_crtc_move_cursor(struct wlr_drm_backend *drm,
struct wlr_drm_crtc *crtc, int x, int y) {
- if (!crtc || !crtc->cursor) {
- return true;
- }
-
- struct wlr_drm_plane *plane = crtc->cursor;
- // We can't use atomic operations on fake planes
- if (plane->id == 0) {
- return legacy_crtc_move_cursor(drm, crtc, x, y);
- }
-
- struct atomic atom;
-
- atomic_begin(crtc, &atom);
- atomic_add(&atom, plane->id, plane->props.crtc_x, x);
- atomic_add(&atom, plane->id, plane->props.crtc_y, y);
- return atomic_end(drm->fd, &atom);
+ /* Cursor updates happen when we pageflip */
+ return true;
}
static bool atomic_crtc_set_gamma(struct wlr_drm_backend *drm,
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index ed74c7d1..8efc9d7f 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -338,9 +338,6 @@ static bool drm_crtc_page_flip(struct wlr_drm_connector *conn,
struct wlr_drm_mode *mode) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(conn->output.backend);
struct wlr_drm_crtc *crtc = conn->crtc;
- struct wlr_drm_plane *plane = crtc->primary;
- struct gbm_bo *bo;
- uint32_t fb_id;
drmModeModeInfo *drm_mode = mode ? &mode->drm_mode : NULL;
if (conn->pageflip_pending) {
@@ -348,13 +345,7 @@ static bool drm_crtc_page_flip(struct wlr_drm_connector *conn,
return false;
}
- bo = drm_fb_acquire(&plane->queued_fb, drm, &plane->mgpu_surf);
- if (!bo) {
- return false;
- }
-
- fb_id = get_fb_for_bo(bo, drm->addfb2_modifiers);
- if (!drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, drm_mode)) {
+ if (!drm->iface->crtc_pageflip(drm, conn, drm_mode)) {
return false;
}
diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c
index 32d68814..be5ec4a0 100644
--- a/backend/drm/legacy.c
+++ b/backend/drm/legacy.c
@@ -7,8 +7,19 @@
#include "backend/drm/util.h"
static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm,
- struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc,
- uint32_t fb_id, drmModeModeInfo *mode) {
+ struct wlr_drm_connector *conn, drmModeModeInfo *mode) {
+ struct wlr_drm_crtc *crtc = conn->crtc;
+ 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;
+ }
+
+ uint32_t fb_id = get_fb_for_bo(bo, drm->addfb2_modifiers);
+ if (!fb_id) {
+ return false;
+ }
+
if (mode) {
if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0,
&conn->id, 1, mode)) {
@@ -60,6 +71,7 @@ bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm,
return false;
}
+ drm_fb_move(&crtc->cursor->queued_fb, &crtc->cursor->pending_fb);
return true;
}
diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h
index 5308b136..d8268347 100644
--- a/include/backend/drm/iface.h
+++ b/include/backend/drm/iface.h
@@ -18,8 +18,7 @@ struct wlr_drm_interface {
struct wlr_drm_connector *conn, bool enable);
// Pageflip on crtc. If mode is non-NULL perform a full modeset using it.
bool (*crtc_pageflip)(struct wlr_drm_backend *drm,
- struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc,
- uint32_t fb_id, drmModeModeInfo *mode);
+ struct wlr_drm_connector *conn, drmModeModeInfo *mode);
// Enable the cursor buffer on crtc. Set bo to NULL to disable
bool (*crtc_set_cursor)(struct wlr_drm_backend *drm,
struct wlr_drm_crtc *crtc, struct gbm_bo *bo);