summaryrefslogtreecommitdiff
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
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.
-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;
}
}