From 81aed2ea01904c73156ade21faa5f12806685f72 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 18 Nov 2018 22:31:51 -0800 Subject: [PATCH] Use a normal vector for buffer sublists --- Alc/alc.cpp | 10 +++---- OpenAL32/Include/alMain.h | 7 ++--- OpenAL32/alBuffer.cpp | 63 +++++++++++++++++++-------------------- OpenAL32/alSource.cpp | 13 ++++---- 4 files changed, 44 insertions(+), 49 deletions(-) diff --git a/Alc/alc.cpp b/Alc/alc.cpp index f4a64199..ae9a6e92 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -2388,7 +2388,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ALCdevice_struct::ALCdevice_struct(DeviceType type) : Type{type} { - VECTOR_INIT(BufferList); almtx_init(&BufferLock, almtx_plain); VECTOR_INIT(EffectList); @@ -2416,10 +2415,11 @@ ALCdevice_struct::~ALCdevice_struct() almtx_destroy(&BackendLock); ReleaseALBuffers(this); -#define FREE_BUFFERSUBLIST(x) al_free((x)->Buffers) - VECTOR_FOR_EACH(BufferSubList, BufferList, FREE_BUFFERSUBLIST); -#undef FREE_BUFFERSUBLIST - VECTOR_DEINIT(BufferList); + std::for_each(BufferList.begin(), BufferList.end(), + [](BufferSubList &entry) noexcept -> void + { al_free(entry.Buffers); } + ); + BufferList.clear(); almtx_destroy(&BufferLock); ReleaseALEffects(this); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index e0d1462b..38c0471b 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -509,10 +509,9 @@ typedef union AmbiConfig { typedef struct BufferSubList { - ALuint64 FreeMask; - struct ALbuffer *Buffers; /* 64 */ + ALuint64 FreeMask{0u}; + struct ALbuffer *Buffers{nullptr}; /* 64 */ } BufferSubList; -TYPEDEF_VECTOR(BufferSubList, vector_BufferSubList) typedef struct EffectSubList { ALuint64 FreeMask; @@ -606,7 +605,7 @@ struct ALCdevice_struct { ALsizei NumAuxSends{}; // Map of Buffers for this device - vector_BufferSubList BufferList{}; + al::vector BufferList; almtx_t BufferLock; // Map of Effects for this device diff --git a/OpenAL32/alBuffer.cpp b/OpenAL32/alBuffer.cpp index 27e3ddd1..cd173193 100644 --- a/OpenAL32/alBuffer.cpp +++ b/OpenAL32/alBuffer.cpp @@ -55,40 +55,37 @@ ALbuffer *AllocBuffer(ALCcontext *context) ALCdevice *device = context->Device; std::unique_lock buflock{device->BufferLock}; + auto sublist = std::find_if(device->BufferList.begin(), device->BufferList.end(), + [](const BufferSubList &entry) noexcept -> bool + { return entry.FreeMask != 0; } + ); + + auto lidx = std::distance(device->BufferList.begin(), sublist); ALbuffer *buffer{nullptr}; - ALsizei lidx{0}, slidx{0}; - BufferSubList *sublist{VECTOR_BEGIN(device->BufferList)}; - BufferSubList *subend{VECTOR_END(device->BufferList)}; - for(;sublist != subend;++sublist) + ALsizei slidx{0}; + if(LIKELY(sublist != device->BufferList.end())) { - if(sublist->FreeMask) - { - slidx = CTZ64(sublist->FreeMask); - buffer = sublist->Buffers + slidx; - break; - } - ++lidx; + slidx = CTZ64(sublist->FreeMask); + buffer = sublist->Buffers + slidx; } - if(UNLIKELY(!buffer)) + else { - static constexpr BufferSubList empty_sublist{ 0, nullptr }; /* Don't allocate so many list entries that the 32-bit ID could * overflow... */ - if(UNLIKELY(VECTOR_SIZE(device->BufferList) >= 1<<25)) + if(UNLIKELY(device->BufferList.size() >= 1<<25)) { buflock.unlock(); alSetError(context, AL_OUT_OF_MEMORY, "Too many buffers allocated"); return nullptr; } - lidx = (ALsizei)VECTOR_SIZE(device->BufferList); - VECTOR_PUSH_BACK(device->BufferList, empty_sublist); - sublist = &VECTOR_BACK(device->BufferList); + device->BufferList.emplace_back(); + sublist = device->BufferList.end() - 1; sublist->FreeMask = ~U64(0); sublist->Buffers = reinterpret_cast(al_calloc(16, sizeof(ALbuffer)*64)); if(UNLIKELY(!sublist->Buffers)) { - VECTOR_POP_BACK(device->BufferList); + device->BufferList.pop_back(); buflock.unlock(); alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate buffer batch"); return nullptr; @@ -98,8 +95,7 @@ ALbuffer *AllocBuffer(ALCcontext *context) buffer = sublist->Buffers + slidx; } - memset(buffer, 0, sizeof(*buffer)); - + buffer = new (buffer) ALbuffer{}; /* Add 1 to avoid buffer ID 0. */ buffer->id = ((lidx<<6) | slidx) + 1; @@ -115,9 +111,10 @@ void FreeBuffer(ALCdevice *device, ALbuffer *buffer) ALsizei slidx = id & 0x3f; al_free(buffer->data); - memset(buffer, 0, sizeof(*buffer)); + buffer->data = nullptr; + buffer->~ALbuffer(); - VECTOR_ELEM(device->BufferList, lidx).FreeMask |= U64(1) << slidx; + device->BufferList[lidx].FreeMask |= U64(1) << slidx; } inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) @@ -125,12 +122,12 @@ inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) ALuint lidx = (id-1) >> 6; ALsizei slidx = (id-1) & 0x3f; - if(UNLIKELY(lidx >= VECTOR_SIZE(device->BufferList))) + if(UNLIKELY(lidx >= device->BufferList.size())) return nullptr; - BufferSubList *sublist{&VECTOR_ELEM(device->BufferList, lidx)}; - if(UNLIKELY(sublist->FreeMask & (U64(1)<BufferList[lidx]; + if(UNLIKELY(sublist.FreeMask & (U64(1)<Buffers + slidx; + return sublist.Buffers + slidx; } @@ -1187,24 +1184,24 @@ ALsizei ChannelsFromFmt(FmtChannels chans) */ ALvoid ReleaseALBuffers(ALCdevice *device) { - BufferSubList *sublist = VECTOR_BEGIN(device->BufferList); - BufferSubList *subend = VECTOR_END(device->BufferList); size_t leftover = 0; - for(;sublist != subend;++sublist) + for(auto &sublist : device->BufferList) { - ALuint64 usemask = ~sublist->FreeMask; + ALuint64 usemask = ~sublist.FreeMask; while(usemask) { ALsizei idx = CTZ64(usemask); - ALbuffer *buffer = sublist->Buffers + idx; + ALbuffer *buffer = sublist.Buffers + idx; al_free(buffer->data); - memset(buffer, 0, sizeof(*buffer)); + buffer->data = nullptr; + buffer->~ALbuffer(); + ++leftover; usemask &= ~(U64(1) << idx); } - sublist->FreeMask = ~usemask; + sublist.FreeMask = ~usemask; } if(leftover > 0) WARN("(%p) Deleted " SZFMT " Buffer%s\n", device, leftover, (leftover==1)?"":"s"); diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index 8b08728a..33aedb09 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -76,16 +76,15 @@ static inline ALsource *LookupSource(ALCcontext *context, ALuint id) static inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) { - BufferSubList *sublist; ALuint lidx = (id-1) >> 6; ALsizei slidx = (id-1) & 0x3f; - if(UNLIKELY(lidx >= VECTOR_SIZE(device->BufferList))) - return NULL; - sublist = &VECTOR_ELEM(device->BufferList, lidx); - if(UNLIKELY(sublist->FreeMask & (U64(1)<Buffers + slidx; + if(UNLIKELY(lidx >= device->BufferList.size())) + return nullptr; + BufferSubList &sublist = device->BufferList[lidx]; + if(UNLIKELY(sublist.FreeMask & (U64(1)<