mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-24 21:55:58 +01:00
backend/drm: rework struct wlr_drm_page_flip for multiple connectors
We need to store the CRTC ID for each connector at the time of the atomic commit, because future commits may change the CRTC/connector mapping.
This commit is contained in:
parent
805807fd5b
commit
fc4996d853
2 changed files with 65 additions and 16 deletions
|
@ -422,33 +422,75 @@ static struct wlr_drm_layer *get_or_create_layer(struct wlr_drm_backend *drm,
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drm_connector_set_pending_page_flip(struct wlr_drm_connector *conn,
|
|
||||||
struct wlr_drm_page_flip *page_flip) {
|
|
||||||
if (conn->pending_page_flip != NULL) {
|
|
||||||
conn->pending_page_flip->conn = NULL;
|
|
||||||
}
|
|
||||||
conn->pending_page_flip = page_flip;
|
|
||||||
}
|
|
||||||
|
|
||||||
void drm_page_flip_destroy(struct wlr_drm_page_flip *page_flip) {
|
void drm_page_flip_destroy(struct wlr_drm_page_flip *page_flip) {
|
||||||
if (!page_flip) {
|
if (!page_flip) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove(&page_flip->link);
|
wl_list_remove(&page_flip->link);
|
||||||
|
free(page_flip->connectors);
|
||||||
free(page_flip);
|
free(page_flip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_drm_page_flip *drm_page_flip_create(struct wlr_drm_connector *conn) {
|
static struct wlr_drm_page_flip *drm_page_flip_create(struct wlr_drm_backend *drm,
|
||||||
|
const struct wlr_drm_device_state *state) {
|
||||||
struct wlr_drm_page_flip *page_flip = calloc(1, sizeof(*page_flip));
|
struct wlr_drm_page_flip *page_flip = calloc(1, sizeof(*page_flip));
|
||||||
if (page_flip == NULL) {
|
if (page_flip == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
page_flip->conn = conn;
|
page_flip->connectors_len = state->connectors_len;
|
||||||
wl_list_insert(&conn->backend->page_flips, &page_flip->link);
|
page_flip->connectors =
|
||||||
|
calloc(page_flip->connectors_len, sizeof(page_flip->connectors[0]));
|
||||||
|
if (page_flip->connectors == NULL) {
|
||||||
|
free(page_flip);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < state->connectors_len; i++) {
|
||||||
|
struct wlr_drm_connector *conn = state->connectors[i].connector;
|
||||||
|
page_flip->connectors[i] = (struct wlr_drm_page_flip_connector){
|
||||||
|
.connector = conn,
|
||||||
|
.crtc_id = conn->crtc->id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
wl_list_insert(&drm->page_flips, &page_flip->link);
|
||||||
return page_flip;
|
return page_flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct wlr_drm_connector *drm_page_flip_pop(
|
||||||
|
struct wlr_drm_page_flip *page_flip, uint32_t crtc_id) {
|
||||||
|
bool found = false;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < page_flip->connectors_len; i++) {
|
||||||
|
if (page_flip->connectors[i].crtc_id == crtc_id) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_drm_connector *conn = page_flip->connectors[i].connector;
|
||||||
|
if (i != page_flip->connectors_len - 1) {
|
||||||
|
page_flip->connectors[i] = page_flip->connectors[page_flip->connectors_len - 1];
|
||||||
|
}
|
||||||
|
page_flip->connectors_len--;
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drm_connector_set_pending_page_flip(struct wlr_drm_connector *conn,
|
||||||
|
struct wlr_drm_page_flip *page_flip) {
|
||||||
|
if (conn->pending_page_flip != NULL) {
|
||||||
|
struct wlr_drm_page_flip *page_flip = conn->pending_page_flip;
|
||||||
|
for (size_t i = 0; i < page_flip->connectors_len; i++) {
|
||||||
|
if (page_flip->connectors[i].connector == conn) {
|
||||||
|
page_flip->connectors[i].connector = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn->pending_page_flip = page_flip;
|
||||||
|
}
|
||||||
|
|
||||||
static void drm_connector_apply_commit(const struct wlr_drm_connector_state *state,
|
static void drm_connector_apply_commit(const struct wlr_drm_connector_state *state,
|
||||||
struct wlr_drm_page_flip *page_flip) {
|
struct wlr_drm_page_flip *page_flip) {
|
||||||
struct wlr_drm_connector *conn = state->connector;
|
struct wlr_drm_connector *conn = state->connector;
|
||||||
|
@ -496,8 +538,7 @@ static bool drm_commit(struct wlr_drm_backend *drm,
|
||||||
|
|
||||||
struct wlr_drm_page_flip *page_flip = NULL;
|
struct wlr_drm_page_flip *page_flip = NULL;
|
||||||
if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
|
if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
|
||||||
assert(state->connectors_len == 1);
|
page_flip = drm_page_flip_create(drm, state);
|
||||||
page_flip = drm_page_flip_create(state->connectors[0].connector);
|
|
||||||
if (page_flip == NULL) {
|
if (page_flip == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1874,11 +1915,13 @@ static void handle_page_flip(int fd, unsigned seq,
|
||||||
unsigned tv_sec, unsigned tv_usec, unsigned crtc_id, void *data) {
|
unsigned tv_sec, unsigned tv_usec, unsigned crtc_id, void *data) {
|
||||||
struct wlr_drm_page_flip *page_flip = data;
|
struct wlr_drm_page_flip *page_flip = data;
|
||||||
|
|
||||||
struct wlr_drm_connector *conn = page_flip->conn;
|
struct wlr_drm_connector *conn = drm_page_flip_pop(page_flip, crtc_id);
|
||||||
if (conn != NULL) {
|
if (conn != NULL) {
|
||||||
conn->pending_page_flip = NULL;
|
conn->pending_page_flip = NULL;
|
||||||
}
|
}
|
||||||
|
if (page_flip->connectors_len == 0) {
|
||||||
drm_page_flip_destroy(page_flip);
|
drm_page_flip_destroy(page_flip);
|
||||||
|
}
|
||||||
|
|
||||||
if (conn == NULL) {
|
if (conn == NULL) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -159,7 +159,13 @@ struct wlr_drm_connector_state {
|
||||||
*/
|
*/
|
||||||
struct wlr_drm_page_flip {
|
struct wlr_drm_page_flip {
|
||||||
struct wl_list link; // wlr_drm_connector.page_flips
|
struct wl_list link; // wlr_drm_connector.page_flips
|
||||||
struct wlr_drm_connector *conn;
|
struct wlr_drm_page_flip_connector *connectors;
|
||||||
|
size_t connectors_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_drm_page_flip_connector {
|
||||||
|
uint32_t crtc_id;
|
||||||
|
struct wlr_drm_connector *connector; // may be NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_connector {
|
struct wlr_drm_connector {
|
||||||
|
|
Loading…
Reference in a new issue