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.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 63a6e2da..024bc929 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -183,18 +183,22 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) {
free(drm->planes);
}
-static void wlr_drm_connector_make_current(struct wlr_output *output) {
+static bool wlr_drm_connector_make_current(struct wlr_output *output,
+ int *buffer_age) {
struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
- wlr_drm_surface_make_current(&conn->crtc->primary->surf);
+ return wlr_drm_surface_make_current(&conn->crtc->primary->surf, buffer_age);
}
-static void wlr_drm_connector_swap_buffers(struct wlr_output *output) {
+static bool wlr_drm_connector_swap_buffers(struct wlr_output *output) {
struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
+ if (!drm->session->active) {
+ return false;
+ }
struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc) {
- return;
+ return false;
}
struct wlr_drm_plane *plane = crtc->primary;
@@ -202,15 +206,21 @@ static void wlr_drm_connector_swap_buffers(struct wlr_output *output) {
if (drm->parent) {
bo = wlr_drm_surface_mgpu_copy(&plane->mgpu_surf, bo);
}
-
uint32_t fb_id = get_fb_for_bo(bo);
+ if (conn->pageflip_pending) {
+ wlr_log(L_ERROR, "Skipping pageflip");
+ return true;
+ }
+
if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) {
conn->pageflip_pending = true;
} else {
wl_event_source_timer_update(conn->retry_pageflip,
- 1000.0f / conn->output.current_mode->refresh);
+ 1000000.0f / conn->output.current_mode->refresh);
}
+
+ return true;
}
static void wlr_drm_connector_set_gamma(struct wlr_output *output,
@@ -247,7 +257,7 @@ void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn) {
conn->pageflip_pending = true;
} else {
wl_event_source_timer_update(conn->retry_pageflip,
- 1000.0f / conn->output.current_mode->refresh);
+ 1000000.0f / conn->output.current_mode->refresh);
}
}
@@ -509,6 +519,10 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
struct wlr_drm_renderer *renderer = &drm->renderer;
+ if (!drm->session->active) {
+ return false;
+ }
+
struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc) {
return false;
@@ -574,15 +588,14 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
}
struct wlr_box hotspot = {
- .width = plane->surf.width,
- .height = plane->surf.height,
.x = hotspot_x,
.y = hotspot_y,
};
enum wl_output_transform transform =
wlr_output_transform_invert(output->transform);
struct wlr_box transformed_hotspot;
- wlr_box_transform(&hotspot, transform, &transformed_hotspot);
+ wlr_box_transform(&hotspot, transform,
+ plane->surf.width, plane->surf.height, &transformed_hotspot);
plane->cursor_hotspot_x = transformed_hotspot.x;
plane->cursor_hotspot_y = transformed_hotspot.y;
@@ -603,7 +616,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
return false;
}
- wlr_drm_surface_make_current(&plane->surf);
+ wlr_drm_surface_make_current(&plane->surf, NULL);
wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888,
stride, width, height, buf);
@@ -627,35 +640,46 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
gbm_bo_unmap(bo, bo_data);
- return drm->iface->crtc_set_cursor(drm, crtc, bo);
+ bool ok = drm->iface->crtc_set_cursor(drm, crtc, bo);
+ if (ok) {
+ wlr_output_update_needs_swap(output);
+ }
+ return ok;
}
static bool wlr_drm_connector_move_cursor(struct wlr_output *output,
int x, int y) {
struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
- if (!conn || !conn->crtc) {
+ if (!drm->session->active) {
+ return false;
+ }
+ if (!conn->crtc) {
return false;
}
struct wlr_drm_plane *plane = conn->crtc->cursor;
- struct wlr_box box;
- box.x = x;
- box.y = y;
- wlr_output_effective_resolution(output, &box.width, &box.height);
+ struct wlr_box box = { .x = x, .y = y };
+
+ int width, height;
+ wlr_output_effective_resolution(output, &width, &height);
enum wl_output_transform transform =
wlr_output_transform_invert(output->transform);
struct wlr_box transformed_box;
- wlr_box_transform(&box, transform, &transformed_box);
+ wlr_box_transform(&box, transform, width, height, &transformed_box);
if (plane != NULL) {
transformed_box.x -= plane->cursor_hotspot_x;
transformed_box.y -= plane->cursor_hotspot_y;
}
- return drm->iface->crtc_move_cursor(drm, conn->crtc, transformed_box.x,
+ bool ok = drm->iface->crtc_move_cursor(drm, conn->crtc, transformed_box.x,
transformed_box.y);
+ if (ok) {
+ wlr_output_update_needs_swap(output);
+ }
+ return ok;
}
static void wlr_drm_connector_destroy(struct wlr_output *output) {
@@ -867,7 +891,7 @@ static void page_flip_handler(int fd, unsigned seq,
}
if (drm->session->active) {
- wl_signal_emit(&conn->output.events.frame, &conn->output);
+ wlr_output_send_frame(&conn->output);
}
}