mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-15 08:22:07 -04:00
backend/drm: Drop parent drm device
Compositors should instead blit to secondary drm devices themselves.
This commit is contained in:
parent
38d761c837
commit
dc7855f674
10 changed files with 13 additions and 310 deletions
|
|
@ -258,7 +258,7 @@ static struct wlr_backend *attempt_drm_backend(struct wlr_backend *backend, stru
|
|||
|
||||
struct wlr_backend *primary_drm = NULL;
|
||||
for (size_t i = 0; i < (size_t)num_gpus; ++i) {
|
||||
struct wlr_backend *drm = wlr_drm_backend_create(session, gpus[i], primary_drm);
|
||||
struct wlr_backend *drm = wlr_drm_backend_create(session, gpus[i]);
|
||||
if (!drm) {
|
||||
wlr_log(WLR_ERROR, "Failed to create DRM backend");
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -275,9 +275,9 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo
|
|||
}
|
||||
|
||||
int in_fence_fd = -1;
|
||||
if (state->wait_timeline != NULL) {
|
||||
in_fence_fd = wlr_drm_syncobj_timeline_export_sync_file(state->wait_timeline,
|
||||
state->wait_point);
|
||||
if (state->base->committed & WLR_OUTPUT_STATE_WAIT_TIMELINE) {
|
||||
in_fence_fd = wlr_drm_syncobj_timeline_export_sync_file(state->base->wait_timeline,
|
||||
state->base->wait_point);
|
||||
if (in_fence_fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,14 +49,9 @@ static void backend_destroy(struct wlr_backend *backend) {
|
|||
|
||||
wl_list_remove(&drm->session_destroy.link);
|
||||
wl_list_remove(&drm->session_active.link);
|
||||
wl_list_remove(&drm->parent_destroy.link);
|
||||
wl_list_remove(&drm->dev_change.link);
|
||||
wl_list_remove(&drm->dev_remove.link);
|
||||
|
||||
if (drm->parent) {
|
||||
finish_drm_renderer(&drm->mgpu_renderer);
|
||||
}
|
||||
|
||||
finish_drm_resources(drm);
|
||||
|
||||
struct wlr_drm_fb *fb, *fb_tmp;
|
||||
|
|
@ -104,11 +99,6 @@ bool wlr_backend_is_drm(struct wlr_backend *b) {
|
|||
return b->impl == &backend_impl;
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_drm_backend_get_parent(struct wlr_backend *backend) {
|
||||
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
|
||||
return drm->parent ? &drm->parent->backend : NULL;
|
||||
}
|
||||
|
||||
static void handle_session_active(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend *drm =
|
||||
wl_container_of(listener, drm, session_active);
|
||||
|
|
@ -159,16 +149,8 @@ static void handle_session_destroy(struct wl_listener *listener, void *data) {
|
|||
backend_destroy(&drm->backend);
|
||||
}
|
||||
|
||||
static void handle_parent_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend *drm =
|
||||
wl_container_of(listener, drm, parent_destroy);
|
||||
backend_destroy(&drm->backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
|
||||
struct wlr_device *dev, struct wlr_backend *parent) {
|
||||
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_device *dev) {
|
||||
assert(session && dev);
|
||||
assert(!parent || wlr_backend_is_drm(parent));
|
||||
|
||||
char *name = drmGetDeviceNameFromFd2(dev->fd);
|
||||
if (name == NULL) {
|
||||
|
|
@ -201,15 +183,6 @@ struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
|
|||
drm->fd = dev->fd;
|
||||
drm->name = name;
|
||||
|
||||
if (parent != NULL) {
|
||||
drm->parent = get_drm_backend_from_backend(parent);
|
||||
|
||||
drm->parent_destroy.notify = handle_parent_destroy;
|
||||
wl_signal_add(&parent->events.destroy, &drm->parent_destroy);
|
||||
} else {
|
||||
wl_list_init(&drm->parent_destroy.link);
|
||||
}
|
||||
|
||||
drm->dev_change.notify = handle_dev_change;
|
||||
wl_signal_add(&dev->events.change, &drm->dev_change);
|
||||
|
||||
|
|
@ -234,52 +207,17 @@ struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
|
|||
goto error_event;
|
||||
}
|
||||
|
||||
if (drm->parent) {
|
||||
if (!init_drm_renderer(drm, &drm->mgpu_renderer)) {
|
||||
wlr_log(WLR_ERROR, "Failed to initialize renderer");
|
||||
goto error_resources;
|
||||
}
|
||||
|
||||
// We'll perform a multi-GPU copy for all submitted buffers, we need
|
||||
// to be able to texture from them
|
||||
struct wlr_renderer *renderer = drm->mgpu_renderer.wlr_rend;
|
||||
const struct wlr_drm_format_set *texture_formats =
|
||||
wlr_renderer_get_texture_formats(renderer, WLR_BUFFER_CAP_DMABUF);
|
||||
if (texture_formats == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to query renderer texture formats");
|
||||
goto error_mgpu_renderer;
|
||||
}
|
||||
|
||||
// Forbid implicit modifiers, because their meaning changes from one
|
||||
// GPU to another.
|
||||
for (size_t i = 0; i < texture_formats->len; i++) {
|
||||
const struct wlr_drm_format *fmt = &texture_formats->formats[i];
|
||||
for (size_t j = 0; j < fmt->len; j++) {
|
||||
uint64_t mod = fmt->modifiers[j];
|
||||
if (mod == DRM_FORMAT_MOD_INVALID) {
|
||||
continue;
|
||||
}
|
||||
wlr_drm_format_set_add(&drm->mgpu_formats, fmt->format, mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drm->session_destroy.notify = handle_session_destroy;
|
||||
wl_signal_add(&session->events.destroy, &drm->session_destroy);
|
||||
|
||||
return &drm->backend;
|
||||
|
||||
error_mgpu_renderer:
|
||||
finish_drm_renderer(&drm->mgpu_renderer);
|
||||
error_resources:
|
||||
finish_drm_resources(drm);
|
||||
error_event:
|
||||
wl_list_remove(&drm->session_active.link);
|
||||
wl_event_source_remove(drm->drm_event);
|
||||
error_fd:
|
||||
wl_list_remove(&drm->dev_remove.link);
|
||||
wl_list_remove(&drm->dev_change.link);
|
||||
wl_list_remove(&drm->parent_destroy.link);
|
||||
wlr_session_close_file(drm->session, dev);
|
||||
free(drm->name);
|
||||
free(drm);
|
||||
|
|
|
|||
|
|
@ -65,15 +65,6 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (drm->parent) {
|
||||
if (drmGetCap(drm->parent->fd, DRM_CAP_PRIME, &cap) ||
|
||||
!(cap & DRM_PRIME_CAP_EXPORT)) {
|
||||
wlr_log(WLR_ERROR,
|
||||
"PRIME export not supported on primary GPU");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (drmSetClientCap(drm->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) {
|
||||
wlr_log(WLR_ERROR, "DRM universal planes unsupported");
|
||||
return false;
|
||||
|
|
@ -369,8 +360,6 @@ static 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->mgpu_surf);
|
||||
}
|
||||
|
||||
void finish_drm_resources(struct wlr_drm_backend *drm) {
|
||||
|
|
@ -709,52 +698,8 @@ static bool drm_connector_state_update_primary_fb(struct wlr_drm_connector *conn
|
|||
struct wlr_drm_plane *plane = crtc->primary;
|
||||
struct wlr_buffer *source_buf = state->base->buffer;
|
||||
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline = NULL;
|
||||
uint64_t wait_point = 0;
|
||||
if (state->base->committed & WLR_OUTPUT_STATE_WAIT_TIMELINE) {
|
||||
wait_timeline = state->base->wait_timeline;
|
||||
wait_point = state->base->wait_point;
|
||||
}
|
||||
assert(state->wait_timeline == NULL);
|
||||
|
||||
struct wlr_buffer *local_buf;
|
||||
if (drm->parent) {
|
||||
struct wlr_drm_format format = {0};
|
||||
if (!drm_plane_pick_render_format(plane, &format, &drm->mgpu_renderer)) {
|
||||
wlr_log(WLR_ERROR, "Failed to pick primary plane format");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: fallback to modifier-less buffer allocation
|
||||
bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer,
|
||||
source_buf->width, source_buf->height, &format);
|
||||
wlr_drm_format_finish(&format);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
local_buf = drm_surface_blit(&plane->mgpu_surf, source_buf,
|
||||
wait_timeline, wait_point);
|
||||
if (local_buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (plane->mgpu_surf.timeline != NULL) {
|
||||
state->wait_timeline = wlr_drm_syncobj_timeline_ref(plane->mgpu_surf.timeline);
|
||||
state->wait_point = plane->mgpu_surf.point;
|
||||
}
|
||||
} else {
|
||||
local_buf = wlr_buffer_lock(source_buf);
|
||||
|
||||
if (wait_timeline != NULL) {
|
||||
state->wait_timeline = wlr_drm_syncobj_timeline_ref(wait_timeline);
|
||||
state->wait_point = wait_point;
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = drm_fb_import(&state->primary_fb, drm, local_buf,
|
||||
bool ok = drm_fb_import(&state->primary_fb, drm, source_buf,
|
||||
&plane->formats);
|
||||
wlr_buffer_unlock(local_buf);
|
||||
if (!ok) {
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||
"Failed to import buffer for scan-out");
|
||||
|
|
@ -769,7 +714,7 @@ static bool drm_connector_set_pending_layer_fbs(struct wlr_drm_connector *conn,
|
|||
struct wlr_drm_backend *drm = conn->backend;
|
||||
|
||||
struct wlr_drm_crtc *crtc = conn->crtc;
|
||||
if (!crtc || drm->parent) {
|
||||
if (!crtc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -828,12 +773,6 @@ static bool drm_connector_prepare(struct wlr_drm_connector_state *conn_state, bo
|
|||
return false;
|
||||
}
|
||||
|
||||
if (test_only && conn->backend->parent) {
|
||||
// If we're running as a secondary GPU, we can't perform an atomic
|
||||
// commit without blitting a buffer.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||
if (!drm_connector_state_update_primary_fb(conn, conn_state)) {
|
||||
return false;
|
||||
|
|
@ -898,13 +837,6 @@ static bool drm_connector_commit_state(struct wlr_drm_connector *conn,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (test_only && conn->backend->parent) {
|
||||
// If we're running as a secondary GPU, we can't perform an atomic
|
||||
// commit without blitting a buffer.
|
||||
ok = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pending.active && conn->crtc == NULL) {
|
||||
// Disabling an already-disabled connector
|
||||
ok = true;
|
||||
|
|
@ -1094,28 +1026,7 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
|
|||
return false;
|
||||
}
|
||||
|
||||
struct wlr_buffer *local_buf;
|
||||
if (drm->parent) {
|
||||
struct wlr_drm_format format = {0};
|
||||
if (!drm_plane_pick_render_format(plane, &format, &drm->mgpu_renderer)) {
|
||||
wlr_log(WLR_ERROR, "Failed to pick cursor plane format");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = init_drm_surface(&plane->mgpu_surf, &drm->mgpu_renderer,
|
||||
buffer->width, buffer->height, &format);
|
||||
wlr_drm_format_finish(&format);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
local_buf = drm_surface_blit(&plane->mgpu_surf, buffer, NULL, 0);
|
||||
if (local_buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
local_buf = wlr_buffer_lock(buffer);
|
||||
}
|
||||
struct wlr_buffer *local_buf = wlr_buffer_lock(buffer);
|
||||
|
||||
bool ok = drm_fb_import(&conn->cursor_pending_fb, drm, local_buf,
|
||||
&plane->formats);
|
||||
|
|
@ -1209,9 +1120,6 @@ static const struct wlr_drm_format_set *drm_connector_get_cursor_formats(
|
|||
if (!plane) {
|
||||
return NULL;
|
||||
}
|
||||
if (conn->backend->parent) {
|
||||
return &conn->backend->mgpu_formats;
|
||||
}
|
||||
return &plane->formats;
|
||||
}
|
||||
|
||||
|
|
@ -1238,9 +1146,6 @@ static const struct wlr_drm_format_set *drm_connector_get_primary_formats(
|
|||
if (!drm_connector_alloc_crtc(conn)) {
|
||||
return NULL;
|
||||
}
|
||||
if (conn->backend->parent) {
|
||||
return &conn->backend->mgpu_formats;
|
||||
}
|
||||
return &conn->crtc->primary->formats;
|
||||
}
|
||||
|
||||
|
|
@ -1647,9 +1552,6 @@ static bool connect_drm_connector(struct wlr_drm_connector *wlr_conn,
|
|||
}
|
||||
|
||||
output->timeline = drm->iface != &legacy_iface;
|
||||
if (drm->parent) {
|
||||
output->timeline = output->timeline && drm->mgpu_renderer.wlr_rend->features.timeline;
|
||||
}
|
||||
|
||||
memset(wlr_conn->max_bpc_bounds, 0, sizeof(wlr_conn->max_bpc_bounds));
|
||||
if (wlr_conn->props.max_bpc != 0) {
|
||||
|
|
@ -2000,13 +1902,6 @@ bool commit_drm_device(struct wlr_drm_backend *drm,
|
|||
modeset |= output_state->base.allow_reconfiguration;
|
||||
}
|
||||
|
||||
if (test_only && drm->parent) {
|
||||
// If we're running as a secondary GPU, we can't perform an atomic
|
||||
// commit without blitting a buffer.
|
||||
ok = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (!test_only) {
|
||||
flags |= DRM_MODE_PAGE_FLIP_EVENT;
|
||||
|
|
@ -2039,7 +1934,8 @@ static void handle_page_flip(int fd, unsigned seq,
|
|||
conn->pending_page_flip = NULL;
|
||||
}
|
||||
|
||||
uint32_t present_flags = WLR_OUTPUT_PRESENT_HW_CLOCK | WLR_OUTPUT_PRESENT_HW_COMPLETION;
|
||||
uint32_t present_flags = WLR_OUTPUT_PRESENT_HW_CLOCK | WLR_OUTPUT_PRESENT_HW_COMPLETION |
|
||||
WLR_OUTPUT_PRESENT_ZERO_COPY;
|
||||
if (!page_flip->async) {
|
||||
present_flags |= WLR_OUTPUT_PRESENT_VSYNC;
|
||||
}
|
||||
|
|
@ -2074,14 +1970,6 @@ static void handle_page_flip(int fd, unsigned seq,
|
|||
drm_fb_move(&layer->current_fb, &layer->queued_fb);
|
||||
}
|
||||
|
||||
/* Don't report ZERO_COPY in multi-gpu situations, because we had to copy
|
||||
* data between the GPUs, even if we were using the direct scanout
|
||||
* interface.
|
||||
*/
|
||||
if (!drm->parent) {
|
||||
present_flags |= WLR_OUTPUT_PRESENT_ZERO_COPY;
|
||||
}
|
||||
|
||||
struct wlr_output_event_present present_event = {
|
||||
/* The DRM backend guarantees that the presentation event will be for
|
||||
* the last submitted frame. */
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ static void handle_add_drm_card(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Creating DRM backend for %s after hotplug", event->path);
|
||||
struct wlr_backend *child_drm = wlr_drm_backend_create(backend_monitor->session,
|
||||
dev, backend_monitor->primary_drm);
|
||||
struct wlr_backend *child_drm = wlr_drm_backend_create(backend_monitor->session, dev);
|
||||
if (!child_drm) {
|
||||
wlr_log(WLR_ERROR, "Failed to create DRM backend after hotplug");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -13,35 +13,6 @@
|
|||
#include "render/pixel_format.h"
|
||||
#include "render/wlr_renderer.h"
|
||||
|
||||
bool init_drm_renderer(struct wlr_drm_backend *drm,
|
||||
struct wlr_drm_renderer *renderer) {
|
||||
renderer->wlr_rend = renderer_autocreate_with_drm_fd(drm->fd);
|
||||
if (!renderer->wlr_rend) {
|
||||
wlr_log(WLR_ERROR, "Failed to create renderer");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t backend_caps = backend_get_buffer_caps(&drm->backend);
|
||||
renderer->allocator = allocator_autocreate_with_drm_fd(backend_caps,
|
||||
renderer->wlr_rend, drm->fd);
|
||||
if (renderer->allocator == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to create allocator");
|
||||
wlr_renderer_destroy(renderer->wlr_rend);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void finish_drm_renderer(struct wlr_drm_renderer *renderer) {
|
||||
if (!renderer) {
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_allocator_destroy(renderer->allocator);
|
||||
wlr_renderer_destroy(renderer->wlr_rend);
|
||||
}
|
||||
|
||||
void finish_drm_surface(struct wlr_drm_surface *surf) {
|
||||
if (!surf || !surf->renderer) {
|
||||
return;
|
||||
|
|
@ -85,62 +56,6 @@ bool init_drm_surface(struct wlr_drm_surface *surf,
|
|||
return true;
|
||||
}
|
||||
|
||||
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
|
||||
struct wlr_buffer *buffer,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) {
|
||||
struct wlr_renderer *renderer = surf->renderer->wlr_rend;
|
||||
|
||||
if (surf->swapchain->width != buffer->width ||
|
||||
surf->swapchain->height != buffer->height) {
|
||||
wlr_log(WLR_ERROR, "Surface size doesn't match buffer size");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_texture *tex = wlr_texture_from_buffer(renderer, buffer);
|
||||
if (tex == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to import source buffer into multi-GPU renderer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_buffer *dst = wlr_swapchain_acquire(surf->swapchain);
|
||||
if (!dst) {
|
||||
wlr_log(WLR_ERROR, "Failed to acquire multi-GPU swapchain buffer");
|
||||
goto error_tex;
|
||||
}
|
||||
|
||||
surf->point++;
|
||||
const struct wlr_buffer_pass_options pass_options = {
|
||||
.signal_timeline = surf->timeline,
|
||||
.signal_point = surf->point,
|
||||
};
|
||||
struct wlr_render_pass *pass = wlr_renderer_begin_buffer_pass(renderer, dst, &pass_options);
|
||||
if (pass == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to begin render pass with multi-GPU destination buffer");
|
||||
goto error_dst;
|
||||
}
|
||||
|
||||
wlr_render_pass_add_texture(pass, &(struct wlr_render_texture_options){
|
||||
.texture = tex,
|
||||
.blend_mode = WLR_RENDER_BLEND_MODE_NONE,
|
||||
.wait_timeline = wait_timeline,
|
||||
.wait_point = wait_point,
|
||||
});
|
||||
if (!wlr_render_pass_submit(pass)) {
|
||||
wlr_log(WLR_ERROR, "Failed to submit multi-GPU render pass");
|
||||
goto error_dst;
|
||||
}
|
||||
|
||||
wlr_texture_destroy(tex);
|
||||
|
||||
return dst;
|
||||
|
||||
error_dst:
|
||||
wlr_buffer_unlock(dst);
|
||||
error_tex:
|
||||
wlr_texture_destroy(tex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool drm_plane_pick_render_format(struct wlr_drm_plane *plane,
|
||||
struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer) {
|
||||
const struct wlr_drm_format_set *render_formats =
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ struct wlr_drm_plane {
|
|||
uint32_t type;
|
||||
uint32_t id;
|
||||
|
||||
/* Only initialized on multi-GPU setups */
|
||||
struct wlr_drm_surface mgpu_surf;
|
||||
|
||||
/* Buffer submitted to the kernel, will be presented on next vblank */
|
||||
struct wlr_drm_fb *queued_fb;
|
||||
/* Buffer currently displayed on screen */
|
||||
|
|
@ -80,7 +77,6 @@ struct wlr_drm_crtc {
|
|||
struct wlr_drm_backend {
|
||||
struct wlr_backend backend;
|
||||
|
||||
struct wlr_drm_backend *parent;
|
||||
const struct wlr_drm_interface *iface;
|
||||
bool addfb2_modifiers;
|
||||
|
||||
|
|
@ -99,7 +95,6 @@ struct wlr_drm_backend {
|
|||
|
||||
struct wl_listener session_destroy;
|
||||
struct wl_listener session_active;
|
||||
struct wl_listener parent_destroy;
|
||||
struct wl_listener dev_change;
|
||||
struct wl_listener dev_remove;
|
||||
|
||||
|
|
@ -108,15 +103,10 @@ struct wlr_drm_backend {
|
|||
|
||||
struct wl_list page_flips; // wlr_drm_page_flip.link
|
||||
|
||||
/* Only initialized on multi-GPU setups */
|
||||
struct wlr_drm_renderer mgpu_renderer;
|
||||
|
||||
struct wlr_session *session;
|
||||
|
||||
uint64_t cursor_width, cursor_height;
|
||||
|
||||
struct wlr_drm_format_set mgpu_formats;
|
||||
|
||||
bool supports_tearing_page_flips;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,19 +25,11 @@ struct wlr_drm_surface {
|
|||
uint64_t point;
|
||||
};
|
||||
|
||||
bool init_drm_renderer(struct wlr_drm_backend *drm,
|
||||
struct wlr_drm_renderer *renderer);
|
||||
void finish_drm_renderer(struct wlr_drm_renderer *renderer);
|
||||
|
||||
bool init_drm_surface(struct wlr_drm_surface *surf,
|
||||
struct wlr_drm_renderer *renderer, int width, int height,
|
||||
const struct wlr_drm_format *drm_format);
|
||||
void finish_drm_surface(struct wlr_drm_surface *surf);
|
||||
|
||||
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
|
||||
struct wlr_buffer *buffer,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point);
|
||||
|
||||
bool drm_plane_pick_render_format(struct wlr_drm_plane *plane,
|
||||
struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,21 +32,12 @@ struct wlr_drm_lease {
|
|||
/**
|
||||
* Creates a DRM backend using the specified GPU file descriptor (typically from
|
||||
* a device node in /dev/dri).
|
||||
*
|
||||
* To slave this to another DRM backend, pass it as the parent (which _must_ be
|
||||
* a DRM backend, other kinds of backends raise SIGABRT).
|
||||
*/
|
||||
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
|
||||
struct wlr_device *dev, struct wlr_backend *parent);
|
||||
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session, struct wlr_device *dev);
|
||||
|
||||
bool wlr_backend_is_drm(struct wlr_backend *backend);
|
||||
bool wlr_output_is_drm(struct wlr_output *output);
|
||||
|
||||
/**
|
||||
* Get the parent DRM backend, if any.
|
||||
*/
|
||||
struct wlr_backend *wlr_drm_backend_get_parent(struct wlr_backend *backend);
|
||||
|
||||
/**
|
||||
* Get the KMS connector object ID.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1070,15 +1070,6 @@ static bool devid_from_fd(int fd, dev_t *devid) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool is_secondary_drm_backend(struct wlr_backend *backend) {
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
return wlr_backend_is_drm(backend) &&
|
||||
wlr_drm_backend_get_parent(backend) != NULL;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feedback_v1 *feedback,
|
||||
const struct wlr_linux_dmabuf_feedback_v1_init_options *options) {
|
||||
assert(options->main_renderer != NULL);
|
||||
|
|
@ -1121,8 +1112,7 @@ bool wlr_linux_dmabuf_feedback_v1_init_with_options(struct wlr_linux_dmabuf_feed
|
|||
wlr_log(WLR_ERROR, "Failed to intersect renderer and scanout formats");
|
||||
goto error;
|
||||
}
|
||||
} else if (options->scanout_primary_output != NULL &&
|
||||
!is_secondary_drm_backend(options->scanout_primary_output->backend)) {
|
||||
} else if (options->scanout_primary_output != NULL) {
|
||||
int backend_drm_fd = wlr_backend_get_drm_fd(options->scanout_primary_output->backend);
|
||||
if (backend_drm_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to get backend DRM FD");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue