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/dri2/dri_drawable.c | 2 +- src/gallium/state_trackers/egl/egl_surface.c | 6 +++--- src/gallium/state_trackers/g3dvl/vl_basic_csc.c | 6 +++--- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 8 ++++---- 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 ++-- src/gallium/state_trackers/xorg/xorg_crtc.c | 4 ++-- src/gallium/state_trackers/xorg/xorg_dri2.c | 2 +- src/gallium/state_trackers/xorg/xorg_exa.c | 12 +++++------ 10 files changed, 40 insertions(+), 34 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri2/dri_drawable.c b/src/gallium/state_trackers/dri2/dri_drawable.c index 2f6913ec5c..aa86411190 100644 --- a/src/gallium/state_trackers/dri2/dri_drawable.c +++ b/src/gallium/state_trackers/dri2/dri_drawable.c @@ -86,7 +86,7 @@ dri_surface_from_handle(struct pipe_screen *screen, buf); /* we don't need the buffer from this point on */ - pipe_buffer_reference(screen, &buf, NULL); + pipe_buffer_reference(&buf, NULL); if (!texture) return NULL; diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c index 7ebc34871c..b8d5f4217f 100644 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ b/src/gallium/state_trackers/egl/egl_surface.c @@ -143,7 +143,7 @@ err_handle: err_surf: pipe_texture_reference(&texture, NULL); err_tex: - pipe_buffer_reference(screen, &buf, NULL); + pipe_buffer_reference(&buf, NULL); err_buf: return; } @@ -173,7 +173,7 @@ drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) pipe_surface_reference(&screen->surface, NULL); pipe_texture_reference(&screen->tex, NULL); - pipe_buffer_reference(dev->screen, &screen->buffer, NULL); + pipe_buffer_reference(&screen->buffer, NULL); screen->shown = 0; } @@ -348,7 +348,7 @@ err_fb: err_bo: pipe_surface_reference(&scrn->surface, NULL); pipe_texture_reference(&scrn->tex, NULL); - pipe_buffer_reference(dev->screen, &scrn->buffer, NULL); + pipe_buffer_reference(&scrn->buffer, NULL); return EGL_FALSE; } diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c index 187a13a560..38cfd5d7f1 100644 --- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c @@ -237,10 +237,10 @@ static int vlDestroy pipe->delete_fs_state(pipe, basic_csc->fragment_shader); for (i = 0; i < 2; ++i) - pipe_buffer_reference(pipe->screen, &basic_csc->vertex_bufs[i].buffer, NULL); + pipe_buffer_reference(&basic_csc->vertex_bufs[i].buffer, NULL); - pipe_buffer_reference(pipe->screen, &basic_csc->vs_const_buf.buffer, NULL); - pipe_buffer_reference(pipe->screen, &basic_csc->fs_const_buf.buffer, NULL); + pipe_buffer_reference(&basic_csc->vs_const_buf.buffer, NULL); + pipe_buffer_reference(&basic_csc->fs_const_buf.buffer, NULL); FREE(basic_csc); diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 7cd753f736..eb8270ecad 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -636,7 +636,7 @@ static int vlFlush for (i = 0; i < 3; ++i) { pipe->screen->transfer_unmap(pipe->screen, mc->tex_transfer[i]); - pipe->screen->tex_transfer_release(pipe->screen, &mc->tex_transfer[i]); + pipe->screen->tex_transfer_destroy(mc->tex_transfer[i]); } mc->render_target.cbufs[0] = pipe->screen->get_tex_surface @@ -856,7 +856,7 @@ static int vlDestroy pipe->delete_sampler_state(pipe, mc->samplers.all[i]); for (i = 0; i < 3; ++i) - pipe_buffer_reference(pipe->screen, &mc->vertex_bufs.all[i].buffer, NULL); + pipe_buffer_reference(&mc->vertex_bufs.all[i].buffer, NULL); /* Textures 3 & 4 are not created directly, no need to release them here */ for (i = 0; i < 3; ++i) @@ -873,8 +873,8 @@ static int vlDestroy pipe->delete_fs_state(pipe, mc->b_fs[i]); } - pipe_buffer_reference(pipe->screen, &mc->vs_const_buf.buffer, NULL); - pipe_buffer_reference(pipe->screen, &mc->fs_const_buf.buffer, NULL); + pipe_buffer_reference(&mc->vs_const_buf.buffer, NULL); + pipe_buffer_reference(&mc->fs_const_buf.buffer, NULL); FREE(mc->macroblocks); FREE(mc); 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; diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 0bd69c214f..7304113a65 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -175,7 +175,7 @@ crtc_destroy(xf86CrtcPtr crtc) struct crtc_private *crtcp = crtc->driver_private; if (crtcp->cursor_buf) - pipe_buffer_reference(ms->screen, &crtcp->cursor_buf, NULL); + pipe_buffer_reference(&crtcp->cursor_buf, NULL); drmModeFreeCrtc(crtcp->drm_crtc); xfree(crtcp); @@ -266,7 +266,7 @@ cursor_destroy(xf86CrtcPtr crtc) struct crtc_private *crtcp = crtc->driver_private; if (crtcp->cursor_buf) { - pipe_buffer_reference(ms->screen, &crtcp->cursor_buf, NULL); + pipe_buffer_reference(&crtcp->cursor_buf, NULL); } } diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index d48b7dd27b..b9993b1ea1 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -147,7 +147,7 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) (*pScreen->DestroyPixmap)(private->pPixmap); pipe_texture_reference(&private->tex, NULL); - pipe_buffer_reference(ms->screen, &private->buf, NULL); + pipe_buffer_reference(&private->buf, NULL); } if (buffers) { diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index c62625c448..e53b46c3ad 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -147,7 +147,7 @@ ExaFinishAccess(PixmapPtr pPix, int index) return; exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); - pipe_transfer_reference(&priv->map_transfer, NULL); + exa->scrn->tex_transfer_destroy(priv->map_transfer); } @@ -163,7 +163,7 @@ ExaDone(PixmapPtr pPixmap) return; if (priv->src_surf) - exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf); + exa->scrn->tex_surface_destroy(priv->src_surf); priv->src_surf = NULL; } @@ -219,7 +219,7 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0, priv->color); - exa->scrn->tex_surface_release(exa->scrn, &surf); + exa->scrn->tex_surface_destroy(surf); } static Bool @@ -276,7 +276,7 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf, srcX, srcY, width, height); - exa->scrn->tex_surface_release(exa->scrn, &surf); + exa->scrn->tex_surface_destroy(surf); } static Bool @@ -336,7 +336,7 @@ ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) return; if (priv->tex) - ms->screen->texture_release(exa->scrn, &priv->tex); + ms->screen->texture_destroy(priv->tex); xfree(priv); } @@ -382,7 +382,7 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap) drm_api_hooks.buffer_from_texture(priv->tex, &buffer, &stride); drm_api_hooks.handle_from_buffer(ms->screen, buffer, &handle); - pipe_buffer_reference(ms->screen, &buffer, NULL); + pipe_buffer_reference(&buffer, NULL); return handle; } -- cgit v1.2.3