Make use of wayland-server shm common code
diff --git a/compositor/compositor.c b/compositor/compositor.c
index bebf8dc..c9928c3 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -296,17 +296,34 @@
{
struct wlsc_surface *es = (struct wlsc_surface *) surface;
struct wlsc_compositor *ec = es->compositor;
+ struct wl_list *surfaces_attached_to;
- if (wlsc_is_shm_buffer(buffer)) {
- wlsc_shm_buffer_attach(buffer, surface);
+ if (es->saved_texture != 0)
+ es->texture = es->saved_texture;
+
+ glBindTexture(GL_TEXTURE_2D, es->texture);
+
+ if (wl_buffer_is_shm(buffer)) {
+ /* Unbind any EGLImage texture that may be bound, so we don't
+ * overwrite it.*/
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+ 0, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+ buffer->width, buffer->height, 0,
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE,
+ wl_shm_buffer_get_data(buffer));
+ es->visual = buffer->visual;
+
+ surfaces_attached_to = buffer->user_data;
+
+ if (es->buffer)
+ wl_list_remove(&es->buffer_link);
+ wl_list_insert(surfaces_attached_to, &es->buffer_link);
} else {
es->image = eglCreateImageKHR(ec->display, NULL,
EGL_WAYLAND_BUFFER_WL,
buffer, NULL);
- if (es->saved_texture != 0)
- es->texture = es->saved_texture;
- glBindTexture(GL_TEXTURE_2D, es->texture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, es->image);
es->visual = buffer->visual;
}
@@ -1517,6 +1534,60 @@
wlsc_output_post_geometry);
}
+static void
+shm_buffer_created(struct wl_buffer *buffer)
+{
+ struct wl_list *surfaces_attached_to;
+
+ surfaces_attached_to = malloc(sizeof *surfaces_attached_to);
+ if (!surfaces_attached_to) {
+ buffer->user_data = NULL;
+ return;
+ }
+
+ wl_list_init(surfaces_attached_to);
+
+ buffer->user_data = surfaces_attached_to;
+}
+
+static void
+shm_buffer_damaged(struct wl_buffer *buffer,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ struct wl_list *surfaces_attached_to = buffer->user_data;
+ struct wlsc_surface *es;
+
+ wl_list_for_each(es, surfaces_attached_to, buffer_link) {
+ glBindTexture(GL_TEXTURE_2D, es->texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+ buffer->width, buffer->height, 0,
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE,
+ wl_shm_buffer_get_data(buffer));
+ /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
+ * support any unpack attributes except GL_UNPACK_ALIGNMENT. */
+ }
+}
+
+static void
+shm_buffer_destroyed(struct wl_buffer *buffer)
+{
+ struct wl_list *surfaces_attached_to = buffer->user_data;
+ struct wlsc_surface *es, *next;
+
+ wl_list_for_each_safe(es, next, surfaces_attached_to, buffer_link) {
+ es->buffer = NULL;
+ wl_list_remove(&es->buffer_link);
+ }
+
+ free(surfaces_attached_to);
+}
+
+const static struct wl_shm_callbacks shm_callbacks = {
+ shm_buffer_created,
+ shm_buffer_damaged,
+ shm_buffer_destroyed
+};
+
int
wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display)
{
@@ -1527,7 +1598,7 @@
wl_compositor_init(&ec->compositor, &compositor_interface, display);
- wlsc_shm_init(ec);
+ ec->shm = wl_shm_init(display, &shm_callbacks);
eglBindWaylandDisplayWL(ec->display, ec->wl_display);
wl_list_init(&ec->surface_list);