buffer: reduce unnecessary painting to new cairo surfaces

Add buffer_adopt_cairo_surface(), which allows wrapping an existing
cairo image surface in a struct lab_data_buffer. This is useful when
loading PNGs since most will be loaded as ARGB32 already.

Fix a memory leak in the non-ARGB32 PNG case, where we do still need to
paint to a new image surface -- we were leaking the original surface.

Eliminate an unnecessary temporary image surface in SVG loading and just
render the SVG to the image surface held by the lab_data_buffer.

I also cleaned up and clarified the buffer API a bit:

- Add a pointer to the held cairo_surface_t (so we can still access it
  if there is no cairo_t).
- Remove the free_on_destroy bool (it was always true).
- Rename unscaled_width/height to logical_width/height and add an
  explanatory comment. It was unclear what "unscaled" meant.
- Rename buffer_create_wrap() to buffer_create_from_data().

This is laying groundwork for some more icon fixes I am working on
(making sure icons are loaded and rendered at the correct scale).
This commit is contained in:
John Lindgren 2024-10-06 01:42:54 -04:00 committed by Johan Malm
parent 328f873db3
commit d2b161bdf8
14 changed files with 123 additions and 84 deletions

View file

@ -84,7 +84,7 @@ _osd_update(struct server *server)
continue;
}
struct lab_data_buffer *buffer = buffer_create_cairo(width, height,
output->wlr_output->scale, true);
output->wlr_output->scale);
if (!buffer) {
wlr_log(WLR_ERROR, "Failed to allocate buffer for workspace OSD");
continue;
@ -168,7 +168,7 @@ _osd_update(struct server *server)
wlr_scene_node_set_position(&output->workspace_osd->node, lx, ly);
wlr_scene_buffer_set_buffer(output->workspace_osd, &buffer->base);
wlr_scene_buffer_set_dest_size(output->workspace_osd,
buffer->unscaled_width, buffer->unscaled_height);
buffer->logical_width, buffer->logical_height);
/* And finally drop the buffer so it will get destroyed on OSD hide */
wlr_buffer_drop(&buffer->base);