Use a normal vector for filter sublists
This commit is contained in:
+5
-7
@@ -2389,10 +2389,7 @@ ALCdevice_struct::ALCdevice_struct(DeviceType type)
|
||||
: Type{type}
|
||||
{
|
||||
almtx_init(&BufferLock, almtx_plain);
|
||||
|
||||
almtx_init(&EffectLock, almtx_plain);
|
||||
|
||||
VECTOR_INIT(FilterList);
|
||||
almtx_init(&FilterLock, almtx_plain);
|
||||
|
||||
almtx_init(&BackendLock, almtx_plain);
|
||||
@@ -2430,10 +2427,11 @@ ALCdevice_struct::~ALCdevice_struct()
|
||||
almtx_destroy(&EffectLock);
|
||||
|
||||
ReleaseALFilters(this);
|
||||
#define FREE_FILTERSUBLIST(x) al_free((x)->Filters)
|
||||
VECTOR_FOR_EACH(FilterSubList, FilterList, FREE_FILTERSUBLIST);
|
||||
#undef FREE_FILTERSUBLIST
|
||||
VECTOR_DEINIT(FilterList);
|
||||
std::for_each(FilterList.begin(), FilterList.end(),
|
||||
[](FilterSubList &entry) noexcept -> void
|
||||
{ al_free(entry.Filters); }
|
||||
);
|
||||
FilterList.clear();
|
||||
almtx_destroy(&FilterLock);
|
||||
|
||||
HrtfList.clear();
|
||||
|
||||
@@ -519,10 +519,9 @@ typedef struct EffectSubList {
|
||||
} EffectSubList;
|
||||
|
||||
typedef struct FilterSubList {
|
||||
ALuint64 FreeMask;
|
||||
struct ALfilter *Filters; /* 64 */
|
||||
ALuint64 FreeMask{0u};
|
||||
struct ALfilter *Filters{nullptr}; /* 64 */
|
||||
} FilterSubList;
|
||||
TYPEDEF_VECTOR(FilterSubList, vector_FilterSubList)
|
||||
|
||||
|
||||
typedef struct EnumeratedHrtf {
|
||||
@@ -612,7 +611,7 @@ struct ALCdevice_struct {
|
||||
almtx_t EffectLock;
|
||||
|
||||
// Map of Filters for this device
|
||||
vector_FilterSubList FilterList{};
|
||||
al::vector<FilterSubList> FilterList;
|
||||
almtx_t FilterLock;
|
||||
|
||||
POSTPROCESS PostProcess{};
|
||||
|
||||
+33
-39
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alcontext.h"
|
||||
#include "alu.h"
|
||||
@@ -38,16 +40,15 @@ static void InitFilterParams(ALfilter *filter, ALenum type);
|
||||
|
||||
static inline ALfilter *LookupFilter(ALCdevice *device, ALuint id)
|
||||
{
|
||||
FilterSubList *sublist;
|
||||
ALuint lidx = (id-1) >> 6;
|
||||
ALsizei slidx = (id-1) & 0x3f;
|
||||
|
||||
if(UNLIKELY(lidx >= VECTOR_SIZE(device->FilterList)))
|
||||
return NULL;
|
||||
sublist = &VECTOR_ELEM(device->FilterList, lidx);
|
||||
if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
|
||||
return NULL;
|
||||
return sublist->Filters + slidx;
|
||||
if(UNLIKELY(lidx >= device->FilterList.size()))
|
||||
return nullptr;
|
||||
FilterSubList &sublist = device->FilterList[lidx];
|
||||
if(UNLIKELY(sublist.FreeMask & (U64(1)<<slidx)))
|
||||
return nullptr;
|
||||
return sublist.Filters + slidx;
|
||||
}
|
||||
|
||||
|
||||
@@ -532,44 +533,39 @@ DEFINE_ALFILTER_VTABLE(ALnullfilter);
|
||||
static ALfilter *AllocFilter(ALCcontext *context)
|
||||
{
|
||||
ALCdevice *device = context->Device;
|
||||
FilterSubList *sublist, *subend;
|
||||
ALfilter *filter = NULL;
|
||||
ALsizei lidx = 0;
|
||||
ALsizei slidx;
|
||||
|
||||
almtx_lock(&device->FilterLock);
|
||||
sublist = VECTOR_BEGIN(device->FilterList);
|
||||
subend = VECTOR_END(device->FilterList);
|
||||
for(;sublist != subend;++sublist)
|
||||
|
||||
auto sublist = std::find_if(device->FilterList.begin(), device->FilterList.end(),
|
||||
[](const FilterSubList &entry) noexcept -> bool
|
||||
{ return entry.FreeMask != 0; }
|
||||
);
|
||||
|
||||
auto lidx = std::distance(device->FilterList.begin(), sublist);
|
||||
ALfilter *filter{nullptr};
|
||||
ALsizei slidx{0};
|
||||
if(LIKELY(sublist != device->FilterList.end()))
|
||||
{
|
||||
if(sublist->FreeMask)
|
||||
{
|
||||
slidx = CTZ64(sublist->FreeMask);
|
||||
filter = sublist->Filters + slidx;
|
||||
break;
|
||||
}
|
||||
++lidx;
|
||||
slidx = CTZ64(sublist->FreeMask);
|
||||
filter = sublist->Filters + slidx;
|
||||
}
|
||||
if(UNLIKELY(!filter))
|
||||
else
|
||||
{
|
||||
const FilterSubList empty_sublist = { 0, NULL };
|
||||
/* Don't allocate so many list entries that the 32-bit ID could
|
||||
* overflow...
|
||||
*/
|
||||
if(UNLIKELY(VECTOR_SIZE(device->FilterList) >= 1<<25))
|
||||
if(UNLIKELY(device->FilterList.size() >= 1<<25))
|
||||
{
|
||||
almtx_unlock(&device->FilterLock);
|
||||
alSetError(context, AL_OUT_OF_MEMORY, "Too many filters allocated");
|
||||
return NULL;
|
||||
}
|
||||
lidx = (ALsizei)VECTOR_SIZE(device->FilterList);
|
||||
VECTOR_PUSH_BACK(device->FilterList, empty_sublist);
|
||||
sublist = &VECTOR_BACK(device->FilterList);
|
||||
device->FilterList.emplace_back();
|
||||
sublist = device->FilterList.end() - 1;
|
||||
sublist->FreeMask = ~U64(0);
|
||||
sublist->Filters = static_cast<ALfilter*>(al_calloc(16, sizeof(ALfilter)*64));
|
||||
if(UNLIKELY(!sublist->Filters))
|
||||
{
|
||||
VECTOR_POP_BACK(device->FilterList);
|
||||
device->FilterList.pop_back();
|
||||
almtx_unlock(&device->FilterLock);
|
||||
alSetError(context, AL_OUT_OF_MEMORY, "Failed to allocate filter batch");
|
||||
return NULL;
|
||||
@@ -579,7 +575,7 @@ static ALfilter *AllocFilter(ALCcontext *context)
|
||||
filter = sublist->Filters + slidx;
|
||||
}
|
||||
|
||||
memset(filter, 0, sizeof(*filter));
|
||||
filter = new (filter) ALfilter{};
|
||||
InitFilterParams(filter, AL_FILTER_NULL);
|
||||
|
||||
/* Add 1 to avoid filter ID 0. */
|
||||
@@ -597,30 +593,28 @@ static void FreeFilter(ALCdevice *device, ALfilter *filter)
|
||||
ALsizei lidx = id >> 6;
|
||||
ALsizei slidx = id & 0x3f;
|
||||
|
||||
memset(filter, 0, sizeof(*filter));
|
||||
filter->~ALfilter();
|
||||
|
||||
VECTOR_ELEM(device->FilterList, lidx).FreeMask |= U64(1) << slidx;
|
||||
device->FilterList[lidx].FreeMask |= U64(1) << slidx;
|
||||
}
|
||||
|
||||
void ReleaseALFilters(ALCdevice *device)
|
||||
{
|
||||
FilterSubList *sublist = VECTOR_BEGIN(device->FilterList);
|
||||
FilterSubList *subend = VECTOR_END(device->FilterList);
|
||||
size_t leftover = 0;
|
||||
for(;sublist != subend;++sublist)
|
||||
for(auto &sublist : device->FilterList)
|
||||
{
|
||||
ALuint64 usemask = ~sublist->FreeMask;
|
||||
ALuint64 usemask = ~sublist.FreeMask;
|
||||
while(usemask)
|
||||
{
|
||||
ALsizei idx = CTZ64(usemask);
|
||||
ALfilter *filter = sublist->Filters + idx;
|
||||
ALfilter *filter = sublist.Filters + idx;
|
||||
|
||||
memset(filter, 0, sizeof(*filter));
|
||||
filter->~ALfilter();
|
||||
++leftover;
|
||||
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
sublist->FreeMask = ~usemask;
|
||||
sublist.FreeMask = ~usemask;
|
||||
}
|
||||
if(leftover > 0)
|
||||
WARN("(%p) Deleted " SZFMT " Filter%s\n", device, leftover, (leftover==1)?"":"s");
|
||||
|
||||
@@ -89,16 +89,15 @@ static inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id)
|
||||
|
||||
static inline ALfilter *LookupFilter(ALCdevice *device, ALuint id)
|
||||
{
|
||||
FilterSubList *sublist;
|
||||
ALuint lidx = (id-1) >> 6;
|
||||
ALsizei slidx = (id-1) & 0x3f;
|
||||
|
||||
if(UNLIKELY(lidx >= VECTOR_SIZE(device->FilterList)))
|
||||
return NULL;
|
||||
sublist = &VECTOR_ELEM(device->FilterList, lidx);
|
||||
if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
|
||||
return NULL;
|
||||
return sublist->Filters + slidx;
|
||||
if(UNLIKELY(lidx >= device->FilterList.size()))
|
||||
return nullptr;
|
||||
FilterSubList &sublist = device->FilterList[lidx];
|
||||
if(UNLIKELY(sublist.FreeMask & (U64(1)<<slidx)))
|
||||
return nullptr;
|
||||
return sublist.Filters + slidx;
|
||||
}
|
||||
|
||||
static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id)
|
||||
|
||||
Reference in New Issue
Block a user