mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-03-20 05:35:12 -04:00
backend/drm: properly delay syncobj signalling
DRM CRTC signals when scanout begins, but wlr_output_state_set_signal_timeline() is defined to signal buffer release. Delay to the next page flip
This commit is contained in:
parent
b2f6a390a4
commit
cd555f9261
3 changed files with 41 additions and 2 deletions
|
|
@ -426,8 +426,13 @@ void drm_atomic_connector_apply_commit(struct wlr_drm_connector_state *state) {
|
||||||
}
|
}
|
||||||
if (state->out_fence_fd >= 0) {
|
if (state->out_fence_fd >= 0) {
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
wlr_drm_syncobj_timeline_import_sync_file(state->base->signal_timeline,
|
if (crtc->primary->current_release_timeline != NULL) {
|
||||||
state->base->signal_point, state->out_fence_fd);
|
wlr_drm_syncobj_timeline_import_sync_file(crtc->primary->current_release_timeline,
|
||||||
|
crtc->primary->current_release_point, state->out_fence_fd);
|
||||||
|
wlr_drm_syncobj_timeline_unref(crtc->primary->current_release_timeline);
|
||||||
|
crtc->primary->current_release_timeline = NULL;
|
||||||
|
crtc->primary->current_release_point = 0;
|
||||||
|
}
|
||||||
close(state->out_fence_fd);
|
close(state->out_fence_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,17 @@ static void drm_plane_finish_surface(struct wlr_drm_plane *plane) {
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_fb_clear(&plane->queued_fb);
|
drm_fb_clear(&plane->queued_fb);
|
||||||
|
if (plane->queued_release_timeline != NULL) {
|
||||||
|
wlr_drm_syncobj_timeline_signal(plane->queued_release_timeline, plane->queued_release_point);
|
||||||
|
wlr_drm_syncobj_timeline_unref(plane->queued_release_timeline);
|
||||||
|
plane->queued_release_timeline = NULL;
|
||||||
|
}
|
||||||
drm_fb_clear(&plane->current_fb);
|
drm_fb_clear(&plane->current_fb);
|
||||||
|
if (plane->current_release_timeline != NULL) {
|
||||||
|
wlr_drm_syncobj_timeline_signal(plane->current_release_timeline, plane->current_release_point);
|
||||||
|
wlr_drm_syncobj_timeline_unref(plane->current_release_timeline);
|
||||||
|
plane->current_release_timeline = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
finish_drm_surface(&plane->mgpu_surf);
|
finish_drm_surface(&plane->mgpu_surf);
|
||||||
}
|
}
|
||||||
|
|
@ -557,6 +567,18 @@ static void drm_connector_apply_commit(const struct wlr_drm_connector_state *sta
|
||||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||||
|
|
||||||
drm_fb_copy(&crtc->primary->queued_fb, state->primary_fb);
|
drm_fb_copy(&crtc->primary->queued_fb, state->primary_fb);
|
||||||
|
if (crtc->primary->queued_release_timeline != NULL) {
|
||||||
|
wlr_drm_syncobj_timeline_signal(crtc->primary->queued_release_timeline, crtc->primary->queued_release_point);
|
||||||
|
wlr_drm_syncobj_timeline_unref(crtc->primary->queued_release_timeline);
|
||||||
|
}
|
||||||
|
if (state->base->signal_timeline != NULL) {
|
||||||
|
crtc->primary->queued_release_timeline = wlr_drm_syncobj_timeline_ref(state->base->signal_timeline);
|
||||||
|
crtc->primary->queued_release_point = state->base->signal_point;
|
||||||
|
} else {
|
||||||
|
crtc->primary->queued_release_timeline = NULL;
|
||||||
|
crtc->primary->queued_release_point = 0;
|
||||||
|
}
|
||||||
|
|
||||||
crtc->primary->viewport = state->primary_viewport;
|
crtc->primary->viewport = state->primary_viewport;
|
||||||
if (crtc->cursor != NULL) {
|
if (crtc->cursor != NULL) {
|
||||||
drm_fb_copy(&crtc->cursor->queued_fb, state->cursor_fb);
|
drm_fb_copy(&crtc->cursor->queued_fb, state->cursor_fb);
|
||||||
|
|
@ -2019,6 +2041,14 @@ static void handle_page_flip(int fd, unsigned seq,
|
||||||
struct wlr_drm_plane *plane = conn->crtc->primary;
|
struct wlr_drm_plane *plane = conn->crtc->primary;
|
||||||
if (plane->queued_fb) {
|
if (plane->queued_fb) {
|
||||||
drm_fb_move(&plane->current_fb, &plane->queued_fb);
|
drm_fb_move(&plane->current_fb, &plane->queued_fb);
|
||||||
|
if (plane->current_release_timeline != NULL) {
|
||||||
|
wlr_drm_syncobj_timeline_signal(plane->current_release_timeline, plane->current_release_point);
|
||||||
|
wlr_drm_syncobj_timeline_unref(plane->current_release_timeline);
|
||||||
|
}
|
||||||
|
plane->current_release_timeline = plane->queued_release_timeline;
|
||||||
|
plane->current_release_point = plane->queued_release_point;
|
||||||
|
plane->queued_release_timeline = NULL;
|
||||||
|
plane->queued_release_point = 0;
|
||||||
}
|
}
|
||||||
if (conn->crtc->cursor && conn->crtc->cursor->queued_fb) {
|
if (conn->crtc->cursor && conn->crtc->cursor->queued_fb) {
|
||||||
drm_fb_move(&conn->crtc->cursor->current_fb,
|
drm_fb_move(&conn->crtc->cursor->current_fb,
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,12 @@ struct wlr_drm_plane {
|
||||||
|
|
||||||
/* Buffer submitted to the kernel, will be presented on next vblank */
|
/* Buffer submitted to the kernel, will be presented on next vblank */
|
||||||
struct wlr_drm_fb *queued_fb;
|
struct wlr_drm_fb *queued_fb;
|
||||||
|
struct wlr_drm_syncobj_timeline *queued_release_timeline;
|
||||||
|
uint64_t queued_release_point;
|
||||||
/* Buffer currently displayed on screen */
|
/* Buffer currently displayed on screen */
|
||||||
struct wlr_drm_fb *current_fb;
|
struct wlr_drm_fb *current_fb;
|
||||||
|
struct wlr_drm_syncobj_timeline *current_release_timeline;
|
||||||
|
uint64_t current_release_point;
|
||||||
/* Viewport belonging to the last committed fb */
|
/* Viewport belonging to the last committed fb */
|
||||||
struct wlr_drm_viewport viewport;
|
struct wlr_drm_viewport viewport;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue