swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

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:
Dlibswc/buffer.c | 39---------------------------------------
Dlibswc/buffer.h | 40----------------------------------------
Mlibswc/compositor.c | 87++++++++++++++++++++++++++++---------------------------------------------------
Mlibswc/cursor_plane.c | 7+++----
Mlibswc/drm.c | 32++++++++++++++++----------------
Mlibswc/framebuffer_plane.c | 104+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mlibswc/local.mk | 1-
Mlibswc/pointer.c | 32+++++++++++++++-----------------
Mlibswc/pointer.h | 5++---
Mlibswc/surface.c | 30++++++++++++++++--------------
Mlibswc/surface.h | 3++-
Mlibswc/view.c | 23+++++------------------
Mlibswc/view.h | 7+++----
Mlibswc/wayland_buffer.c | 68++++++++++++++++++++++++--------------------------------------------
Mlibswc/wayland_buffer.h | 7++-----
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