Automatically clean up filters and effects with their sublists

This commit is contained in:
Chris Robinson 2018-11-25 16:13:07 -08:00
parent 8ae07ad1ae
commit 127ec026e7
6 changed files with 54 additions and 60 deletions

View File

@ -2404,19 +2404,19 @@ ALCdevice_struct::~ALCdevice_struct()
BufferList.clear(); BufferList.clear();
almtx_destroy(&BufferLock); almtx_destroy(&BufferLock);
ReleaseALEffects(this); count = 0;
std::for_each(EffectList.begin(), EffectList.end(), for(auto &sublist : EffectList)
[](EffectSubList &entry) noexcept -> void count += POPCNT64(~sublist.FreeMask);
{ al_free(entry.Effects); } if(count > 0)
); WARN(SZFMT " Effect%s not deleted\n", count, (count==1)?"":"s");
EffectList.clear(); EffectList.clear();
almtx_destroy(&EffectLock); almtx_destroy(&EffectLock);
ReleaseALFilters(this); count = 0;
std::for_each(FilterList.begin(), FilterList.end(), for(auto &sublist : FilterList)
[](FilterSubList &entry) noexcept -> void count += POPCNT64(~sublist.FreeMask);
{ al_free(entry.Filters); } if(count > 0)
); WARN(SZFMT " Filter%s not deleted\n", count, (count==1)?"":"s");
FilterList.clear(); FilterList.clear();
almtx_destroy(&FilterLock); almtx_destroy(&FilterLock);

View File

@ -199,7 +199,6 @@ inline ALboolean IsReverbEffect(ALenum type)
{ return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; } { return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; }
void InitEffect(ALeffect *effect); void InitEffect(ALeffect *effect);
void ReleaseALEffects(ALCdevice *device);
void LoadReverbPreset(const char *name, ALeffect *effect); void LoadReverbPreset(const char *name, ALeffect *effect);

View File

@ -4,9 +4,6 @@
#include "AL/alc.h" #include "AL/alc.h"
#include "AL/al.h" #include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LOWPASSFREQREF (5000.0f) #define LOWPASSFREQREF (5000.0f)
#define HIGHPASSFREQREF (250.0f) #define HIGHPASSFREQREF (250.0f)
@ -58,10 +55,4 @@ typedef struct ALfilter {
#define ALfilter_getParamiv(o, c, p, v) ((o)->vtab->getParamiv(o, c, p, v)) #define ALfilter_getParamiv(o, c, p, v) ((o)->vtab->getParamiv(o, c, p, v))
#define ALfilter_getParamfv(o, c, p, v) ((o)->vtab->getParamfv(o, c, p, v)) #define ALfilter_getParamfv(o, c, p, v) ((o)->vtab->getParamfv(o, c, p, v))
void ReleaseALFilters(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -566,15 +566,35 @@ struct BufferSubList {
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; } { std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
}; };
typedef struct EffectSubList { struct EffectSubList {
ALuint64 FreeMask{~ALuint64{}}; uint64_t FreeMask{~uint64_t{}};
struct ALeffect *Effects{nullptr}; /* 64 */ struct ALeffect *Effects{nullptr}; /* 64 */
} EffectSubList;
typedef struct FilterSubList { EffectSubList() noexcept = default;
ALuint64 FreeMask{~ALuint64{}}; EffectSubList(const EffectSubList&) = delete;
EffectSubList(EffectSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Effects{rhs.Effects}
{ rhs.FreeMask = ~uint64_t{}; rhs.Effects = nullptr; }
~EffectSubList();
EffectSubList& operator=(const EffectSubList&) = delete;
EffectSubList& operator=(EffectSubList&& rhs) noexcept
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Effects, rhs.Effects); return *this; }
};
struct FilterSubList {
uint64_t FreeMask{~uint64_t{}};
struct ALfilter *Filters{nullptr}; /* 64 */ struct ALfilter *Filters{nullptr}; /* 64 */
} FilterSubList;
FilterSubList() noexcept = default;
FilterSubList(const FilterSubList&) = delete;
FilterSubList(FilterSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Filters{rhs.Filters}
{ rhs.FreeMask = ~uint64_t{}; rhs.Filters = nullptr; }
~FilterSubList();
FilterSubList& operator=(const FilterSubList&) = delete;
FilterSubList& operator=(FilterSubList&& rhs) noexcept
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Filters, rhs.Filters); return *this; }
};
typedef struct EnumeratedHrtf { typedef struct EnumeratedHrtf {

View File

@ -571,26 +571,18 @@ void InitEffect(ALeffect *effect)
InitEffectParams(effect, AL_EFFECT_NULL); InitEffectParams(effect, AL_EFFECT_NULL);
} }
void ReleaseALEffects(ALCdevice *device) EffectSubList::~EffectSubList()
{ {
size_t leftover = 0; ALuint64 usemask = ~FreeMask;
for(auto &sublist : device->EffectList) while(usemask)
{ {
ALuint64 usemask = ~sublist.FreeMask; ALsizei idx = CTZ64(usemask);
while(usemask) Effects[idx].~ALeffect();
{ usemask &= ~(U64(1) << idx);
ALsizei idx = CTZ64(usemask);
ALeffect *effect = sublist.Effects + idx;
effect->~ALeffect();
++leftover;
usemask &= ~(U64(1) << idx);
}
sublist.FreeMask = ~usemask;
} }
if(leftover > 0) FreeMask = ~usemask;
WARN("(%p) Deleted " SZFMT " Effect%s\n", device, leftover, (leftover==1)?"":"s"); al_free(Effects);
Effects = nullptr;
} }

View File

@ -622,24 +622,16 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *va
} }
void ReleaseALFilters(ALCdevice *device) FilterSubList::~FilterSubList()
{ {
size_t leftover = 0; ALuint64 usemask = ~FreeMask;
for(auto &sublist : device->FilterList) while(usemask)
{ {
ALuint64 usemask = ~sublist.FreeMask; ALsizei idx = CTZ64(usemask);
while(usemask) Filters[idx].~ALfilter();
{ usemask &= ~(U64(1) << idx);
ALsizei idx = CTZ64(usemask);
ALfilter *filter = sublist.Filters + idx;
filter->~ALfilter();
++leftover;
usemask &= ~(U64(1) << idx);
}
sublist.FreeMask = ~usemask;
} }
if(leftover > 0) FreeMask = ~usemask;
WARN("(%p) Deleted " SZFMT " Filter%s\n", device, leftover, (leftover==1)?"":"s"); al_free(Filters);
Filters = nullptr;
} }