aboutsummaryrefslogtreecommitdiffstats
path: root/al/filter.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-09-12 06:29:32 -0700
committerChris Robinson <[email protected]>2019-09-12 06:29:32 -0700
commitc0ce03d8b9533c768687964743420b18c5003455 (patch)
tree83d5f99d77098251339adc30237b5733964d5b56 /al/filter.cpp
parentb71eb4dafd9e525020a5f2cd869d671fb3e8e5bd (diff)
Get rid of more implicit conversions
Diffstat (limited to 'al/filter.cpp')
-rw-r--r--al/filter.cpp81
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);