diff options
author | Chris Robinson <[email protected]> | 2019-09-12 06:29:32 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-09-12 06:29:32 -0700 |
commit | c0ce03d8b9533c768687964743420b18c5003455 (patch) | |
tree | 83d5f99d77098251339adc30237b5733964d5b56 /al/filter.cpp | |
parent | b71eb4dafd9e525020a5f2cd869d671fb3e8e5bd (diff) |
Get rid of more implicit conversions
Diffstat (limited to 'al/filter.cpp')
-rw-r--r-- | al/filter.cpp | 81 |
1 files changed, 42 insertions, 39 deletions
diff --git a/al/filter.cpp b/al/filter.cpp index abb2795b..920b4ca1 100644 --- a/al/filter.cpp +++ b/al/filter.cpp @@ -28,6 +28,7 @@ #include <memory> #include <mutex> #include <new> +#include <numeric> #include "AL/al.h" #include "AL/alc.h" @@ -278,42 +279,42 @@ void InitFilterParams(ALfilter *filter, ALenum type) filter->type = type; } -ALfilter *AllocFilter(ALCcontext *context) +bool EnsureFilters(ALCdevice *device, size_t needed) { - ALCdevice *device{context->mDevice.get()}; - std::lock_guard<std::mutex> _{device->FilterLock}; - auto sublist = std::find_if(device->FilterList.begin(), device->FilterList.end(), - [](const FilterSubList &entry) noexcept -> bool - { return entry.FreeMask != 0; } - ); + size_t count{std::accumulate(device->FilterList.cbegin(), device->FilterList.cend(), size_t{0}, + [](size_t cur, const FilterSubList &sublist) noexcept -> size_t + { return cur + static_cast<ALuint>(POPCNT64(~sublist.FreeMask)); } + )}; - auto lidx = static_cast<ALsizei>(std::distance(device->FilterList.begin(), sublist)); - ALsizei slidx{0}; - if LIKELY(sublist != device->FilterList.end()) - slidx = CTZ64(sublist->FreeMask); - else + while(needed > count) { - /* Don't allocate so many list entries that the 32-bit ID could - * overflow... - */ if UNLIKELY(device->FilterList.size() >= 1<<25) - { - context->setError(AL_OUT_OF_MEMORY, "Too many filters allocated"); - return nullptr; - } + return false; + device->FilterList.emplace_back(); - sublist = device->FilterList.end() - 1; + auto sublist = device->FilterList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Filters = static_cast<ALfilter*>(al_calloc(16, sizeof(ALfilter)*64)); + sublist->Filters = static_cast<ALfilter*>(al_calloc(alignof(ALfilter), sizeof(ALfilter)*64)); if UNLIKELY(!sublist->Filters) { device->FilterList.pop_back(); - context->setError(AL_OUT_OF_MEMORY, "Failed to allocate filter batch"); - return nullptr; + return false; } - - slidx = 0; + count += 64; } + return true; +} + + +ALfilter *AllocFilter(ALCdevice *device) +{ + auto sublist = std::find_if(device->FilterList.begin(), device->FilterList.end(), + [](const FilterSubList &entry) noexcept -> bool + { return entry.FreeMask != 0; } + ); + + auto lidx = static_cast<ALuint>(std::distance(device->FilterList.begin(), sublist)); + auto slidx = static_cast<ALuint>(CTZ64(sublist->FreeMask)); ALfilter *filter{::new (sublist->Filters + slidx) ALfilter{}}; InitFilterParams(filter, AL_FILTER_NULL); @@ -328,9 +329,9 @@ ALfilter *AllocFilter(ALCcontext *context) void FreeFilter(ALCdevice *device, ALfilter *filter) { - ALuint id = filter->id - 1; - ALsizei lidx = id >> 6; - ALsizei slidx = id & 0x3f; + const ALuint id{filter->id - 1}; + const size_t lidx{id >> 6}; + const ALuint slidx{id & 0x3f}; al::destroy_at(filter); @@ -340,8 +341,8 @@ void FreeFilter(ALCdevice *device, ALfilter *filter) inline ALfilter *LookupFilter(ALCdevice *device, ALuint id) { - ALuint lidx = (id-1) >> 6; - ALsizei slidx = (id-1) & 0x3f; + const size_t lidx{(id-1) >> 6}; + const ALuint slidx{(id-1) & 0x3f}; if UNLIKELY(lidx >= device->FilterList.size()) return nullptr; @@ -363,10 +364,18 @@ START_API_FUNC context->setError(AL_INVALID_VALUE, "Generating %d filters", n); if UNLIKELY(n <= 0) return; + ALCdevice *device{context->mDevice.get()}; + std::lock_guard<std::mutex> _{device->EffectLock}; + if(!EnsureFilters(device, static_cast<ALuint>(n))) + { + context->setError(AL_OUT_OF_MEMORY, "Failed to allocate %d filter%s", n, (n==1)?"":"s"); + return; + } + if LIKELY(n == 1) { /* Special handling for the easy and normal case. */ - ALfilter *filter = AllocFilter(context.get()); + ALfilter *filter{AllocFilter(device)}; if(filter) filters[0] = filter->id; } else @@ -375,15 +384,9 @@ START_API_FUNC * modifying the user storage in case of failure. */ al::vector<ALuint> ids; - ids.reserve(n); + ids.reserve(static_cast<ALuint>(n)); do { - ALfilter *filter = AllocFilter(context.get()); - if(!filter) - { - alDeleteFilters(static_cast<ALsizei>(ids.size()), ids.data()); - return; - } - + ALfilter *filter{AllocFilter(device)}; ids.emplace_back(filter->id); } while(--n); std::copy(ids.begin(), ids.end(), filters); |