aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/auxeffectslot.cpp110
-rw-r--r--al/effect.cpp86
-rw-r--r--al/error.cpp3
-rw-r--r--al/filter.cpp81
-rw-r--r--al/state.cpp20
5 files changed, 156 insertions, 144 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 06627bc8..f2801329 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -27,6 +27,7 @@
#include <iterator>
#include <memory>
#include <mutex>
+#include <numeric>
#include <thread>
#include "AL/al.h"
@@ -158,58 +159,52 @@ void RemoveActiveEffectSlots(const ALuint *slotids, size_t count, ALCcontext *co
}
-ALeffectslot *AllocEffectSlot(ALCcontext *context)
+bool EnsureEffectSlots(ALCcontext *context, size_t needed)
{
- ALCdevice *device{context->mDevice.get()};
- std::lock_guard<std::mutex> _{context->mEffectSlotLock};
- if(context->mNumEffectSlots >= device->AuxiliaryEffectSlotMax)
- {
- context->setError(AL_OUT_OF_MEMORY, "Exceeding %u effect slot limit",
- device->AuxiliaryEffectSlotMax);
- return nullptr;
- }
- auto sublist = std::find_if(context->mEffectSlotList.begin(), context->mEffectSlotList.end(),
- [](const EffectSlotSubList &entry) noexcept -> bool
- { return entry.FreeMask != 0; }
- );
- auto lidx = static_cast<ALuint>(std::distance(context->mEffectSlotList.begin(), sublist));
- ALuint slidx;
- if LIKELY(sublist != context->mEffectSlotList.end())
- slidx = static_cast<ALuint>(CTZ64(sublist->FreeMask));
- else
+ size_t count{std::accumulate(context->mEffectSlotList.cbegin(),
+ context->mEffectSlotList.cend(), size_t{0},
+ [](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
+ { return cur + static_cast<ALuint>(POPCNT64(~sublist.FreeMask)); }
+ )};
+
+ while(needed > count)
{
- /* Don't allocate so many list entries that the 32-bit ID could
- * overflow...
- */
if UNLIKELY(context->mEffectSlotList.size() >= 1<<25)
- {
- context->setError(AL_OUT_OF_MEMORY, "Too many effect slots allocated");
- return nullptr;
- }
- context->mEffectSlotList.emplace_back();
- sublist = context->mEffectSlotList.end() - 1;
+ return false;
+ context->mEffectSlotList.emplace_back();
+ auto sublist = context->mEffectSlotList.end() - 1;
sublist->FreeMask = ~0_u64;
- sublist->EffectSlots = static_cast<ALeffectslot*>(al_calloc(16, sizeof(ALeffectslot)*64));
+ sublist->EffectSlots = static_cast<ALeffectslot*>(
+ al_calloc(alignof(ALeffectslot), sizeof(ALeffectslot)*64));
if UNLIKELY(!sublist->EffectSlots)
{
context->mEffectSlotList.pop_back();
- context->setError(AL_OUT_OF_MEMORY, "Failed to allocate effect slot batch");
- return nullptr;
+ return false;
}
-
- slidx = 0;
+ count += 64;
}
+ return true;
+}
+
+ALeffectslot *AllocEffectSlot(ALCcontext *context)
+{
+ auto sublist = std::find_if(context->mEffectSlotList.begin(), context->mEffectSlotList.end(),
+ [](const EffectSlotSubList &entry) noexcept -> bool
+ { return entry.FreeMask != 0; }
+ );
+
+ auto lidx = static_cast<ALuint>(std::distance(context->mEffectSlotList.begin(), sublist));
+ auto slidx = static_cast<ALuint>(CTZ64(sublist->FreeMask));
ALeffectslot *slot{::new (sublist->EffectSlots + slidx) ALeffectslot{}};
- ALenum err{InitEffectSlot(slot)};
- if(err != AL_NO_ERROR)
+ if(ALenum err{InitEffectSlot(slot)})
{
al::destroy_at(slot);
context->setError(err, "Effect slot object initialization failed");
return nullptr;
}
- aluInitEffectPanning(slot, device);
+ aluInitEffectPanning(slot, context->mDevice.get());
/* Add 1 to avoid source ID 0. */
slot->id = ((lidx<<6) | slidx) + 1;
@@ -224,7 +219,7 @@ void FreeEffectSlot(ALCcontext *context, ALeffectslot *slot)
{
const ALuint id{slot->id - 1};
const size_t lidx{id >> 6};
- const size_t slidx{id & 0x3f};
+ const ALuint slidx{id & 0x3f};
al::destroy_at(slot);
@@ -262,6 +257,21 @@ START_API_FUNC
SETERR_RETURN(context, AL_INVALID_VALUE,, "Generating %d effect slots", n);
if(n == 0) return;
+ std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock};
+ ALCdevice *device{context->mDevice.get()};
+ if(static_cast<ALuint>(n) > device->AuxiliaryEffectSlotMax-context->mNumEffectSlots)
+ {
+ context->setError(AL_OUT_OF_MEMORY, "Exceeding %u effect slot limit (%u + %d)",
+ device->AuxiliaryEffectSlotMax, context->mNumEffectSlots, n);
+ return;
+ }
+ if(!EnsureEffectSlots(context.get(), static_cast<ALuint>(n)))
+ {
+ context->setError(AL_OUT_OF_MEMORY, "Failed to allocate %d effectslot%s", n,
+ (n==1) ? "" : "s");
+ return;
+ }
+
if(n == 1)
{
ALeffectslot *slot{AllocEffectSlot(context.get())};
@@ -270,27 +280,21 @@ START_API_FUNC
}
else
{
- auto tempids = al::vector<ALuint>(static_cast<ALuint>(n));
- auto alloc_end = std::find_if_not(tempids.begin(), tempids.end(),
- [&context](ALuint &id) -> bool
+ al::vector<ALuint> ids;
+ ids.reserve(static_cast<ALuint>(n));
+ do {
+ ALeffectslot *slot{AllocEffectSlot(context.get())};
+ if(!slot)
{
- ALeffectslot *slot{AllocEffectSlot(context.get())};
- if(!slot) return false;
- id = slot->id;
- return true;
+ slotlock.unlock();
+ alDeleteAuxiliaryEffectSlots(static_cast<ALsizei>(ids.size()), ids.data());
+ return;
}
- );
- if(alloc_end != tempids.end())
- {
- auto count = static_cast<ALsizei>(std::distance(tempids.begin(), alloc_end));
- alDeleteAuxiliaryEffectSlots(count, tempids.data());
- return;
- }
-
- std::copy(tempids.cbegin(), tempids.cend(), effectslots);
+ ids.emplace_back(slot->id);
+ } while(--n);
+ std::copy(ids.cbegin(), ids.cend(), effectslots);
}
- std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock};
AddActiveEffectSlots(effectslots, static_cast<ALuint>(n), context.get());
}
END_API_FUNC
diff --git a/al/effect.cpp b/al/effect.cpp
index 3836a5e4..c27fc8df 100644
--- a/al/effect.cpp
+++ b/al/effect.cpp
@@ -29,6 +29,7 @@
#include <memory>
#include <mutex>
#include <new>
+#include <numeric>
#include <utility>
#include "AL/al.h"
@@ -136,42 +137,41 @@ void InitEffectParams(ALeffect *effect, ALenum type)
effect->type = type;
}
-ALeffect *AllocEffect(ALCcontext *context)
+bool EnsureEffects(ALCdevice *device, size_t needed)
{
- ALCdevice *device{context->mDevice.get()};
- std::lock_guard<std::mutex> _{device->EffectLock};
- auto sublist = std::find_if(device->EffectList.begin(), device->EffectList.end(),
- [](const EffectSubList &entry) noexcept -> bool
- { return entry.FreeMask != 0; }
- );
+ size_t count{std::accumulate(device->EffectList.cbegin(), device->EffectList.cend(), size_t{0},
+ [](size_t cur, const EffectSubList &sublist) noexcept -> size_t
+ { return cur + static_cast<ALuint>(POPCNT64(~sublist.FreeMask)); }
+ )};
- auto lidx = static_cast<ALsizei>(std::distance(device->EffectList.begin(), sublist));
- ALsizei slidx{0};
- if LIKELY(sublist != device->EffectList.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->EffectList.size() >= 1<<25)
- {
- context->setError(AL_OUT_OF_MEMORY, "Too many effects allocated");
- return nullptr;
- }
+ return false;
+
device->EffectList.emplace_back();
- sublist = device->EffectList.end() - 1;
+ auto sublist = device->EffectList.end() - 1;
sublist->FreeMask = ~0_u64;
- sublist->Effects = static_cast<ALeffect*>(al_calloc(16, sizeof(ALeffect)*64));
+ sublist->Effects = static_cast<ALeffect*>(al_calloc(alignof(ALeffect), sizeof(ALeffect)*64));
if UNLIKELY(!sublist->Effects)
{
device->EffectList.pop_back();
- context->setError(AL_OUT_OF_MEMORY, "Failed to allocate effect batch");
- return nullptr;
+ return false;
}
-
- slidx = 0;
+ count += 64;
}
+ return true;
+}
+
+ALeffect *AllocEffect(ALCdevice *device)
+{
+ auto sublist = std::find_if(device->EffectList.begin(), device->EffectList.end(),
+ [](const EffectSubList &entry) noexcept -> bool
+ { return entry.FreeMask != 0; }
+ );
+
+ auto lidx = static_cast<ALuint>(std::distance(device->EffectList.begin(), sublist));
+ auto slidx = static_cast<ALuint>(CTZ64(sublist->FreeMask));
ALeffect *effect{::new (sublist->Effects + slidx) ALeffect{}};
InitEffectParams(effect, AL_EFFECT_NULL);
@@ -186,9 +186,9 @@ ALeffect *AllocEffect(ALCcontext *context)
void FreeEffect(ALCdevice *device, ALeffect *effect)
{
- ALuint id = effect->id - 1;
- ALsizei lidx = id >> 6;
- ALsizei slidx = id & 0x3f;
+ const ALuint id{effect->id - 1};
+ const size_t lidx{id >> 6};
+ const ALuint slidx{id & 0x3f};
al::destroy_at(effect);
@@ -197,8 +197,8 @@ void FreeEffect(ALCdevice *device, ALeffect *effect)
inline ALeffect *LookupEffect(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->EffectList.size())
return nullptr;
@@ -220,11 +220,19 @@ START_API_FUNC
context->setError(AL_INVALID_VALUE, "Generating %d effects", n);
if UNLIKELY(n <= 0) return;
+ ALCdevice *device{context->mDevice.get()};
+ std::lock_guard<std::mutex> _{device->EffectLock};
+ if(!EnsureEffects(device, static_cast<ALuint>(n)))
+ {
+ context->setError(AL_OUT_OF_MEMORY, "Failed to allocate %d effect%s", n, (n==1)?"":"s");
+ return;
+ }
+
if LIKELY(n == 1)
{
/* Special handling for the easy and normal case. */
- ALeffect *effect = AllocEffect(context.get());
- if(effect) effects[0] = effect->id;
+ ALeffect *effect{AllocEffect(device)};
+ effects[0] = effect->id;
}
else
{
@@ -232,18 +240,12 @@ 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 {
- ALeffect *effect = AllocEffect(context.get());
- if(!effect)
- {
- alDeleteEffects(static_cast<ALsizei>(ids.size()), ids.data());
- return;
- }
-
+ ALeffect *effect{AllocEffect(device)};
ids.emplace_back(effect->id);
} while(--n);
- std::copy(ids.begin(), ids.end(), effects);
+ std::copy(ids.cbegin(), ids.cend(), effects);
}
}
END_API_FUNC
@@ -722,7 +724,7 @@ void LoadReverbPreset(const char *name, ALeffect *effect)
effect->Props.Reverb.HFReference = props->flHFReference;
effect->Props.Reverb.LFReference = props->flLFReference;
effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor;
- effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit;
+ effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit ? AL_TRUE : AL_FALSE;
return;
}
diff --git a/al/error.cpp b/al/error.cpp
index a7080493..f3e2dbb3 100644
--- a/al/error.cpp
+++ b/al/error.cpp
@@ -86,7 +86,8 @@ void ALCcontext::setError(ALenum errorCode, const char *msg, ...)
std::lock_guard<std::mutex> _{mEventCbLock};
ALbitfieldSOFT enabledevts{mEnabledEvts.load(std::memory_order_relaxed)};
if((enabledevts&EventType_Error) && mEventCb)
- (*mEventCb)(AL_EVENT_TYPE_ERROR_SOFT, 0, errorCode, msglen, msg, mEventParam);
+ (*mEventCb)(AL_EVENT_TYPE_ERROR_SOFT, 0, static_cast<ALuint>(errorCode), msglen, msg,
+ mEventParam);
}
}
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);
diff --git a/al/state.cpp b/al/state.cpp
index cc5d8bac..74fb3b55 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -218,11 +218,11 @@ START_API_FUNC
switch(pname)
{
case AL_DOPPLER_FACTOR:
- value = static_cast<ALdouble>(context->mDopplerFactor);
+ value = context->mDopplerFactor;
break;
case AL_DOPPLER_VELOCITY:
- value = static_cast<ALdouble>(context->mDopplerVelocity);
+ value = context->mDopplerVelocity;
break;
case AL_DISTANCE_MODEL:
@@ -230,7 +230,7 @@ START_API_FUNC
break;
case AL_SPEED_OF_SOUND:
- value = static_cast<ALdouble>(context->mSpeedOfSound);
+ value = context->mSpeedOfSound;
break;
case AL_DEFERRED_UPDATES_SOFT:
@@ -239,7 +239,7 @@ START_API_FUNC
break;
case AL_GAIN_LIMIT_SOFT:
- value = static_cast<ALdouble>GAIN_MIX_MAX/context->mGainBoost;
+ value = ALdouble{GAIN_MIX_MAX}/context->mGainBoost;
break;
case AL_NUM_RESAMPLERS_SOFT:
@@ -337,7 +337,7 @@ START_API_FUNC
case AL_DEFERRED_UPDATES_SOFT:
if(context->mDeferUpdates.load(std::memory_order_acquire))
- value = static_cast<ALint>(AL_TRUE);
+ value = AL_TRUE;
break;
case AL_GAIN_LIMIT_SOFT:
@@ -710,14 +710,16 @@ START_API_FUNC
if((context->mEnabledEvts.load(std::memory_order_relaxed)&EventType_Deprecated))
{
- static constexpr ALCchar msg[] =
- "alDopplerVelocity is deprecated in AL1.1, use alSpeedOfSound";
- const ALsizei msglen = static_cast<ALsizei>(strlen(msg));
std::lock_guard<std::mutex> _{context->mEventCbLock};
ALbitfieldSOFT enabledevts{context->mEnabledEvts.load(std::memory_order_relaxed)};
if((enabledevts&EventType_Deprecated) && context->mEventCb)
+ {
+ static constexpr ALCchar msg[] =
+ "alDopplerVelocity is deprecated in AL1.1, use alSpeedOfSound";
+ const ALsizei msglen{sizeof(msg)-1};
(*context->mEventCb)(AL_EVENT_TYPE_DEPRECATED_SOFT, 0, 0, msglen, msg,
- context->mEventParam);
+ context->mEventParam);
+ }
}
if(!(value >= 0.0f && std::isfinite(value)))