backend/drm: remove mode argument to crtc_pageflip
Add a new wlr_drm_crtc.pending bitfield which keeps track of pending output changes. More fields will be added in the future (e.g. active, gamma).
This commit is contained in:
parent
7a149fe5ba
commit
69b2279092
|
@ -110,23 +110,24 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm,
|
static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_connector *conn, drmModeModeInfo *mode) {
|
struct wlr_drm_connector *conn) {
|
||||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||||
|
|
||||||
if (mode != NULL) {
|
bool modeset = crtc->pending & WLR_DRM_CRTC_MODE;
|
||||||
|
if (modeset) {
|
||||||
if (crtc->mode_id != 0) {
|
if (crtc->mode_id != 0) {
|
||||||
drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id);
|
drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drmModeCreatePropertyBlob(drm->fd, mode, sizeof(*mode),
|
if (drmModeCreatePropertyBlob(drm->fd, &crtc->mode,
|
||||||
&crtc->mode_id)) {
|
sizeof(drmModeModeInfo), &crtc->mode_id)) {
|
||||||
wlr_log_errno(WLR_ERROR, "Unable to create property blob");
|
wlr_log_errno(WLR_ERROR, "Unable to create mode property blob");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT;
|
uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT;
|
||||||
if (mode != NULL) {
|
if (modeset) {
|
||||||
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
} else {
|
} else {
|
||||||
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||||
|
@ -135,7 +136,7 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm,
|
||||||
struct atomic atom;
|
struct atomic atom;
|
||||||
atomic_begin(crtc, &atom);
|
atomic_begin(crtc, &atom);
|
||||||
atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id);
|
atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id);
|
||||||
if (mode != NULL && conn->props.link_status != 0) {
|
if (modeset && conn->props.link_status != 0) {
|
||||||
atomic_add(&atom, conn->id, conn->props.link_status,
|
atomic_add(&atom, conn->id, conn->props.link_status,
|
||||||
DRM_MODE_LINK_STATUS_GOOD);
|
DRM_MODE_LINK_STATUS_GOOD);
|
||||||
}
|
}
|
||||||
|
@ -151,12 +152,13 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!atomic_end(drm->fd, mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : 0, &atom)) {
|
if (!atomic_end(drm->fd, modeset ? DRM_MODE_ATOMIC_ALLOW_MODESET : 0,
|
||||||
|
&atom)) {
|
||||||
drmModeAtomicSetCursor(atom.req, 0);
|
drmModeAtomicSetCursor(atom.req, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!atomic_commit(drm->fd, &atom, conn, flags, mode)) {
|
if (!atomic_commit(drm->fd, &atom, conn, flags, modeset)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,11 +334,10 @@ static bool drm_connector_attach_render(struct wlr_output *output,
|
||||||
return drm_surface_make_current(&conn->crtc->primary->surf, buffer_age);
|
return drm_surface_make_current(&conn->crtc->primary->surf, buffer_age);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool drm_crtc_page_flip(struct wlr_drm_connector *conn,
|
static bool drm_crtc_page_flip(struct wlr_drm_connector *conn) {
|
||||||
struct wlr_drm_mode *mode) {
|
struct wlr_drm_backend *drm =
|
||||||
struct wlr_drm_backend *drm = get_drm_backend_from_backend(conn->output.backend);
|
get_drm_backend_from_backend(conn->output.backend);
|
||||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||||
drmModeModeInfo *drm_mode = mode ? &mode->drm_mode : NULL;
|
|
||||||
|
|
||||||
if (conn->pageflip_pending) {
|
if (conn->pageflip_pending) {
|
||||||
wlr_log(WLR_ERROR, "Failed to page-flip output '%s': "
|
wlr_log(WLR_ERROR, "Failed to page-flip output '%s': "
|
||||||
|
@ -346,7 +345,11 @@ static bool drm_crtc_page_flip(struct wlr_drm_connector *conn,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drm->iface->crtc_pageflip(drm, conn, drm_mode)) {
|
bool ok = drm->iface->crtc_pageflip(drm, conn);
|
||||||
|
|
||||||
|
crtc->pending = 0;
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +457,7 @@ static bool drm_connector_commit_buffer(struct wlr_output *output) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drm_crtc_page_flip(conn, NULL)) {
|
if (!drm_crtc_page_flip(conn)) {
|
||||||
drm_fb_clear(&plane->pending_fb);
|
drm_fb_clear(&plane->pending_fb);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -661,8 +664,7 @@ struct wlr_drm_fb *plane_get_next_fb(struct wlr_drm_plane *plane) {
|
||||||
return &plane->current_fb;
|
return &plane->current_fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool drm_connector_pageflip_renderer(struct wlr_drm_connector *conn,
|
static bool drm_connector_pageflip_renderer(struct wlr_drm_connector *conn) {
|
||||||
struct wlr_drm_mode *mode) {
|
|
||||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||||
if (!crtc) {
|
if (!crtc) {
|
||||||
wlr_log(WLR_ERROR, "Page-flip failed on connector '%s': no CRTC",
|
wlr_log(WLR_ERROR, "Page-flip failed on connector '%s': no CRTC",
|
||||||
|
@ -679,10 +681,12 @@ static bool drm_connector_pageflip_renderer(struct wlr_drm_connector *conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return drm_crtc_page_flip(conn, mode);
|
return drm_crtc_page_flip(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drm_connector_start_renderer(struct wlr_drm_connector *conn) {
|
static void drm_connector_start_renderer(struct wlr_drm_connector *conn) {
|
||||||
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||||
|
|
||||||
if (conn->state != WLR_DRM_CONN_CONNECTED) {
|
if (conn->state != WLR_DRM_CONN_CONNECTED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +694,10 @@ static void drm_connector_start_renderer(struct wlr_drm_connector *conn) {
|
||||||
wlr_log(WLR_DEBUG, "Starting renderer on output '%s'", conn->output.name);
|
wlr_log(WLR_DEBUG, "Starting renderer on output '%s'", conn->output.name);
|
||||||
|
|
||||||
struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode;
|
struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode;
|
||||||
if (!drm_connector_pageflip_renderer(conn, mode)) {
|
memcpy(&crtc->mode, &mode->drm_mode, sizeof(drmModeModeInfo));
|
||||||
|
crtc->pending |= WLR_DRM_CRTC_MODE;
|
||||||
|
|
||||||
|
if (!drm_connector_pageflip_renderer(conn)) {
|
||||||
wl_event_source_timer_update(conn->retry_pageflip,
|
wl_event_source_timer_update(conn->retry_pageflip,
|
||||||
1000000.0f / conn->output.current_mode->refresh);
|
1000000.0f / conn->output.current_mode->refresh);
|
||||||
}
|
}
|
||||||
|
@ -717,6 +724,9 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn,
|
||||||
}
|
}
|
||||||
struct wlr_drm_plane *plane = crtc->primary;
|
struct wlr_drm_plane *plane = crtc->primary;
|
||||||
|
|
||||||
|
crtc->pending |= WLR_DRM_CRTC_MODE;
|
||||||
|
memcpy(&crtc->mode, &mode->drm_mode, sizeof(drmModeModeInfo));
|
||||||
|
|
||||||
int width = mode->wlr_mode.width;
|
int width = mode->wlr_mode.width;
|
||||||
int height = mode->wlr_mode.height;
|
int height = mode->wlr_mode.height;
|
||||||
uint32_t format = drm->renderer.gbm_format;
|
uint32_t format = drm->renderer.gbm_format;
|
||||||
|
@ -730,7 +740,7 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drm_plane_init_surface(plane, drm, width, height, format, 0, modifiers) ||
|
if (!drm_plane_init_surface(plane, drm, width, height, format, 0, modifiers) ||
|
||||||
!drm_connector_pageflip_renderer(conn, mode)) {
|
!drm_connector_pageflip_renderer(conn)) {
|
||||||
if (!modifiers) {
|
if (!modifiers) {
|
||||||
wlr_log(WLR_ERROR, "Failed to initialize renderer "
|
wlr_log(WLR_ERROR, "Failed to initialize renderer "
|
||||||
"on connector '%s': initial page-flip failed",
|
"on connector '%s': initial page-flip failed",
|
||||||
|
@ -748,7 +758,7 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn,
|
||||||
0, modifiers)) {
|
0, modifiers)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!drm_connector_pageflip_renderer(conn, mode)) {
|
if (!drm_connector_pageflip_renderer(conn)) {
|
||||||
wlr_log(WLR_ERROR, "Failed to initialize renderer "
|
wlr_log(WLR_ERROR, "Failed to initialize renderer "
|
||||||
"on connector '%s': initial page-flip failed",
|
"on connector '%s': initial page-flip failed",
|
||||||
conn->output.name);
|
conn->output.name);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "backend/drm/util.h"
|
#include "backend/drm/util.h"
|
||||||
|
|
||||||
static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm,
|
static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_connector *conn, drmModeModeInfo *mode) {
|
struct wlr_drm_connector *conn) {
|
||||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||||
struct wlr_drm_plane *cursor = crtc->cursor;
|
struct wlr_drm_plane *cursor = crtc->cursor;
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode) {
|
if (crtc->pending & WLR_DRM_CRTC_MODE) {
|
||||||
if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0,
|
if (drmModeSetCrtc(drm->fd, crtc->id, fb_id, 0, 0,
|
||||||
&conn->id, 1, mode)) {
|
&conn->id, 1, &crtc->mode)) {
|
||||||
wlr_log_errno(WLR_ERROR, "%s: Failed to set CRTC", conn->output.name);
|
wlr_log_errno(WLR_ERROR, "%s: Failed to set CRTC", conn->output.name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,15 @@ struct wlr_drm_plane {
|
||||||
union wlr_drm_plane_props props;
|
union wlr_drm_plane_props props;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wlr_drm_crtc_field {
|
||||||
|
WLR_DRM_CRTC_MODE = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_drm_crtc {
|
struct wlr_drm_crtc {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
uint32_t pending; // bitfield of enum wlr_drm_crtc_field
|
||||||
|
|
||||||
|
drmModeModeInfo mode;
|
||||||
|
|
||||||
// Atomic modesetting only
|
// Atomic modesetting only
|
||||||
uint32_t mode_id;
|
uint32_t mode_id;
|
||||||
|
|
|
@ -16,9 +16,9 @@ struct wlr_drm_interface {
|
||||||
// Enable or disable DPMS for connector
|
// Enable or disable DPMS for connector
|
||||||
bool (*conn_enable)(struct wlr_drm_backend *drm,
|
bool (*conn_enable)(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_connector *conn, bool enable);
|
struct wlr_drm_connector *conn, bool enable);
|
||||||
// Pageflip on crtc. If mode is non-NULL perform a full modeset using it.
|
// Pageflip on crtc.
|
||||||
bool (*crtc_pageflip)(struct wlr_drm_backend *drm,
|
bool (*crtc_pageflip)(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_connector *conn, drmModeModeInfo *mode);
|
struct wlr_drm_connector *conn);
|
||||||
// Enable the cursor buffer on crtc. Set bo to NULL to disable
|
// Enable the cursor buffer on crtc. Set bo to NULL to disable
|
||||||
bool (*crtc_set_cursor)(struct wlr_drm_backend *drm,
|
bool (*crtc_set_cursor)(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_crtc *crtc, struct gbm_bo *bo);
|
struct wlr_drm_crtc *crtc, struct gbm_bo *bo);
|
||||||
|
|
Loading…
Reference in New Issue