Skip to content

Commit

Permalink
Only rescale background images once
Browse files Browse the repository at this point in the history
This greatly improves performance as rescaling it for every frame is
very expensive.

Resolves #59.
  • Loading branch information
MithicSpirit authored and jirutka committed Dec 30, 2023
1 parent 4f2234c commit 496059a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 11 deletions.
16 changes: 13 additions & 3 deletions background-image.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,13 @@ cairo_surface_t *load_background_image(const char *path) {
return image;
}

void render_background_image(cairo_t *cairo, cairo_surface_t *image,
enum background_mode mode, int buffer_width, int buffer_height, double alpha) {
cairo_surface_t *scale_background_image(cairo_surface_t *image,
enum background_mode mode, int buffer_width, int buffer_height) {
cairo_surface_t *target = cairo_image_surface_create(CAIRO_FORMAT_RGB24, buffer_width, buffer_height);
cairo_t *cairo = cairo_create(target);
double width = cairo_image_surface_get_width(image);
double height = cairo_image_surface_get_height(image);

cairo_save(cairo);
switch (mode) {
case BACKGROUND_MODE_STRETCH:
cairo_scale(cairo,
Expand Down Expand Up @@ -435,7 +436,16 @@ void render_background_image(cairo_t *cairo, cairo_surface_t *image,
assert(0);
break;
}

cairo_pattern_set_filter(cairo_get_source(cairo), CAIRO_FILTER_BILINEAR);
cairo_paint(cairo);
cairo_destroy(cairo);
return target;
}

void render_background_image(cairo_t *cairo, cairo_surface_t *image, double alpha) {
cairo_save(cairo);
cairo_set_source_surface(cairo, image, 0, 0);
cairo_paint_with_alpha(cairo, alpha);
cairo_restore(cairo);
}
5 changes: 3 additions & 2 deletions include/background-image.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ enum background_mode parse_background_mode(const char *mode);
cairo_surface_t *load_background_image(const char *path);
cairo_surface_t *load_background_from_buffer(void *buf, uint32_t format,
uint32_t width, uint32_t height, uint32_t stride, enum wl_output_transform transform);
void render_background_image(cairo_t *cairo, cairo_surface_t *image,
enum background_mode mode, int buffer_width, int buffer_height, double alpha);
cairo_surface_t *scale_background_image(cairo_surface_t *image,
enum background_mode mode, int buffer_width, int buffer_height);
void render_background_image(cairo_t *cairo, cairo_surface_t *image, double alpha);

#endif
2 changes: 2 additions & 0 deletions include/swaylock.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,13 @@ struct swaylock_state {

struct swaylock_surface {
cairo_surface_t *image;
cairo_surface_t *scaled_image;
struct {
uint32_t format, width, height, stride;
enum wl_output_transform transform;
void *data;
cairo_surface_t *original_image;
cairo_surface_t *scaled_image;
struct swaylock_image *image;
} screencopy;
struct swaylock_state *state;
Expand Down
24 changes: 18 additions & 6 deletions render.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,25 @@ void render_frame_background(struct swaylock_surface *surface, bool commit) {
if (surface->image && state->args.mode != BACKGROUND_MODE_SOLID_COLOR) {
cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
if (fade_is_complete(&surface->fade)) {
render_background_image(cairo, surface->image,
state->args.mode, buffer_width, buffer_height, 1);
if (!surface->scaled_image) {
surface->scaled_image =
scale_background_image(surface->image, state->args.mode,
buffer_width, buffer_height);
}
render_background_image(cairo, surface->scaled_image, 1);
} else {
render_background_image(cairo, surface->screencopy.original_image,
state->args.mode, buffer_width, buffer_height, 1);
render_background_image(cairo, surface->image,
state->args.mode, buffer_width, buffer_height, surface->fade.alpha);
if (!surface->screencopy.scaled_image) {
surface->screencopy.scaled_image =
scale_background_image(surface->screencopy.original_image,
state->args.mode, buffer_width, buffer_height);
}
render_background_image(cairo, surface->screencopy.scaled_image, 1);
if (!surface->scaled_image) {
surface->scaled_image =
scale_background_image(surface->image, state->args.mode,
buffer_width, buffer_height);
}
render_background_image(cairo, surface->scaled_image, surface->fade.alpha);
}
}
cairo_restore(cairo);
Expand Down

0 comments on commit 496059a

Please sign in to comment.