mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-17 06:46:39 -04:00
start using texture sets
There are really two main uses of texture sets: checking if a dmabuf is importable, and actually importing it for the client buffer's texture
This commit is contained in:
parent
a446e1801f
commit
0925a529ab
6 changed files with 54 additions and 19 deletions
|
|
@ -25,7 +25,7 @@ static struct wlr_client_buffer *client_buffer_from_buffer(
|
|||
static void client_buffer_destroy(struct wlr_buffer *buffer) {
|
||||
struct wlr_client_buffer *client_buffer = client_buffer_from_buffer(buffer);
|
||||
wl_list_remove(&client_buffer->source_destroy.link);
|
||||
wlr_texture_destroy(client_buffer->texture);
|
||||
wlr_texture_set_destroy(client_buffer->texture_set);
|
||||
free(client_buffer);
|
||||
}
|
||||
|
||||
|
|
@ -56,21 +56,21 @@ static void client_buffer_handle_source_destroy(struct wl_listener *listener,
|
|||
|
||||
struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
|
||||
struct wlr_renderer *renderer) {
|
||||
struct wlr_texture *texture = wlr_texture_from_buffer(renderer, buffer);
|
||||
if (texture == NULL) {
|
||||
struct wlr_texture_set *texture_set = wlr_texture_set_from_buffer(renderer, buffer);
|
||||
if (texture_set == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to create texture");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_client_buffer *client_buffer = calloc(1, sizeof(*client_buffer));
|
||||
if (client_buffer == NULL) {
|
||||
wlr_texture_destroy(texture);
|
||||
wlr_texture_set_destroy(texture_set);
|
||||
return NULL;
|
||||
}
|
||||
wlr_buffer_init(&client_buffer->base, &client_buffer_impl,
|
||||
texture->width, texture->height);
|
||||
buffer->width, buffer->height);
|
||||
client_buffer->source = buffer;
|
||||
client_buffer->texture = texture;
|
||||
client_buffer->texture_set = texture_set;
|
||||
|
||||
wl_signal_add(&buffer->events.destroy, &client_buffer->source_destroy);
|
||||
client_buffer->source_destroy.notify = client_buffer_handle_source_destroy;
|
||||
|
|
@ -89,5 +89,5 @@ bool wlr_client_buffer_apply_damage(struct wlr_client_buffer *client_buffer,
|
|||
return false;
|
||||
}
|
||||
|
||||
return wlr_texture_update_from_buffer(client_buffer->texture, next, damage);
|
||||
return wlr_texture_set_update_from_buffer(client_buffer->texture_set, next, damage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -878,7 +878,8 @@ static struct wlr_texture *scene_buffer_get_texture(
|
|||
struct wlr_client_buffer *client_buffer =
|
||||
wlr_client_buffer_get(scene_buffer->buffer);
|
||||
if (client_buffer != NULL) {
|
||||
return client_buffer->texture;
|
||||
return wlr_texture_set_get_tex_for_renderer(client_buffer->texture_set,
|
||||
renderer);
|
||||
}
|
||||
|
||||
scene_buffer->texture =
|
||||
|
|
|
|||
|
|
@ -445,7 +445,11 @@ static void surface_apply_damage(struct wlr_surface *surface) {
|
|||
}
|
||||
|
||||
static void surface_update_opaque_region(struct wlr_surface *surface) {
|
||||
if (!wlr_surface_has_buffer(surface)) {
|
||||
/*
|
||||
* The surface's client_buffer may not have a texture imported yet,
|
||||
* but if it has a texture set it is tracking a valid buffer.
|
||||
*/
|
||||
if (!wlr_surface_has_buffer(surface) || !surface->buffer->texture_set) {
|
||||
pixman_region32_clear(&surface->opaque_region);
|
||||
return;
|
||||
}
|
||||
|
|
@ -817,7 +821,8 @@ struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface) {
|
|||
if (surface->buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return surface->buffer->texture;
|
||||
return wlr_texture_set_get_tex_for_renderer(surface->buffer->texture_set,
|
||||
surface->renderer);
|
||||
}
|
||||
|
||||
bool wlr_surface_has_buffer(struct wlr_surface *surface) {
|
||||
|
|
|
|||
|
|
@ -211,16 +211,39 @@ static bool check_import_dmabuf(struct wlr_dmabuf_attributes *attribs, void *dat
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: check number of planes
|
||||
for (int i = 0; i < attribs->n_planes; i++) {
|
||||
uint32_t handle = 0;
|
||||
if (drmPrimeFDToHandle(linux_dmabuf->main_device_fd, attribs->fd[i], &handle) != 0) {
|
||||
wlr_log_errno(WLR_DEBUG, "Failed to import DMA-BUF FD");
|
||||
/*
|
||||
* Some compositors will be using this linux dmabuf manager with custom renderers,
|
||||
* while others will use a wlroots-managed wlr_renderer. When checking if a dmabuf
|
||||
* is valid for import we should treat these differently. In the first case we just
|
||||
* need to check if the dmabuf is importable into the DRM device, in the wlroots-managed
|
||||
* renderer case we should check if this dmabuf can be imported into the renderer.
|
||||
*
|
||||
* In the case where we have a wlr_renderer we need to check if a texture set can
|
||||
* be created in order to handle multi-gpu systems. The texture set will handle ensuring
|
||||
* that the dmabuf is importable on one GPU in the system, instead of only checking
|
||||
* the main device.
|
||||
*/
|
||||
if (linux_dmabuf->main_renderer) {
|
||||
struct wlr_texture_set *set=
|
||||
wlr_texture_set_from_dmabuf(linux_dmabuf->main_renderer, attribs);
|
||||
if (!set) {
|
||||
return false;
|
||||
}
|
||||
if (drmCloseBufferHandle(linux_dmabuf->main_device_fd, handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to close buffer handle");
|
||||
return false;
|
||||
// We can import the image, good. No need to keep it since wlr_surface will
|
||||
// import it again on commit.
|
||||
wlr_texture_set_destroy(set);
|
||||
} else {
|
||||
// TODO: check number of planes
|
||||
for (int i = 0; i < attribs->n_planes; i++) {
|
||||
uint32_t handle = 0;
|
||||
if (drmPrimeFDToHandle(linux_dmabuf->main_device_fd, attribs->fd[i], &handle) != 0) {
|
||||
wlr_log_errno(WLR_DEBUG, "Failed to import DMA-BUF FD");
|
||||
return false;
|
||||
}
|
||||
if (drmCloseBufferHandle(linux_dmabuf->main_device_fd, handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to close buffer handle");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1001,6 +1024,9 @@ struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_create_with_renderer(struct wl_d
|
|||
struct wlr_linux_dmabuf_v1 *linux_dmabuf =
|
||||
wlr_linux_dmabuf_v1_create(display, version, &feedback);
|
||||
wlr_linux_dmabuf_feedback_v1_finish(&feedback);
|
||||
|
||||
linux_dmabuf->main_renderer = renderer;
|
||||
|
||||
return linux_dmabuf;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue