backend/drm: hold buffers while scanning out
This commit is contained in:
parent
ff6b352d75
commit
44ba603c0e
|
@ -350,6 +350,11 @@ static bool drm_connector_commit(struct wlr_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->pageflip_pending = true;
|
conn->pageflip_pending = true;
|
||||||
|
if (output->pending.buffer_type == WLR_OUTPUT_STATE_BUFFER_SCANOUT) {
|
||||||
|
wlr_buffer_unref(conn->pending_buffer);
|
||||||
|
conn->pending_buffer = wlr_buffer_ref(output->pending.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
wlr_output_update_enabled(output, true);
|
wlr_output_update_enabled(output, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1440,10 +1445,22 @@ static void page_flip_handler(int fd, unsigned seq,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release the old buffer as it's not displayed anymore. The pending
|
||||||
|
// buffer becomes the current buffer.
|
||||||
|
wlr_buffer_unref(conn->current_buffer);
|
||||||
|
conn->current_buffer = conn->pending_buffer;
|
||||||
|
conn->pending_buffer = NULL;
|
||||||
|
|
||||||
|
uint32_t present_flags = WLR_OUTPUT_PRESENT_VSYNC |
|
||||||
|
WLR_OUTPUT_PRESENT_HW_CLOCK | WLR_OUTPUT_PRESENT_HW_COMPLETION;
|
||||||
|
if (conn->current_buffer != NULL) {
|
||||||
|
present_flags |= WLR_OUTPUT_PRESENT_ZERO_COPY;
|
||||||
|
} else {
|
||||||
post_drm_surface(&conn->crtc->primary->surf);
|
post_drm_surface(&conn->crtc->primary->surf);
|
||||||
if (drm->parent) {
|
if (drm->parent) {
|
||||||
post_drm_surface(&conn->crtc->primary->mgpu_surf);
|
post_drm_surface(&conn->crtc->primary->mgpu_surf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct timespec present_time = {
|
struct timespec present_time = {
|
||||||
.tv_sec = tv_sec,
|
.tv_sec = tv_sec,
|
||||||
|
@ -1453,8 +1470,7 @@ static void page_flip_handler(int fd, unsigned seq,
|
||||||
.when = &present_time,
|
.when = &present_time,
|
||||||
.seq = seq,
|
.seq = seq,
|
||||||
.refresh = mhz_to_nsec(conn->output.refresh),
|
.refresh = mhz_to_nsec(conn->output.refresh),
|
||||||
.flags = WLR_OUTPUT_PRESENT_VSYNC | WLR_OUTPUT_PRESENT_HW_CLOCK |
|
.flags = present_flags,
|
||||||
WLR_OUTPUT_PRESENT_HW_COMPLETION,
|
|
||||||
};
|
};
|
||||||
wlr_output_send_present(&conn->output, &present_event);
|
wlr_output_send_present(&conn->output, &present_event);
|
||||||
|
|
||||||
|
@ -1559,6 +1575,10 @@ static void drm_connector_cleanup(struct wlr_drm_connector *conn) {
|
||||||
conn->output.needs_frame = false;
|
conn->output.needs_frame = false;
|
||||||
conn->output.frame_pending = false;
|
conn->output.frame_pending = false;
|
||||||
|
|
||||||
|
wlr_buffer_unref(conn->pending_buffer);
|
||||||
|
wlr_buffer_unref(conn->current_buffer);
|
||||||
|
conn->pending_buffer = conn->current_buffer = NULL;
|
||||||
|
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
case WLR_DRM_CONN_NEEDS_MODESET:
|
case WLR_DRM_CONN_NEEDS_MODESET:
|
||||||
wlr_log(WLR_INFO, "Emitting destruction signal for '%s'",
|
wlr_log(WLR_INFO, "Emitting destruction signal for '%s'",
|
||||||
|
|
|
@ -149,7 +149,12 @@ struct wlr_drm_connector {
|
||||||
struct wl_event_source *retry_pageflip;
|
struct wl_event_source *retry_pageflip;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
|
// DMA-BUF to be displayed on next commit
|
||||||
struct wlr_dmabuf_attributes pending_dmabuf;
|
struct wlr_dmabuf_attributes pending_dmabuf;
|
||||||
|
// Buffer submitted to the kernel but not yet displayed
|
||||||
|
struct wlr_buffer *pending_buffer;
|
||||||
|
// Buffer currently being displayed
|
||||||
|
struct wlr_buffer *current_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_backend *get_drm_backend_from_backend(
|
struct wlr_drm_backend *get_drm_backend_from_backend(
|
||||||
|
|
Loading…
Reference in New Issue