diff options
author | Marek Olšák <[email protected]> | 2015-09-01 04:07:54 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2015-09-03 18:41:40 +0200 |
commit | 35d0f12797237cdd38e7fd2c39d3c19e875875ca (patch) | |
tree | b3e272b98facfcef8335b402f89a1655d6ed5033 /src/gallium | |
parent | 44dbaa1746833f2874786fc2067f8837f149261f (diff) |
gallium/pb_bufmgr_cache: add a way to remove buffers from the cache explicitly
This must be done before exporting a buffer as dmabuf fds, because
we lose track of who is using it and can't trust the reference counter.
Cc: 11.0 <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 5 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 42 |
2 files changed, 41 insertions, 6 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 147ce39041c..1638d96a63b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -166,6 +166,11 @@ pb_cache_manager_create(struct pb_manager *provider, unsigned bypass_usage, uint64_t maximum_cache_size); +/** + * Remove a buffer from the cache, but keep it alive. + */ +void +pb_cache_manager_remove_buffer(struct pb_buffer *buf); struct pb_fence_ops; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 3b35049f679..cc8ae84bb1b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -104,18 +104,42 @@ pb_cache_manager(struct pb_manager *mgr) } +static void +_pb_cache_manager_remove_buffer_locked(struct pb_cache_buffer *buf) +{ + struct pb_cache_manager *mgr = buf->mgr; + + if (buf->head.next) { + LIST_DEL(&buf->head); + assert(mgr->numDelayed); + --mgr->numDelayed; + mgr->cache_size -= buf->base.size; + } + buf->mgr = NULL; +} + +void +pb_cache_manager_remove_buffer(struct pb_buffer *pb_buf) +{ + struct pb_cache_buffer *buf = (struct pb_cache_buffer*)pb_buf; + struct pb_cache_manager *mgr = buf->mgr; + + if (!mgr) + return; + + pipe_mutex_lock(mgr->mutex); + _pb_cache_manager_remove_buffer_locked(buf); + pipe_mutex_unlock(mgr->mutex); +} + /** * Actually destroy the buffer. */ static inline void _pb_cache_buffer_destroy(struct pb_cache_buffer *buf) { - struct pb_cache_manager *mgr = buf->mgr; - - LIST_DEL(&buf->head); - assert(mgr->numDelayed); - --mgr->numDelayed; - mgr->cache_size -= buf->base.size; + if (buf->mgr) + _pb_cache_manager_remove_buffer_locked(buf); assert(!pipe_is_referenced(&buf->base.reference)); pb_reference(&buf->buffer, NULL); FREE(buf); @@ -156,6 +180,12 @@ pb_cache_buffer_destroy(struct pb_buffer *_buf) struct pb_cache_buffer *buf = pb_cache_buffer(_buf); struct pb_cache_manager *mgr = buf->mgr; + if (!mgr) { + pb_reference(&buf->buffer, NULL); + FREE(buf); + return; + } + pipe_mutex_lock(mgr->mutex); assert(!pipe_is_referenced(&buf->base.reference)); |