mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
backend/drm: add support for explicit sync APIs
This commit is contained in:
parent
26aa4f5f5c
commit
7aff45fa0d
5 changed files with 75 additions and 1 deletions
|
|
@ -1,6 +1,8 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <wlr/render/timeline.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
|
@ -202,6 +204,41 @@ error:
|
|||
atom->failed = true;
|
||||
}
|
||||
|
||||
static int set_plane_in_fence_fd(struct atomic *atom, struct wlr_drm_plane *plane,
|
||||
struct wlr_render_timeline *timeline, uint64_t src_point) {
|
||||
if (!plane->props.in_fence_fd) {
|
||||
wlr_log(WLR_ERROR, "Missing IN_FENCE_FD property");
|
||||
goto error;
|
||||
}
|
||||
|
||||
int sync_file_fd = wlr_render_timeline_export_sync_file(timeline, src_point);
|
||||
if (sync_file_fd < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
atomic_add(atom, plane->id, plane->props.in_fence_fd, sync_file_fd);
|
||||
|
||||
return sync_file_fd;
|
||||
|
||||
error:
|
||||
wlr_log(WLR_ERROR, "Failed to set plane %"PRIu32" IN_FENCE_FD", plane->id);
|
||||
atom->failed = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void set_crtc_out_fence_ptr(struct atomic *atom, struct wlr_drm_crtc *crtc,
|
||||
int *fd_ptr) {
|
||||
if (!crtc->props.out_fence_ptr) {
|
||||
wlr_log(WLR_ERROR,
|
||||
"CRTC %"PRIu32" is missing the OUT_FENCE_PTR property",
|
||||
crtc->id);
|
||||
atom->failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_add(atom, crtc->id, crtc->props.out_fence_ptr, (uintptr_t)fd_ptr);
|
||||
}
|
||||
|
||||
static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||
const struct wlr_drm_connector_state *state, uint32_t flags,
|
||||
bool test_only) {
|
||||
|
|
@ -273,6 +310,8 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
|||
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||
}
|
||||
|
||||
int in_fence_fd = -1, out_fence_fd = -1;
|
||||
|
||||
struct atomic atom;
|
||||
atomic_begin(&atom);
|
||||
atomic_add(&atom, conn->id, conn->props.crtc_id, active ? crtc->id : 0);
|
||||
|
|
@ -301,6 +340,13 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
|||
atomic_add(&atom, crtc->primary->id,
|
||||
crtc->primary->props.fb_damage_clips, fb_damage_clips);
|
||||
}
|
||||
if (state->base->committed & WLR_OUTPUT_STATE_WAIT_TIMELINE) {
|
||||
in_fence_fd = set_plane_in_fence_fd(&atom, crtc->primary,
|
||||
state->base->wait_timeline, state->base->wait_point);
|
||||
}
|
||||
if (state->base->committed & WLR_OUTPUT_STATE_SIGNAL_TIMELINE) {
|
||||
set_crtc_out_fence_ptr(&atom, crtc, &out_fence_fd);
|
||||
}
|
||||
if (crtc->cursor) {
|
||||
if (drm_connector_is_cursor_visible(conn)) {
|
||||
set_plane_props(&atom, drm, crtc->cursor, crtc->id,
|
||||
|
|
@ -340,6 +386,14 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
|||
wlr_log_errno(WLR_ERROR, "Failed to destroy FB_DAMAGE_CLIPS property blob");
|
||||
}
|
||||
|
||||
close(in_fence_fd);
|
||||
|
||||
if (out_fence_fd > 0) {
|
||||
ok = wlr_render_timeline_import_sync_file(state->base->signal_timeline,
|
||||
state->base->signal_point, out_fence_fd);
|
||||
close(out_fence_fd);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ static const uint32_t COMMIT_OUTPUT_STATE =
|
|||
WLR_OUTPUT_STATE_BUFFER |
|
||||
WLR_OUTPUT_STATE_MODE |
|
||||
WLR_OUTPUT_STATE_ENABLED |
|
||||
WLR_OUTPUT_STATE_GAMMA_LUT;
|
||||
WLR_OUTPUT_STATE_GAMMA_LUT |
|
||||
WLR_OUTPUT_STATE_WAIT_TIMELINE |
|
||||
WLR_OUTPUT_STATE_SIGNAL_TIMELINE;
|
||||
|
||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL | COMMIT_OUTPUT_STATE;
|
||||
|
|
@ -491,6 +493,13 @@ static bool drm_connector_test(struct wlr_output *output,
|
|||
}
|
||||
}
|
||||
|
||||
if ((output->pending.committed & (WLR_OUTPUT_STATE_WAIT_TIMELINE |
|
||||
WLR_OUTPUT_STATE_SIGNAL_TIMELINE)) && conn->backend->parent) {
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||
"Sync timelines are unsupported in multi-GPU mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_drm_connector_state pending = {0};
|
||||
drm_connector_state_init(&pending, conn, state);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,13 @@ static bool legacy_crtc_test(struct wlr_drm_connector *conn,
|
|||
}
|
||||
}
|
||||
|
||||
if (state->base->committed & (WLR_OUTPUT_STATE_WAIT_TIMELINE |
|
||||
WLR_OUTPUT_STATE_SIGNAL_TIMELINE)) {
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||
"Sync timelines are unsupported with legacy KMS interface");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ static const struct prop_info crtc_info[] = {
|
|||
{ "GAMMA_LUT", INDEX(gamma_lut) },
|
||||
{ "GAMMA_LUT_SIZE", INDEX(gamma_lut_size) },
|
||||
{ "MODE_ID", INDEX(mode_id) },
|
||||
{ "OUT_FENCE_PTR", INDEX(out_fence_ptr) },
|
||||
{ "VRR_ENABLED", INDEX(vrr_enabled) },
|
||||
#undef INDEX
|
||||
};
|
||||
|
|
@ -54,6 +55,7 @@ static const struct prop_info plane_info[] = {
|
|||
{ "CRTC_Y", INDEX(crtc_y) },
|
||||
{ "FB_DAMAGE_CLIPS", INDEX(fb_damage_clips) },
|
||||
{ "FB_ID", INDEX(fb_id) },
|
||||
{ "IN_FENCE_FD", INDEX(in_fence_fd) },
|
||||
{ "IN_FORMATS", INDEX(in_formats) },
|
||||
{ "SRC_H", INDEX(src_h) },
|
||||
{ "SRC_W", INDEX(src_w) },
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ union wlr_drm_crtc_props {
|
|||
|
||||
uint32_t active;
|
||||
uint32_t mode_id;
|
||||
uint32_t out_fence_ptr;
|
||||
};
|
||||
uint32_t props[6];
|
||||
};
|
||||
|
|
@ -64,6 +65,7 @@ union wlr_drm_plane_props {
|
|||
uint32_t fb_id;
|
||||
uint32_t crtc_id;
|
||||
uint32_t fb_damage_clips;
|
||||
uint32_t in_fence_fd;
|
||||
};
|
||||
uint32_t props[14];
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue