commit 9242691

Michael Forney  ·  2014-01-15 12:42:50 +0000 UTC
parent 33f9ab0
wayland-shm: Use buffer map interface instead of mapping and then importing

This way the mapped memory gets unmapped correctly when the buffer is
destroyed.
1 files changed,  +60, -25
+60, -25
  1@@ -44,8 +44,16 @@ struct shm_context
  2     struct wl_array formats;
  3 };
  4 
  5+struct shm_buffer
  6+{
  7+    struct wld_buffer base;
  8+    int fd;
  9+};
 10+
 11 #include "interface/context.h"
 12+#include "interface/buffer.h"
 13 IMPL(shm, context)
 14+IMPL(shm, buffer)
 15 
 16 static void registry_global(void * data, struct wl_registry * registry,
 17                             uint32_t name, const char * interface,
 18@@ -154,63 +162,54 @@ struct wld_buffer * context_create_buffer(struct wld_context * base,
 19                                           uint32_t format)
 20 {
 21     struct shm_context * context = shm_context(base);
 22-    struct wld_buffer * buffer;
 23+    struct shm_buffer * buffer;
 24     struct wld_exporter * exporter;
 25     char name[] = "/tmp/wld-XXXXXX";
 26     uint32_t pitch = width * format_bytes_per_pixel(format);
 27     size_t size = pitch * height;
 28     int fd;
 29-    union wld_object object;
 30     struct wl_shm_pool * pool;
 31     struct wl_buffer * wl;
 32 
 33+    if (!(buffer = malloc(sizeof *buffer)))
 34+        goto error0;
 35+
 36     fd = mkostemp(name, O_CLOEXEC);
 37 
 38     if (fd < 0)
 39-        goto error0;
 40+        goto error1;
 41 
 42     unlink(name);
 43 
 44     if (posix_fallocate(fd, 0, size) != 0)
 45-        goto error1;
 46-
 47-    object.ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 48-
 49-    if (object.ptr == MAP_FAILED)
 50-        goto error1;
 51-
 52-    buffer = wld_import_buffer(wld_pixman_context, WLD_OBJECT_DATA, object,
 53-                               width, height, format, pitch);
 54-
 55-    if (!buffer)
 56         goto error2;
 57 
 58     if (!(pool = wl_shm_create_pool(context->wl, fd, size)))
 59-        goto error3;
 60+        goto error2;
 61 
 62     wl = wl_shm_pool_create_buffer(pool, 0, width, height, pitch,
 63                                    format_wld_to_shm(format));
 64     wl_shm_pool_destroy(pool);
 65 
 66     if (!wl)
 67-        goto error3;
 68+        goto error2;
 69 
 70     if (!(exporter = wayland_create_exporter(wl)))
 71-        goto error4;
 72+        goto error3;
 73 
 74-    buffer_add_exporter(buffer, exporter);
 75-    close(fd);
 76+    buffer_initialize(&buffer->base, &buffer_impl,
 77+                      width, height, format, pitch);
 78+    buffer->fd = fd;
 79+    buffer_add_exporter(&buffer->base, exporter);
 80 
 81-    return buffer;
 82+    return &buffer->base;
 83 
 84-  error4:
 85-    wl_buffer_destroy(wl);
 86   error3:
 87-    wld_destroy_buffer(buffer);
 88+    wl_buffer_destroy(wl);
 89   error2:
 90-    munmap(object.ptr, size);
 91-  error1:
 92     close(fd);
 93+  error1:
 94+    free(buffer);
 95   error0:
 96     return NULL;
 97 }
 98@@ -235,6 +234,42 @@ void context_destroy(struct wld_context * base)
 99     free(context);
100 }
101 
102+/**** Buffer ****/
103+
104+bool buffer_map(struct wld_buffer * base)
105+{
106+    struct shm_buffer * buffer = shm_buffer(base);
107+    void * data;
108+
109+    data = mmap(NULL, base->pitch * base->height, PROT_READ | PROT_WRITE,
110+                MAP_SHARED, buffer->fd, 0);
111+
112+    if (data == MAP_FAILED)
113+        return false;
114+
115+    buffer->base.map.data = data;
116+
117+    return true;
118+}
119+
120+bool buffer_unmap(struct wld_buffer * buffer)
121+{
122+    if (munmap(buffer->map.data, buffer->pitch * buffer->height) == -1)
123+        return false;
124+
125+    buffer->map.data = NULL;
126+
127+    return true;
128+}
129+
130+void buffer_destroy(struct wld_buffer * base)
131+{
132+    struct shm_buffer * buffer = shm_buffer(base);
133+
134+    close(buffer->fd);
135+    free(buffer);
136+}
137+
138 void registry_global(void * data, struct wl_registry * registry, uint32_t name,
139                      const char * interface, uint32_t version)
140 {