mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-17 06:46:39 -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);
|
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_texture *wlr_raster_obtain_texture_with_allocator(struct wlr_raster *raster,
|
||||||
struct wlr_renderer *renderer, struct wlr_allocator *allocator) {
|
struct wlr_renderer *renderer, struct wlr_allocator *allocator) {
|
||||||
struct wlr_texture *texture = wlr_raster_get_texture(raster, renderer);
|
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;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue