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