Skip to content

Commit 55b88bc

Browse files
stacyharperproycon
authored andcommitted
Optimize the backporting condition
At the moment we flip the two buffers, and we backport the damaged area on every frame callback. We completely ignore the compositor sent event buffer->release. This event means that the compositor finished reading the buffer pixels, and will never read them again. So we can keep using the same buffer instead of fliping, if we receive the event before asking for a new frame callback. The change is not complicated, but we have to distinguish drwsurf_attach, and drwsurf_flip. We try to flip before trying to draw anything. And if the buffer has already been released, we don't flip. We also have to track the backport_damage separately than the buffer current damage. Signed-off-by: Maarten van Gompel <[email protected]>
1 parent 686b27a commit 55b88bc

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

drw.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66
#include "shm_open.h"
77
#include "math.h"
88

9+
void drwbuf_handle_release(void *data, struct wl_buffer *wl_buffer) {
10+
struct drwbuf *db = data;
11+
db->released = true;
12+
};
13+
14+
const struct wl_buffer_listener buffer_listener = {
15+
.release = drwbuf_handle_release
16+
};
17+
918
void drwsurf_handle_frame_cb(void* data, struct wl_callback* callback,
1019
uint32_t time)
1120
{
@@ -18,8 +27,9 @@ void drwsurf_handle_frame_cb(void* data, struct wl_callback* callback,
1827
cairo_region_get_rectangle(ds->back_buffer->damage, i, &r);
1928
wl_surface_damage(ds->surf, r.x, r.y, r.width, r.height);
2029
};
30+
cairo_region_subtract(ds->display_buffer->damage, ds->display_buffer->damage);
2131

22-
drwsurf_flip(ds);
32+
drwsurf_attach(ds);
2333
}
2434

2535
const struct wl_callback_listener frame_listener = {
@@ -41,6 +51,7 @@ void drwsurf_damage(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint
4151
{
4252
cairo_rectangle_int_t rect = { x, y, w, h };
4353
cairo_region_union_rectangle(ds->back_buffer->damage, &rect);
54+
cairo_region_union_rectangle(ds->back_buffer->backport_damage, &rect);
4455
drwsurf_register_frame_cb(ds);
4556
}
4657

@@ -64,8 +75,8 @@ drwsurf_backport(struct drwsurf *ds)
6475
cairo_set_operator(ds->back_buffer->cairo, CAIRO_OPERATOR_SOURCE);
6576

6677
cairo_rectangle_int_t r = {0};
67-
for (int i = 0; i < cairo_region_num_rectangles(ds->display_buffer->damage); i++) {
68-
cairo_region_get_rectangle(ds->display_buffer->damage, i, &r);
78+
for (int i = 0; i < cairo_region_num_rectangles(ds->display_buffer->backport_damage); i++) {
79+
cairo_region_get_rectangle(ds->display_buffer->backport_damage, i, &r);
6980

7081
cairo_set_source_surface(ds->back_buffer->cairo, ds->display_buffer->cairo_surf, 0, 0);
7182
cairo_rectangle(
@@ -79,16 +90,23 @@ drwsurf_backport(struct drwsurf *ds)
7990
};
8091

8192
cairo_restore(ds->back_buffer->cairo);
82-
cairo_region_subtract(ds->display_buffer->damage, ds->display_buffer->damage);
93+
cairo_region_subtract(ds->display_buffer->backport_damage, ds->display_buffer->backport_damage);
8394
}
8495

8596
void
86-
drwsurf_flip(struct drwsurf *ds)
97+
drwsurf_attach(struct drwsurf *ds)
8798
{
8899
wl_surface_attach(ds->surf, ds->back_buffer->buf, 0, 0);
89100
wl_surface_commit(ds->surf);
101+
ds->back_buffer->released = false;
90102
ds->attached = true;
103+
}
91104

105+
void
106+
drwsurf_flip(struct drwsurf *ds)
107+
{
108+
if (ds->back_buffer->released)
109+
return;
92110
struct drwbuf *tmp = ds->back_buffer;
93111
ds->back_buffer = ds->display_buffer;
94112
ds->display_buffer = tmp;
@@ -101,6 +119,7 @@ drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
101119
uint32_t w, uint32_t h, uint32_t b, const char *label,
102120
PangoFontDescription *font_description)
103121
{
122+
drwsurf_flip(ds);
104123
struct drwbuf *d = ds->back_buffer;
105124

106125
cairo_save(d->cairo);
@@ -128,6 +147,7 @@ drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
128147
void
129148
drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
130149
{
150+
drwsurf_flip(ds);
131151
struct drwbuf *d = ds->back_buffer;
132152

133153
cairo_save(d->cairo);
@@ -143,6 +163,7 @@ void
143163
drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
144164
uint32_t w, uint32_t h, bool over, int rounding)
145165
{
166+
drwsurf_flip(ds);
146167
struct drwbuf *d = ds->back_buffer;
147168

148169
cairo_save(d->cairo);
@@ -229,6 +250,8 @@ setup_buffer(struct drwsurf *drwsurf, struct drwbuf *drwbuf)
229250
stride, WL_SHM_FORMAT_ARGB8888);
230251
wl_shm_pool_destroy(pool);
231252
close(fd);
253+
wl_buffer_add_listener(drwbuf->buf, &buffer_listener, drwbuf);
254+
drwbuf->released = true;
232255

233256

234257
if (drwbuf->cairo_surf)
@@ -240,6 +263,9 @@ setup_buffer(struct drwsurf *drwsurf, struct drwbuf *drwbuf)
240263
if (drwbuf->damage)
241264
cairo_region_destroy(drwbuf->damage);
242265
drwbuf->damage = cairo_region_create();
266+
if (drwbuf->backport_damage)
267+
cairo_region_destroy(drwbuf->backport_damage);
268+
drwbuf->backport_damage = cairo_region_create();
243269

244270
if (drwbuf->cairo)
245271
cairo_destroy(drwbuf->cairo);

drw.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ struct drw {
1010
struct drwbuf {
1111
uint32_t size;
1212
struct wl_buffer *buf;
13-
cairo_region_t *damage;
13+
cairo_region_t *damage, *backport_damage;
1414
cairo_surface_t *cairo_surf;
1515
cairo_t *cairo;
1616
PangoLayout *layout;
1717
unsigned char *pool_data;
18+
bool released;
1819
};
1920
struct drwsurf {
2021
uint32_t width, height;
@@ -34,6 +35,7 @@ struct kbd;
3435

3536
void drwsurf_damage(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
3637
void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s);
38+
void drwsurf_attach(struct drwsurf *ds);
3739
void drwsurf_flip(struct drwsurf *ds);
3840

3941
typedef union {

main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ xdg_popup_surface_configure(void *data, struct xdg_surface *xdg_surface,
517517
{
518518
xdg_surface_ack_configure(xdg_surface, serial);
519519
popup_xdg_surface_configured = true;
520-
drwsurf_flip(&popup_draw_surf);
520+
drwsurf_attach(&popup_draw_surf);
521521
}
522522

523523
static const struct xdg_surface_listener xdg_popup_surface_listener = {
@@ -664,7 +664,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
664664

665665
zwlr_layer_surface_v1_ack_configure(surface, serial);
666666
kbd_resize(&keyboard, layouts, NumLayouts);
667-
drwsurf_flip(&draw_surf);
667+
drwsurf_attach(&draw_surf);
668668
} else {
669669
zwlr_layer_surface_v1_ack_configure(surface, serial);
670670
}

0 commit comments

Comments
 (0)