diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-05-13 16:57:03 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-05-14 11:57:03 +0300 |
commit | e5349f14eb17689316ab5a85a7d4ffbb740ec93c (patch) | |
tree | 3ad2b81b1db82c932c67f2bf573265e772be1520 /source/blender | |
parent | 0e5da91f0aa534c3dfdb6a650cfb067fa84099da (diff) |
BLI_memblock: Add more options
- Use int instead of uint for safety and less conversions.
- Add free callback
- Add cleared alloc option
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/BLI_memblock.h | 12 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_memblock.c | 82 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 24 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 12 |
4 files changed, 86 insertions, 44 deletions
diff --git a/source/blender/blenlib/BLI_memblock.h b/source/blender/blenlib/BLI_memblock.h index 375cb22c415..81dd2100362 100644 --- a/source/blender/blenlib/BLI_memblock.h +++ b/source/blender/blenlib/BLI_memblock.h @@ -33,16 +33,18 @@ extern "C" { struct BLI_memblock; typedef struct BLI_memblock BLI_memblock; +typedef void (*MemblockValFreeFP)(void *val); -BLI_memblock *BLI_memblock_create(uint elem_size) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +BLI_memblock *BLI_memblock_create(uint elem_size, + const bool clear_alloc) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; void *BLI_memblock_alloc(BLI_memblock *mblk) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -void BLI_memblock_clear(BLI_memblock *mblk) ATTR_NONNULL(1); -void BLI_memblock_destroy(BLI_memblock *mblk) ATTR_NONNULL(1); +void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP valfreefp) ATTR_NONNULL(1); +void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1); typedef struct BLI_memblock_iter { BLI_memblock *mblk; - uint current_index; - uint elem_per_chunk; + int current_index; + int elem_per_chunk; } BLI_memblock_iter; void BLI_memblock_iternew(BLI_memblock *pool, BLI_memblock_iter *iter) ATTR_NONNULL(); diff --git a/source/blender/blenlib/intern/BLI_memblock.c b/source/blender/blenlib/intern/BLI_memblock.c index f50aa22a1c0..50b1e14757c 100644 --- a/source/blender/blenlib/intern/BLI_memblock.c +++ b/source/blender/blenlib/intern/BLI_memblock.c @@ -44,31 +44,51 @@ struct BLI_memblock { void **chunk_list; /** Element size in bytes. */ - uint elem_size; + int elem_size; /** First unused element index. */ - uint elem_next; + int elem_next; + /** Last "touched" element. */ + int elem_last; /** Chunck size in bytes. */ - uint chunk_size; + int chunk_size; /** Number of allocated chunck. */ - uint chunk_len; + int chunk_len; + /** Clear newly allocated chuncks. */ + bool clear_alloc; }; -BLI_memblock *BLI_memblock_create(uint elem_size) +/** + * /clear_alloc will clear the memory the first time a chunck is allocated. + */ +BLI_memblock *BLI_memblock_create(uint elem_size, const bool clear_alloc) { BLI_assert(elem_size < BLI_MEM_BLOCK_CHUNK_SIZE); BLI_memblock *mblk = MEM_mallocN(sizeof(BLI_memblock), "BLI_memblock"); - mblk->elem_size = elem_size; + mblk->elem_size = (int)elem_size; mblk->elem_next = 0; + mblk->elem_last = -1; mblk->chunk_size = BLI_MEM_BLOCK_CHUNK_SIZE; mblk->chunk_len = CHUNK_LIST_SIZE; - mblk->chunk_list = MEM_callocN(sizeof(void *) * mblk->chunk_len, "BLI_memblock chunk list"); + mblk->chunk_list = MEM_callocN(sizeof(void *) * (uint)mblk->chunk_len, "chunk list"); + mblk->clear_alloc = clear_alloc; return mblk; } -void BLI_memblock_destroy(BLI_memblock *mblk) +void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) { - for (uint i = 0; i < mblk->chunk_len; i++) { + if (free_callback) { + int elem_per_chunk = mblk->chunk_size / mblk->elem_size; + + for (int i = mblk->elem_last; i >= 0; i--) { + int chunk_idx = i / elem_per_chunk; + int elem_idx = i - elem_per_chunk * chunk_idx; + void *val = (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx; + free_callback(val); + } + } + + for (int i = 0; i < mblk->chunk_len; i++) { MEM_SAFE_FREE(mblk->chunk_list[i]); } MEM_SAFE_FREE(mblk->chunk_list); @@ -77,37 +97,57 @@ void BLI_memblock_destroy(BLI_memblock *mblk) /* Reset elem count to 0 but keep as much memory allocated needed for at least the previous elem * count. */ -void BLI_memblock_clear(BLI_memblock *mblk) +void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) { - uint elem_per_chunk = mblk->chunk_size / mblk->elem_size; - uint last_used_chunk = (mblk->elem_next - 1) / elem_per_chunk; + int elem_per_chunk = mblk->chunk_size / mblk->elem_size; + int last_used_chunk = (mblk->elem_next - 1) / elem_per_chunk; + + if (free_callback) { + for (int i = mblk->elem_last; i >= mblk->elem_next; i--) { + int chunk_idx = i / elem_per_chunk; + int elem_idx = i - elem_per_chunk * chunk_idx; + void *val = (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx; + free_callback(val); + } + } - for (uint i = last_used_chunk + 1; i < mblk->chunk_len; i++) { + for (int i = last_used_chunk + 1; i < mblk->chunk_len; i++) { MEM_SAFE_FREE(mblk->chunk_list[i]); } if (UNLIKELY(last_used_chunk + 1 < mblk->chunk_len - CHUNK_LIST_SIZE)) { mblk->chunk_len -= CHUNK_LIST_SIZE; - mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * mblk->chunk_len); + mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * (uint)mblk->chunk_len); } + mblk->elem_last = mblk->elem_next - 1; mblk->elem_next = 0; } void *BLI_memblock_alloc(BLI_memblock *mblk) { - uint elem_per_chunk = mblk->chunk_size / mblk->elem_size; - uint chunk_idx = mblk->elem_next / elem_per_chunk; - uint elem_idx = mblk->elem_next - elem_per_chunk * chunk_idx; + int elem_per_chunk = mblk->chunk_size / mblk->elem_size; + int chunk_idx = mblk->elem_next / elem_per_chunk; + int elem_idx = mblk->elem_next - elem_per_chunk * chunk_idx; + + if (mblk->elem_last < mblk->elem_next) { + mblk->elem_last = mblk->elem_next; + } + mblk->elem_next++; if (UNLIKELY(chunk_idx >= mblk->chunk_len)) { mblk->chunk_len += CHUNK_LIST_SIZE; - mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * mblk->chunk_len); + mblk->chunk_list = MEM_recallocN(mblk->chunk_list, sizeof(void *) * (uint)mblk->chunk_len); } if (UNLIKELY(mblk->chunk_list[chunk_idx] == NULL)) { - mblk->chunk_list[chunk_idx] = MEM_mallocN(mblk->chunk_size, "BLI_memblock chunk"); + if (mblk->clear_alloc) { + mblk->chunk_list[chunk_idx] = MEM_callocN((uint)mblk->chunk_size, "BLI_memblock chunk"); + } + else { + mblk->chunk_list[chunk_idx] = MEM_mallocN((uint)mblk->chunk_size, "BLI_memblock chunk"); + } } return (char *)(mblk->chunk_list[chunk_idx]) + mblk->elem_size * elem_idx; @@ -126,8 +166,8 @@ void *BLI_memblock_iterstep(BLI_memblock_iter *iter) return NULL; } - uint chunk_idx = iter->current_index / iter->elem_per_chunk; - uint elem_idx = iter->current_index - iter->elem_per_chunk * chunk_idx; + int chunk_idx = iter->current_index / iter->elem_per_chunk; + int elem_idx = iter->current_index - iter->elem_per_chunk * chunk_idx; iter->current_index++; return (char *)(iter->mblk->chunk_list[chunk_idx]) + iter->mblk->elem_size * elem_idx; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 1d215dcefe1..f4830916ecf 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -535,12 +535,12 @@ static void drw_viewport_cache_resize(void) GPU_texture_free(*tex); } - BLI_memblock_clear(DST.vmempool->calls); - BLI_memblock_clear(DST.vmempool->states); - BLI_memblock_clear(DST.vmempool->shgroups); - BLI_memblock_clear(DST.vmempool->uniforms); - BLI_memblock_clear(DST.vmempool->passes); - BLI_memblock_clear(DST.vmempool->images); + BLI_memblock_clear(DST.vmempool->calls, NULL); + BLI_memblock_clear(DST.vmempool->states, NULL); + BLI_memblock_clear(DST.vmempool->shgroups, NULL); + BLI_memblock_clear(DST.vmempool->uniforms, NULL); + BLI_memblock_clear(DST.vmempool->passes, NULL); + BLI_memblock_clear(DST.vmempool->images, NULL); } DRW_instance_data_list_free_unused(DST.idatalist); @@ -605,22 +605,22 @@ static void drw_viewport_var_init(void) DST.vmempool = GPU_viewport_mempool_get(DST.viewport); if (DST.vmempool->calls == NULL) { - DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall)); + DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall), false); } if (DST.vmempool->states == NULL) { - DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState)); + DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState), false); } if (DST.vmempool->shgroups == NULL) { - DST.vmempool->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup)); + DST.vmempool->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup), false); } if (DST.vmempool->uniforms == NULL) { - DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniform)); + DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniform), false); } if (DST.vmempool->passes == NULL) { - DST.vmempool->passes = BLI_memblock_create(sizeof(DRWPass)); + DST.vmempool->passes = BLI_memblock_create(sizeof(DRWPass), false); } if (DST.vmempool->images == NULL) { - DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *)); + DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *), false); } DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport); diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 9b53f623746..b825819ceb4 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -620,19 +620,19 @@ void GPU_viewport_free(GPUViewport *viewport) MEM_freeN(viewport->txl); if (viewport->vmempool.calls != NULL) { - BLI_memblock_destroy(viewport->vmempool.calls); + BLI_memblock_destroy(viewport->vmempool.calls, NULL); } if (viewport->vmempool.states != NULL) { - BLI_memblock_destroy(viewport->vmempool.states); + BLI_memblock_destroy(viewport->vmempool.states, NULL); } if (viewport->vmempool.shgroups != NULL) { - BLI_memblock_destroy(viewport->vmempool.shgroups); + BLI_memblock_destroy(viewport->vmempool.shgroups, NULL); } if (viewport->vmempool.uniforms != NULL) { - BLI_memblock_destroy(viewport->vmempool.uniforms); + BLI_memblock_destroy(viewport->vmempool.uniforms, NULL); } if (viewport->vmempool.passes != NULL) { - BLI_memblock_destroy(viewport->vmempool.passes); + BLI_memblock_destroy(viewport->vmempool.passes, NULL); } if (viewport->vmempool.images != NULL) { BLI_memblock_iter iter; @@ -641,7 +641,7 @@ void GPU_viewport_free(GPUViewport *viewport) while ((tex = BLI_memblock_iterstep(&iter))) { GPU_texture_free(*tex); } - BLI_memblock_destroy(viewport->vmempool.images); + BLI_memblock_destroy(viewport->vmempool.images, NULL); } DRW_instance_data_list_free(viewport->idatalist); |