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

@ -110,7 +110,7 @@ copy_icon_buffer(struct theme *theme, struct lab_data_buffer *icon_buffer)
int buffer_width = (double)width * scale;
int buffer_height = (double)height * scale;
struct lab_data_buffer *buffer = buffer_create_cairo(
buffer_width, buffer_height, 1.0, true);
buffer_width, buffer_height, 1.0);
cairo_t *cairo = buffer->cairo;
cairo_set_source_surface(cairo, icon.surface,
@ -1087,7 +1087,7 @@ rounded_rect(struct rounded_corner_ctx *ctx)
struct lab_data_buffer *buffer;
/* TODO: scale */
buffer = buffer_create_cairo(w, h, 1, /*free_on_destroy*/ true);
buffer = buffer_create_cairo(w, h, 1);
cairo_t *cairo = buffer->cairo;
cairo_surface_t *surf = cairo_get_target(cairo);
@ -1406,11 +1406,11 @@ create_shadows(struct theme *theme)
*/
if (visible_active_size > 0) {
theme->shadow_edge_active = buffer_create_cairo(
visible_active_size, 1, 1.0, true);
visible_active_size, 1, 1.0);
theme->shadow_corner_top_active = buffer_create_cairo(
total_active_size, total_active_size, 1.0, true);
total_active_size, total_active_size, 1.0);
theme->shadow_corner_bottom_active = buffer_create_cairo(
total_active_size, total_active_size, 1.0, true);
total_active_size, total_active_size, 1.0);
if (!theme->shadow_corner_top_active
|| !theme->shadow_corner_bottom_active
|| !theme->shadow_edge_active) {
@ -1420,11 +1420,11 @@ create_shadows(struct theme *theme)
}
if (visible_inactive_size > 0) {
theme->shadow_edge_inactive = buffer_create_cairo(
visible_inactive_size, 1, 1.0, true);
visible_inactive_size, 1, 1.0);
theme->shadow_corner_top_inactive = buffer_create_cairo(
total_inactive_size, total_inactive_size, 1.0, true);
total_inactive_size, total_inactive_size, 1.0);
theme->shadow_corner_bottom_inactive = buffer_create_cairo(
total_inactive_size, total_inactive_size, 1.0, true);
total_inactive_size, total_inactive_size, 1.0);
if (!theme->shadow_corner_top_inactive
|| !theme->shadow_corner_bottom_inactive
|| !theme->shadow_edge_inactive) {