summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorManuel Stoeckl <code@mstoeckl.com>2021-09-26 13:16:03 -0400
committerSimon Ser <contact@emersion.fr>2021-10-01 09:15:35 +0200
commit5e2df3a600e07b71923c28a8cd51861289319c91 (patch)
tree166c000708fab436e46337cbbb7288a29206085c /main.c
parent96cf26d605d491d0cbb9e931c0bf8dcd28258e52 (diff)
downloadswaybg-5e2df3a600e07b71923c28a8cd51861289319c91.tar.gz
swaybg-5e2df3a600e07b71923c28a8cd51861289319c91.tar.bz2
Only render a new frame when the buffer size changes
The contents of the buffer associated to an output depend only on the output config (which does not change at runtime), and the buffer dimensions. When the compositor changes the output scale, it often sends a configure event which exactly compensates for the scale change, so that the size of the buffer needed for the surface remains the same. Thus no new frame needs to be rendered.
Diffstat (limited to '')
-rw-r--r--main.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/main.c b/main.c
index ee9550f..29e8627 100644
--- a/main.c
+++ b/main.c
@@ -78,6 +78,7 @@ struct swaybg_output {
uint32_t configure_serial;
bool dirty, needs_ack;
+ int32_t committed_width, committed_height, committed_scale;
struct wl_list link;
};
@@ -103,6 +104,19 @@ bool is_valid_color(const char *color) {
static void render_frame(struct swaybg_output *output, cairo_surface_t *surface) {
int buffer_width = output->width * output->scale,
buffer_height = output->height * output->scale;
+
+ // If the last committed buffer has the same size as this one would, do
+ // not render a new buffer, because it will be identical to the old one
+ if (output->committed_width == buffer_width &&
+ output->committed_height == buffer_height) {
+ if (output->committed_scale != output->scale) {
+ wl_surface_set_buffer_scale(output->surface, output->scale);
+ wl_surface_commit(output->surface);
+
+ output->committed_scale = output->scale;
+ }
+ return;
+ }
struct pool_buffer buffer;
if (!create_buffer(&buffer, output->state->shm,
buffer_width, buffer_height, WL_SHM_FORMAT_ARGB8888)) {
@@ -133,6 +147,11 @@ static void render_frame(struct swaybg_output *output, cairo_surface_t *surface)
wl_surface_attach(output->surface, buffer.buffer, 0, 0);
wl_surface_damage_buffer(output->surface, 0, 0, INT32_MAX, INT32_MAX);
wl_surface_commit(output->surface);
+
+ output->committed_width = buffer_width;
+ output->committed_height = buffer_height;
+ output->committed_scale = output->scale;
+
// we will not reuse the buffer, so destroy it immediately
destroy_buffer(&buffer);
}
@@ -580,7 +599,12 @@ int main(int argc, char **argv) {
output->configure_serial);
}
- if (output->dirty && output->config->image) {
+ int buffer_width = output->width * output->scale,
+ buffer_height = output->height * output->scale;
+ bool buffer_change =
+ output->committed_height != buffer_height ||
+ output->committed_width != buffer_width;
+ if (output->dirty && output->config->image && buffer_change) {
output->config->image->load_required = true;
}
}