mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-14 08:22:25 -04:00
wlr_raster: Implement CPU blits
We need this really slow path if the user is using GPUs that don't have common compatible modifiers. One example of a vendor that doesn't support rendering to a LINEAR modifier (which otherwise should always exist) is NVIDIA.
This commit is contained in:
parent
df20cd28d0
commit
21b04a8c7f
1 changed files with 48 additions and 0 deletions
|
|
@ -298,6 +298,47 @@ static struct wlr_texture *raster_try_texture_from_blit(struct wlr_raster *raste
|
|||
return wlr_texture_from_buffer(renderer, imported);
|
||||
}
|
||||
|
||||
static struct wlr_texture *raster_try_cpu_copy(struct wlr_raster *raster,
|
||||
struct wlr_renderer *dst) {
|
||||
if (wl_list_empty(&raster->sources)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Performing multigpu blit through the CPU");
|
||||
struct wlr_texture *texture = NULL;
|
||||
|
||||
uint32_t format = DRM_FORMAT_ARGB8888;
|
||||
uint32_t stride = raster->width * 4;
|
||||
void *data = malloc(stride * raster->height);
|
||||
if (!data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_raster_source *source;
|
||||
wl_list_for_each(source, &raster->sources, link) {
|
||||
if (!wlr_texture_read_pixels(source->texture, &(struct wlr_texture_read_pixels_options){
|
||||
.format = format,
|
||||
.stride = stride,
|
||||
.data = data,
|
||||
})) {
|
||||
wlr_log(WLR_ERROR, "Failed to read pixels");
|
||||
continue;
|
||||
}
|
||||
|
||||
texture = wlr_texture_from_pixels(dst, format,
|
||||
stride, raster->width, raster->height, data);
|
||||
if (!texture) {
|
||||
wlr_log(WLR_ERROR, "Failed to upload texture from cpu data");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
free(data);
|
||||
return texture;
|
||||
}
|
||||
|
||||
struct wlr_texture *wlr_raster_obtain_texture_with_allocator(struct wlr_raster *raster,
|
||||
struct wlr_renderer *renderer, struct wlr_allocator *allocator) {
|
||||
struct wlr_texture *texture = wlr_raster_get_texture(raster, renderer);
|
||||
|
|
@ -327,6 +368,13 @@ struct wlr_texture *wlr_raster_obtain_texture_with_allocator(struct wlr_raster *
|
|||
return texture;
|
||||
}
|
||||
|
||||
// as a last resort we need to do a copy through the CPU
|
||||
texture = raster_try_cpu_copy(raster, renderer);
|
||||
if (texture) {
|
||||
raster_attach_with_allocator(raster, texture, allocator);
|
||||
return texture;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue