dwldrwbufpool.patch

· kitten's pastes · raw

expires: 11 Nov, 2024

  1diff --git a/dwl.c b/dwl.c
  2index 8614fdd..35f611d 100644
  3--- a/dwl.c
  4+++ b/dwl.c
  5@@ -193,6 +193,15 @@ typedef struct {
  6 	void (*arrange)(Monitor *);
  7 } Layout;
  8 
  9+typedef struct {
 10+	struct wlr_buffer base;
 11+	struct wl_listener release;
 12+	size_t stride;
 13+	bool acquired;
 14+	Img *image;
 15+	uint32_t data[];
 16+} Buffer;
 17+
 18 struct Monitor {
 19 	struct wl_list link;
 20 	struct wlr_output *wlr_output;
 21@@ -222,15 +231,10 @@ struct Monitor {
 22 	char ltsymbol[16];
 23 	int asleep;
 24 	Drwl *drw;
 25+	Buffer *pool[2];
 26 	int lrpad;
 27 };
 28 
 29-typedef struct {
 30-    struct wlr_buffer base;
 31-    size_t stride;
 32-    uint32_t data[];
 33-} Buffer;
 34-
 35 typedef struct {
 36 	const char *name;
 37 	float mfact;
 38@@ -272,6 +276,7 @@ static void arrangelayer(Monitor *m, struct wl_list *list,
 39 static void arrangelayers(Monitor *m);
 40 static void axisnotify(struct wl_listener *listener, void *data);
 41 static bool bar_accepts_input(struct wlr_scene_buffer *buffer, double *sx, double *sy);
 42+static void buffer_release(struct wl_listener *listener, void *data);
 43 static void buffer_destroy(struct wlr_buffer *buffer);
 44 static bool buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags, void **data, uint32_t *format, size_t *stride);
 45 static void buffer_end_data_ptr_access(struct wlr_buffer *buffer);
 46@@ -644,11 +649,22 @@ bar_accepts_input(struct wlr_scene_buffer *buffer, double *sx, double *sy)
 47 	return true;
 48 }
 49 
 50+void
 51+buffer_release(struct wl_listener *listener, void *data)
 52+{
 53+	Buffer *buf = wl_container_of(listener, buf, release);
 54+	buf->acquired = false;
 55+	wlr_log(WLR_ERROR, "buffer %p ready for reuse", buf);
 56+	wl_list_remove(&buf->release.link);
 57+}
 58+
 59 void
 60 buffer_destroy(struct wlr_buffer *wlr_buffer)
 61 {
 62-	Buffer *buf;
 63-	buf = wl_container_of(wlr_buffer, buf, base);
 64+	Buffer *buf = wl_container_of(wlr_buffer, buf, base);
 65+	if (buf->acquired)
 66+		wl_list_remove(&buf->release.link);
 67+	drwl_image_destroy(buf->image);
 68 	free(buf);
 69 }
 70 
 71@@ -656,8 +672,7 @@ bool
 72 buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer, uint32_t flags,
 73                              void **data, uint32_t *format, size_t *stride)
 74 {
 75-	Buffer *buf;
 76-	buf = wl_container_of(wlr_buffer, buf, base);
 77+	Buffer *buf = wl_container_of(wlr_buffer, buf, base);
 78 
 79 	if (flags & WLR_BUFFER_DATA_PTR_ACCESS_WRITE) return false;
 80 
 81@@ -669,7 +684,7 @@ buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer, uint32_t flags,
 82 }
 83 
 84 void
 85-buffer_end_data_ptr_access(struct wlr_buffer *buffer)
 86+buffer_end_data_ptr_access(struct wlr_buffer *wlr_buffer)
 87 {
 88 }
 89 
 90@@ -821,6 +836,9 @@ cleanupmon(struct wl_listener *listener, void *data)
 91 			wlr_layer_surface_v1_destroy(l->layer_surface);
 92 	}
 93 
 94+	for (i = 0; i < LENGTH(m->pool); i++)
 95+		wlr_buffer_drop(&m->pool[i]->base);
 96+
 97 	drwl_destroy(m->drw);
 98 
 99 	wl_list_remove(&m->destroy.link);
100@@ -1455,6 +1473,50 @@ dirtomon(enum wlr_direction dir)
101 	return selmon;
102 }
103 
104+Buffer *
105+bufmon(Monitor *m)
106+{
107+	size_t i;
108+	size_t stride = drwl_image_stride(m->b.width);
109+	Buffer *buf = NULL;
110+
111+	wlr_log(WLR_ERROR, "looking for drawbar buffer for stride=%d", stride);
112+	
113+	for (i = 0; i < LENGTH(m->pool); i++) {
114+		if (m->pool[i])
115+			wlr_log(WLR_ERROR, "buffer slot %d %p busy=%d stride=%d", i, m->pool[i], m->pool[i]->acquired, m->pool[i]->stride);
116+		if (m->pool[i] && !m->pool[i]->acquired && m->pool[i]->stride != stride) {
117+			wlr_log(WLR_ERROR, "destroying buffer %d (%p) old stride %d vs %d",
118+				i, &m->pool[i], stride, m->pool[i]->stride);
119+			wlr_buffer_drop(&m->pool[i]->base);
120+			m->pool[i] = NULL;
121+		}
122+		if (m->pool[i] && !m->pool[i]->acquired) {
123+			buf = m->pool[i];
124+			wlr_log(WLR_ERROR, "reusing available buffer %d (%p) stride=%d", i, buf, stride);
125+		}
126+		if (m->pool[i] || buf) {
127+			wlr_log(WLR_ERROR, "successfully selected buffer %d (%p) stride=%d", i, buf, stride);
128+			continue;
129+		}
130+
131+		buf = ecalloc(1, sizeof(Buffer) + (stride * m->b.height));
132+		buf->stride = stride;
133+		buf->image = drwl_image_create(m->drw, m->b.width, m->b.height, buf->data, stride);
134+		wlr_buffer_init(&buf->base, &buffer_impl, m->b.width, m->b.height);
135+		m->pool[i] = buf;
136+		wlr_log(WLR_ERROR, "empty slot; creating buffer %d (%p) stride=%d", i, buf, stride);
137+	}
138+	if (!buf)
139+		return NULL;
140+
141+	wlr_log(WLR_ERROR, "using drawbar buffer %p stride=%d", buf, stride);
142+
143+	buf->acquired = true;
144+	LISTEN(&buf->base.events.release, &buf->release, buffer_release);
145+	return buf;
146+}
147+
148 void
149 drawbar(Monitor *m)
150 {
151@@ -1462,21 +1524,20 @@ drawbar(Monitor *m)
152 	int boxs = m->drw->font->height / 9;
153 	int boxw = m->drw->font->height / 6 + 2;
154 	uint32_t i, occ = 0, urg = 0;
155-	int32_t stride, size;
156 	Client *c;
157 	Buffer *buf;
158 
159 	if (!m->scene_buffer->node.enabled)
160 		return;
161 
162-	stride = drwl_stride(m->b.width);
163-	size = stride * m->b.height;
164+	if (!(buf = bufmon(m)))
165+		return;
166 
167-	buf = ecalloc(1, sizeof(Buffer) + size);
168-	buf->stride = stride;
169-	wlr_buffer_init(&buf->base, &buffer_impl, m->b.width, m->b.height);
170+	wlr_buffer_lock(&buf->base);
171 
172-	drwl_prepare_drawing(m->drw, m->b.width, m->b.height, buf->data, stride);
173+	char addr[24];
174+	snprintf(addr, sizeof(addr), "%p %d", buf, buf->stride);
175+	strncpy(stext, addr, 256);
176 
177 	/* draw status first so it can be overdrawn by tags later */
178 	if (m == selmon) { /* status is only drawn on selected monitor */
179@@ -1520,13 +1581,12 @@ drawbar(Monitor *m)
180 		}
181 	}
182 
183-	drwl_finish_drawing(m->drw);
184 	wlr_scene_buffer_set_dest_size(m->scene_buffer,
185 		m->b.real_width, m->b.real_height);
186 	wlr_scene_node_set_position(&m->scene_buffer->node, m->m.x,
187 		m->m.y + (topbar ? 0 : m->m.height - m->b.real_height));
188 	wlr_scene_buffer_set_buffer(m->scene_buffer, &buf->base);
189-	wlr_buffer_drop(&buf->base);
190+	wlr_buffer_unlock(&buf->base);
191 }
192 
193 void