mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-18 06:47:31 -04:00
Replace wlr_client_buffer with wlr_surface_texture
wlr_client_buffer has a bad design: just because it needs some ref'counting functionality, it's implemented as a wlr_buffer. Its purpose is to allow compositors to obtain a frozen wlr_texture to keep painting an old representation of the surface for an arbitrary amount of time (e.g. during layout reconfigurations). However a wlr_buffer lock means something else entirely, and abusing it for ref'counting a texture leads to various issues. In particular, wlr_surface checks the wlr_client_buffer lock count to decide whether to mutate a texture on commit. This falls apart if the buffer is locked for another purpose than freezing a surface texture (e.g. locked by another wlroots helper). Additionally, wlr_client_buffer forces backends to re-import and re-check the buffer each time the client commits, since DMA-BUF wlr_client_buffers are destroyed and re-created on each commit. wlr_client_buffer also doesn't properly forward all wlr_buffer operations to the source buffer: some are unimplemented, and the source buffer is not locked by wlr_client_buffer thus may be destroyed anytime. To fix all of this mess, introduce a new struct wlr_surface_texture whose purpose is just to track whether a wlr_texture is frozen. Compositors can lock the texture to freeze it. The wlr_buffer can be accessed from wlr_surface_texture.buffer, or at surface commit time from wlr_surface.current.buffer.
This commit is contained in:
parent
119c634d94
commit
5f6b9e5620
3 changed files with 107 additions and 53 deletions
|
|
@ -119,16 +119,29 @@ struct wlr_surface_output {
|
|||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct wlr_surface_texture {
|
||||
struct wlr_texture *texture;
|
||||
// The buffer this surface texture was created from. NULL if released.
|
||||
struct wlr_buffer *buffer;
|
||||
// True if the texture won't be mutated by client surface commits.
|
||||
bool locked;
|
||||
|
||||
// private state
|
||||
|
||||
struct wl_listener buffer_release;
|
||||
bool dropped;
|
||||
};
|
||||
|
||||
struct wlr_surface {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_renderer *renderer; // may be NULL
|
||||
/**
|
||||
* The surface's buffer, if any. A surface has an attached buffer when it
|
||||
* The surface's texture, 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.
|
||||
* have a texture if it has never committed one, has committed a null
|
||||
* buffer, or something went wrong with uploading the buffer.
|
||||
*/
|
||||
struct wlr_client_buffer *buffer;
|
||||
struct wlr_surface_texture *texture;
|
||||
/**
|
||||
* The last commit's buffer damage, in buffer-local coordinates. This
|
||||
* contains both the damage accumulated by the client via
|
||||
|
|
@ -257,6 +270,9 @@ struct wlr_compositor {
|
|||
typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
|
||||
int sx, int sy, void *data);
|
||||
|
||||
void wlr_surface_texture_lock(struct wlr_surface_texture *surf_tex);
|
||||
void wlr_surface_texture_unlock(struct wlr_surface_texture *surf_tex);
|
||||
|
||||
/**
|
||||
* Set the lifetime role for this surface.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue