aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-11-07 12:58:19 -0800
committerChris Robinson <[email protected]>2020-11-07 12:58:19 -0800
commit0498ca200d95b3c6f6411c6485bbae1d611ef5f6 (patch)
treeca3e4347cf356f953cb4b3b03400ae31f0a07431 /al
parent4e760bbecc6ac4031dca45b4882c6faa71842e90 (diff)
Use an array of auxslot pointers instead of IDs to lookup
Diffstat (limited to 'al')
-rw-r--r--al/auxeffectslot.cpp100
1 files changed, 59 insertions, 41 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 8271f988..3b7a45fd 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -91,19 +91,18 @@ inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) noexcept
}
-void AddActiveEffectSlots(const al::span<const ALuint> slotids, ALCcontext *context)
+void AddActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext *context)
{
- if(slotids.empty()) return;
+ if(auxslots.empty()) return;
EffectSlotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_acquire)};
- size_t newcount{curarray->size() + slotids.size()};
+ size_t newcount{curarray->size() + auxslots.size()};
/* Insert the new effect slots into the head of the array, followed by the
* existing ones.
*/
EffectSlotArray *newarray = EffectSlot::CreatePtrArray(newcount);
- auto slotiter = std::transform(slotids.begin(), slotids.end(), newarray->begin(),
- [context](ALuint id) noexcept -> EffectSlot*
- { return &LookupEffectSlot(context, id)->mSlot; });
+ auto slotiter = std::transform(auxslots.begin(), auxslots.end(), newarray->begin(),
+ [](ALeffectslot *auxslot) noexcept { return &auxslot->mSlot; });
std::copy(curarray->begin(), curarray->end(), slotiter);
/* Remove any duplicates (first instance of each will be kept). */
@@ -136,9 +135,9 @@ void AddActiveEffectSlots(const al::span<const ALuint> slotids, ALCcontext *cont
delete curarray;
}
-void RemoveActiveEffectSlots(const al::span<const ALuint> slotids, ALCcontext *context)
+void RemoveActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext *context)
{
- if(slotids.empty()) return;
+ if(auxslots.empty()) return;
EffectSlotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_acquire)};
/* Don't shrink the allocated array size since we don't know how many (if
@@ -148,14 +147,11 @@ void RemoveActiveEffectSlots(const al::span<const ALuint> slotids, ALCcontext *c
auto new_end = std::copy(curarray->begin(), curarray->end(), newarray->begin());
/* Remove elements from newarray that match any ID in slotids. */
- for(const ALuint id : slotids)
+ for(const ALeffectslot *auxslot : auxslots)
{
- if(ALeffectslot *auxslot{LookupEffectSlot(context, id)})
- {
- auto proc_match = [auxslot](EffectSlot *slot) noexcept -> bool
- { return (slot == &auxslot->mSlot); };
- new_end = std::remove_if(newarray->begin(), new_end, proc_match);
- }
+ auto slot_match = [auxslot](EffectSlot *slot) noexcept -> bool
+ { return (slot == &auxslot->mSlot); };
+ new_end = std::remove_if(newarray->begin(), new_end, slot_match);
}
/* Reallocate with the new size. */
@@ -184,8 +180,7 @@ bool EnsureEffectSlots(ALCcontext *context, size_t needed)
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>(PopCount(sublist.FreeMask)); }
- )};
+ { return cur + static_cast<ALuint>(PopCount(sublist.FreeMask)); })};
while(needed > count)
{
@@ -320,33 +315,56 @@ START_API_FUNC
if UNLIKELY(n <= 0) return;
std::lock_guard<std::mutex> _{context->mEffectSlotLock};
- auto validate_slot = [&context](const ALuint id) -> bool
+ if(n == 1)
{
- ALeffectslot *slot{LookupEffectSlot(context.get(), id)};
+ ALeffectslot *slot{LookupEffectSlot(context.get(), effectslots[0])};
if UNLIKELY(!slot)
{
- context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", id);
- return false;
+ context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", effectslots[0]);
+ return;
}
if UNLIKELY(ReadRef(slot->ref) != 0)
{
- context->setError(AL_INVALID_OPERATION, "Deleting in-use effect slot %u", id);
- return false;
+ context->setError(AL_INVALID_OPERATION, "Deleting in-use effect slot %u",
+ effectslots[0]);
+ return;
}
- return true;
- };
- auto effectslots_end = effectslots + n;
- auto bad_slot = std::find_if_not(effectslots, effectslots_end, validate_slot);
- if UNLIKELY(bad_slot != effectslots_end) return;
-
- // All effectslots are valid, remove and delete them
- RemoveActiveEffectSlots({effectslots, static_cast<ALuint>(n)}, context.get());
- auto delete_slot = [&context](const ALuint sid) -> void
+ RemoveActiveEffectSlots({&slot, 1u}, context.get());
+ FreeEffectSlot(context.get(), slot);
+ }
+ else
{
- ALeffectslot *slot{LookupEffectSlot(context.get(), sid)};
- if(slot) FreeEffectSlot(context.get(), slot);
- };
- std::for_each(effectslots, effectslots_end, delete_slot);
+ auto slots = al::vector<ALeffectslot*>(static_cast<ALuint>(n));
+ for(size_t i{0};i < slots.size();++i)
+ {
+ ALeffectslot *slot{LookupEffectSlot(context.get(), effectslots[i])};
+ if UNLIKELY(!slot)
+ {
+ context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", effectslots[i]);
+ return;
+ }
+ if UNLIKELY(ReadRef(slot->ref) != 0)
+ {
+ context->setError(AL_INVALID_OPERATION, "Deleting in-use effect slot %u",
+ effectslots[i]);
+ return;
+ }
+ slots[i] = slot;
+ }
+ /* Remove any duplicates. */
+ auto slots_end = slots.end();
+ for(auto start=slots.begin()+1;start != slots_end;++start)
+ {
+ slots_end = std::remove(start, slots_end, *(start-1));
+ if(start == slots_end) break;
+ }
+ slots.erase(slots_end, slots.end());
+
+ /* All effectslots are valid, remove and delete them */
+ RemoveActiveEffectSlots(slots, context.get());
+ for(ALeffectslot *slot : slots)
+ FreeEffectSlot(context.get(), slot);
+ }
}
END_API_FUNC
@@ -384,7 +402,7 @@ START_API_FUNC
slot->PropsClean.test_and_set(std::memory_order_acq_rel);
slot->updateProps(context.get());
- AddActiveEffectSlots({&slotid, 1}, context.get());
+ AddActiveEffectSlots({&slot, 1}, context.get());
slot->mState = SlotState::Playing;
}
END_API_FUNC
@@ -418,7 +436,7 @@ START_API_FUNC
slots[i] = slot;
};
- AddActiveEffectSlots({slotids, static_cast<ALuint>(n)}, context.get());
+ AddActiveEffectSlots(slots, context.get());
for(auto slot : slots)
slot->mState = SlotState::Playing;
}
@@ -438,7 +456,7 @@ START_API_FUNC
return;
}
- RemoveActiveEffectSlots({&slotid, 1}, context.get());
+ RemoveActiveEffectSlots({&slot, 1}, context.get());
slot->mState = SlotState::Stopped;
}
END_API_FUNC
@@ -467,7 +485,7 @@ START_API_FUNC
slots[i] = slot;
};
- RemoveActiveEffectSlots({slotids, static_cast<ALuint>(n)}, context.get());
+ RemoveActiveEffectSlots(slots, context.get());
for(auto slot : slots)
slot->mState = SlotState::Stopped;
}
@@ -508,7 +526,7 @@ START_API_FUNC
}
if UNLIKELY(slot->mState == SlotState::Initial)
{
- AddActiveEffectSlots({&slot->id, 1}, context.get());
+ AddActiveEffectSlots({&slot, 1}, context.get());
slot->mState = SlotState::Playing;
}
break;