mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-17 06:46:39 -04:00
Merge branch 'dmabuf' into 'master'
Allow scanning out fullscreen surfaces on secondary GPUs See merge request wlroots/wlroots!4055
This commit is contained in:
commit
772265a81a
18 changed files with 782 additions and 76 deletions
|
|
@ -107,6 +107,7 @@ struct wlr_drm_backend {
|
|||
|
||||
/* Only initialized on multi-GPU setups */
|
||||
struct wlr_drm_renderer mgpu_renderer;
|
||||
struct wlr_multi_gpu *multi_gpu;
|
||||
|
||||
struct wlr_session *session;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ bool init_drm_surface(struct wlr_drm_surface *surf,
|
|||
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_renderer *parent_renderer, struct wlr_buffer *buffer);
|
||||
|
||||
bool drm_plane_pick_render_format(struct wlr_drm_plane *plane,
|
||||
struct wlr_drm_format *fmt, struct wlr_drm_renderer *renderer);
|
||||
|
|
|
|||
|
|
@ -4,10 +4,31 @@
|
|||
#include <wayland-util.h>
|
||||
#include <wlr/backend/interface.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
|
||||
struct wlr_multi_gpu_device {
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper struct for tracking multiple renderers. This solves the
|
||||
* problem of us having many renderers (primary, plus individual
|
||||
* secondary GPU drm renderers) but not tracking them in one location.
|
||||
* We can use this struct to access renderers for each GPU in
|
||||
* the system all from one place. Will be populated by the renderer
|
||||
* the compositor makes, plus every time a drm mgpu renderer is made.
|
||||
*/
|
||||
struct wlr_multi_gpu {
|
||||
struct wl_list devices;
|
||||
};
|
||||
|
||||
struct wlr_multi_backend {
|
||||
struct wlr_backend backend;
|
||||
|
||||
struct wlr_multi_gpu *multi_gpu;
|
||||
struct wl_list backends;
|
||||
|
||||
struct wl_listener event_loop_destroy;
|
||||
|
|
|
|||
|
|
@ -32,4 +32,7 @@ bool wlr_multi_is_empty(struct wlr_backend *backend);
|
|||
void wlr_multi_for_each_backend(struct wlr_backend *backend,
|
||||
void (*callback)(struct wlr_backend *backend, void *data), void *data);
|
||||
|
||||
struct wlr_multi_gpu *wlr_multi_gpu_create(void);
|
||||
void wlr_multi_gpu_destroy(struct wlr_multi_gpu *multi_gpu);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,13 +14,10 @@
|
|||
#include <wlr/render/pass.h>
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
|
||||
struct wlr_backend;
|
||||
struct wlr_renderer_impl;
|
||||
struct wlr_drm_format_set;
|
||||
struct wlr_buffer;
|
||||
struct wlr_box;
|
||||
struct wlr_fbox;
|
||||
|
||||
/**
|
||||
* A renderer for basic 2D operations.
|
||||
|
|
@ -39,6 +36,9 @@ struct wlr_renderer {
|
|||
// private state
|
||||
|
||||
const struct wlr_renderer_impl *impl;
|
||||
|
||||
/* The GPU list we are a part of, may be null if not created from multi backend */
|
||||
struct wlr_multi_gpu *multi_gpu;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
struct wlr_buffer;
|
||||
struct wlr_renderer;
|
||||
struct wlr_texture_impl;
|
||||
struct wlr_multi_gpu;
|
||||
|
||||
struct wlr_texture {
|
||||
const struct wlr_texture_impl *impl;
|
||||
|
|
@ -82,4 +83,123 @@ void wlr_texture_destroy(struct wlr_texture *texture);
|
|||
struct wlr_texture *wlr_texture_from_buffer(struct wlr_renderer *renderer,
|
||||
struct wlr_buffer *buffer);
|
||||
|
||||
struct wlr_texture_renderer_pair {
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_texture *texture;
|
||||
struct wlr_allocator *allocator;
|
||||
};
|
||||
|
||||
/**
|
||||
* The texture set provides a mapping between renderers and the texture
|
||||
* imported into them. You can use it to query a texture for a particular
|
||||
* renderer and it will handle importing and any blitting that needs to
|
||||
* take place.
|
||||
*/
|
||||
struct wlr_texture_set {
|
||||
/* The buffer this texture set was made from */
|
||||
struct wlr_buffer *buffer;
|
||||
struct wl_listener buffer_release;
|
||||
|
||||
/**
|
||||
* Index into pairings of the device that this texture directly
|
||||
* imports into. This texture is "native" to that device, and
|
||||
* will have to be blitted to other gpus.
|
||||
*
|
||||
* This will be -1 if no buffer has been imported yet.
|
||||
*/
|
||||
int32_t native_pair;
|
||||
struct wlr_multi_gpu *multi_gpu;
|
||||
/*
|
||||
* This will cache the result of creating a linear-layout version of
|
||||
* this texture on the native device. This can then be imported into
|
||||
* the other GPUs.
|
||||
*/
|
||||
uint32_t format;
|
||||
void *pixel_data;
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
/* This is the size of the pairings array */
|
||||
int pairing_count;
|
||||
struct wlr_texture_renderer_pair *pairings;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an empty texture set. When setting up our wlr_multi_gpu struct we put
|
||||
* all renderers into a list. This lets us iterate them from here. If this
|
||||
* request is made on a renderer not in the multi-GPU set, then the list will
|
||||
* be of length 1, and the renderer will be the only entry in the set.
|
||||
*
|
||||
* A buffer must be imported for this set to be used.
|
||||
*/
|
||||
struct wlr_texture_set *wlr_texture_set_create(struct wlr_renderer *renderer,
|
||||
struct wlr_allocator *allocator);
|
||||
|
||||
/**
|
||||
* Add a renderer to the set. This adds an entry to the set tracking this renderer
|
||||
* in the set's internal list. No texture is created for this renderer.
|
||||
*/
|
||||
void wlr_texture_set_add_renderer(struct wlr_texture_set *set, struct wlr_renderer *renderer,
|
||||
struct wlr_allocator *allocator);
|
||||
|
||||
/*
|
||||
* Imports a buffer into the texture set. This initializes the native_pair
|
||||
* internal state and returns true if the buffer was imported on at least one
|
||||
* of the renderers in the set.
|
||||
*
|
||||
* This should only be called once per texture set initialization.
|
||||
*/
|
||||
bool wlr_texture_set_import_buffer(struct wlr_texture_set *set, struct wlr_buffer *buffer);
|
||||
|
||||
/**
|
||||
* Create a new texture set from a DMA-BUF. The returned texture is immutable.
|
||||
* The dmabuf will be imported on only one of the mgpu renderers in the system,
|
||||
* no copies will be made. Returns NULL if the dmabuf could not be imported into
|
||||
* any renderer.
|
||||
*/
|
||||
struct wlr_texture_set *wlr_texture_set_from_dmabuf(struct wlr_renderer *renderer,
|
||||
struct wlr_dmabuf_attributes *attribs);
|
||||
|
||||
/**
|
||||
* Create a new texture set from a buffer.
|
||||
*/
|
||||
struct wlr_texture_set *wlr_texture_set_from_buffer(struct wlr_renderer *renderer,
|
||||
struct wlr_buffer *buffer);
|
||||
|
||||
/**
|
||||
* Request a wlr_texture for this resource that is compatible with the given
|
||||
* renderer. This allows for on-demand cross-GPU blits in multi-GPU setups.
|
||||
* The texture will have been imported into the renderer that corresponds to
|
||||
* its native device. If a texture is requeseted with a different renderer,
|
||||
* this function will perform a blit and return the appropriate texture.
|
||||
*
|
||||
* Textures are cached, so if multiple requests with a non-native renderer
|
||||
* are made there will be only one blit.
|
||||
*/
|
||||
struct wlr_texture *wlr_texture_set_get_tex_for_renderer(struct wlr_texture_set *set,
|
||||
struct wlr_renderer *renderer);
|
||||
|
||||
/**
|
||||
* Get the wlr_texture corresponding to the texture's local GPU. This is the GPU it
|
||||
* is directly importable into.
|
||||
*/
|
||||
struct wlr_texture *wlr_texture_set_get_native_texture(struct wlr_texture_set *set);
|
||||
|
||||
/**
|
||||
* Get the linear pixel data for the backing texture.
|
||||
*/
|
||||
void *wlr_texture_set_get_linear_data(struct wlr_texture_set *set);
|
||||
|
||||
/**
|
||||
* Update all textures in a set with the contents of the next buffer. This will call
|
||||
* wlr_texture_update_from_buffer for each texture in the set.
|
||||
*/
|
||||
bool wlr_texture_set_update_from_buffer(struct wlr_texture_set *set,
|
||||
struct wlr_buffer *next, const pixman_region32_t *damage);
|
||||
|
||||
/**
|
||||
* Destroys the texture set and all textures held inside it.
|
||||
*/
|
||||
void wlr_texture_set_destroy(struct wlr_texture_set *set);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ struct wlr_client_buffer {
|
|||
* 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;
|
||||
struct wlr_texture_set *texture_set;
|
||||
/**
|
||||
* The buffer this client buffer was created from. NULL if destroyed.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ struct wlr_linux_dmabuf_v1 {
|
|||
|
||||
int main_device_fd; // to sanity check FDs sent by clients, -1 if unavailable
|
||||
|
||||
// This is only set when the compositor isn't providing a custom renderer.
|
||||
struct wlr_renderer *main_renderer;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
bool (*check_dmabuf_callback)(struct wlr_dmabuf_attributes *attribs, void *data);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue