Automatically clean up buffers with ther sublist
This commit is contained in:
parent
05845b53e8
commit
8ae07ad1ae
10
Alc/alc.cpp
10
Alc/alc.cpp
@ -2396,11 +2396,11 @@ ALCdevice_struct::~ALCdevice_struct()
|
||||
|
||||
almtx_destroy(&BackendLock);
|
||||
|
||||
ReleaseALBuffers(this);
|
||||
std::for_each(BufferList.begin(), BufferList.end(),
|
||||
[](BufferSubList &entry) noexcept -> void
|
||||
{ al_free(entry.Buffers); }
|
||||
);
|
||||
size_t count{0u};
|
||||
for(auto &sublist : BufferList)
|
||||
count += POPCNT64(~sublist.FreeMask);
|
||||
if(count > 0)
|
||||
WARN(SZFMT " Buffer%s not deleted\n", count, (count==1)?"":"s");
|
||||
BufferList.clear();
|
||||
almtx_destroy(&BufferLock);
|
||||
|
||||
|
@ -121,6 +121,4 @@ struct ALbuffer {
|
||||
ALuint id{0};
|
||||
};
|
||||
|
||||
ALvoid ReleaseALBuffers(ALCdevice *device);
|
||||
|
||||
#endif
|
||||
|
@ -551,10 +551,20 @@ typedef union AmbiConfig {
|
||||
} AmbiConfig;
|
||||
|
||||
|
||||
typedef struct BufferSubList {
|
||||
ALuint64 FreeMask{~ALuint64{}};
|
||||
struct BufferSubList {
|
||||
uint64_t FreeMask{~uint64_t{}};
|
||||
struct ALbuffer *Buffers{nullptr}; /* 64 */
|
||||
} BufferSubList;
|
||||
|
||||
BufferSubList() noexcept = default;
|
||||
BufferSubList(const BufferSubList&) = delete;
|
||||
BufferSubList(BufferSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Buffers{rhs.Buffers}
|
||||
{ rhs.FreeMask = ~uint64_t{}; rhs.Buffers = nullptr; }
|
||||
~BufferSubList();
|
||||
|
||||
BufferSubList& operator=(const BufferSubList&) = delete;
|
||||
BufferSubList& operator=(BufferSubList&& rhs) noexcept
|
||||
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
|
||||
};
|
||||
|
||||
typedef struct EffectSubList {
|
||||
ALuint64 FreeMask{~ALuint64{}};
|
||||
|
@ -1174,30 +1174,16 @@ ALsizei ChannelsFromFmt(FmtChannels chans)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ReleaseALBuffers()
|
||||
*
|
||||
* INTERNAL: Called to destroy any buffers that still exist on the device
|
||||
*/
|
||||
ALvoid ReleaseALBuffers(ALCdevice *device)
|
||||
BufferSubList::~BufferSubList()
|
||||
{
|
||||
size_t leftover = 0;
|
||||
for(auto &sublist : device->BufferList)
|
||||
ALuint64 usemask = ~FreeMask;
|
||||
while(usemask)
|
||||
{
|
||||
ALuint64 usemask = ~sublist.FreeMask;
|
||||
while(usemask)
|
||||
{
|
||||
ALsizei idx = CTZ64(usemask);
|
||||
ALbuffer *buffer = sublist.Buffers + idx;
|
||||
|
||||
buffer->~ALbuffer();
|
||||
|
||||
++leftover;
|
||||
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
sublist.FreeMask = ~usemask;
|
||||
ALsizei idx{CTZ64(usemask)};
|
||||
Buffers[idx].~ALbuffer();
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
if(leftover > 0)
|
||||
WARN("(%p) Deleted " SZFMT " Buffer%s\n", device, leftover, (leftover==1)?"":"s");
|
||||
FreeMask = ~usemask;
|
||||
al_free(Buffers);
|
||||
Buffers = nullptr;
|
||||
}
|
||||
|
@ -3405,10 +3405,7 @@ SourceSubList::~SourceSubList()
|
||||
while(usemask)
|
||||
{
|
||||
ALsizei idx{CTZ64(usemask)};
|
||||
ALsource *source{Sources + idx};
|
||||
|
||||
source->~ALsource();
|
||||
|
||||
Sources[idx].~ALsource();
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
FreeMask = ~usemask;
|
||||
|
Loading…
x
Reference in New Issue
Block a user