|
|
|
@ -69,6 +69,22 @@ static void atomic_add(struct atomic *atom, uint32_t id, uint32_t prop, uint64_t
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool create_mode_blob(struct wlr_drm_backend *drm,
|
|
|
|
|
struct wlr_drm_crtc *crtc, uint32_t *blob_id) {
|
|
|
|
|
if (!crtc->active) {
|
|
|
|
|
*blob_id = 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (drmModeCreatePropertyBlob(drm->fd, &crtc->mode,
|
|
|
|
|
sizeof(drmModeModeInfo), blob_id)) {
|
|
|
|
|
wlr_log_errno(WLR_ERROR, "Unable to create mode property blob");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool create_gamma_lut_blob(struct wlr_drm_backend *drm,
|
|
|
|
|
struct wlr_drm_crtc *crtc, uint32_t *blob_id) {
|
|
|
|
|
if (crtc->gamma_table_size == 0) {
|
|
|
|
@ -148,15 +164,12 @@ static bool atomic_crtc_commit(struct wlr_drm_backend *drm,
|
|
|
|
|
struct wlr_drm_connector *conn, uint32_t flags) {
|
|
|
|
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
|
|
|
|
|
|
|
|
|
bool modeset = crtc->pending & WLR_DRM_CRTC_MODE;
|
|
|
|
|
if (modeset) {
|
|
|
|
|
if (crtc->pending & WLR_DRM_CRTC_MODE) {
|
|
|
|
|
if (crtc->mode_id != 0) {
|
|
|
|
|
drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (drmModeCreatePropertyBlob(drm->fd, &crtc->mode,
|
|
|
|
|
sizeof(drmModeModeInfo), &crtc->mode_id)) {
|
|
|
|
|
wlr_log_errno(WLR_ERROR, "Unable to create mode property blob");
|
|
|
|
|
if (!create_mode_blob(drm, crtc, &crtc->mode_id)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -179,6 +192,7 @@ static bool atomic_crtc_commit(struct wlr_drm_backend *drm,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool modeset = crtc->pending & WLR_DRM_CRTC_MODE;
|
|
|
|
|
if (modeset) {
|
|
|
|
|
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
|
|
|
|
} else {
|
|
|
|
@ -187,20 +201,28 @@ static bool atomic_crtc_commit(struct wlr_drm_backend *drm,
|
|
|
|
|
|
|
|
|
|
struct atomic atom;
|
|
|
|
|
atomic_begin(crtc, &atom);
|
|
|
|
|
atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id);
|
|
|
|
|
if (modeset && conn->props.link_status != 0) {
|
|
|
|
|
atomic_add(&atom, conn->id, conn->props.crtc_id,
|
|
|
|
|
crtc->active ? crtc->id : 0);
|
|
|
|
|
if (modeset && crtc->active && conn->props.link_status != 0) {
|
|
|
|
|
atomic_add(&atom, conn->id, conn->props.link_status,
|
|
|
|
|
DRM_MODE_LINK_STATUS_GOOD);
|
|
|
|
|
}
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id);
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.active, 1);
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.gamma_lut, crtc->gamma_lut);
|
|
|
|
|
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 {
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.active, crtc->active);
|
|
|
|
|
if (crtc->active) {
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.gamma_lut, crtc->gamma_lut);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
plane_disable(&atom, crtc->primary);
|
|
|
|
|
if (crtc->cursor) {
|
|
|
|
|
plane_disable(&atom, crtc->cursor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -215,33 +237,12 @@ static bool atomic_crtc_commit(struct wlr_drm_backend *drm,
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (crtc->cursor) {
|
|
|
|
|
if (crtc->active && 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,
|
|
|
|
|
struct wlr_drm_connector *conn, bool enable) {
|
|
|
|
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
|
|
|
|
if (crtc == NULL) {
|
|
|
|
|
return !enable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct atomic atom;
|
|
|
|
|
atomic_begin(crtc, &atom);
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.active, enable);
|
|
|
|
|
if (enable) {
|
|
|
|
|
atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id);
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id);
|
|
|
|
|
} else {
|
|
|
|
|
atomic_add(&atom, conn->id, conn->props.crtc_id, 0);
|
|
|
|
|
atomic_add(&atom, crtc->id, crtc->props.mode_id, 0);
|
|
|
|
|
}
|
|
|
|
|
return atomic_commit(drm->fd, &atom, conn, DRM_MODE_ATOMIC_ALLOW_MODESET,
|
|
|
|
|
true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool atomic_crtc_set_cursor(struct wlr_drm_backend *drm,
|
|
|
|
|
struct wlr_drm_crtc *crtc, struct gbm_bo *bo) {
|
|
|
|
|
/* Cursor updates happen when we pageflip */
|
|
|
|
@ -265,7 +266,6 @@ static size_t atomic_crtc_get_gamma_size(struct wlr_drm_backend *drm,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct wlr_drm_interface atomic_iface = {
|
|
|
|
|
.conn_enable = atomic_conn_enable,
|
|
|
|
|
.crtc_commit = atomic_crtc_commit,
|
|
|
|
|
.crtc_set_cursor = atomic_crtc_set_cursor,
|
|
|
|
|
.crtc_get_gamma_size = atomic_crtc_get_gamma_size,
|
|
|
|
|