commit 8820ace
Michael Forney
·
2013-07-25 07:04:26 +0000 UTC
parent 6fb96f3
wayland: Ensure buffer is released before drawing
1 files changed,
+50,
-0
+50,
-0
1@@ -33,6 +33,7 @@
2
3 struct wld_wayland_context
4 {
5+ struct wl_display * display;
6 struct wl_event_queue * queue;
7 const struct wld_wayland_interface * interface;
8 void * context;
9@@ -48,6 +49,7 @@ struct wayland_drawable
10 {
11 struct wl_buffer * wl;
12 struct wld_drawable * drawable;
13+ bool busy;
14 } buffers[2];
15 uint8_t front_buffer;
16 };
17@@ -58,6 +60,8 @@ _Static_assert(offsetof(struct wayland_drawable, base) == 0,
18 static void sync_done(void * data, struct wl_callback * callback,
19 uint32_t msecs);
20
21+static void buffer_release(void * data, struct wl_buffer * buffer);
22+
23 static void wayland_fill_rectangle(struct wld_drawable * drawable,
24 uint32_t color, int32_t x, int32_t y,
25 uint32_t width, uint32_t height);
26@@ -83,6 +87,10 @@ const struct wl_callback_listener sync_listener = {
27 .done = &sync_done
28 };
29
30+const struct wl_buffer_listener buffer_listener = {
31+ .release = &buffer_release
32+};
33+
34 const struct wld_draw_interface wayland_draw = {
35 .fill_rectangle = &wayland_fill_rectangle,
36 .fill_region = &wayland_fill_region,
37@@ -115,6 +123,7 @@ struct wld_wayland_context * wld_wayland_create_context
38 if (!wayland)
39 goto error0;
40
41+ wayland->display = display;
42 wayland->queue = wl_display_create_queue(display);
43 wayland->context = NULL;
44 wayland->interface = NULL;
45@@ -206,6 +215,8 @@ struct wld_drawable * wld_wayland_create_drawable
46 if (!wayland->buffers[1].drawable)
47 goto error2;
48
49+ wayland->buffers[0].busy = false;
50+ wayland->buffers[1].busy = false;
51 wayland->front_buffer = 0;
52 wayland->surface = surface;
53
54@@ -213,6 +224,11 @@ struct wld_drawable * wld_wayland_create_drawable
55 wayland->base.width = width;
56 wayland->base.height = height;
57
58+ wl_buffer_add_listener(wayland->buffers[0].wl, &buffer_listener,
59+ &wayland->buffers[0].busy);
60+ wl_buffer_add_listener(wayland->buffers[1].wl, &buffer_listener,
61+ &wayland->buffers[1].busy);
62+
63 return &wayland->base;
64
65 error2:
66@@ -250,12 +266,39 @@ void sync_done(void * data, struct wl_callback * callback, uint32_t msecs)
67 *done = true;
68 }
69
70+void buffer_release(void * data, struct wl_buffer * buffer)
71+{
72+ bool * busy = data;
73+
74+ *busy = false;
75+}
76+
77+static void wait_for_backbuf(struct wayland_drawable * wayland)
78+{
79+ if (BACKBUF(wayland).busy)
80+ {
81+ int ret, count = 0;
82+
83+ do {
84+ ret = wl_display_dispatch_queue(wayland->context->display,
85+ wayland->context->queue);
86+ } while (BACKBUF(wayland).busy && ret != -1);
87+ }
88+}
89+
90+static void begin(struct wayland_drawable * wayland)
91+{
92+ /* Wait for the back buffer to become available. */
93+ wait_for_backbuf(wayland);
94+}
95+
96 static void wayland_fill_rectangle(struct wld_drawable * drawable,
97 uint32_t color, int32_t x, int32_t y,
98 uint32_t width, uint32_t height)
99 {
100 struct wayland_drawable * wayland = (void *) drawable;
101
102+ begin(wayland);
103 wld_fill_rectangle(BACKBUF(wayland).drawable, color, x, y, width, height);
104 }
105
106@@ -264,6 +307,7 @@ static void wayland_fill_region(struct wld_drawable * drawable, uint32_t color,
107 {
108 struct wayland_drawable * wayland = (void *) drawable;
109
110+ begin(wayland);
111 wld_fill_region(BACKBUF(wayland).drawable, color, region);
112 }
113
114@@ -291,6 +335,7 @@ static void wayland_draw_text_utf8(struct wld_drawable * drawable,
115 {
116 struct wayland_drawable * wayland = (void *) drawable;
117
118+ begin(wayland);
119 wld_draw_text_utf8_n(BACKBUF(wayland).drawable, &font->base, color,
120 x, y, text, length);
121 }
122@@ -299,9 +344,14 @@ static void wayland_flush(struct wld_drawable * drawable)
123 {
124 struct wayland_drawable * wayland = (void *) drawable;
125
126+ wait_for_backbuf(wayland);
127+
128 wld_flush(BACKBUF(wayland).drawable);
129 wl_surface_attach(wayland->surface, BACKBUF(wayland).wl, 0, 0);
130 wl_surface_commit(wayland->surface);
131+
132+ BACKBUF(wayland).busy = true;
133+
134 wayland->front_buffer ^= 1;
135 }
136