buffer: remove buffer->cairo

It's more common for cairo_t to have a temporary lifetime and it will
prevent accidentally reusing its previous state.
This commit is contained in:
tokyo4j 2024-11-28 06:58:17 +09:00 committed by Hiroaki Yamamoto
parent c48324975d
commit 4502d58eec
8 changed files with 39 additions and 22 deletions

View file

@ -34,7 +34,6 @@ struct lab_data_buffer {
bool surface_owns_data;
cairo_surface_t *surface;
cairo_t *cairo;
void *data;
uint32_t format; /* currently always DRM_FORMAT_ARGB8888 */
size_t stride;

View file

@ -45,7 +45,6 @@ static void
data_buffer_destroy(struct wlr_buffer *wlr_buffer)
{
struct lab_data_buffer *buffer = data_buffer_from_buffer(wlr_buffer);
cairo_destroy(buffer->cairo);
/* this also frees buffer->data if surface_owns_data == true */
cairo_surface_destroy(buffer->surface);
if (!buffer->surface_owns_data) {
@ -97,7 +96,6 @@ buffer_adopt_cairo_surface(cairo_surface_t *surface)
buffer->stride = cairo_image_surface_get_stride(buffer->surface);
buffer->logical_width = width;
buffer->logical_height = height;
buffer->cairo = cairo_create(surface);
buffer->surface_owns_data = true;
return buffer;
@ -167,7 +165,7 @@ buffer_convert_cairo_surface_for_icon(cairo_surface_t *surface,
buffer = buffer_create_cairo(logical.width,
logical.height, scale);
cairo_t *cairo = buffer->cairo;
cairo_t *cairo = cairo_create(buffer->surface);
cairo_scale(cairo, (double)logical.width / width,
(double)logical.height / height);
cairo_set_source_surface(cairo, surface, 0, 0);
@ -177,8 +175,9 @@ buffer_convert_cairo_surface_for_icon(cairo_surface_t *surface,
/* ensure pixel data is updated */
cairo_surface_flush(buffer->surface);
/* destroy original surface */
/* destroy original cairo surface & context */
cairo_surface_destroy(surface);
cairo_destroy(cairo);
}
return buffer;
@ -197,7 +196,6 @@ buffer_create_from_data(void *pixel_data, uint32_t width, uint32_t height,
buffer->stride = stride;
buffer->surface = cairo_image_surface_create_for_data(
pixel_data, CAIRO_FORMAT_ARGB32, width, height, stride);
buffer->cairo = cairo_create(buffer->surface);
buffer->surface_owns_data = false;
return buffer;
}

View file

@ -115,8 +115,8 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
return;
}
cairo_t *cairo = (*buffer)->cairo;
cairo_surface_t *surf = cairo_get_target(cairo);
cairo_surface_t *surf = (*buffer)->surface;
cairo_t *cairo = cairo_create(surf);
/*
* Fill with the background color first IF the background color
@ -171,6 +171,7 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
g_object_unref(layout);
cairo_surface_flush(surf);
cairo_destroy(cairo);
}
void

View file

@ -39,7 +39,7 @@ _create_buffer(struct scaled_scene_buffer *scaled_buffer, double scale)
return NULL;
}
cairo_t *cairo = buffer->cairo;
cairo_t *cairo = cairo_create(buffer->surface);
/* Clear background */
cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
@ -58,6 +58,8 @@ _create_buffer(struct scaled_scene_buffer *scaled_buffer, double scale)
set_cairo_color(cairo, self->border_color);
cairo_stroke(cairo);
cairo_destroy(cairo);
return buffer;
}

View file

@ -41,7 +41,7 @@ img_svg_load(const char *filename, struct lab_data_buffer **buffer, int size,
*buffer = buffer_create_cairo(size, size, scale);
cairo_surface_t *image = (*buffer)->surface;
cairo_t *cr = (*buffer)->cairo;
cairo_t *cr = cairo_create(image);
rsvg_handle_render_document(svg, cr, &viewport, &err);
if (err) {
@ -55,6 +55,7 @@ img_svg_load(const char *filename, struct lab_data_buffer **buffer, int size,
goto error;
}
cairo_surface_flush(image);
cairo_destroy(cr);
g_object_unref(svg);
return;
@ -62,5 +63,6 @@ img_svg_load(const char *filename, struct lab_data_buffer **buffer, int size,
error:
wlr_buffer_drop(&(*buffer)->base);
*buffer = NULL;
cairo_destroy(cr);
g_object_unref(svg);
}

View file

@ -354,8 +354,9 @@ display_osd(struct output *output, struct wl_array *views)
}
/* Render OSD image */
cairo_t *cairo = buffer->cairo;
cairo_t *cairo = cairo_create(buffer->surface);
render_osd(server, cairo, w, h, show_workspace, workspace_name, views);
cairo_destroy(cairo);
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_create(
output->osd_tree, &buffer->base);

View file

@ -80,7 +80,12 @@ zdrop(struct lab_data_buffer **buffer)
}
}
static struct lab_data_buffer *
struct icon_drawing_context {
struct lab_data_buffer *buffer;
cairo_t *cairo;
};
static struct icon_drawing_context
copy_icon_buffer(struct theme *theme, struct lab_data_buffer *icon_buffer)
{
assert(icon_buffer);
@ -110,7 +115,7 @@ copy_icon_buffer(struct theme *theme, struct lab_data_buffer *icon_buffer)
int buffer_height = (double)height * scale;
struct lab_data_buffer *buffer = buffer_create_cairo(
buffer_width, buffer_height, 1.0);
cairo_t *cairo = buffer->cairo;
cairo_t *cairo = cairo_create(buffer->surface);
cairo_set_source_surface(cairo, surface,
(buffer_width - icon_width) / 2, (buffer_height - icon_height) / 2);
@ -122,7 +127,10 @@ copy_icon_buffer(struct theme *theme, struct lab_data_buffer *icon_buffer)
*/
cairo_scale(cairo, scale, scale);
return buffer;
return (struct icon_drawing_context){
.buffer = buffer,
.cairo = cairo,
};
}
static void
@ -136,8 +144,9 @@ create_hover_fallback(struct theme *theme,
int width = theme->window_button_width;
int height = theme->window_button_height;
*hover_buffer = copy_icon_buffer(theme, icon_buffer);
cairo_t *cairo = (*hover_buffer)->cairo;
struct icon_drawing_context ctx = copy_icon_buffer(theme, icon_buffer);
*hover_buffer = ctx.buffer;
cairo_t *cairo = ctx.cairo;
/* Overlay (pre-multiplied alpha) */
float overlay_color[4] = { 0.15f, 0.15f, 0.15f, 0.3f};
@ -156,6 +165,7 @@ create_hover_fallback(struct theme *theme,
cairo_fill(cairo);
cairo_surface_flush(cairo_get_target(cairo));
cairo_destroy(cairo);
}
static void
@ -163,8 +173,9 @@ create_rounded_buffer(struct theme *theme, enum corner corner,
struct lab_data_buffer **rounded_buffer,
struct lab_data_buffer *icon_buffer)
{
*rounded_buffer = copy_icon_buffer(theme, icon_buffer);
cairo_t *cairo = (*rounded_buffer)->cairo;
struct icon_drawing_context ctx = copy_icon_buffer(theme, icon_buffer);
*rounded_buffer = ctx.buffer;
cairo_t *cairo = ctx.cairo;
int width = theme->window_button_width;
int height = theme->window_button_height;
@ -189,12 +200,13 @@ create_rounded_buffer(struct theme *theme, enum corner corner,
};
struct lab_data_buffer *mask_buffer = rounded_rect(&rounded_ctx);
cairo_set_operator(cairo, CAIRO_OPERATOR_DEST_IN);
cairo_set_source_surface(cairo, cairo_get_target(mask_buffer->cairo),
cairo_set_source_surface(cairo, mask_buffer->surface,
(corner == LAB_CORNER_TOP_LEFT) ? -margin_x : 0,
-margin_y);
cairo_paint(cairo);
cairo_surface_flush(cairo_get_target(cairo));
cairo_destroy(cairo);
wlr_buffer_drop(&mask_buffer->base);
}
@ -1088,8 +1100,8 @@ rounded_rect(struct rounded_corner_ctx *ctx)
/* TODO: scale */
buffer = buffer_create_cairo(w, h, 1);
cairo_t *cairo = buffer->cairo;
cairo_surface_t *surf = cairo_get_target(cairo);
cairo_surface_t *surf = buffer->surface;
cairo_t *cairo = cairo_create(surf);
/* set transparent background */
cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
@ -1231,6 +1243,7 @@ rounded_rect(struct rounded_corner_ctx *ctx)
out:
cairo_surface_flush(surf);
cairo_destroy(cairo);
return buffer;
}

View file

@ -90,7 +90,7 @@ _osd_update(struct server *server)
continue;
}
cairo = buffer->cairo;
cairo = cairo_create(buffer->surface);
/* Background */
set_cairo_color(cairo, theme->osd_bg_color);
@ -150,6 +150,7 @@ _osd_update(struct server *server)
g_object_unref(layout);
surface = cairo_get_target(cairo);
cairo_surface_flush(surface);
cairo_destroy(cairo);
if (!output->workspace_osd) {
output->workspace_osd = wlr_scene_buffer_create(