commit 5a5999d

Michael Forney  ·  2014-02-07 11:57:05 +0000 UTC
parent b8123be
Remove struct swc_buffer, instead using wld_buffer directly
15 files changed,  +173, -312
+0, -39
 1@@ -1,39 +0,0 @@
 2-/* swc: libswc/buffer.c
 3- *
 4- * Copyright (c) 2013 Michael Forney
 5- *
 6- * Permission is hereby granted, free of charge, to any person obtaining a copy
 7- * of this software and associated documentation files (the "Software"), to deal
 8- * in the Software without restriction, including without limitation the rights
 9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-#include "buffer.h"
26-
27-#include <wld/wld.h>
28-
29-void swc_buffer_initialize(struct swc_buffer * buffer, struct wld_buffer * wld)
30-{
31-    buffer->wld = wld;
32-    wl_signal_init(&buffer->destroy_signal);
33-}
34-
35-void swc_buffer_finalize(struct swc_buffer * buffer)
36-{
37-    wl_signal_emit(&buffer->destroy_signal, buffer);
38-    wld_destroy_buffer(buffer->wld);
39-}
40-
+0, -40
 1@@ -1,40 +0,0 @@
 2-/* swc: libswc/buffer.h
 3- *
 4- * Copyright (c) 2013 Michael Forney
 5- *
 6- * Permission is hereby granted, free of charge, to any person obtaining a copy
 7- * of this software and associated documentation files (the "Software"), to deal
 8- * in the Software without restriction, including without limitation the rights
 9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-#ifndef SWC_BUFFER_H
26-#define SWC_BUFFER_H
27-
28-#include <stdbool.h>
29-#include <wayland-server.h>
30-
31-struct swc_buffer
32-{
33-    struct wld_buffer * wld;
34-    struct wl_signal destroy_signal;
35-};
36-
37-void swc_buffer_initialize(struct swc_buffer * buffer, struct wld_buffer * wld);
38-void swc_buffer_finalize(struct swc_buffer * buffer);
39-
40-#endif
41-
+31, -56
  1@@ -28,7 +28,6 @@
  2  */
  3 
  4 #include "swc.h"
  5-#include "buffer.h"
  6 #include "compositor.h"
  7 #include "data_device_manager.h"
  8 #include "drm.h"
  9@@ -67,7 +66,7 @@ struct view
 10     struct swc_view base;
 11     struct wl_listener event_listener;
 12     struct swc_surface * surface;
 13-    struct wld_buffer * wld;
 14+    struct wld_buffer * buffer;
 15 
 16     /* The box that the surface covers (including it's border). */
 17     pixman_box32_t extents;
 18@@ -117,31 +116,6 @@ const struct swc_compositor swc_compositor = {
 19     .pointer_handler = &pointer_handler
 20 };
 21 
 22-static void buffer_destroy(void * data)
 23-{
 24-    struct swc_buffer * buffer = data;
 25-
 26-    swc_buffer_finalize(buffer);
 27-    free(buffer);
 28-}
 29-
 30-struct swc_buffer * buffer_get(struct wld_buffer * wld)
 31-{
 32-    if (wld->destroy_data)
 33-        return wld->data;
 34-
 35-    struct swc_buffer * buffer;
 36-
 37-    if (!(buffer = malloc(sizeof *buffer)))
 38-        return NULL;
 39-
 40-    swc_buffer_initialize(buffer, wld);
 41-    wld->data = buffer;
 42-    wld->destroy_data = &buffer_destroy;
 43-
 44-    return buffer;
 45-}
 46-
 47 static void handle_screen_event(struct wl_listener * listener, void * data)
 48 {
 49     struct swc_event * event = data;
 50@@ -207,12 +181,9 @@ static void handle_screen_view_event(struct wl_listener * listener, void * data)
 51 
 52 static bool target_swap_buffers(struct target * target)
 53 {
 54-    struct swc_buffer * buffer;
 55-
 56     target->next_buffer = wld_surface_take(target->surface);
 57-    buffer = buffer_get(target->next_buffer);
 58 
 59-    if (!swc_view_attach(target->view, buffer))
 60+    if (!swc_view_attach(target->view, target->next_buffer))
 61     {
 62         ERROR("Failed to attach next frame to screen\n");
 63         return false;
 64@@ -281,7 +252,7 @@ static void repaint_view(struct target * target, struct view * view,
 65     if (pixman_region32_not_empty(&view_damage))
 66     {
 67         pixman_region32_translate(&view_damage, -geometry->x, -geometry->y);
 68-        wld_copy_region(swc.drm->renderer, view->wld,
 69+        wld_copy_region(swc.drm->renderer, view->buffer,
 70                         geometry->x - target->view->geometry.x,
 71                         geometry->y - target->view->geometry.y, &view_damage);
 72     }
 73@@ -333,18 +304,18 @@ static void renderer_repaint(struct target * target,
 74     wld_flush(swc.drm->renderer);
 75 }
 76 
 77-static bool renderer_attach(struct view * view, struct swc_buffer * buffer)
 78+static bool renderer_attach(struct view * view, struct wld_buffer * client_buffer)
 79 {
 80-    struct wld_buffer * wld;
 81-    bool was_proxy = view->base.buffer && view->wld != view->base.buffer->wld;
 82-    bool needs_proxy = buffer
 83+    struct wld_buffer * buffer;
 84+    bool was_proxy = view->buffer != view->base.buffer;
 85+    bool needs_proxy = client_buffer
 86         && !(wld_capabilities(swc.drm->renderer,
 87-                              buffer->wld) & WLD_CAPABILITY_READ);
 88-    bool resized = view->wld && buffer
 89-        && (view->wld->width != buffer->wld->width
 90-            || view->wld->height != buffer->wld->height);
 91+                              client_buffer) & WLD_CAPABILITY_READ);
 92+    bool resized = view->buffer && client_buffer
 93+        && (view->buffer->width != client_buffer->width
 94+            || view->buffer->height != client_buffer->height);
 95 
 96-    if (buffer)
 97+    if (client_buffer)
 98     {
 99         /* Create a proxy buffer if necessary (for example a hardware buffer
100          * backing a SHM buffer). */
101@@ -353,42 +324,46 @@ static bool renderer_attach(struct view * view, struct swc_buffer * buffer)
102             if (!was_proxy || resized)
103             {
104                 DEBUG("Creating a proxy buffer\n");
105-                wld = wld_create_buffer(swc.drm->context,
106-                                        buffer->wld->width, buffer->wld->height,
107-                                        buffer->wld->format, WLD_FLAG_MAP);
108+                buffer = wld_create_buffer(swc.drm->context,
109+                                           client_buffer->width,
110+                                           client_buffer->height,
111+                                           client_buffer->format, WLD_FLAG_MAP);
112 
113-                if (!wld)
114+                if (!buffer)
115                     return false;
116             }
117             else
118             {
119                 /* Otherwise we can keep the original proxy buffer. */
120-                wld = view->wld;
121+                buffer = view->buffer;
122             }
123         }
124         else
125-            wld = buffer->wld;
126+            buffer = client_buffer;
127     }
128     else
129-        wld = NULL;
130+        buffer = NULL;
131 
132     /* If we no longer need a proxy buffer, or the original buffer is of a
133      * different size, destroy the old proxy image. */
134-    if (view->wld && ((!needs_proxy && was_proxy) || (needs_proxy && resized)))
135-        wld_destroy_buffer(view->wld);
136+    if (view->buffer && ((!needs_proxy && was_proxy)
137+                         || (needs_proxy && resized)))
138+    {
139+        wld_buffer_unreference(view->buffer);
140+    }
141 
142-    view->wld = wld;
143+    view->buffer = buffer;
144 
145     return true;
146 }
147 
148 static void renderer_flush_view(struct view * view)
149 {
150-    if (view->wld == view->base.buffer->wld)
151+    if (view->buffer == view->base.buffer)
152         return;
153 
154-    wld_set_target_buffer(swc.shm->renderer, view->wld);
155-    wld_copy_region(swc.shm->renderer, view->base.buffer->wld,
156+    wld_set_target_buffer(swc.shm->renderer, view->buffer);
157+    wld_copy_region(swc.shm->renderer, view->base.buffer,
158                     0, 0, &view->surface->state.damage);
159     wld_flush(swc.shm->renderer);
160 }
161@@ -461,7 +436,7 @@ static bool update(struct swc_view * view)
162     return true;
163 }
164 
165-static bool attach(struct swc_view * base, struct swc_buffer * buffer)
166+static bool attach(struct swc_view * base, struct wld_buffer * buffer)
167 {
168     struct view * view = (void *) base;
169 
170@@ -548,7 +523,7 @@ bool swc_compositor_add_surface(struct swc_surface * surface)
171     view->event_listener.notify = &handle_view_event;
172     wl_signal_add(&view->base.event_signal, &view->event_listener);
173     view->surface = surface;
174-    view->wld = NULL;
175+    view->buffer = NULL;
176     view->extents.x1 = 0;
177     view->extents.y1 = 0;
178     view->extents.x2 = 0;
+3, -4
 1@@ -22,7 +22,6 @@
 2  */
 3 
 4 #include "cursor_plane.h"
 5-#include "buffer.h"
 6 #include "drm.h"
 7 #include "internal.h"
 8 #include "launch.h"
 9@@ -39,7 +38,7 @@ static bool update(struct swc_view * view)
10     return true;
11 }
12 
13-static bool attach(struct swc_view * view, struct swc_buffer * buffer)
14+static bool attach(struct swc_view * view, struct wld_buffer * buffer)
15 {
16     struct swc_cursor_plane * plane = CONTAINER_OF(view, typeof(*plane), view);
17 
18@@ -47,14 +46,14 @@ static bool attach(struct swc_view * view, struct swc_buffer * buffer)
19     {
20         union wld_object object;
21 
22-        if (!wld_export(buffer->wld, WLD_DRM_OBJECT_HANDLE, &object))
23+        if (!wld_export(buffer, WLD_DRM_OBJECT_HANDLE, &object))
24         {
25             ERROR("Could not get export buffer to DRM handle\n");
26             return false;
27         }
28 
29         if (drmModeSetCursor(swc.drm->fd, plane->crtc, object.u32,
30-                             buffer->wld->width, buffer->wld->height) != 0)
31+                             buffer->width, buffer->height) != 0)
32         {
33             ERROR("Could not set cursor: %s\n", strerror(errno));
34             return false;
+16, -16
 1@@ -74,25 +74,25 @@ static void create_buffer(struct wl_client * client,
 2                           uint32_t name, int32_t width, int32_t height,
 3                           uint32_t stride, uint32_t format)
 4 {
 5-    struct wld_buffer * wld;
 6-    struct swc_buffer * buffer;
 7+    struct wld_buffer * buffer;
 8+    struct wl_resource * buffer_resource;
 9     union wld_object object = { .u32 = name };
10 
11-    wld = wld_import_buffer(swc.drm->context, WLD_DRM_OBJECT_GEM_NAME, object,
12-                            width, height, format, stride);
13+    buffer = wld_import_buffer(swc.drm->context, WLD_DRM_OBJECT_GEM_NAME,
14+                               object, width, height, format, stride);
15 
16-    if (!wld)
17+    if (!buffer)
18         goto error0;
19 
20-    buffer = swc_wayland_buffer_new(client, id, wld);
21+    buffer_resource = swc_wayland_buffer_create_resource(client, id, buffer);
22 
23-    if (!buffer)
24+    if (!buffer_resource)
25         goto error1;
26 
27     return;
28 
29   error1:
30-    wld_destroy_buffer(wld);
31+    wld_buffer_unreference(buffer);
32   error0:
33     wl_resource_post_no_memory(resource);
34 }
35@@ -117,26 +117,26 @@ static void create_prime_buffer(struct wl_client * client,
36                                 int32_t offset1, int32_t stride1,
37                                 int32_t offset2, int32_t stride2)
38 {
39-    struct wld_buffer * wld;
40-    struct swc_buffer * buffer;
41+    struct wld_buffer * buffer;
42+    struct wl_resource * buffer_resource;
43     union wld_object object = { .i = fd };
44 
45-    wld = wld_import_buffer(swc.drm->context, WLD_DRM_OBJECT_PRIME_FD, object,
46-                            width, height, format, stride0);
47+    buffer = wld_import_buffer(swc.drm->context, WLD_DRM_OBJECT_PRIME_FD,
48+                               object, width, height, format, stride0);
49     close(fd);
50 
51-    if (!wld)
52+    if (!buffer)
53         goto error0;
54 
55-    buffer = swc_wayland_buffer_new(client, id, wld);
56+    buffer_resource = swc_wayland_buffer_create_resource(client, id, buffer);
57 
58-    if (!buffer)
59+    if (!buffer_resource)
60         goto error1;
61 
62     return;
63 
64   error1:
65-    wld_destroy_buffer(wld);
66+    wld_buffer_unreference(buffer);
67   error0:
68     wl_resource_post_no_memory(resource);
69 }
+54, -50
  1@@ -22,7 +22,6 @@
  2  */
  3 
  4 #include "framebuffer_plane.h"
  5-#include "buffer.h"
  6 #include "drm.h"
  7 #include "internal.h"
  8 #include "util.h"
  9@@ -33,63 +32,43 @@
 10 #include <xf86drm.h>
 11 #include <xf86drmMode.h>
 12 
 13+enum
 14+{
 15+    WLD_USER_OBJECT_FRAMEBUFFER = WLD_USER_ID
 16+};
 17+
 18 struct framebuffer
 19 {
 20+    struct wld_exporter exporter;
 21+    struct wld_destructor destructor;
 22     uint32_t id;
 23-    struct wl_listener destroy_listener;
 24 };
 25 
 26-static void handle_buffer_destroy(struct wl_listener * listener, void * data)
 27+static bool framebuffer_export(struct wld_exporter * exporter,
 28+                               struct wld_buffer * buffer,
 29+                               uint32_t type, union wld_object * object)
 30 {
 31     struct framebuffer * framebuffer
 32-        = CONTAINER_OF(listener, typeof(*framebuffer), destroy_listener);
 33-
 34-    drmModeRmFB(swc.drm->fd, framebuffer->id);
 35-    free(framebuffer);
 36-}
 37-
 38-static struct framebuffer * framebuffer_get(struct swc_buffer * buffer)
 39-{
 40-    struct wl_listener * listener
 41-        = wl_signal_get(&buffer->destroy_signal, &handle_buffer_destroy);
 42-    struct framebuffer * framebuffer;
 43+        = CONTAINER_OF(exporter, typeof(*framebuffer), exporter);
 44 
 45-    if (listener)
 46+    switch (type)
 47     {
 48-        framebuffer = CONTAINER_OF(listener, typeof(*framebuffer),
 49-                                   destroy_listener);
 50+        case WLD_USER_OBJECT_FRAMEBUFFER:
 51+            object->u32 = framebuffer->id;
 52+            break;
 53+        default: return false;
 54     }
 55-    else
 56-    {
 57-        struct wld_buffer * wld = buffer->wld;
 58-        union wld_object object;
 59 
 60-        if (!wld_export(wld, WLD_DRM_OBJECT_HANDLE, &object))
 61-        {
 62-            ERROR("Could not get buffer handle\n");
 63-            goto error0;
 64-        }
 65-
 66-
 67-        if (!(framebuffer = malloc(sizeof *framebuffer)))
 68-            goto error0;
 69-
 70-        if (drmModeAddFB(swc.drm->fd, wld->width, wld->height, 24, 32,
 71-                         wld->pitch, object.u32, &framebuffer->id) != 0)
 72-        {
 73-            goto error1;
 74-        }
 75-
 76-        framebuffer->destroy_listener.notify = &handle_buffer_destroy;
 77-        wl_signal_add(&buffer->destroy_signal, &framebuffer->destroy_listener);
 78-    }
 79+    return true;
 80+}
 81 
 82-    return framebuffer;
 83+static void framebuffer_destroy(struct wld_destructor * destructor)
 84+{
 85+    struct framebuffer * framebuffer
 86+        = CONTAINER_OF(destructor, typeof(*framebuffer), destructor);
 87 
 88-  error1:
 89+    drmModeRmFB(swc.drm->fd, framebuffer->id);
 90     free(framebuffer);
 91-  error0:
 92-    return NULL;
 93 }
 94 
 95 static bool update(struct swc_view * view)
 96@@ -104,18 +83,43 @@ static void send_frame(void * data)
 97     swc_view_frame(&plane->view, swc_time());
 98 }
 99 
100-static bool attach(struct swc_view * view, struct swc_buffer * buffer)
101+static bool attach(struct swc_view * view, struct wld_buffer * buffer)
102 {
103     struct swc_framebuffer_plane * plane
104         = CONTAINER_OF(view, typeof(*plane), view);
105-    struct framebuffer * framebuffer = framebuffer_get(buffer);
106+    union wld_object object;
107+
108+    if (!wld_export(buffer, WLD_USER_OBJECT_FRAMEBUFFER, &object))
109+    {
110+        struct framebuffer * framebuffer;
111+
112+        if (!wld_export(buffer, WLD_DRM_OBJECT_HANDLE, &object))
113+        {
114+            ERROR("Could not get buffer handle\n");
115+            return false;
116+        }
117+
118+        if (!(framebuffer = malloc(sizeof *framebuffer)))
119+            return false;
120 
121-    if (!framebuffer)
122-        return false;
123+        if (drmModeAddFB(swc.drm->fd, buffer->width, buffer->height, 24, 32,
124+                         buffer->pitch, object.u32, &framebuffer->id) != 0)
125+        {
126+            free(framebuffer);
127+            return false;
128+        }
129+
130+        framebuffer->exporter.export = &framebuffer_export;
131+        wld_buffer_add_exporter(buffer, &framebuffer->exporter);
132+        framebuffer->destructor.destroy = &framebuffer_destroy;
133+        wld_buffer_add_destructor(buffer, &framebuffer->destructor);
134+
135+        object.u32 = framebuffer->id;
136+    }
137 
138     if (plane->need_modeset)
139     {
140-        if (drmModeSetCrtc(swc.drm->fd, plane->crtc, framebuffer->id, 0, 0,
141+        if (drmModeSetCrtc(swc.drm->fd, plane->crtc, object.u32, 0, 0,
142                            plane->connectors.data, plane->connectors.size / 4,
143                            &plane->mode.info) == 0)
144         {
145@@ -131,7 +135,7 @@ static bool attach(struct swc_view * view, struct swc_buffer * buffer)
146     }
147     else
148     {
149-        if (drmModePageFlip(swc.drm->fd, plane->crtc, framebuffer->id,
150+        if (drmModePageFlip(swc.drm->fd, plane->crtc, object.u32,
151                             DRM_MODE_PAGE_FLIP_EVENT, &plane->drm_handler) != 0)
152         {
153             ERROR("Page flip failed: %s\n", strerror(errno));
+0, -1
1@@ -29,7 +29,6 @@ $(dir)_PACKAGES =   \
2 SWC_SOURCES =                       \
3     launch/protocol.c               \
4     libswc/bindings.c               \
5-    libswc/buffer.c                 \
6     libswc/compositor.c             \
7     libswc/cursor_plane.c           \
8     libswc/data.c                   \
+15, -17
 1@@ -84,7 +84,7 @@ static bool update(struct swc_view * view)
 2     return true;
 3 }
 4 
 5-static bool attach(struct swc_view * view, struct swc_buffer * buffer)
 6+static bool attach(struct swc_view * view, struct wld_buffer * buffer)
 7 {
 8     struct swc_pointer * pointer
 9         = CONTAINER_OF(view, typeof(*pointer), cursor.view);
10@@ -93,10 +93,10 @@ static bool attach(struct swc_view * view, struct swc_buffer * buffer)
11     if (surface && !pixman_region32_not_empty(&surface->state.damage))
12         return true;
13 
14-    wld_set_target_buffer(swc.shm->renderer, pointer->cursor.buffer.wld);
15+    wld_set_target_buffer(swc.shm->renderer, pointer->cursor.buffer);
16     wld_fill_rectangle(swc.shm->renderer, 0x00000000, 0, 0, 64, 64);
17-    wld_copy_rectangle(swc.shm->renderer, buffer->wld, 0, 0, 0, 0,
18-                       buffer->wld->width, buffer->wld->height);
19+    wld_copy_rectangle(swc.shm->renderer, buffer, 0, 0, 0, 0,
20+                       buffer->width, buffer->height);
21     wld_flush(swc.shm->renderer);
22 
23     if (surface)
24@@ -145,7 +145,7 @@ static void handle_view_event(struct wl_listener * listener, void * data)
25                     if (!screen->planes.cursor.view.buffer)
26                     {
27                         swc_view_attach(&screen->planes.cursor.view,
28-                                        &pointer->cursor.buffer);
29+                                        pointer->cursor.buffer);
30                     }
31                 }
32                 else if (screen->planes.cursor.view.buffer)
33@@ -164,7 +164,7 @@ static void handle_view_event(struct wl_listener * listener, void * data)
34                 if (entered & screen_mask(screen))
35                 {
36                     swc_view_attach(&screen->planes.cursor.view,
37-                                    &pointer->cursor.buffer);
38+                                    pointer->cursor.buffer);
39                 }
40                 else if (left & screen_mask(screen))
41                     swc_view_attach(&screen->planes.cursor.view, NULL);
42@@ -186,14 +186,14 @@ void swc_pointer_set_cursor(struct swc_pointer * pointer, uint32_t id)
43     struct cursor * cursor = &cursor_metadata[id];
44     union wld_object object = { .ptr = &cursor_data[cursor->offset] };
45 
46-    if (pointer->cursor.internal_buffer.wld)
47-        wld_destroy_buffer(pointer->cursor.internal_buffer.wld);
48+    if (pointer->cursor.internal_buffer)
49+        wld_buffer_unreference(pointer->cursor.internal_buffer);
50 
51-    pointer->cursor.internal_buffer.wld = wld_import_buffer
52+    pointer->cursor.internal_buffer = wld_import_buffer
53         (swc.shm->context, WLD_OBJECT_DATA, object,
54          cursor->width, cursor->height, WLD_FORMAT_ARGB8888, cursor->width * 4);
55 
56-    if (!pointer->cursor.internal_buffer.wld)
57+    if (!pointer->cursor.internal_buffer)
58     {
59         ERROR("Failed to create cursor buffer\n");
60         return;
61@@ -202,12 +202,11 @@ void swc_pointer_set_cursor(struct swc_pointer * pointer, uint32_t id)
62     pointer->cursor.hotspot.x = cursor->hotspot_x;
63     pointer->cursor.hotspot.y = cursor->hotspot_y;
64     update_cursor(pointer);
65-    swc_view_attach(&pointer->cursor.view, &pointer->cursor.internal_buffer);
66+    swc_view_attach(&pointer->cursor.view, pointer->cursor.internal_buffer);
67 }
68 
69 bool swc_pointer_initialize(struct swc_pointer * pointer)
70 {
71-    struct wld_buffer * buffer;
72     struct screen * screen;
73 
74     /* Center cursor in the geometry of the first screen. */
75@@ -226,14 +225,13 @@ bool swc_pointer_initialize(struct swc_pointer * pointer)
76                   &pointer->cursor.view_listener);
77     pointer->cursor.surface = NULL;
78     pointer->cursor.destroy_listener.notify = &handle_cursor_surface_destroy;
79-    buffer = wld_create_buffer(swc.drm->context, 64, 64, WLD_FORMAT_ARGB8888,
80-                               WLD_FLAG_MAP);
81+    pointer->cursor.buffer = wld_create_buffer
82+        (swc.drm->context, 64, 64, WLD_FORMAT_ARGB8888, WLD_FLAG_MAP);
83+    pointer->cursor.internal_buffer = NULL;
84 
85-    if (!buffer)
86+    if (!pointer->cursor.buffer)
87         return false;
88 
89-    swc_buffer_initialize(&pointer->cursor.buffer, buffer);
90-    swc_buffer_initialize(&pointer->cursor.internal_buffer, NULL);
91     swc_pointer_set_cursor(pointer, cursor_left_ptr);
92 
93     swc_input_focus_initialize(&pointer->focus, &pointer->focus_handler);
+2, -3
 1@@ -24,7 +24,6 @@
 2 #ifndef SWC_POINTER_H
 3 #define SWC_POINTER_H
 4 
 5-#include "buffer.h"
 6 #include "input_focus.h"
 7 #include "surface.h"
 8 #include "view.h"
 9@@ -55,10 +54,10 @@ struct swc_pointer
10         struct wl_listener view_listener;
11         struct swc_surface * surface;
12         struct wl_listener destroy_listener;
13-        struct swc_buffer buffer;
14+        struct wld_buffer * buffer;
15 
16         /* Used for cursors set with swc_pointer_set_cursor */
17-        struct swc_buffer internal_buffer;
18+        struct wld_buffer * internal_buffer;
19 
20         struct
21         {
+16, -14
 1@@ -22,7 +22,6 @@
 2  */
 3 
 4 #include "surface.h"
 5-#include "buffer.h"
 6 #include "event.h"
 7 #include "internal.h"
 8 #include "output.h"
 9@@ -85,8 +84,11 @@ static void state_finish(struct swc_surface_state * state)
10  * @return: Whether or not the buffer was changed.
11  */
12 static void state_set_buffer(struct swc_surface_state * state,
13-                             struct swc_buffer * buffer)
14+                             struct wl_resource * resource)
15 {
16+    struct wld_buffer * buffer = resource ? swc_wayland_buffer_get(resource)
17+                                          : NULL;
18+
19     if (state->buffer)
20     {
21         /* No longer need to worry about the old buffer being destroyed. */
22@@ -97,10 +99,12 @@ static void state_set_buffer(struct swc_surface_state * state,
23     {
24         /* Need to watch the new buffer for destruction so we can remove it
25          * from state. */
26-        wl_signal_add(&buffer->destroy_signal, &state->buffer_destroy_listener);
27+        wl_resource_add_destroy_listener(resource,
28+                                         &state->buffer_destroy_listener);
29     }
30 
31     state->buffer = buffer;
32+    state->buffer_resource = resource;
33 }
34 
35 static void destroy(struct wl_client * client, struct wl_resource * resource)
36@@ -112,13 +116,10 @@ static void attach(struct wl_client * client, struct wl_resource * resource,
37                    struct wl_resource * buffer_resource, int32_t x, int32_t y)
38 {
39     struct swc_surface * surface = wl_resource_get_user_data(resource);
40-    struct swc_buffer * buffer
41-        = buffer_resource ? swc_wayland_buffer_get(buffer_resource) : NULL;
42 
43     surface->pending.commit |= SWC_SURFACE_COMMIT_ATTACH;
44 
45-    state_set_buffer(&surface->pending.state, buffer);
46-
47+    state_set_buffer(&surface->pending.state, buffer_resource);
48     surface->pending.x = x;
49     surface->pending.y = y;
50 }
51@@ -195,16 +196,17 @@ static void commit(struct wl_client * client, struct wl_resource * resource)
52     /* Attach */
53     if (surface->pending.commit & SWC_SURFACE_COMMIT_ATTACH)
54     {
55-        struct swc_buffer * current_buffer = surface->state.buffer,
56-                          * pending_buffer = surface->pending.state.buffer;
57-
58-        if (current_buffer && current_buffer != pending_buffer)
59-            swc_wayland_buffer_release(current_buffer);
60+        if (surface->state.buffer
61+            && surface->state.buffer != surface->pending.state.buffer)
62+        {
63+            wl_buffer_send_release(surface->state.buffer_resource);
64+        }
65 
66-        state_set_buffer(&surface->state, surface->pending.state.buffer);
67+        state_set_buffer(&surface->state,
68+                         surface->pending.state.buffer_resource);
69     }
70 
71-    buffer = surface->state.buffer ? surface->state.buffer->wld : NULL;
72+    buffer = surface->state.buffer;
73 
74     /* Damage */
75     if (surface->pending.commit & SWC_SURFACE_COMMIT_DAMAGE)
+2, -1
 1@@ -39,7 +39,8 @@ enum
 2 
 3 struct swc_surface_state
 4 {
 5-    struct swc_buffer * buffer;
 6+    struct wld_buffer * buffer;
 7+    struct wl_resource * buffer_resource;
 8     struct wl_listener buffer_destroy_listener;
 9 
10     /* The region that needs to be repainted. */
+5, -18
 1@@ -22,7 +22,6 @@
 2  */
 3 
 4 #include "view.h"
 5-#include "buffer.h"
 6 #include "event.h"
 7 #include "internal.h"
 8 #include "screen.h"
 9@@ -72,16 +71,6 @@ static void set_size(struct swc_view * view, uint32_t width, uint32_t height)
10     }
11 }
12 
13-static void handle_buffer_destroy(struct wl_listener * listener, void * data)
14-{
15-    struct swc_view * view
16-        = CONTAINER_OF(listener, typeof(*view), buffer_destroy_listener);
17-
18-    view->impl->attach(view, NULL);
19-    view->buffer = NULL;
20-    set_size(view, 0, 0);
21-}
22-
23 void swc_view_initialize(struct swc_view * view,
24                          const struct swc_view_impl * impl)
25 {
26@@ -92,7 +81,6 @@ void swc_view_initialize(struct swc_view * view,
27     view->geometry.width = 0;
28     view->geometry.height = 0;
29     view->buffer = NULL;
30-    view->buffer_destroy_listener.notify = &handle_buffer_destroy;
31     view->screens = 0;
32     wl_signal_init(&view->event_signal);
33 }
34@@ -100,21 +88,20 @@ void swc_view_initialize(struct swc_view * view,
35 void swc_view_finalize(struct swc_view * view)
36 {
37     if (view->buffer)
38-        wl_list_remove(&view->buffer_destroy_listener.link);
39+        wld_buffer_unreference(view->buffer);
40 }
41 
42-bool swc_view_attach(struct swc_view * view, struct swc_buffer * buffer)
43+bool swc_view_attach(struct swc_view * view, struct wld_buffer * buffer)
44 {
45     if (view->impl->attach(view, buffer))
46     {
47         if (view->buffer)
48-            wl_list_remove(&view->buffer_destroy_listener.link);
49+            wld_buffer_unreference(view->buffer);
50 
51         if (buffer)
52         {
53-            wl_signal_add(&buffer->destroy_signal,
54-                          &view->buffer_destroy_listener);
55-            set_size(view, buffer->wld->width, buffer->wld->height);
56+            wld_buffer_reference(buffer);
57+            set_size(view, buffer->width, buffer->height);
58         }
59         else
60             set_size(view, 0, 0);
+3, -4
 1@@ -93,8 +93,7 @@ struct swc_view
 2      */
 3     struct screen * screen;
 4 
 5-    struct swc_buffer * buffer;
 6-    struct wl_listener buffer_destroy_listener;
 7+    struct wld_buffer * buffer;
 8 };
 9 
10 /**
11@@ -105,7 +104,7 @@ struct swc_view
12 struct swc_view_impl
13 {
14     bool (* update)(struct swc_view * view);
15-    bool (* attach)(struct swc_view * view, struct swc_buffer * buffer);
16+    bool (* attach)(struct swc_view * view, struct wld_buffer * buffer);
17     bool (* move)(struct swc_view * view, int32_t x, int32_t y);
18 
19     /**
20@@ -135,7 +134,7 @@ void swc_view_finalize(struct swc_view * view);
21  *
22  * @return Whether or not the buffer was successfully attached to the view.
23  */
24-bool swc_view_attach(struct swc_view * view, struct swc_buffer * buffer);
25+bool swc_view_attach(struct swc_view * view, struct wld_buffer * buffer);
26 
27 /**
28  * Display a new frame consisting of the currently attached buffer.
+24, -44
  1@@ -22,7 +22,6 @@
  2  */
  3 
  4 #include "wayland_buffer.h"
  5-#include "buffer.h"
  6 #include "internal.h"
  7 #include "shm.h"
  8 #include "util.h"
  9@@ -32,8 +31,7 @@
 10 
 11 struct wayland_buffer
 12 {
 13-    struct swc_buffer base;
 14-    struct wl_resource * resource;
 15+    struct wld_buffer * wld;
 16     struct wl_listener destroy_listener;
 17 };
 18 
 19@@ -53,7 +51,7 @@ static void handle_buffer_destroy(struct wl_listener * listener, void * data)
 20     struct wayland_buffer * buffer
 21         = CONTAINER_OF(listener, typeof(*buffer), destroy_listener);
 22 
 23-    swc_buffer_finalize(&buffer->base);
 24+    wld_buffer_unreference(buffer->wld);
 25     free(buffer);
 26 }
 27 
 28@@ -70,7 +68,7 @@ static inline uint32_t format_shm_to_wld(uint32_t format)
 29     }
 30 }
 31 
 32-struct swc_buffer * swc_wayland_buffer_get(struct wl_resource * resource)
 33+struct wld_buffer * swc_wayland_buffer_get(struct wl_resource * resource)
 34 {
 35     if (wl_resource_instance_of(resource, &wl_buffer_interface,
 36                                 &buffer_implementation))
 37@@ -88,11 +86,13 @@ struct swc_buffer * swc_wayland_buffer_get(struct wl_resource * resource)
 38     {
 39         buffer = CONTAINER_OF(listener, typeof(*buffer), destroy_listener);
 40 
 41-        return &buffer->base;
 42+        return buffer->wld;
 43     }
 44 
 45+    if (!(buffer = malloc(sizeof *buffer)))
 46+        goto error0;
 47+
 48     struct wl_shm_buffer * shm_buffer;
 49-    struct wld_buffer * wld = NULL;
 50 
 51     if ((shm_buffer = wl_shm_buffer_get(resource)))
 52     {
 53@@ -100,7 +100,7 @@ struct swc_buffer * swc_wayland_buffer_get(struct wl_resource * resource)
 54             .ptr = wl_shm_buffer_get_data(shm_buffer)
 55         };
 56 
 57-        wld = wld_import_buffer
 58+        buffer->wld = wld_import_buffer
 59             (swc.shm->context, WLD_OBJECT_DATA, object,
 60              wl_shm_buffer_get_width(shm_buffer),
 61              wl_shm_buffer_get_height(shm_buffer),
 62@@ -108,64 +108,44 @@ struct swc_buffer * swc_wayland_buffer_get(struct wl_resource * resource)
 63              wl_shm_buffer_get_stride(shm_buffer));
 64     }
 65 
 66-    if (!wld)
 67-        goto error0;
 68-
 69-    if (!(buffer = malloc(sizeof *buffer)))
 70+    if (!buffer->wld)
 71         goto error1;
 72 
 73-    swc_buffer_initialize(&buffer->base, wld);
 74-    buffer->resource = resource;
 75     buffer->destroy_listener.notify = &handle_buffer_destroy;
 76     wl_resource_add_destroy_listener(resource,
 77                                      &buffer->destroy_listener);
 78 
 79-    return &buffer->base;
 80+    return buffer->wld;
 81 
 82   error1:
 83-    wld_destroy_buffer(wld);
 84+    free(buffer);
 85   error0:
 86     return NULL;
 87 }
 88 
 89 static void destroy_buffer(struct wl_resource * resource)
 90 {
 91-    struct wayland_buffer * buffer = wl_resource_get_user_data(resource);
 92+    struct wld_buffer * buffer = wl_resource_get_user_data(resource);
 93 
 94-    swc_buffer_finalize(&buffer->base);
 95-    free(buffer);
 96+    wld_buffer_unreference(buffer);
 97 }
 98 
 99-struct swc_buffer * swc_wayland_buffer_new
100-    (struct wl_client * client, uint32_t id, struct wld_buffer * wld)
101+struct wl_resource * swc_wayland_buffer_create_resource
102+    (struct wl_client * client, uint32_t id, struct wld_buffer * buffer)
103 {
104-    struct wayland_buffer * buffer;
105-
106-    buffer = malloc(sizeof *buffer);
107-
108-    if (!buffer)
109-        goto error0;
110+    struct wl_resource * resource;
111 
112-    buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
113+    resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
114 
115-    if (!buffer->resource)
116-        goto error1;
117+    if (!resource)
118+    {
119+        wl_client_post_no_memory(client);
120+        return NULL;
121+    }
122 
123-    wl_resource_set_implementation(buffer->resource, &buffer_implementation,
124+    wl_resource_set_implementation(resource, &buffer_implementation,
125                                    buffer, &destroy_buffer);
126-    swc_buffer_initialize(&buffer->base, wld);
127-
128-    return &buffer->base;
129-
130-  error1:
131-    free(buffer);
132-  error0:
133-    wl_client_post_no_memory(client);
134-    return NULL;
135-}
136 
137-void swc_wayland_buffer_release(struct swc_buffer * buffer)
138-{
139-    wl_buffer_send_release(((struct wayland_buffer *) buffer)->resource);
140+    return resource;
141 }
142 
+2, -5
 1@@ -28,14 +28,11 @@
 2 
 3 struct wl_client;
 4 struct wl_resource;
 5-struct wld_buffer;
 6 
 7-struct swc_buffer * swc_wayland_buffer_get(struct wl_resource * resource);
 8+struct wld_buffer * swc_wayland_buffer_get(struct wl_resource * resource);
 9 
10-struct swc_buffer * swc_wayland_buffer_new
11+struct wl_resource * swc_wayland_buffer_create_resource
12     (struct wl_client * client, uint32_t id, struct wld_buffer * buffer);
13 
14-void swc_wayland_buffer_release(struct swc_buffer * buffer);
15-
16 #endif
17