]> git.mdlowis.com Git - proto/labwc.git/commitdiff
buffer: remove buffer->cairo
authortokyo4j <hrak1529@gmail.com>
Wed, 27 Nov 2024 21:58:17 +0000 (06:58 +0900)
committerHiroaki Yamamoto <hrak1529@gmail.com>
Thu, 28 Nov 2024 09:56:03 +0000 (18:56 +0900)
It's more common for cairo_t to have a temporary lifetime and it will
prevent accidentally reusing its previous state.

include/buffer.h
src/buffer.c
src/common/font.c
src/common/scaled-rect-buffer.c
src/img/img-svg.c
src/osd.c
src/theme.c
src/workspaces.c

index 7daa464328675f8775676744ade76a1a2639c0ca..52fa257316cd3d59a23b69ac45e396a6e141f1ac 100644 (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;
index 251f69308d73b5a2e42fef7b3038581863b3d9af..7b626bc9dc6abd4b8a163095f7b767beb67dc178 100644 (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;
 }
index ff984ce4a5563957eaf938c4896a55dd4e33d83e..f93e3e882e01de274b98ba7202b23154b163a047 100644 (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
index 43a81563f353a2e0422a4af78769d66b16713b36..a6778d95a853b94ead565d2943fc701425886a9c 100644 (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;
 }
 
index 9480ce56df1f21900fda5f01c53437d659b6dbf4..f217d72a158ace230d9e64af1aebdcc9e7795a5f 100644 (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);
 }
index ca5a705991522be8dfd91205f35780575cb749dd..24365f608bf4910ef5deaa2c722fcdcea7ed2b95 100644 (file)
--- a/src/osd.c
+++ b/src/osd.c
@@ -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);
index b49c6cc5f3dc83bd2bbaa652fb95a88cc47e7ae8..2a7111b28c904ea29db25689faa7e1ab865a9434 100644 (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;
 }
index 93bd0db67ce120646067ef80cd2dea141448b324..806f250fe8d8e1d8a559a265de575eda21e709f8 100644 (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(