struct lab_data_buffer {
struct wlr_buffer base;
- cairo_surface_t *surface; /* optional */
- cairo_t *cairo; /* optional */
- void *data; /* owned by surface if surface != NULL */
- uint32_t format;
+ bool surface_owns_data;
+ cairo_surface_t *surface;
+ cairo_t *cairo;
+ void *data;
+ uint32_t format; /* currently always DRM_FORMAT_ARGB8888 */
size_t stride;
/*
* The logical size of the surface in layout pixels.
* CAIRO_FORMAT_ARGB32 image surface.
*
* The logical size is set to the surface size in pixels, ignoring
- * device scale. No cairo context is created.
+ * device scale.
*/
struct lab_data_buffer *buffer_adopt_cairo_surface(cairo_surface_t *surface);
* in pre-multiplied ARGB32 format.
*
* The logical size is set to the width and height of the pixel data.
- * No cairo surface or context is created.
*/
struct lab_data_buffer *buffer_create_from_data(void *pixel_data, uint32_t width,
uint32_t height, uint32_t stride);
struct lab_data_buffer;
-struct surface_context {
- bool is_duplicate;
- cairo_surface_t *surface;
-};
-
-struct surface_context get_cairo_surface_from_lab_data_buffer(
- struct lab_data_buffer *buffer);
-
#endif /* LABWC_GRAPHIC_HELPERS_H */
data_buffer_destroy(struct wlr_buffer *wlr_buffer)
{
struct lab_data_buffer *buffer = data_buffer_from_buffer(wlr_buffer);
- if (buffer->cairo) {
- cairo_destroy(buffer->cairo);
- }
- if (buffer->surface) {
- /* this also frees buffer->data */
- cairo_surface_destroy(buffer->surface);
- } else if (buffer->data) {
+ cairo_destroy(buffer->cairo);
+ /* this also frees buffer->data if surface_owns_data == true */
+ cairo_surface_destroy(buffer->surface);
+ if (!buffer->surface_owns_data) {
free(buffer->data);
- buffer->data = NULL;
}
free(buffer);
}
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;
}
struct lab_data_buffer *buffer = buffer_adopt_cairo_surface(surface);
buffer->logical_width = logical_width;
buffer->logical_height = logical_height;
- buffer->cairo = cairo_create(surface);
return buffer;
}
buffer->data = pixel_data;
buffer->format = DRM_FORMAT_ARGB8888;
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;
}
cairo_set_source_rgba(cairo, c[0] / alpha, c[1] / alpha,
c[2] / alpha, alpha);
}
-
-struct surface_context
-get_cairo_surface_from_lab_data_buffer(struct lab_data_buffer *buffer)
-{
- /* Handle CAIRO_FORMAT_ARGB32 buffers */
- if (buffer->cairo) {
- return (struct surface_context){
- .is_duplicate = false,
- .surface = cairo_get_target(buffer->cairo),
- };
- }
-
- /* Handle DRM_FORMAT_ARGB8888 buffers */
- int w = buffer->base.width;
- int h = buffer->base.height;
- cairo_surface_t *surface =
- cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
- if (!surface) {
- return (struct surface_context){0};
- }
- unsigned char *data = cairo_image_surface_get_data(surface);
- cairo_surface_flush(surface);
- memcpy(data, buffer->data, h * buffer->stride);
- cairo_surface_mark_dirty(surface);
- return (struct surface_context){
- .is_duplicate = true,
- .surface = surface,
- };
-}
{
assert(icon_buffer);
- struct surface_context icon =
- get_cairo_surface_from_lab_data_buffer(icon_buffer);
- int icon_width = cairo_image_surface_get_width(icon.surface);
- int icon_height = cairo_image_surface_get_height(icon.surface);
+ cairo_surface_t *surface = icon_buffer->surface;
+ int icon_width = cairo_image_surface_get_width(surface);
+ int icon_height = cairo_image_surface_get_height(surface);
int width = theme->window_button_width;
int height = theme->window_button_height;
buffer_width, buffer_height, 1.0);
cairo_t *cairo = buffer->cairo;
- cairo_set_source_surface(cairo, icon.surface,
+ cairo_set_source_surface(cairo, surface,
(buffer_width - icon_width) / 2, (buffer_height - icon_height) / 2);
cairo_paint(cairo);
*/
cairo_scale(cairo, scale, scale);
- if (icon.is_duplicate) {
- cairo_surface_destroy(icon.surface);
- }
-
return buffer;
}