From 5e27cd46c04a9e7b5904cc014bffd0f4daae31fe Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Wed, 4 Mar 2009 11:58:48 +0100 Subject: gallium: Unify reference counting. The core reference counting code is centralized in p_refcnt.h. This has some consequences related to struct pipe_buffer: * The screen member of struct pipe_buffer must be initialized, or pipe_buffer_reference() will crash trying to destroy a buffer with reference count 0. u_simple_screen takes care of this, but I may have missed some of the drivers not using it. * Except for rare exceptions deep in winsys code, buffers must always be allocated via pipe_buffer_create() or via screen->*buffer_create() rather than via winsys->*buffer_create(). --- src/gallium/state_trackers/python/st_device.c | 24 ++++++++++++++-------- src/gallium/state_trackers/python/st_device.h | 6 +++--- .../state_trackers/python/st_softpipe_winsys.c | 4 ++-- 3 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src/gallium/state_trackers/python') diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 20dd8d269d..a2cd25067d 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -51,11 +51,20 @@ st_device_really_destroy(struct st_device *st_dev) } +static void +st_device_reference(struct st_device **ptr, struct st_device *st_dev) +{ + struct st_device *old_dev = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &st_dev->reference)) + st_device_really_destroy(old_dev); +} + + void st_device_destroy(struct st_device *st_dev) { - if(!--st_dev->refcount) - st_device_really_destroy(st_dev); + st_device_reference(&st_dev, NULL); } @@ -72,7 +81,7 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws) if(!st_dev) return NULL; - st_dev->refcount = 1; + pipe_reference_init(&st_dev->reference, 1); st_dev->st_ws = st_ws; st_dev->real_screen = st_ws->screen_create(); @@ -124,8 +133,7 @@ st_context_destroy(struct st_context *st_ctx) FREE(st_ctx); - if(!--st_dev->refcount) - st_device_really_destroy(st_dev); + st_device_reference(&st_dev, NULL); } } @@ -139,8 +147,7 @@ st_context_create(struct st_device *st_dev) if(!st_ctx) return NULL; - st_ctx->st_dev = st_dev; - ++st_dev->refcount; + st_device_reference(&st_ctx->st_dev, st_dev); st_ctx->real_pipe = st_dev->st_ws->context_create(st_dev->real_screen); if(!st_ctx->real_pipe) { @@ -292,8 +299,7 @@ void st_buffer_destroy(struct st_buffer *st_buf) { if(st_buf) { - struct pipe_screen *screen = st_buf->st_dev->screen; - pipe_buffer_reference(screen, &st_buf->buffer, NULL); + pipe_buffer_reference(&st_buf->buffer, NULL); FREE(st_buf); } } diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 7cfe6de9f6..0641aff149 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -68,13 +68,13 @@ struct st_context { struct st_device { + /* FIXME: we also need to refcount for textures and surfaces... */ + struct pipe_reference reference; + const struct st_winsys *st_ws; struct pipe_screen *real_screen; struct pipe_screen *screen; - - /* FIXME: we also need to refcount for textures and surfaces... */ - unsigned refcount; }; diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index 4d798df99b..426f347d18 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -124,7 +124,7 @@ st_softpipe_buffer_create(struct pipe_winsys *winsys, { struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); - buffer->base.refcount = 1; + pipe_reference_init(&buffer->base.reference, 1); buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; @@ -149,7 +149,7 @@ st_softpipe_user_buffer_create(struct pipe_winsys *winsys, if(!buffer) return NULL; - buffer->base.refcount = 1; + pipe_reference_init(&buffer->base.reference, 1); buffer->base.size = bytes; buffer->userBuffer = TRUE; buffer->data = ptr; -- cgit v1.2.3