aboutsummaryrefslogtreecommitdiff
path: root/backend/drm
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2021-06-08 11:05:50 +0200
committerSimon Ser <contact@emersion.fr>2021-07-28 22:52:35 +0200
commitf5900c1f00f86078f576f5367f6cd707fdeec8c3 (patch)
tree137bd8e7ba70ec057e3bcb927751d76dc88551d8 /backend/drm
parent85d7ad2eef99b5ddc9da514231306c3678179f10 (diff)
backend/drm: remove primary swapchain
We can't nuke it completely, we still need it for multi-GPU.
Diffstat (limited to 'backend/drm')
-rw-r--r--backend/drm/drm.c146
-rw-r--r--backend/drm/renderer.c103
2 files changed, 52 insertions, 197 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index e6e45455..54b225a0 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -329,21 +329,6 @@ static struct wlr_drm_connector *get_drm_connector_from_output(
return (struct wlr_drm_connector *)wlr_output;
}
-static bool drm_connector_attach_render(struct wlr_output *output,
- int *buffer_age) {
- struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
- return drm_surface_make_current(&conn->crtc->primary->surf, buffer_age);
-}
-
-static void drm_plane_set_committed(struct wlr_drm_plane *plane) {
- drm_fb_move(&plane->queued_fb, &plane->pending_fb);
-
- if (plane->queued_fb && plane->surf.swapchain) {
- wlr_swapchain_set_buffer_submitted(plane->surf.swapchain,
- plane->queued_fb->wlr_buf);
- }
-}
-
static bool drm_crtc_commit(struct wlr_drm_connector *conn,
const struct wlr_output_state *state, uint32_t flags, bool test_only) {
// Disallow atomic-only flags
@@ -353,9 +338,9 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn,
struct wlr_drm_crtc *crtc = conn->crtc;
bool ok = drm->iface->crtc_commit(conn, state, flags, test_only);
if (ok && !test_only) {
- drm_plane_set_committed(crtc->primary);
+ drm_fb_move(&crtc->primary->queued_fb, &crtc->primary->pending_fb);
if (crtc->cursor != NULL) {
- drm_plane_set_committed(crtc->cursor);
+ drm_fb_move(&crtc->cursor->queued_fb, &crtc->cursor->pending_fb);
}
} else {
drm_fb_clear(&crtc->primary->pending_fb);
@@ -411,21 +396,37 @@ static bool drm_connector_set_pending_fb(struct wlr_drm_connector *conn,
struct wlr_drm_plane *plane = crtc->primary;
assert(state->committed & WLR_OUTPUT_STATE_BUFFER);
- switch (state->buffer_type) {
- case WLR_OUTPUT_STATE_BUFFER_RENDER:
- if (!drm_plane_lock_surface(plane, drm)) {
- wlr_drm_conn_log(conn, WLR_ERROR, "drm_plane_lock_surface failed");
+ assert(state->buffer_type == WLR_OUTPUT_STATE_BUFFER_SCANOUT);
+
+ struct wlr_buffer *local_buf;
+ if (drm->parent) {
+ struct wlr_drm_format *format =
+ drm_plane_pick_render_format(plane, &drm->renderer);
+ if (format == NULL) {
+ wlr_log(WLR_ERROR, "Failed to pick primary plane format");
return false;
}
- break;
- case WLR_OUTPUT_STATE_BUFFER_SCANOUT:;
- if (!drm_fb_import(&plane->pending_fb, drm, state->buffer,
- &crtc->primary->formats)) {
- wlr_drm_conn_log(conn, WLR_DEBUG,
- "Failed to import buffer for scan-out");
+
+ // TODO: fallback to modifier-less buffer allocation
+ bool ok = init_drm_surface(&plane->mgpu_surf, &drm->renderer,
+ state->buffer->width, state->buffer->height, format);
+ free(format);
+ if (!ok) {
return false;
}
- break;
+
+ local_buf = drm_surface_blit(&plane->mgpu_surf, state->buffer);
+ } else {
+ local_buf = wlr_buffer_lock(state->buffer);
+ }
+
+ bool ok = drm_fb_import(&plane->pending_fb, drm, local_buf,
+ &crtc->primary->formats);
+ wlr_buffer_unlock(local_buf);
+ if (!ok) {
+ wlr_drm_conn_log(conn, WLR_DEBUG,
+ "Failed to import buffer for scan-out");
+ return false;
}
return true;
@@ -572,11 +573,6 @@ static bool drm_connector_commit(struct wlr_output *output) {
return drm_connector_commit_state(conn, &output->pending);
}
-static void drm_connector_rollback_render(struct wlr_output *output) {
- struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
- return drm_surface_unset_current(&conn->crtc->primary->surf);
-}
-
size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm,
struct wlr_drm_crtc *crtc) {
if (crtc->props.gamma_lut_size == 0 || drm->iface == &legacy_iface) {
@@ -615,34 +611,6 @@ struct wlr_drm_fb *plane_get_next_fb(struct wlr_drm_plane *plane) {
return plane->current_fb;
}
-static bool drm_connector_test_renderer(struct wlr_drm_connector *conn,
- const struct wlr_output_state *state) {
- struct wlr_drm_backend *drm = conn->backend;
-
- if (drm->iface == &legacy_iface) {
- return true;
- }
-
- struct wlr_drm_plane *plane = conn->crtc->primary;
-
- struct wlr_drm_fb *prev_fb = NULL;
- drm_fb_move(&prev_fb, &plane->pending_fb);
-
- bool ok = false;
- if (!drm_surface_render_black_frame(&plane->surf)) {
- goto out;
- }
- if (!drm_plane_lock_surface(plane, drm)) {
- goto out;
- }
-
- ok = drm_crtc_commit(conn, state, 0, true);
-
-out:
- drm_fb_move(&plane->pending_fb, &prev_fb);
- return ok;
-}
-
static bool drm_connector_init_renderer(struct wlr_drm_connector *conn,
const struct wlr_output_state *state) {
struct wlr_drm_backend *drm = conn->backend;
@@ -654,37 +622,33 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn,
assert(conn->crtc != NULL);
- wlr_drm_conn_log(conn, WLR_DEBUG, "Initializing renderer");
+ if (drm->parent) {
+ wlr_drm_conn_log(conn, WLR_DEBUG, "Initializing multi-GPU renderer");
- drmModeModeInfo mode = {0};
- drm_connector_state_mode(conn, state, &mode);
+ drmModeModeInfo mode = {0};
+ drm_connector_state_mode(conn, state, &mode);
- struct wlr_drm_plane *plane = conn->crtc->primary;
- int width = mode.hdisplay;
- int height = mode.vdisplay;
-
- if (drm->addfb2_modifiers) {
- // Modifiers are supported, try to use them
- if (drm_plane_init_surface(plane, drm, width, height, true) &&
- drm_connector_test_renderer(conn, state)) {
- return true;
- }
+ struct wlr_drm_plane *plane = conn->crtc->primary;
+ int width = mode.hdisplay;
+ int height = mode.vdisplay;
- // If page-flipping with modifiers enabled doesn't work, retry without
- // modifiers
- wlr_drm_conn_log(conn, WLR_INFO,
- "Page-flip failed with primary FB modifiers enabled, "
- "retrying without modifiers");
- }
+ struct wlr_drm_format *format =
+ drm_plane_pick_render_format(plane, &drm->renderer);
+ if (format == NULL) {
+ wlr_log(WLR_ERROR, "Failed to pick primary plane format");
+ return false;
+ }
- if (drm_plane_init_surface(plane, drm, width, height, false) &&
- drm_connector_test_renderer(conn, state)) {
- return true;
+ // TODO: fallback to modifier-less buffer allocation
+ bool ok = init_drm_surface(&plane->mgpu_surf, &drm->renderer,
+ width, height, format);
+ free(format);
+ if (!ok) {
+ return false;
+ }
}
- wlr_drm_conn_log(conn, WLR_ERROR, "Failed to initialize renderer: "
- "initial page-flip failed");
- return false;
+ return true;
}
static void realloc_crtcs(struct wlr_drm_backend *drm);
@@ -778,12 +742,8 @@ static bool drm_connector_set_mode(struct wlr_drm_connector *conn,
// drm_crtc_page_flip expects a FB to be available
struct wlr_drm_plane *plane = conn->crtc->primary;
if (!plane_get_next_fb(plane)) {
- if (!drm_surface_render_black_frame(&plane->surf)) {
- return false;
- }
- if (!drm_plane_lock_surface(plane, drm)) {
- return false;
- }
+ wlr_drm_conn_log(conn, WLR_ERROR, "Missing FB in modeset");
+ return false;
}
if (!drm_crtc_page_flip(conn, state)) {
@@ -1023,10 +983,8 @@ static const struct wlr_output_impl output_impl = {
.set_cursor = drm_connector_set_cursor,
.move_cursor = drm_connector_move_cursor,
.destroy = drm_connector_destroy_output,
- .attach_render = drm_connector_attach_render,
.test = drm_connector_test,
.commit = drm_connector_commit,
- .rollback_render = drm_connector_rollback_render,
.get_gamma_size = drm_connector_get_gamma_size,
.get_cursor_formats = drm_connector_get_cursor_formats,
.get_cursor_size = drm_connector_get_cursor_size,
diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c
index 5c38f8fb..2d3adfd4 100644
--- a/backend/drm/renderer.c
+++ b/backend/drm/renderer.c
@@ -176,22 +176,9 @@ void drm_plane_finish_surface(struct wlr_drm_plane *plane) {
drm_fb_clear(&plane->queued_fb);
drm_fb_clear(&plane->current_fb);
- finish_drm_surface(&plane->surf);
finish_drm_surface(&plane->mgpu_surf);
}
-static struct wlr_drm_format *create_linear_format(uint32_t format) {
- struct wlr_drm_format *fmt = wlr_drm_format_create(format);
- if (fmt == NULL) {
- return NULL;
- }
- if (!wlr_drm_format_add(&fmt, DRM_FORMAT_MOD_LINEAR)) {
- free(fmt);
- return NULL;
- }
- return fmt;
-}
-
struct wlr_drm_format *drm_plane_pick_render_format(
struct wlr_drm_plane *plane, struct wlr_drm_renderer *renderer) {
const struct wlr_drm_format_set *render_formats =
@@ -238,53 +225,6 @@ struct wlr_drm_format *drm_plane_pick_render_format(
return format;
}
-bool drm_plane_init_surface(struct wlr_drm_plane *plane,
- struct wlr_drm_backend *drm, int32_t width, uint32_t height,
- bool with_modifiers) {
- struct wlr_drm_format *format =
- drm_plane_pick_render_format(plane, &drm->renderer);
- if (format == NULL) {
- wlr_log(WLR_ERROR, "Failed to pick render format for plane %"PRIu32,
- plane->id);
- return false;
- }
-
- if (!with_modifiers) {
- struct wlr_drm_format *format_implicit_modifier =
- wlr_drm_format_create(format->format);
- free(format);
- format = format_implicit_modifier;
- }
-
- drm_plane_finish_surface(plane);
-
- bool ok = true;
- if (!drm->parent) {
- ok = init_drm_surface(&plane->surf, &drm->renderer,
- width, height, format);
- } else {
- struct wlr_drm_format *format_linear = create_linear_format(format->format);
- if (format_linear == NULL) {
- free(format);
- return false;
- }
-
- ok = init_drm_surface(&plane->surf, &drm->parent->renderer,
- width, height, format_linear);
- free(format_linear);
-
- if (ok && !init_drm_surface(&plane->mgpu_surf, &drm->renderer,
- width, height, format)) {
- finish_drm_surface(&plane->surf);
- ok = false;
- }
- }
-
- free(format);
-
- return ok;
-}
-
void drm_fb_clear(struct wlr_drm_fb **fb_ptr) {
if (*fb_ptr == NULL) {
return;
@@ -296,36 +236,6 @@ void drm_fb_clear(struct wlr_drm_fb **fb_ptr) {
*fb_ptr = NULL;
}
-bool drm_plane_lock_surface(struct wlr_drm_plane *plane,
- struct wlr_drm_backend *drm) {
- assert(plane->surf.back_buffer != NULL);
- struct wlr_buffer *buf = wlr_buffer_lock(plane->surf.back_buffer);
-
- // Unset the current EGL context ASAP, because other operations may require
- // making another context current.
- drm_surface_unset_current(&plane->surf);
-
- struct wlr_buffer *local_buf;
- if (drm->parent) {
- // Perform a copy across GPUs
- local_buf = drm_surface_blit(&plane->mgpu_surf, buf);
- if (!local_buf) {
- wlr_log(WLR_ERROR, "Failed to blit buffer across GPUs");
- return false;
- }
- } else {
- local_buf = wlr_buffer_lock(buf);
- }
- wlr_buffer_unlock(buf);
-
- bool ok = drm_fb_import(&plane->pending_fb, drm, local_buf, NULL);
- if (!ok) {
- wlr_log(WLR_ERROR, "Failed to import buffer");
- }
- wlr_buffer_unlock(local_buf);
- return ok;
-}
-
static struct gbm_bo *get_bo_for_dmabuf(struct gbm_device *gbm,
struct wlr_dmabuf_attributes *attribs) {
if (attribs->modifier != DRM_FORMAT_MOD_INVALID ||
@@ -478,16 +388,3 @@ void drm_fb_move(struct wlr_drm_fb **new, struct wlr_drm_fb **old) {
*new = *old;
*old = NULL;
}
-
-bool drm_surface_render_black_frame(struct wlr_drm_surface *surf) {
- if (!drm_surface_make_current(surf, NULL)) {
- return false;
- }
-
- struct wlr_renderer *renderer = surf->renderer->wlr_rend;
- wlr_renderer_begin(renderer, surf->width, surf->height);
- wlr_renderer_clear(renderer, (float[]){ 0.0, 0.0, 0.0, 1.0 });
- wlr_renderer_end(renderer);
-
- return true;
-}