fix(blur): optimize blur to only render after commit

This commit is contained in:
Jeremy Attali 2021-02-15 18:29:59 -05:00 committed by Jeremy Attali
parent c2e9462e89
commit 27fcecedae
3 changed files with 41 additions and 18 deletions

View File

@ -23,6 +23,11 @@ enum swappy_paint_type {
SWAPPY_PAINT_MODE_BLUR, /* Blur mode */
};
enum swappy_paint_shape_operation {
SWAPPY_PAINT_SHAPE_OPERATION_STROKE = 0, /* Used to stroke the shape */
SWAPPY_PAINT_SHAPE_OPERATION_FILL, /* Used to fill the shape */
};
enum swappy_text_mode {
SWAPPY_TEXT_MODE_EDIT = 0,
SWAPPY_TEXT_MODE_DONE,
@ -56,6 +61,7 @@ struct swappy_paint_shape {
struct swappy_point from;
struct swappy_point to;
enum swappy_paint_type type;
enum swappy_paint_shape_operation operation;
};
struct swappy_paint_brush {

View File

@ -118,6 +118,7 @@ void paint_add_temporary(struct swappy_state *state, double x, double y,
paint->content.shape.a = a;
paint->content.shape.w = w;
paint->content.shape.type = type;
paint->content.shape.operation = SWAPPY_PAINT_SHAPE_OPERATION_STROKE;
break;
case SWAPPY_PAINT_MODE_TEXT:
paint->can_draw = false;

View File

@ -315,7 +315,18 @@ static void render_shape_rectangle(cairo_t *cr,
cairo_rectangle(cr, x, y, w, h);
cairo_close_path(cr);
cairo_stroke(cr);
switch (shape.operation) {
case SWAPPY_PAINT_SHAPE_OPERATION_STROKE:
cairo_stroke(cr);
break;
case SWAPPY_PAINT_SHAPE_OPERATION_FILL:
cairo_fill(cr);
break;
default:
cairo_stroke(cr);
break;
}
}
static void render_shape(cairo_t *cr, struct swappy_paint_shape shape) {
@ -353,18 +364,29 @@ static void render_blur(cairo_t *cr, struct swappy_paint *paint) {
cairo_save(cr);
if (!paint->is_committed) {
cairo_surface_t *blurred = blur_surface(target, x, y, w, h);
if (blurred && cairo_surface_status(blurred) == CAIRO_STATUS_SUCCESS) {
cairo_set_source_surface(cr, blurred, x, y);
cairo_paint(cr);
if (blur.surface) {
cairo_surface_destroy(blur.surface);
if (paint->is_committed) {
// Surface has already been blurred, reuse it in future passes
if (blur.surface) {
cairo_surface_t *surface = blur.surface;
if (surface && cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) {
cairo_set_source_surface(cr, surface, x, y);
cairo_paint(cr);
}
paint->content.blur.surface = blurred;
}
} else {
// Blur surface and reuse it in future passes
g_info(
"blurring surface on following image coordinates: %.2lf,%.2lf size: "
"%.2lfx%.2lf",
x, y, w, h);
cairo_surface_t *blurred = blur_surface(target, x, y, w, h);
if (blurred && cairo_surface_status(blurred) == CAIRO_STATUS_SUCCESS) {
cairo_set_source_surface(cr, blurred, x, y);
cairo_paint(cr);
paint->content.blur.surface = blurred;
}
}
} else {
// Blur not committed yet, draw bounding rectangle
struct swappy_paint_shape rect = {
.r = 0,
@ -375,15 +397,9 @@ static void render_blur(cairo_t *cr, struct swappy_paint *paint) {
.from = blur.from,
.to = blur.to,
.type = SWAPPY_PAINT_MODE_RECTANGLE,
.operation = SWAPPY_PAINT_SHAPE_OPERATION_FILL,
};
render_shape_rectangle(cr, rect);
} else {
cairo_surface_t *surface = blur.surface;
if (surface && cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) {
cairo_set_source_surface(cr, surface, x, y);
cairo_paint(cr);
}
}
cairo_restore(cr);