summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-08-22 12:41:59 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-08-22 12:41:59 -0600
commit8a868919b50bdca4dc697d61e220a8fb50764f8e (patch)
tree85d7bab697bc56619ba9afef662116f327d2977e /src
parentc0bb4ba9e665e40a325d82aa2ee48d7b8abd603b (diff)
Improved pipe_region/surface_reference() functions
Now dereferences the old object first. Target object may be NULL to clear the pointer.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/pipe/p_context.h66
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c2
2 files changed, 45 insertions, 23 deletions
diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h
index 0d90a967cc..ec9973383c 100644
--- a/src/mesa/pipe/p_context.h
+++ b/src/mesa/pipe/p_context.h
@@ -213,38 +213,60 @@ struct pipe_context {
};
-
+/**
+ * Set 'ptr' to point to 'region' and update reference counting.
+ * The old thing pointed to, if any, will be unreferenced first.
+ * 'region' may be NULL.
+ */
static INLINE void
-pipe_region_reference(struct pipe_region **dst, struct pipe_region *src)
+pipe_region_reference(struct pipe_region **ptr, struct pipe_region *region)
{
- assert(*dst == NULL);
- if (src) {
- src->refcount++;
- *dst = src;
+ assert(ptr);
+ if (*ptr) {
+ /* unreference the old thing */
+ struct pipe_region *oldReg = *ptr;
+ oldReg->refcount--;
+ assert(oldReg->refcount >= 0);
+ if (oldReg->refcount == 0) {
+ /* free the old region */
+ assert(oldReg->map_refcount == 0);
+ /* XXX dereference the region->buffer */
+ free(oldReg);
+ }
+ *ptr = NULL;
+ }
+ if (region) {
+ /* reference the new thing */
+ region->refcount++;
+ *ptr = region;
}
}
+/**
+ * \sa pipe_region_reference
+ */
static INLINE void
-pipe_surface_reference(struct pipe_surface **dst, struct pipe_surface *src)
+pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
{
- assert(*dst == NULL);
- if (src) {
- src->refcount++;
- *dst = src;
+ assert(ptr);
+ if (*ptr) {
+ /* unreference the old thing */
+ struct pipe_surface *oldSurf = *ptr;
+ oldSurf->refcount--;
+ assert(oldSurf->refcount >= 0);
+ if (oldSurf->refcount == 0) {
+ /* free the old region */
+ pipe_region_reference(&oldSurf->region, NULL);
+ free(oldSurf);
+ }
+ *ptr = NULL;
}
-}
-
-static INLINE void
-pipe_surface_unreference(struct pipe_surface **ps)
-{
- assert(*ps);
- (*ps)->refcount--;
- if ((*ps)->refcount <= 0) {
- /* XXX need a proper surface->free method */
- free(*ps);
+ if (surf) {
+ /* reference the new thing */
+ surf->refcount++;
+ *ptr = surf;
}
- *ps = NULL;
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 2b9aa3e9d2..430ac715e5 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -351,7 +351,7 @@ st_finish_render_texture(GLcontext *ctx,
printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);
*/
- pipe_surface_unreference(&strb->surface);
+ pipe_surface_reference(&strb->surface, NULL);
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);