From ff63188cc2eb307eb874350e5281733d9c50f258 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 21 Mar 2014 00:54:37 -0700 Subject: Add a generic vector interface and use it for the active effect slots --- Alc/ALc.c | 21 ++++++++++++++------- Alc/ALu.c | 4 ++-- Alc/helpers.c | 21 +++++++++++++++++++++ Alc/vector.h | 38 ++++++++++++++++++++++++++++++++++++++ OpenAL32/Include/alMain.h | 9 ++++++--- OpenAL32/alAuxEffectSlot.c | 34 ++++++++++++---------------------- OpenAL32/alState.c | 4 ++-- 7 files changed, 95 insertions(+), 36 deletions(-) create mode 100644 Alc/vector.h diff --git a/Alc/ALc.c b/Alc/ALc.c index 77175730..1b5f8109 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2173,10 +2173,7 @@ static ALCvoid FreeContext(ALCcontext *context) context->ActiveSourceCount = 0; context->MaxActiveSources = 0; - context->ActiveEffectSlotCount = 0; - free(context->ActiveEffectSlots); - context->ActiveEffectSlots = NULL; - context->MaxActiveEffectSlots = 0; + VECTOR_DEINIT(context->ActiveAuxSlots); ALCdevice_DecRef(context->Device); context->Device = NULL; @@ -2891,11 +2888,13 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin ALContext->ref = 1; ALContext->Listener = (ALlistener*)ALContext->_listener_mem; + VECTOR_INIT(ALContext->ActiveAuxSlots); + ALContext->MaxActiveSources = 256; ALContext->ActiveSources = calloc(ALContext->MaxActiveSources, sizeof(ALContext->ActiveSources[0])); } - if(!ALContext || !ALContext->ActiveSources) + if(!ALContext || !ALContext->ActiveAuxSlots || !ALContext->ActiveSources) { if(!device->ContextList) { @@ -2904,8 +2903,16 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin } UnlockLists(); - free(ALContext); - ALContext = NULL; + if(ALContext) + { + free(ALContext->ActiveSources); + ALContext->ActiveSources = NULL; + + VECTOR_DEINIT(ALContext->ActiveAuxSlots); + + free(ALContext); + ALContext = NULL; + } alcSetError(device, ALC_OUT_OF_MEMORY); ALCdevice_DecRef(device); diff --git a/Alc/ALu.c b/Alc/ALu.c index 85cb6332..b0e9ea24 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1086,8 +1086,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) } /* effect slot processing */ - slot = ctx->ActiveEffectSlots; - slot_end = slot + ctx->ActiveEffectSlotCount; + slot = VECTOR_ITER_BEGIN(ctx->ActiveAuxSlots); + slot_end = VECTOR_ITER_END(ctx->ActiveAuxSlots); while(slot != slot_end) { ALfloat offset = (*slot)->ClickRemoval[0]; diff --git a/Alc/helpers.c b/Alc/helpers.c index 66ca58a9..80aab889 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -86,6 +86,7 @@ DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, #include "alMain.h" #include "atomic.h" #include "uintmap.h" +#include "vector.h" #include "compat.h" @@ -700,6 +701,26 @@ void WriteUnlock(RWLock *lock) } +ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size) +{ + if(orig_count < obj_count) + { + vector_ *vecptr = ptr; + void *temp; + + /* Need to be explicit with the caller type's base size, because it + * could have extra padding between the count and array start (that is, + * sizeof(*vector_) may not equal base_size). */ + temp = realloc(*vecptr, base_size + obj_size*obj_count); + if(temp == NULL) return AL_FALSE; + + *vecptr = temp; + (*vecptr)->Max = obj_count; + } + return AL_TRUE; +} + + void InitUIntMap(UIntMap *map, ALsizei limit) { map->array = NULL; diff --git a/Alc/vector.h b/Alc/vector.h new file mode 100644 index 00000000..51e642ee --- /dev/null +++ b/Alc/vector.h @@ -0,0 +1,38 @@ +#ifndef AL_VECTOR_H +#define AL_VECTOR_H + +#include + +#include + +/* "Base" vector type, designed to alias with the actual vector types. */ +typedef struct vector__s { + ALsizei Max; + ALsizei Size; +} *vector_; + +#define DECL_VECTOR(T) typedef struct vector_##T##_s { \ + ALsizei Max; \ + ALsizei Size; \ + T Data[]; \ +} *vector_##T; + +#define VECTOR_INIT(_x) (((_x) = calloc(1, sizeof(*(_x)))) != NULL) +#define VECTOR_DEINIT(_x) do { free(_x); _x = NULL; } while(0) + +/* Helper to increase a vector's reserve. Do not call directly. */ +ALboolean vector_reserve(void *ptr, size_t orig_count, size_t base_size, size_t obj_count, size_t obj_size); +#define VECTOR_RESERVE(_x, _c) (vector_reserve(&(_x), (_x)->Max, sizeof(*(_x)), (_c), sizeof((_x)->Data[0]))) + +#define VECTOR_SIZE(_x) ((const ALsizei)(_x)->Size) + +#define VECTOR_ITER_BEGIN(_x) ((_x)->Data) +#define VECTOR_ITER_END(_x) ((_x)->Data + (_x)->Size) + +/* NOTE: The caller must ensure enough space is reserved before pushing in new objects. */ +#define VECTOR_PUSH_BACK(_x, _obj) ((void)((_x)->Data[(_x)->Size++] = (_obj))) +#define VECTOR_POP_BACK(_x) ((void)((_x)->Size--)) + +#define VECTOR_ELEM(_x, _o) ((_x)->Data[_o]) + +#endif /* AL_VECTOR_H */ diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index a00f2d4c..0f4a3c7e 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -22,6 +22,7 @@ #include "atomic.h" #include "uintmap.h" +#include "vector.h" #ifndef ALC_SOFT_HRTF #define ALC_SOFT_HRTF 1 @@ -722,6 +723,10 @@ struct ALCdevice_struct #define MIXER_THREAD_NAME "alsoft-mixer" +typedef struct ALeffectslot *ALeffectslotPtr; +DECL_VECTOR(ALeffectslotPtr) + + struct ALCcontext_struct { volatile RefCount ref; @@ -747,9 +752,7 @@ struct ALCcontext_struct ALsizei ActiveSourceCount; ALsizei MaxActiveSources; - struct ALeffectslot **ActiveEffectSlots; - ALsizei ActiveEffectSlotCount; - ALsizei MaxActiveEffectSlots; + vector_ALeffectslotPtr ActiveAuxSlots; ALCdevice *Device; const ALCchar *ExtensionList; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index aa071de2..dcd64fc8 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -380,14 +380,14 @@ static ALvoid RemoveEffectSlotArray(ALCcontext *context, ALeffectslot *slot) ALeffectslot **slotlist, **slotlistend; LockContext(context); - slotlist = context->ActiveEffectSlots; - slotlistend = slotlist + context->ActiveEffectSlotCount; + slotlist = VECTOR_ITER_BEGIN(context->ActiveAuxSlots); + slotlistend = VECTOR_ITER_END(context->ActiveAuxSlots); while(slotlist != slotlistend) { if(*slotlist == slot) { *slotlist = *(--slotlistend); - context->ActiveEffectSlotCount--; + VECTOR_POP_BACK(context->ActiveAuxSlots); break; } slotlist++; @@ -397,33 +397,23 @@ static ALvoid RemoveEffectSlotArray(ALCcontext *context, ALeffectslot *slot) static ALenum AddEffectSlotArray(ALCcontext *context, ALsizei count, const ALuint *slots) { - ALsizei i; + ALsizei total = count + VECTOR_SIZE(context->ActiveAuxSlots); LockContext(context); - if(count > context->MaxActiveEffectSlots-context->ActiveEffectSlotCount) + if(total < VECTOR_SIZE(context->ActiveAuxSlots) || VECTOR_RESERVE(context->ActiveAuxSlots, total) == AL_FALSE) { - ALsizei newcount; - void *temp = NULL; - - newcount = context->MaxActiveEffectSlots ? (context->MaxActiveEffectSlots<<1) : 1; - if(newcount > context->MaxActiveEffectSlots) - temp = realloc(context->ActiveEffectSlots, - newcount * sizeof(*context->ActiveEffectSlots)); - if(!temp) - { - UnlockContext(context); - return AL_OUT_OF_MEMORY; - } - context->ActiveEffectSlots = temp; - context->MaxActiveEffectSlots = newcount; + UnlockContext(context); + return AL_OUT_OF_MEMORY; } - for(i = 0;i < count;i++) + + while(VECTOR_SIZE(context->ActiveAuxSlots) < total) { - ALeffectslot *slot = LookupEffectSlot(context, slots[i]); + ALeffectslot *slot = LookupEffectSlot(context, *(slots++)); assert(slot != NULL); - context->ActiveEffectSlots[context->ActiveEffectSlotCount++] = slot; + VECTOR_PUSH_BACK(context->ActiveAuxSlots, slot); } UnlockContext(context); + return AL_NO_ERROR; } diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index f97168d6..c6deda46 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -748,8 +748,8 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void) src++; } - slot = context->ActiveEffectSlots; - slot_end = slot + context->ActiveEffectSlotCount; + slot = VECTOR_ITER_BEGIN(context->ActiveAuxSlots); + slot_end = VECTOR_ITER_END(context->ActiveAuxSlots); while(slot != slot_end) { if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE)) -- cgit v1.2.3