[PATCH weston] Remove weston_buffer_reference
Jason Ekstrand
jason at jlekstrand.net
Thu Jun 27 19:13:21 PDT 2013
This commit removes the weston_buffer_reference structure and replaces it's
funtionality with weston_buffer_ref and weston_buffer_decref functions.
NOTE: This patch needs thurough review before committing. I do not know
the weston internals all that well and so I don't know if this will break
anything. In particular, I don't know which of the buffer_ref.buffer !=
NULL checks check to see if the resource is destroyed or just if the buffer
has gone missing. There may be dragons in this patch.
---
src/compositor-drm.c | 37 +++++++++++---------
src/compositor.c | 95 +++++++++++++++++++++++++--------------------------
src/compositor.h | 15 ++++----
src/data-device.c | 2 +-
src/gl-renderer.c | 17 +++++----
src/input.c | 2 +-
src/pixman-renderer.c | 15 +++++---
src/rpi-renderer.c | 11 +++---
src/shell.c | 4 +--
9 files changed, 105 insertions(+), 93 deletions(-)
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index e704c9f..d62c7aa 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -118,7 +118,7 @@ struct drm_fb {
uint32_t fb_id, stride, handle, size;
int fd;
int is_client_buffer;
- struct weston_buffer_reference buffer_ref;
+ struct weston_buffer *buffer;
/* Used by gbm fbs */
struct gbm_bo *bo;
@@ -220,7 +220,8 @@ drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
if (fb->fb_id)
drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id);
- weston_buffer_reference(&fb->buffer_ref, NULL);
+ weston_buffer_decref(fb->buffer);
+ fb->buffer = NULL;
free(data);
}
@@ -292,7 +293,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
if (fb->fb_id)
drmModeRmFB(fb->fd, fb->fb_id);
- weston_buffer_reference(&fb->buffer_ref, NULL);
+ weston_buffer_decref(fb->buffer);
+ fb->buffer = NULL;
munmap(fb->map, fb->size);
@@ -373,11 +375,12 @@ err_free:
static void
drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
{
- assert(fb->buffer_ref.buffer == NULL);
+ assert(fb->buffer == NULL);
fb->is_client_buffer = 1;
- weston_buffer_reference(&fb->buffer_ref, buffer);
+ weston_buffer_ref(buffer);
+ fb->buffer = buffer;
}
static void
@@ -437,7 +440,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
struct drm_output *output = (struct drm_output *) _output;
struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor;
- struct weston_buffer *buffer = es->buffer_ref.buffer;
+ struct weston_buffer *buffer = es->buffer;
struct gbm_bo *bo;
uint32_t format;
@@ -785,13 +788,13 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
if (es->output_mask != (1u << output_base->id))
return NULL;
- if (es->buffer_ref.buffer == NULL)
+ if (es->buffer == NULL)
return NULL;
if (es->alpha != 1.0f)
return NULL;
- if (wl_shm_buffer_get(es->buffer_ref.buffer->resource))
+ if (wl_shm_buffer_get(es->buffer->resource))
return NULL;
if (!drm_surface_transform_supported(es))
@@ -812,7 +815,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
return NULL;
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
- es->buffer_ref.buffer, GBM_BO_USE_SCANOUT);
+ es->buffer, GBM_BO_USE_SCANOUT);
if (!bo)
return NULL;
@@ -828,7 +831,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
return NULL;
}
- drm_fb_set_buffer(s->next, es->buffer_ref.buffer);
+ drm_fb_set_buffer(s->next, es->buffer);
box = pixman_region32_extents(&es->transform.boundingbox);
s->plane.x = box->x1;
@@ -914,8 +917,8 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base,
return NULL;
if (c->cursors_are_broken)
return NULL;
- if (es->buffer_ref.buffer == NULL ||
- !wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
+ if (es->buffer == NULL ||
+ !wl_shm_buffer_get(es->buffer->resource) ||
es->geometry.width > 64 || es->geometry.height > 64)
return NULL;
@@ -942,15 +945,15 @@ drm_output_set_cursor(struct drm_output *output)
return;
}
- if (es->buffer_ref.buffer &&
+ if (es->buffer &&
pixman_region32_not_empty(&output->cursor_plane.damage)) {
pixman_region32_fini(&output->cursor_plane.damage);
pixman_region32_init(&output->cursor_plane.damage);
output->current_cursor ^= 1;
bo = output->cursor_bo[output->current_cursor];
memset(buf, 0, sizeof buf);
- stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer);
- s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer);
+ stride = wl_shm_buffer_get_stride(es->buffer->shm_buffer);
+ s = wl_shm_buffer_get_data(es->buffer->shm_buffer);
for (i = 0; i < es->geometry.height; i++)
memcpy(buf + i * 64, s + i * stride,
es->geometry.width * 4);
@@ -1007,8 +1010,8 @@ drm_assign_planes(struct weston_output *output)
/* test whether this buffer can ever go into a plane:
* non-shm, or small enough to be a cursor
*/
- if ((es->buffer_ref.buffer &&
- !wl_shm_buffer_get(es->buffer_ref.buffer->resource)) ||
+ if ((es->buffer &&
+ !wl_shm_buffer_get(es->buffer->resource)) ||
(es->geometry.width <= 64 && es->geometry.height <= 64))
es->keep_buffer = 1;
else
diff --git a/src/compositor.c b/src/compositor.c
index bc17218..55831f6 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -900,10 +900,10 @@ weston_surface_buffer_width(struct weston_surface *surface)
case WL_OUTPUT_TRANSFORM_270:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- width = surface->buffer_ref.buffer->height;
+ width = surface->buffer->height;
break;
default:
- width = surface->buffer_ref.buffer->width;
+ width = surface->buffer->width;
break;
}
return width / surface->buffer_scale;
@@ -918,10 +918,10 @@ weston_surface_buffer_height(struct weston_surface *surface)
case WL_OUTPUT_TRANSFORM_270:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- height = surface->buffer_ref.buffer->width;
+ height = surface->buffer->width;
break;
default:
- height = surface->buffer_ref.buffer->height;
+ height = surface->buffer->height;
break;
}
return height / surface->buffer_scale;
@@ -1025,7 +1025,8 @@ weston_surface_destroy(struct weston_surface *surface)
if (surface->pending.buffer)
wl_list_remove(&surface->pending.buffer_destroy_listener.link);
- weston_buffer_reference(&surface->buffer_ref, NULL);
+ weston_buffer_decref(surface->buffer);
+ surface->buffer = NULL;
compositor->renderer->destroy_surface(surface);
@@ -1058,8 +1059,8 @@ weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
struct weston_buffer *buffer =
container_of(listener, struct weston_buffer, destroy_listener);
- wl_signal_emit(&buffer->destroy_signal, buffer);
- free(buffer);
+ buffer->resource = NULL;
+ weston_buffer_decref(buffer);
}
struct weston_buffer *
@@ -1079,6 +1080,7 @@ weston_buffer_from_resource(struct wl_resource *resource)
memset(buffer, 0, sizeof *buffer);
buffer->resource = resource;
+ buffer->busy_count = 1;
wl_signal_init(&buffer->destroy_signal);
buffer->destroy_listener.notify = weston_buffer_destroy_handler;
wl_resource_add_destroy_listener(resource,
@@ -1088,47 +1090,39 @@ weston_buffer_from_resource(struct wl_resource *resource)
return buffer;
}
-static void
-weston_buffer_reference_handle_destroy(struct wl_listener *listener,
- void *data)
+WL_EXPORT void
+weston_buffer_ref(struct weston_buffer *buffer)
{
- struct weston_buffer_reference *ref =
- container_of(listener, struct weston_buffer_reference,
- destroy_listener);
+ if (buffer == NULL)
+ return;
- assert((struct weston_buffer *)data == ref->buffer);
- ref->buffer = NULL;
+ buffer->busy_count++;
}
WL_EXPORT void
-weston_buffer_reference(struct weston_buffer_reference *ref,
- struct weston_buffer *buffer)
-{
- if (ref->buffer && buffer != ref->buffer) {
- ref->buffer->busy_count--;
- if (ref->buffer->busy_count == 0) {
- assert(wl_resource_get_client(ref->buffer->resource));
- wl_resource_queue_event(ref->buffer->resource,
- WL_BUFFER_RELEASE);
- }
- wl_list_remove(&ref->destroy_listener.link);
- }
+weston_buffer_decref(struct weston_buffer *buffer)
+{
+ if (buffer == NULL)
+ return;
- if (buffer && buffer != ref->buffer) {
- buffer->busy_count++;
- wl_signal_add(&buffer->destroy_signal,
- &ref->destroy_listener);
+ buffer->busy_count--;
+ if (buffer->resource && buffer->busy_count == 1) {
+ /* The only resource left is the one held by the resource */
+ wl_resource_queue_event(buffer->resource,
+ WL_BUFFER_RELEASE);
+ } else if (!buffer->resource && buffer->busy_count == 0) {
+ wl_signal_emit(&buffer->destroy_signal, buffer);
+ free(buffer);
}
-
- ref->buffer = buffer;
- ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
}
static void
weston_surface_attach(struct weston_surface *surface,
struct weston_buffer *buffer)
{
- weston_buffer_reference(&surface->buffer_ref, buffer);
+ weston_buffer_ref(buffer);
+ weston_buffer_decref(surface->buffer);
+ surface->buffer = buffer;
if (!buffer) {
if (weston_surface_is_mapped(surface))
@@ -1171,8 +1165,8 @@ static void
surface_accumulate_damage(struct weston_surface *surface,
pixman_region32_t *opaque)
{
- if (surface->buffer_ref.buffer &&
- wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
+ if (surface->buffer &&
+ wl_shm_buffer_get(surface->buffer->resource))
surface->compositor->renderer->flush_damage(surface);
if (surface->transform.enabled) {
@@ -1236,8 +1230,10 @@ compositor_accumulate_damage(struct weston_compositor *ec)
* reference now, and allow early buffer release. This enables
* clients to use single-buffering.
*/
- if (!es->keep_buffer)
- weston_buffer_reference(&es->buffer_ref, NULL);
+ if (!es->keep_buffer) {
+ weston_buffer_decref(es->buffer);
+ es->buffer = NULL;
+ }
}
}
@@ -1561,7 +1557,7 @@ weston_surface_commit(struct weston_surface *surface)
if (surface->pending.buffer || surface->pending.newly_attached)
weston_surface_attach(surface, surface->pending.buffer);
- if (surface->buffer_ref.buffer) {
+ if (surface->buffer) {
surface_width = weston_surface_buffer_width(surface);
surface_height = weston_surface_buffer_height(surface);
}
@@ -1780,11 +1776,12 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
surface->buffer_scale = sub->cached.buffer_scale;
/* wl_surface.attach */
- if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached)
- weston_surface_attach(surface, sub->cached.buffer_ref.buffer);
- weston_buffer_reference(&sub->cached.buffer_ref, NULL);
+ if (sub->cached.buffer || sub->cached.newly_attached)
+ weston_surface_attach(surface, sub->cached.buffer);
+ weston_buffer_decref(sub->cached.buffer);
+ sub->cached.buffer = NULL;
- if (surface->buffer_ref.buffer) {
+ if (surface->buffer) {
surface_width = weston_surface_buffer_width(surface);
surface_height = weston_surface_buffer_height(surface);
}
@@ -1858,8 +1855,9 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
if (surface->pending.newly_attached) {
sub->cached.newly_attached = 1;
- weston_buffer_reference(&sub->cached.buffer_ref,
- surface->pending.buffer);
+ weston_buffer_ref(surface->pending.buffer);
+ weston_buffer_decref(sub->cached.buffer);
+ sub->cached.buffer = surface->pending.buffer;
}
sub->cached.sx += surface->pending.sx;
sub->cached.sy += surface->pending.sy;
@@ -2144,7 +2142,7 @@ weston_subsurface_cache_init(struct weston_subsurface *sub)
pixman_region32_init(&sub->cached.opaque);
pixman_region32_init(&sub->cached.input);
wl_list_init(&sub->cached.frame_callback_list);
- sub->cached.buffer_ref.buffer = NULL;
+ sub->cached.buffer = NULL;
}
static void
@@ -2155,7 +2153,8 @@ weston_subsurface_cache_fini(struct weston_subsurface *sub)
wl_list_for_each_safe(cb, tmp, &sub->cached.frame_callback_list, link)
wl_resource_destroy(cb->resource);
- weston_buffer_reference(&sub->cached.buffer_ref, NULL);
+ weston_buffer_decref(sub->cached.buffer);
+ sub->cached.buffer = NULL;
pixman_region32_fini(&sub->cached.damage);
pixman_region32_fini(&sub->cached.opaque);
pixman_region32_fini(&sub->cached.input);
diff --git a/src/compositor.h b/src/compositor.h
index 60da054..8db175e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -595,11 +595,6 @@ struct weston_buffer {
uint32_t busy_count;
};
-struct weston_buffer_reference {
- struct weston_buffer *buffer;
- struct wl_listener destroy_listener;
-};
-
struct weston_region {
struct wl_resource *resource;
pixman_region32_t region;
@@ -629,7 +624,7 @@ struct weston_subsurface {
/* wl_surface.attach */
int newly_attached;
- struct weston_buffer_reference buffer_ref;
+ struct weston_buffer *buffer;
int32_t sx;
int32_t sy;
@@ -752,7 +747,7 @@ struct weston_surface {
struct wl_list frame_callback_list;
- struct weston_buffer_reference buffer_ref;
+ struct weston_buffer *buffer;
uint32_t buffer_transform;
int32_t buffer_scale;
int keep_buffer; /* bool for backends to prevent early release */
@@ -1042,8 +1037,10 @@ struct weston_buffer *
weston_buffer_from_resource(struct wl_resource *resource);
void
-weston_buffer_reference(struct weston_buffer_reference *ref,
- struct weston_buffer *buffer);
+weston_buffer_ref(struct weston_buffer *buffer);
+
+void
+weston_buffer_decref(struct weston_buffer *buffer);
uint32_t
weston_compositor_get_time(void);
diff --git a/src/data-device.c b/src/data-device.c
index e87c2b6..eee1d3a 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -170,7 +170,7 @@ drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_
struct wl_list *list;
float fx, fy;
- if (!weston_surface_is_mapped(es) && es->buffer_ref.buffer) {
+ if (!weston_surface_is_mapped(es) && es->buffer) {
if (pointer->sprite && weston_surface_is_mapped(pointer->sprite))
list = &pointer->sprite->layer_link;
else
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index d13781c..e5d6c16 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -73,7 +73,7 @@ struct gl_surface_state {
GLenum target;
int num_images;
- struct weston_buffer_reference buffer_ref;
+ struct weston_buffer *buffer;
enum buffer_type buffer_type;
int pitch; /* in pixels */
int height; /* in pixels */
@@ -1108,7 +1108,7 @@ gl_renderer_flush_damage(struct weston_surface *surface)
{
struct gl_renderer *gr = get_renderer(surface->compositor);
struct gl_surface_state *gs = get_surface_state(surface);
- struct weston_buffer *buffer = gs->buffer_ref.buffer;
+ struct weston_buffer *buffer = gs->buffer;
#ifdef GL_UNPACK_ROW_LENGTH
pixman_box32_t *rectangles;
@@ -1177,7 +1177,8 @@ done:
pixman_region32_init(&gs->texture_damage);
gs->needs_full_upload = 0;
- weston_buffer_reference(&gs->buffer_ref, NULL);
+ weston_buffer_decref(gs->buffer);
+ gs->buffer = NULL;
}
static void
@@ -1320,7 +1321,9 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
EGLint format;
int i;
- weston_buffer_reference(&gs->buffer_ref, buffer);
+ weston_buffer_ref(buffer);
+ weston_buffer_decref(gs->buffer);
+ gs->buffer = buffer;
if (!buffer) {
for (i = 0; i < gs->num_images; i++) {
@@ -1344,7 +1347,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
gl_renderer_attach_egl(es, buffer, format);
else {
weston_log("unhandled buffer type!\n");
- weston_buffer_reference(&gs->buffer_ref, NULL);
+ weston_buffer_decref(gs->buffer);
+ gs->buffer = NULL;
gs->buffer_type = BUFFER_TYPE_NULL;
}
}
@@ -1397,7 +1401,8 @@ gl_renderer_destroy_surface(struct weston_surface *surface)
for (i = 0; i < gs->num_images; i++)
gr->destroy_image(gr->egl_display, gs->images[i]);
- weston_buffer_reference(&gs->buffer_ref, NULL);
+ weston_buffer_decref(gs->buffer);
+ gs->buffer = NULL;
pixman_region32_fini(&gs->texture_damage);
free(gs);
}
diff --git a/src/input.c b/src/input.c
index 5d3cafa..8a61e5b 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1144,7 +1144,7 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
pointer->hotspot_x = x;
pointer->hotspot_y = y;
- if (surface->buffer_ref.buffer)
+ if (surface->buffer)
pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
weston_surface_buffer_height(surface));
}
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index 25bffbe..b98bc07 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -38,7 +38,7 @@ struct pixman_output_state {
struct pixman_surface_state {
pixman_image_t *image;
- struct weston_buffer_reference buffer_ref;
+ struct weston_buffer *buffer;
};
struct pixman_renderer {
@@ -535,7 +535,9 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
struct wl_shm_buffer *shm_buffer;
pixman_format_code_t pixman_format;
- weston_buffer_reference(&ps->buffer_ref, buffer);
+ weston_buffer_ref(buffer);
+ weston_buffer_decref(ps->buffer);
+ ps->buffer = buffer;
if (ps->image) {
pixman_image_unref(ps->image);
@@ -549,7 +551,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
if (! shm_buffer) {
weston_log("Pixman renderer supports only SHM buffers\n");
- weston_buffer_reference(&ps->buffer_ref, NULL);
+ weston_buffer_decref(ps->buffer);
+ ps->buffer = NULL;
return;
}
@@ -562,7 +565,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
break;
default:
weston_log("Unsupported SHM buffer format\n");
- weston_buffer_reference(&ps->buffer_ref, NULL);
+ weston_buffer_decref(ps->buffer);
+ ps->buffer = NULL;
return;
break;
}
@@ -620,7 +624,8 @@ pixman_renderer_destroy_surface(struct weston_surface *surface)
pixman_image_unref(ps->image);
ps->image = NULL;
}
- weston_buffer_reference(&ps->buffer_ref, NULL);
+ weston_buffer_decref(ps->buffer);
+ ps->buffer = NULL;
free(ps);
}
diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c
index 919ecc5..75f032c 100644
--- a/src/rpi-renderer.c
+++ b/src/rpi-renderer.c
@@ -102,7 +102,7 @@ struct rpir_surface {
struct rpi_resource *back;
pixman_region32_t prev_damage;
- struct weston_buffer_reference buffer_ref;
+ struct weston_buffer *buffer;
};
struct rpir_output {
@@ -1113,7 +1113,7 @@ rpi_renderer_flush_damage(struct weston_surface *base)
* having an shm buffer.
*/
struct rpir_surface *surface = to_rpir_surface(base);
- struct weston_buffer *buffer = surface->buffer_ref.buffer;
+ struct weston_buffer *buffer = surface->buffer;
int ret;
assert(buffer);
@@ -1124,7 +1124,8 @@ rpi_renderer_flush_damage(struct weston_surface *base)
weston_log("%s error: updating Dispmanx resource failed.\n",
__func__);
- weston_buffer_reference(&surface->buffer_ref, NULL);
+ weston_buffer_decref(surface->buffer);
+ surface->buffer = NULL;
}
static void
@@ -1150,7 +1151,9 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer);
}
- weston_buffer_reference(&surface->buffer_ref, buffer);
+ weston_buffer_ref(buffer);
+ weston_buffer_decref(surface->buffer);
+ surface->buffer = buffer;
/* XXX: need to check if in middle of update
if (!buffer && !surface->single_buffer)
diff --git a/src/shell.c b/src/shell.c
index 665cee7..d2d7baa 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1796,7 +1796,7 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
switch (shsurf->fullscreen.type) {
case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT:
- if (surface->buffer_ref.buffer)
+ if (surface->buffer)
center_on_output(surface, shsurf->fullscreen_output);
break;
case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
@@ -3249,7 +3249,7 @@ show_input_panels(struct wl_listener *listener, void *data)
wl_list_for_each_safe(surface, next,
&shell->input_panel.surfaces, link) {
ws = surface->surface;
- if (!ws->buffer_ref.buffer)
+ if (!ws->buffer)
continue;
wl_list_insert(&shell->input_panel_layer.surface_list,
&ws->layer_link);
--
1.8.2.1
More information about the wayland-devel
mailing list