Improve construction and destruction of ALvoices

This commit is contained in:
Chris Robinson
2018-11-30 19:04:38 -08:00
parent 4b7ac4a6ed
commit c7569c31ad
3 changed files with 65 additions and 30 deletions
+45 -12
View File
@@ -2795,11 +2795,51 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
for(;v < v_count;v++)
{
ALvoice *old_voice{context->Voices[v]};
voice = new (voice) ALvoice{};
/* Copy the old voice data and source property set to the new
* storage.
* storage. Make sure the old voice's Update (if any) is cleared so
* it doesn't get deleted on deinit.
*/
memcpy(voice, old_voice, sizeof(*voice));
voice->Update.store(old_voice->Update.exchange(nullptr, std::memory_order_relaxed),
std::memory_order_relaxed);
voice->SourceID.store(old_voice->SourceID.load(std::memory_order_relaxed),
std::memory_order_relaxed);
voice->Playing.store(old_voice->Playing.load(std::memory_order_relaxed),
std::memory_order_relaxed);
voice->Props = old_voice->Props;
/* Clear extraneous property set sends. */
std::fill(std::begin(voice->Props.Send)+s_count, std::end(voice->Props.Send),
ALvoiceProps::SendData{});
voice->position.store(old_voice->position.load(std::memory_order_relaxed),
std::memory_order_relaxed);
voice->position_fraction.store(
old_voice->position_fraction.load(std::memory_order_relaxed),
std::memory_order_relaxed);
voice->current_buffer.store(old_voice->current_buffer.load(std::memory_order_relaxed),
std::memory_order_relaxed);
voice->loop_buffer.store(old_voice->loop_buffer.load(std::memory_order_relaxed),
std::memory_order_relaxed);
voice->NumChannels = old_voice->NumChannels;
voice->SampleSize = old_voice->SampleSize;
voice->Step = old_voice->Step;
voice->Resampler = old_voice->Resampler;
voice->Flags = old_voice->Flags;
voice->Offset = old_voice->Offset;
memcpy(voice->PrevSamples, old_voice->PrevSamples, sizeof(voice->PrevSamples));
voice->ResampleState = old_voice->ResampleState;
voice->Direct = old_voice->Direct;
std::copy_n(old_voice->Send, s_count, voice->Send);
/* Set this voice's reference. */
@@ -2808,21 +2848,14 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
/* Increment pointer to the next storage space. */
voice = reinterpret_cast<ALvoice*>((char*)voice + sizeof_voice);
}
/* Deinit any left over voices that weren't copied over to the new
* array. NOTE: If this does anything, v equals num_voices and
* num_voices is less than VoiceCount, so the following loop won't do
* anything.
*/
/* Deinit old voices. */
auto voices_end = context->Voices + context->VoiceCount.load(std::memory_order_relaxed);
std::for_each(context->Voices + v, voices_end,
[](ALvoice *voice) -> void { DeinitVoice(voice); }
);
std::for_each(context->Voices, voices_end, DeinitVoice);
}
/* Finish setting the voices' property set pointers and references. */
for(;v < num_voices;v++)
{
voice->Update.store(nullptr, std::memory_order_relaxed);
voice = new (voice) ALvoice{};
voices[v] = voice;
voice = reinterpret_cast<ALvoice*>((char*)voice + sizeof_voice);
+9 -9
View File
@@ -102,6 +102,7 @@ void aluInit(void)
void DeinitVoice(ALvoice *voice) noexcept
{
delete voice->Update.exchange(nullptr, std::memory_order_acq_rel);
voice->~ALvoice();
}
@@ -505,7 +506,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
const ALfloat DryGainLF, const ALfloat *WetGain,
const ALfloat *WetGainLF, const ALfloat *WetGainHF,
ALeffectslot **SendSlots, const ALbuffer *Buffer,
const ALvoiceProps *props, const ALlistener &Listener,
const ALvoicePropsBase *props, const ALlistener &Listener,
const ALCdevice *Device)
{
struct ChanMap StereoMap[2] = {
@@ -1023,7 +1024,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
}
}
void CalcNonAttnSourceParams(ALvoice *voice, const ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
void CalcNonAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
{
const ALCdevice *Device = ALContext->Device;
const ALlistener &Listener = ALContext->Listener;
@@ -1086,7 +1087,7 @@ void CalcNonAttnSourceParams(ALvoice *voice, const ALvoiceProps *props, const AL
WetGainLF, WetGainHF, SendSlots, ALBuffer, props, Listener, Device);
}
void CalcAttnSourceParams(ALvoice *voice, const ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
{
const ALCdevice *Device = ALContext->Device;
const ALlistener &Listener = ALContext->Listener;
@@ -1461,11 +1462,10 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
if(props)
{
memcpy(&voice->Props, props, FAM_SIZE(ALvoiceProps, Send, context->Device->NumAuxSends));
voice->Props = *props;
AtomicReplaceHead(context->FreeVoiceProps, props);
}
props = &voice->Props;
ALbufferlistitem *BufferListItem{voice->current_buffer.load(std::memory_order_relaxed)};
while(BufferListItem)
@@ -1477,11 +1477,11 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
);
if(LIKELY(buffer != buffers_end))
{
if(props->SpatializeMode == SpatializeOn ||
(props->SpatializeMode == SpatializeAuto && (*buffer)->FmtChannels == FmtMono))
CalcAttnSourceParams(voice, props, *buffer, context);
if(voice->Props.SpatializeMode == SpatializeOn ||
(voice->Props.SpatializeMode == SpatializeAuto && (*buffer)->FmtChannels == FmtMono))
CalcAttnSourceParams(voice, &voice->Props, *buffer, context);
else
CalcNonAttnSourceParams(voice, props, *buffer, context);
CalcNonAttnSourceParams(voice, &voice->Props, *buffer, context);
break;
}
BufferListItem = BufferListItem->next.load(std::memory_order_acquire);
+11 -9
View File
@@ -141,7 +141,7 @@ typedef struct SendParams {
} SendParams;
struct ALvoiceProps {
struct ALvoicePropsBase {
ALfloat Pitch;
ALfloat Gain;
ALfloat OuterGain;
@@ -183,7 +183,7 @@ struct ALvoiceProps {
ALfloat GainLF;
ALfloat LFReference;
} Direct;
struct {
struct SendData {
struct ALeffectslot *Slot;
ALfloat Gain;
ALfloat GainHF;
@@ -191,8 +191,10 @@ struct ALvoiceProps {
ALfloat GainLF;
ALfloat LFReference;
} Send[MAX_SENDS];
};
std::atomic<ALvoiceProps*> next;
struct ALvoiceProps : public ALvoicePropsBase {
std::atomic<ALvoiceProps*> next{nullptr};
DEF_NEWDEL(ALvoiceProps)
};
@@ -202,13 +204,13 @@ struct ALvoiceProps {
#define VOICE_HAS_HRTF (1<<2)
#define VOICE_HAS_NFC (1<<3)
typedef struct ALvoice {
std::atomic<ALvoiceProps*> Update;
struct ALvoice {
std::atomic<ALvoiceProps*> Update{nullptr};
std::atomic<ALuint> SourceID;
std::atomic<bool> Playing;
std::atomic<ALuint> SourceID{0u};
std::atomic<bool> Playing{false};
ALvoiceProps Props;
ALvoicePropsBase Props;
/**
* Source offset in samples, relative to the currently playing buffer, NOT
@@ -262,7 +264,7 @@ typedef struct ALvoice {
ALfloat (*Buffer)[BUFFERSIZE];
ALsizei Channels;
} Send[];
} ALvoice;
};
void DeinitVoice(ALvoice *voice) noexcept;