mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-22 07:02:28 +00:00
backend/drm: implement wlr_backend_impl.{test,commit}
This commit is contained in:
parent
d41b5efc65
commit
52e01a9c8b
@ -75,15 +75,29 @@ static int backend_get_drm_fd(struct wlr_backend *backend) {
|
|||||||
return drm->fd;
|
return drm->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t drm_backend_get_buffer_caps(struct wlr_backend *backend) {
|
static uint32_t backend_get_buffer_caps(struct wlr_backend *backend) {
|
||||||
return WLR_BUFFER_CAP_DMABUF;
|
return WLR_BUFFER_CAP_DMABUF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool backend_test(struct wlr_backend *backend,
|
||||||
|
const struct wlr_backend_output_state *states, size_t states_len) {
|
||||||
|
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
|
||||||
|
return commit_drm_device(drm, states, states_len, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool backend_commit(struct wlr_backend *backend,
|
||||||
|
const struct wlr_backend_output_state *states, size_t states_len) {
|
||||||
|
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
|
||||||
|
return commit_drm_device(drm, states, states_len, false);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wlr_backend_impl backend_impl = {
|
static const struct wlr_backend_impl backend_impl = {
|
||||||
.start = backend_start,
|
.start = backend_start,
|
||||||
.destroy = backend_destroy,
|
.destroy = backend_destroy,
|
||||||
.get_drm_fd = backend_get_drm_fd,
|
.get_drm_fd = backend_get_drm_fd,
|
||||||
.get_buffer_caps = drm_backend_get_buffer_caps,
|
.get_buffer_caps = backend_get_buffer_caps,
|
||||||
|
.test = backend_test,
|
||||||
|
.commit = backend_commit,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool wlr_backend_is_drm(struct wlr_backend *b) {
|
bool wlr_backend_is_drm(struct wlr_backend *b) {
|
||||||
|
@ -1870,6 +1870,73 @@ void restore_drm_device(struct wlr_drm_backend *drm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool commit_drm_device(struct wlr_drm_backend *drm,
|
||||||
|
const struct wlr_backend_output_state *output_states, size_t output_states_len,
|
||||||
|
bool test_only) {
|
||||||
|
if (!drm->session->active) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_drm_connector_state *conn_states = calloc(output_states_len, sizeof(conn_states[0]));
|
||||||
|
if (conn_states == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
bool modeset = false;
|
||||||
|
size_t conn_states_len = 0;
|
||||||
|
for (size_t i = 0; i < output_states_len; i++) {
|
||||||
|
const struct wlr_backend_output_state *output_state = &output_states[i];
|
||||||
|
struct wlr_output *output = output_state->output;
|
||||||
|
if (!output->enabled && !output_pending_enabled(output, &output_state->base)) {
|
||||||
|
// KMS rejects commits which disable already-disabled connectors
|
||||||
|
// and have the DRM_MODE_PAGE_FLIP_EVENT flag
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
|
||||||
|
|
||||||
|
if (output_pending_enabled(output, &output_state->base) && !drm_connector_alloc_crtc(conn)) {
|
||||||
|
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||||
|
"No CRTC available for this connector");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_drm_connector_state *conn_state = &conn_states[conn_states_len];
|
||||||
|
drm_connector_state_init(conn_state, conn, &output_state->base);
|
||||||
|
conn_states_len++;
|
||||||
|
|
||||||
|
if (!drm_connector_prepare(conn_state, test_only)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output_state->base.tearing_page_flip) {
|
||||||
|
wlr_log(WLR_DEBUG, "Tearing not supported for DRM device-wide commits");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
modeset |= output_state->base.allow_reconfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t flags = 0;
|
||||||
|
if (!test_only) {
|
||||||
|
flags |= DRM_MODE_PAGE_FLIP_EVENT;
|
||||||
|
}
|
||||||
|
struct wlr_drm_device_state dev_state = {
|
||||||
|
.modeset = modeset,
|
||||||
|
.connectors = conn_states,
|
||||||
|
.connectors_len = conn_states_len,
|
||||||
|
};
|
||||||
|
ok = drm_commit(drm, &dev_state, flags, test_only);
|
||||||
|
|
||||||
|
out:
|
||||||
|
for (size_t i = 0; i < conn_states_len; i++) {
|
||||||
|
drm_connector_state_finish(&conn_states[i]);
|
||||||
|
}
|
||||||
|
free(conn_states);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
static int mhz_to_nsec(int mhz) {
|
static int mhz_to_nsec(int mhz) {
|
||||||
return 1000000000000LL / mhz;
|
return 1000000000000LL / mhz;
|
||||||
}
|
}
|
||||||
|
@ -206,6 +206,8 @@ void finish_drm_resources(struct wlr_drm_backend *drm);
|
|||||||
void scan_drm_connectors(struct wlr_drm_backend *state,
|
void scan_drm_connectors(struct wlr_drm_backend *state,
|
||||||
struct wlr_device_hotplug_event *event);
|
struct wlr_device_hotplug_event *event);
|
||||||
void scan_drm_leases(struct wlr_drm_backend *drm);
|
void scan_drm_leases(struct wlr_drm_backend *drm);
|
||||||
|
bool commit_drm_device(struct wlr_drm_backend *drm,
|
||||||
|
const struct wlr_backend_output_state *states, size_t states_len, bool test_only);
|
||||||
void restore_drm_device(struct wlr_drm_backend *drm);
|
void restore_drm_device(struct wlr_drm_backend *drm);
|
||||||
int handle_drm_event(int fd, uint32_t mask, void *data);
|
int handle_drm_event(int fd, uint32_t mask, void *data);
|
||||||
void destroy_drm_connector(struct wlr_drm_connector *conn);
|
void destroy_drm_connector(struct wlr_drm_connector *conn);
|
||||||
|
Loading…
Reference in New Issue
Block a user