/* * This an unstable interface of wlroots. No guarantees are made regarding the * future consistency of this API. */ #ifndef WLR_USE_UNSTABLE #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" #endif #ifndef WLR_RENDER_WLR_TEXTURE_H #define WLR_RENDER_WLR_TEXTURE_H #include #include #include #include #include struct wlr_buffer; struct wlr_renderer; struct wlr_texture_impl; struct wlr_multi_gpu; struct wlr_texture { const struct wlr_texture_impl *impl; uint32_t width, height; struct wlr_renderer *renderer; }; struct wlr_texture_read_pixels_options { /** Memory location to read pixels into */ void *data; /** Format used for writing the pixel data */ uint32_t format; /** Stride in bytes for the data */ uint32_t stride; /** Destination offsets */ uint32_t dst_x, dst_y; /** Source box of the texture to read from. If empty, the full texture is assumed. */ const struct wlr_box src_box; }; bool wlr_texture_read_pixels(struct wlr_texture *texture, const struct wlr_texture_read_pixels_options *options); uint32_t wlr_texture_preferred_read_format(struct wlr_texture *texture); /** * Create a new texture from raw pixel data. `stride` is in bytes. The returned * texture is mutable. */ struct wlr_texture *wlr_texture_from_pixels(struct wlr_renderer *renderer, uint32_t fmt, uint32_t stride, uint32_t width, uint32_t height, const void *data); /** * Create a new texture from a DMA-BUF. The returned texture is immutable. */ struct wlr_texture *wlr_texture_from_dmabuf(struct wlr_renderer *renderer, struct wlr_dmabuf_attributes *attribs); /** * Update a texture with a struct wlr_buffer's contents. * * The update might be rejected (in case the texture is immutable, the buffer * has an unsupported type/format, etc), so callers must be prepared to fall * back to re-creating the texture from scratch via wlr_texture_from_buffer(). * * The damage can be used by the renderer as an optimization: only the supplied * region needs to be updated. */ bool wlr_texture_update_from_buffer(struct wlr_texture *texture, struct wlr_buffer *buffer, const pixman_region32_t *damage); /** * Destroys the texture. */ void wlr_texture_destroy(struct wlr_texture *texture); /** * Create a new texture from a buffer. */ 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