mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-21 06:46:46 -04:00
Nuke wlr_client_buffer
This abstraction is incompatible with wlr_raster in every way, let's just use the client submitted buffers directly. This will regress a couple of things until wlr_raster has been fully integrated.
This commit is contained in:
parent
d8def1aa65
commit
ba8230b00a
9 changed files with 21 additions and 203 deletions
|
|
@ -1508,8 +1508,7 @@ static void handle_page_flip(int fd, unsigned seq,
|
||||||
* data between the GPUs, even if we were using the direct scanout
|
* data between the GPUs, even if we were using the direct scanout
|
||||||
* interface.
|
* interface.
|
||||||
*/
|
*/
|
||||||
if (!drm->parent && plane->current_fb &&
|
if (!drm->parent && plane->current_fb && false) {
|
||||||
wlr_client_buffer_get(plane->current_fb->wlr_buf)) {
|
|
||||||
present_flags |= WLR_OUTPUT_PRESENT_ZERO_COPY;
|
present_flags |= WLR_OUTPUT_PRESENT_ZERO_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,8 @@ static void render_surface(struct wlr_surface *surface,
|
||||||
struct render_data *rdata = data;
|
struct render_data *rdata = data;
|
||||||
struct wlr_output *output = rdata->output;
|
struct wlr_output *output = rdata->output;
|
||||||
|
|
||||||
struct wlr_texture *texture = wlr_surface_get_texture(surface);
|
struct wlr_texture *texture = wlr_texture_from_buffer(output->renderer,
|
||||||
|
surface->current.buffer);
|
||||||
if (texture == NULL) {
|
if (texture == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +78,8 @@ static void render_surface(struct wlr_surface *surface,
|
||||||
wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
|
wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1);
|
||||||
|
|
||||||
wlr_surface_send_frame_done(surface, rdata->when);
|
wlr_surface_send_frame_done(surface, rdata->when);
|
||||||
|
|
||||||
|
wlr_texture_destroy(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_handle_frame(struct wl_listener *listener, void *data) {
|
static void output_handle_frame(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
||||||
|
|
@ -132,50 +132,9 @@ bool wlr_buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags,
|
||||||
void **data, uint32_t *format, size_t *stride);
|
void **data, uint32_t *format, size_t *stride);
|
||||||
void wlr_buffer_end_data_ptr_access(struct wlr_buffer *buffer);
|
void wlr_buffer_end_data_ptr_access(struct wlr_buffer *buffer);
|
||||||
|
|
||||||
/**
|
|
||||||
* A client buffer.
|
|
||||||
*/
|
|
||||||
struct wlr_client_buffer {
|
|
||||||
struct wlr_buffer base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The buffer's texture, if any. A buffer will not have a texture if the
|
|
||||||
* client destroys the buffer before it has been released.
|
|
||||||
*/
|
|
||||||
struct wlr_texture *texture;
|
|
||||||
/**
|
|
||||||
* The buffer this client buffer was created from. NULL if destroyed.
|
|
||||||
*/
|
|
||||||
struct wlr_buffer *source;
|
|
||||||
|
|
||||||
// private state
|
|
||||||
|
|
||||||
struct wl_listener source_destroy;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a struct wlr_client_buffer from a given struct wlr_buffer by creating
|
|
||||||
* a texture from it, and copying its struct wl_resource.
|
|
||||||
*/
|
|
||||||
struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
|
|
||||||
struct wlr_renderer *renderer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a client buffer from a generic buffer. If the buffer isn't a client
|
|
||||||
* buffer, returns NULL.
|
|
||||||
*/
|
|
||||||
struct wlr_client_buffer *wlr_client_buffer_get(struct wlr_buffer *buffer);
|
|
||||||
/**
|
/**
|
||||||
* Check if a resource is a wl_buffer resource.
|
* Check if a resource is a wl_buffer resource.
|
||||||
*/
|
*/
|
||||||
bool wlr_resource_is_buffer(struct wl_resource *resource);
|
bool wlr_resource_is_buffer(struct wl_resource *resource);
|
||||||
/**
|
|
||||||
* Try to update the buffer's content.
|
|
||||||
*
|
|
||||||
* Fails if there's more than one reference to the buffer or if the texture
|
|
||||||
* isn't mutable.
|
|
||||||
*/
|
|
||||||
bool wlr_client_buffer_apply_damage(struct wlr_client_buffer *client_buffer,
|
|
||||||
struct wlr_buffer *next, pixman_region32_t *damage);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -89,13 +89,6 @@ struct wlr_surface_output {
|
||||||
struct wlr_surface {
|
struct wlr_surface {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wlr_renderer *renderer;
|
struct wlr_renderer *renderer;
|
||||||
/**
|
|
||||||
* The surface's buffer, if any. A surface has an attached buffer when it
|
|
||||||
* commits with a non-null buffer in its pending state. A surface will not
|
|
||||||
* have a buffer if it has never committed one, has committed a null buffer,
|
|
||||||
* or something went wrong with uploading the buffer.
|
|
||||||
*/
|
|
||||||
struct wlr_client_buffer *buffer;
|
|
||||||
/**
|
/**
|
||||||
* The buffer position, in surface-local units.
|
* The buffer position, in surface-local units.
|
||||||
*/
|
*/
|
||||||
|
|
@ -199,13 +192,6 @@ bool wlr_surface_set_role(struct wlr_surface *surface,
|
||||||
*/
|
*/
|
||||||
bool wlr_surface_has_buffer(struct wlr_surface *surface);
|
bool wlr_surface_has_buffer(struct wlr_surface *surface);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the texture of the buffer currently attached to this surface. Returns
|
|
||||||
* NULL if no buffer is currently attached or if something went wrong with
|
|
||||||
* uploading the buffer.
|
|
||||||
*/
|
|
||||||
struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the root of the subsurface tree for this surface. Can return NULL if
|
* Get the root of the subsurface tree for this surface. Can return NULL if
|
||||||
* a surface in the tree has been destroyed.
|
* a surface in the tree has been destroyed.
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,6 @@ static void output_cursor_render(struct wlr_output_cursor *cursor,
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
|
|
||||||
struct wlr_texture *texture = cursor->texture;
|
struct wlr_texture *texture = cursor->texture;
|
||||||
if (cursor->surface != NULL) {
|
|
||||||
texture = wlr_surface_get_texture(cursor->surface);
|
|
||||||
}
|
|
||||||
if (texture == NULL) {
|
if (texture == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +233,6 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
||||||
enum wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
enum wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
struct wlr_texture *texture = cursor->texture;
|
struct wlr_texture *texture = cursor->texture;
|
||||||
if (cursor->surface != NULL) {
|
if (cursor->surface != NULL) {
|
||||||
texture = wlr_surface_get_texture(cursor->surface);
|
|
||||||
scale = cursor->surface->current.scale;
|
scale = cursor->surface->current.scale;
|
||||||
transform = cursor->surface->current.transform;
|
transform = cursor->surface->current.transform;
|
||||||
}
|
}
|
||||||
|
|
@ -337,11 +333,8 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_texture *texture = cursor->texture;
|
|
||||||
if (cursor->surface != NULL) {
|
|
||||||
// TODO: try using the surface buffer directly
|
// TODO: try using the surface buffer directly
|
||||||
texture = wlr_surface_get_texture(cursor->surface);
|
struct wlr_texture *texture = cursor->texture;
|
||||||
}
|
|
||||||
|
|
||||||
// If the cursor was hidden or was a software cursor, the hardware
|
// If the cursor was hidden or was a software cursor, the hardware
|
||||||
// cursor position is outdated
|
// cursor position is outdated
|
||||||
|
|
@ -445,6 +438,17 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor,
|
||||||
struct wlr_surface *surface = cursor->surface;
|
struct wlr_surface *surface = cursor->surface;
|
||||||
assert(surface != NULL);
|
assert(surface != NULL);
|
||||||
|
|
||||||
|
wlr_texture_destroy(cursor->texture);
|
||||||
|
cursor->texture = NULL;
|
||||||
|
|
||||||
|
if (surface->current.buffer) {
|
||||||
|
cursor->texture = wlr_texture_from_buffer(cursor->output->renderer,
|
||||||
|
surface->current.buffer);
|
||||||
|
if (cursor->texture == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Some clients commit a cursor surface with a NULL buffer to hide it.
|
// Some clients commit a cursor surface with a NULL buffer to hide it.
|
||||||
cursor->enabled = wlr_surface_has_buffer(surface);
|
cursor->enabled = wlr_surface_has_buffer(surface);
|
||||||
cursor->width = surface->current.width * cursor->output->scale;
|
cursor->width = surface->current.width * cursor->output->scale;
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,9 @@ static void set_buffer_with_surface_state(struct wlr_scene_buffer *scene_buffer,
|
||||||
wlr_scene_buffer_set_dest_size(scene_buffer, state->width, state->height);
|
wlr_scene_buffer_set_dest_size(scene_buffer, state->width, state->height);
|
||||||
wlr_scene_buffer_set_transform(scene_buffer, state->transform);
|
wlr_scene_buffer_set_transform(scene_buffer, state->transform);
|
||||||
|
|
||||||
if (surface->buffer) {
|
if (surface->current.buffer) {
|
||||||
wlr_scene_buffer_set_buffer_with_damage(scene_buffer,
|
wlr_scene_buffer_set_buffer_with_damage(scene_buffer,
|
||||||
&surface->buffer->base, &surface->buffer_damage);
|
surface->current.buffer, &surface->buffer_damage);
|
||||||
} else {
|
} else {
|
||||||
wlr_scene_buffer_set_buffer(scene_buffer, NULL);
|
wlr_scene_buffer_set_buffer(scene_buffer, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -477,12 +477,6 @@ void wlr_scene_buffer_send_frame_done(struct wlr_scene_buffer *scene_buffer,
|
||||||
|
|
||||||
static struct wlr_texture *scene_buffer_get_texture(
|
static struct wlr_texture *scene_buffer_get_texture(
|
||||||
struct wlr_scene_buffer *scene_buffer, struct wlr_renderer *renderer) {
|
struct wlr_scene_buffer *scene_buffer, struct wlr_renderer *renderer) {
|
||||||
struct wlr_client_buffer *client_buffer =
|
|
||||||
wlr_client_buffer_get(scene_buffer->buffer);
|
|
||||||
if (client_buffer != NULL) {
|
|
||||||
return client_buffer->texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scene_buffer->texture != NULL) {
|
if (scene_buffer->texture != NULL) {
|
||||||
return scene_buffer->texture;
|
return scene_buffer->texture;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,54 +109,6 @@ bool wlr_resource_is_buffer(struct wl_resource *resource) {
|
||||||
return strcmp(wl_resource_get_class(resource), wl_buffer_interface.name) == 0;
|
return strcmp(wl_resource_get_class(resource), wl_buffer_interface.name) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_buffer_impl client_buffer_impl;
|
|
||||||
|
|
||||||
struct wlr_client_buffer *wlr_client_buffer_get(struct wlr_buffer *buffer) {
|
|
||||||
if (buffer->impl != &client_buffer_impl) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (struct wlr_client_buffer *)buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct wlr_client_buffer *client_buffer_from_buffer(
|
|
||||||
struct wlr_buffer *buffer) {
|
|
||||||
struct wlr_client_buffer *client_buffer = wlr_client_buffer_get(buffer);
|
|
||||||
assert(client_buffer != NULL);
|
|
||||||
return client_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);
|
|
||||||
free(client_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool client_buffer_get_dmabuf(struct wlr_buffer *buffer,
|
|
||||||
struct wlr_dmabuf_attributes *attribs) {
|
|
||||||
struct wlr_client_buffer *client_buffer = client_buffer_from_buffer(buffer);
|
|
||||||
|
|
||||||
if (client_buffer->source == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wlr_buffer_get_dmabuf(client_buffer->source, attribs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wlr_buffer_impl client_buffer_impl = {
|
|
||||||
.destroy = client_buffer_destroy,
|
|
||||||
.get_dmabuf = client_buffer_get_dmabuf,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void client_buffer_handle_source_destroy(struct wl_listener *listener,
|
|
||||||
void *data) {
|
|
||||||
struct wlr_client_buffer *client_buffer =
|
|
||||||
wl_container_of(listener, client_buffer, source_destroy);
|
|
||||||
wl_list_remove(&client_buffer->source_destroy.link);
|
|
||||||
wl_list_init(&client_buffer->source_destroy.link);
|
|
||||||
client_buffer->source = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct wlr_shm_client_buffer *shm_client_buffer_get_or_create(
|
static struct wlr_shm_client_buffer *shm_client_buffer_get_or_create(
|
||||||
struct wl_resource *resource);
|
struct wl_resource *resource);
|
||||||
static bool buffer_is_shm_client_buffer(struct wlr_buffer *buffer);
|
static bool buffer_is_shm_client_buffer(struct wlr_buffer *buffer);
|
||||||
|
|
@ -263,45 +215,6 @@ bool buffer_is_opaque(struct wlr_buffer *buffer) {
|
||||||
return !format_info->has_alpha;
|
return !format_info->has_alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to create texture");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_client_buffer *client_buffer =
|
|
||||||
calloc(1, sizeof(struct wlr_client_buffer));
|
|
||||||
if (client_buffer == NULL) {
|
|
||||||
wlr_texture_destroy(texture);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
wlr_buffer_init(&client_buffer->base, &client_buffer_impl,
|
|
||||||
texture->width, texture->height);
|
|
||||||
client_buffer->source = buffer;
|
|
||||||
client_buffer->texture = texture;
|
|
||||||
|
|
||||||
wl_signal_add(&buffer->events.destroy, &client_buffer->source_destroy);
|
|
||||||
client_buffer->source_destroy.notify = client_buffer_handle_source_destroy;
|
|
||||||
|
|
||||||
// Ensure the buffer will be released before being destroyed
|
|
||||||
wlr_buffer_lock(&client_buffer->base);
|
|
||||||
wlr_buffer_drop(&client_buffer->base);
|
|
||||||
|
|
||||||
return client_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wlr_client_buffer_apply_damage(struct wlr_client_buffer *client_buffer,
|
|
||||||
struct wlr_buffer *next, pixman_region32_t *damage) {
|
|
||||||
if (client_buffer->base.n_locks > 1) {
|
|
||||||
// Someone else still has a reference to the buffer
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wlr_texture_update_from_buffer(client_buffer->texture, next, damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wlr_buffer_impl shm_client_buffer_impl;
|
static const struct wlr_buffer_impl shm_client_buffer_impl;
|
||||||
|
|
||||||
static bool buffer_is_shm_client_buffer(struct wlr_buffer *buffer) {
|
static bool buffer_is_shm_client_buffer(struct wlr_buffer *buffer) {
|
||||||
|
|
|
||||||
|
|
@ -333,45 +333,15 @@ static void surface_state_move(struct wlr_surface_state *state,
|
||||||
static void surface_apply_damage(struct wlr_surface *surface) {
|
static void surface_apply_damage(struct wlr_surface *surface) {
|
||||||
if (surface->current.buffer == NULL) {
|
if (surface->current.buffer == NULL) {
|
||||||
// NULL commit
|
// NULL commit
|
||||||
if (surface->buffer != NULL) {
|
|
||||||
wlr_buffer_unlock(&surface->buffer->base);
|
|
||||||
}
|
|
||||||
surface->buffer = NULL;
|
|
||||||
surface->opaque = false;
|
surface->opaque = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->opaque = buffer_is_opaque(surface->current.buffer);
|
surface->opaque = buffer_is_opaque(surface->current.buffer);
|
||||||
|
|
||||||
if (surface->buffer != NULL) {
|
|
||||||
if (wlr_client_buffer_apply_damage(surface->buffer,
|
|
||||||
surface->current.buffer, &surface->buffer_damage)) {
|
|
||||||
wlr_buffer_unlock(surface->current.buffer);
|
|
||||||
surface->current.buffer = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_client_buffer *buffer = wlr_client_buffer_create(
|
|
||||||
surface->current.buffer, surface->renderer);
|
|
||||||
|
|
||||||
wlr_buffer_unlock(surface->current.buffer);
|
|
||||||
surface->current.buffer = NULL;
|
|
||||||
|
|
||||||
if (buffer == NULL) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to upload buffer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surface->buffer != NULL) {
|
|
||||||
wlr_buffer_unlock(&surface->buffer->base);
|
|
||||||
}
|
|
||||||
surface->buffer = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_update_opaque_region(struct wlr_surface *surface) {
|
static void surface_update_opaque_region(struct wlr_surface *surface) {
|
||||||
struct wlr_texture *texture = wlr_surface_get_texture(surface);
|
if (!wlr_surface_has_buffer(surface)) {
|
||||||
if (texture == NULL) {
|
|
||||||
pixman_region32_clear(&surface->opaque_region);
|
pixman_region32_clear(&surface->opaque_region);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -660,9 +630,6 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) {
|
||||||
pixman_region32_fini(&surface->external_damage);
|
pixman_region32_fini(&surface->external_damage);
|
||||||
pixman_region32_fini(&surface->opaque_region);
|
pixman_region32_fini(&surface->opaque_region);
|
||||||
pixman_region32_fini(&surface->input_region);
|
pixman_region32_fini(&surface->input_region);
|
||||||
if (surface->buffer != NULL) {
|
|
||||||
wlr_buffer_unlock(&surface->buffer->base);
|
|
||||||
}
|
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -716,15 +683,8 @@ static struct wlr_surface *surface_create(struct wl_client *client,
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface) {
|
|
||||||
if (surface->buffer == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return surface->buffer->texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wlr_surface_has_buffer(struct wlr_surface *surface) {
|
bool wlr_surface_has_buffer(struct wlr_surface *surface) {
|
||||||
return wlr_surface_get_texture(surface) != NULL;
|
return surface->current.buffer != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_surface_set_role(struct wlr_surface *surface,
|
bool wlr_surface_set_role(struct wlr_surface *surface,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue