Store effects in an array of lists
This commit is contained in:
@@ -2392,13 +2392,12 @@ static ALCvoid FreeDevice(ALCdevice *device)
|
||||
VECTOR_DEINIT(device->BufferList);
|
||||
almtx_destroy(&device->BufferLock);
|
||||
|
||||
if(device->EffectMap.size > 0)
|
||||
{
|
||||
WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size,
|
||||
(device->EffectMap.size==1)?"":"s");
|
||||
ReleaseALEffects(device);
|
||||
}
|
||||
ResetUIntMap(&device->EffectMap);
|
||||
ReleaseALEffects(device);
|
||||
#define FREE_EFFECTSUBLIST(x) al_free((x)->Effects)
|
||||
VECTOR_FOR_EACH(EffectSubList, device->EffectList, FREE_EFFECTSUBLIST);
|
||||
#undef FREE_EFFECTSUBLIST
|
||||
VECTOR_DEINIT(device->EffectList);
|
||||
almtx_destroy(&device->EffectLock);
|
||||
|
||||
if(device->FilterMap.size > 0)
|
||||
{
|
||||
@@ -4000,7 +3999,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
||||
device->NumAuxSends = DEFAULT_SENDS;
|
||||
|
||||
VECTOR_INIT(device->BufferList);
|
||||
InitUIntMap(&device->EffectMap, INT_MAX);
|
||||
VECTOR_INIT(device->EffectList);
|
||||
InitUIntMap(&device->FilterMap, INT_MAX);
|
||||
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
@@ -4132,6 +4131,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
||||
}
|
||||
almtx_init(&device->BackendLock, almtx_plain);
|
||||
almtx_init(&device->BufferLock, almtx_plain);
|
||||
almtx_init(&device->EffectLock, almtx_plain);
|
||||
|
||||
if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt))
|
||||
{
|
||||
@@ -4278,7 +4278,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
|
||||
device->RealOut.NumChannels = 0;
|
||||
|
||||
VECTOR_INIT(device->BufferList);
|
||||
InitUIntMap(&device->EffectMap, INT_MAX);
|
||||
VECTOR_INIT(device->EffectList);
|
||||
InitUIntMap(&device->FilterMap, INT_MAX);
|
||||
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
@@ -4327,6 +4327,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
|
||||
}
|
||||
almtx_init(&device->BackendLock, almtx_plain);
|
||||
almtx_init(&device->BufferLock, almtx_plain);
|
||||
almtx_init(&device->EffectLock, almtx_plain);
|
||||
|
||||
{
|
||||
ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList);
|
||||
@@ -4502,7 +4503,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
|
||||
device->NumAuxSends = DEFAULT_SENDS;
|
||||
|
||||
VECTOR_INIT(device->BufferList);
|
||||
InitUIntMap(&device->EffectMap, INT_MAX);
|
||||
VECTOR_INIT(device->EffectList);
|
||||
InitUIntMap(&device->FilterMap, INT_MAX);
|
||||
|
||||
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
|
||||
@@ -4522,6 +4523,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
|
||||
}
|
||||
almtx_init(&device->BackendLock, almtx_plain);
|
||||
almtx_init(&device->BufferLock, almtx_plain);
|
||||
almtx_init(&device->EffectLock, almtx_plain);
|
||||
|
||||
//Set output format
|
||||
device->NumUpdates = 0;
|
||||
|
||||
@@ -166,20 +166,6 @@ typedef struct ALeffect {
|
||||
ALuint id;
|
||||
} ALeffect;
|
||||
|
||||
inline void LockEffectsRead(ALCdevice *device)
|
||||
{ LockUIntMapRead(&device->EffectMap); }
|
||||
inline void UnlockEffectsRead(ALCdevice *device)
|
||||
{ UnlockUIntMapRead(&device->EffectMap); }
|
||||
inline void LockEffectsWrite(ALCdevice *device)
|
||||
{ LockUIntMapWrite(&device->EffectMap); }
|
||||
inline void UnlockEffectsWrite(ALCdevice *device)
|
||||
{ UnlockUIntMapWrite(&device->EffectMap); }
|
||||
|
||||
inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id)
|
||||
{ return (struct ALeffect*)LookupUIntMapKeyNoLock(&device->EffectMap, id); }
|
||||
inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id)
|
||||
{ return (struct ALeffect*)RemoveUIntMapKeyNoLock(&device->EffectMap, id); }
|
||||
|
||||
inline ALboolean IsReverbEffect(ALenum type)
|
||||
{ return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; }
|
||||
|
||||
|
||||
@@ -165,6 +165,7 @@ struct FrontStablizer;
|
||||
struct Compressor;
|
||||
struct ALCbackend;
|
||||
struct ALbuffer;
|
||||
struct ALeffect;
|
||||
struct ALsource;
|
||||
struct ALcontextProps;
|
||||
struct ALlistenerProps;
|
||||
@@ -381,6 +382,12 @@ typedef struct BufferSubList {
|
||||
} BufferSubList;
|
||||
TYPEDEF_VECTOR(BufferSubList, vector_BufferSubList)
|
||||
|
||||
typedef struct EffectSubList {
|
||||
ALuint64 FreeMask;
|
||||
struct ALeffect *Effects; /* 64 */
|
||||
} EffectSubList;
|
||||
TYPEDEF_VECTOR(EffectSubList, vector_EffectSubList)
|
||||
|
||||
typedef struct SourceSubList {
|
||||
ALuint64 FreeMask;
|
||||
struct ALsource *Sources; /* 64 */
|
||||
@@ -485,7 +492,8 @@ struct ALCdevice_struct
|
||||
almtx_t BufferLock;
|
||||
|
||||
// Map of Effects for this device
|
||||
UIntMap EffectMap;
|
||||
vector_EffectSubList EffectList;
|
||||
almtx_t EffectLock;
|
||||
|
||||
// Map of Filters for this device
|
||||
UIntMap FilterMap;
|
||||
|
||||
@@ -61,6 +61,20 @@ static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id)
|
||||
return VECTOR_ELEM(context->EffectSlotList, id);
|
||||
}
|
||||
|
||||
static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id)
|
||||
{
|
||||
EffectSubList *sublist;
|
||||
ALuint lidx = (id-1) >> 6;
|
||||
ALsizei slidx = (id-1) & 0x3f;
|
||||
|
||||
if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList)))
|
||||
return NULL;
|
||||
sublist = &VECTOR_ELEM(device->EffectList, lidx);
|
||||
if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
|
||||
return NULL;
|
||||
return sublist->Effects + slidx;
|
||||
}
|
||||
|
||||
|
||||
#define DO_UPDATEPROPS() do { \
|
||||
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \
|
||||
@@ -261,15 +275,15 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
device = context->Device;
|
||||
|
||||
LockEffectsRead(device);
|
||||
almtx_lock(&device->EffectLock);
|
||||
effect = (value ? LookupEffect(device, value) : NULL);
|
||||
if(!(value == 0 || effect != NULL))
|
||||
{
|
||||
UnlockEffectsRead(device);
|
||||
almtx_unlock(&device->EffectLock);
|
||||
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid effect ID %u", value);
|
||||
}
|
||||
err = InitializeEffect(context, slot, effect);
|
||||
UnlockEffectsRead(device);
|
||||
almtx_unlock(&device->EffectLock);
|
||||
|
||||
if(err != AL_NO_ERROR)
|
||||
SETERR_GOTO(context, err, done, "Effect initialization failed");
|
||||
|
||||
+134
-61
@@ -48,20 +48,34 @@ const struct EffectList EffectList[EFFECTLIST_SIZE] = {
|
||||
|
||||
ALboolean DisabledEffects[MAX_EFFECTS];
|
||||
|
||||
extern inline void LockEffectsRead(ALCdevice *device);
|
||||
extern inline void UnlockEffectsRead(ALCdevice *device);
|
||||
extern inline void LockEffectsWrite(ALCdevice *device);
|
||||
extern inline void UnlockEffectsWrite(ALCdevice *device);
|
||||
extern inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id);
|
||||
extern inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id);
|
||||
extern inline ALboolean IsReverbEffect(ALenum type);
|
||||
|
||||
static ALeffect *AllocEffect(ALCcontext *context);
|
||||
static void FreeEffect(ALCdevice *device, ALeffect *effect);
|
||||
static void InitEffectParams(ALeffect *effect, ALenum type);
|
||||
|
||||
static inline void LockEffectList(ALCdevice *device)
|
||||
{ almtx_lock(&device->EffectLock); }
|
||||
static inline void UnlockEffectList(ALCdevice *device)
|
||||
{ almtx_unlock(&device->EffectLock); }
|
||||
|
||||
static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id)
|
||||
{
|
||||
EffectSubList *sublist;
|
||||
ALuint lidx = (id-1) >> 6;
|
||||
ALsizei slidx = (id-1) & 0x3f;
|
||||
|
||||
if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList)))
|
||||
return NULL;
|
||||
sublist = &VECTOR_ELEM(device->EffectList, lidx);
|
||||
if(UNLIKELY(sublist->FreeMask & (U64(1)<<slidx)))
|
||||
return NULL;
|
||||
return sublist->Effects + slidx;
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALsizei cur;
|
||||
|
||||
@@ -71,31 +85,14 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
|
||||
if(!(n >= 0))
|
||||
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effects", n);
|
||||
|
||||
device = context->Device;
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
ALeffect *effect = al_calloc(16, sizeof(ALeffect));
|
||||
ALenum err = AL_OUT_OF_MEMORY;
|
||||
if(!effect || (err=InitEffect(effect)) != AL_NO_ERROR)
|
||||
ALeffect *effect = AllocEffect(context);
|
||||
if(!effect)
|
||||
{
|
||||
al_free(effect);
|
||||
alDeleteEffects(cur, effects);
|
||||
SETERR_GOTO(context, err, done, "Failed to allocate effect object");
|
||||
break;
|
||||
}
|
||||
|
||||
err = NewThunkEntry(&effect->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&device->EffectMap, effect->id, effect);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(effect->id);
|
||||
memset(effect, 0, sizeof(ALeffect));
|
||||
al_free(effect);
|
||||
|
||||
alDeleteEffects(cur, effects);
|
||||
SETERR_GOTO(context, err, done, "Failed to set effect ID");
|
||||
}
|
||||
|
||||
effects[cur] = effect->id;
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
|
||||
if(!context) return;
|
||||
|
||||
device = context->Device;
|
||||
LockEffectsWrite(device);
|
||||
LockEffectList(device);
|
||||
if(!(n >= 0))
|
||||
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effects", n);
|
||||
for(i = 0;i < n;i++)
|
||||
@@ -124,16 +121,12 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
|
||||
}
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if((effect=RemoveEffect(device, effects[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(effect->id);
|
||||
|
||||
memset(effect, 0, sizeof(*effect));
|
||||
al_free(effect);
|
||||
if((effect=LookupEffect(device, effects[i])) != NULL)
|
||||
FreeEffect(device, effect);
|
||||
}
|
||||
|
||||
done:
|
||||
UnlockEffectsWrite(device);
|
||||
UnlockEffectList(device);
|
||||
ALCcontext_DecRef(context);
|
||||
}
|
||||
|
||||
@@ -145,10 +138,10 @@ AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
LockEffectsRead(Context->Device);
|
||||
LockEffectList(Context->Device);
|
||||
result = ((!effect || LookupEffect(Context->Device, effect)) ?
|
||||
AL_TRUE : AL_FALSE);
|
||||
UnlockEffectsRead(Context->Device);
|
||||
UnlockEffectList(Context->Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
@@ -165,7 +158,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsWrite(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -192,7 +185,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
|
||||
V(ALEffect,setParami)(Context, param, value);
|
||||
}
|
||||
}
|
||||
UnlockEffectsWrite(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -214,7 +207,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsWrite(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -222,7 +215,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v
|
||||
/* Call the appropriate handler */
|
||||
V(ALEffect,setParamiv)(Context, param, values);
|
||||
}
|
||||
UnlockEffectsWrite(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -237,7 +230,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsWrite(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -245,7 +238,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
|
||||
/* Call the appropriate handler */
|
||||
V(ALEffect,setParamf)(Context, param, value);
|
||||
}
|
||||
UnlockEffectsWrite(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -260,7 +253,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsWrite(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -268,7 +261,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat
|
||||
/* Call the appropriate handler */
|
||||
V(ALEffect,setParamfv)(Context, param, values);
|
||||
}
|
||||
UnlockEffectsWrite(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -283,7 +276,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsRead(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -296,7 +289,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value
|
||||
V(ALEffect,getParami)(Context, param, value);
|
||||
}
|
||||
}
|
||||
UnlockEffectsRead(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -318,7 +311,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsRead(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -326,7 +319,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu
|
||||
/* Call the appropriate handler */
|
||||
V(ALEffect,getParamiv)(Context, param, values);
|
||||
}
|
||||
UnlockEffectsRead(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -341,7 +334,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsRead(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -349,7 +342,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val
|
||||
/* Call the appropriate handler */
|
||||
V(ALEffect,getParamf)(Context, param, value);
|
||||
}
|
||||
UnlockEffectsRead(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -364,7 +357,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
LockEffectsRead(Device);
|
||||
LockEffectList(Device);
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||
else
|
||||
@@ -372,7 +365,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va
|
||||
/* Call the appropriate handler */
|
||||
V(ALEffect,getParamfv)(Context, param, values);
|
||||
}
|
||||
UnlockEffectsRead(Device);
|
||||
UnlockEffectList(Device);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -384,19 +377,99 @@ ALenum InitEffect(ALeffect *effect)
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALeffect *AllocEffect(ALCcontext *context)
|
||||
{
|
||||
ALCdevice *device = context->Device;
|
||||
EffectSubList *sublist, *subend;
|
||||
ALeffect *effect = NULL;
|
||||
ALsizei lidx = 0;
|
||||
ALsizei slidx;
|
||||
|
||||
almtx_lock(&device->EffectLock);
|
||||
sublist = VECTOR_BEGIN(device->EffectList);
|
||||
subend = VECTOR_END(device->EffectList);
|
||||
for(;sublist != subend;++sublist)
|
||||
{
|
||||
if(sublist->FreeMask)
|
||||
{
|
||||
slidx = CTZ64(sublist->FreeMask);
|
||||
effect = sublist->Effects + slidx;
|
||||
break;
|
||||
}
|
||||
++lidx;
|
||||
}
|
||||
if(UNLIKELY(!effect))
|
||||
{
|
||||
const EffectSubList empty_sublist = { 0, NULL };
|
||||
/* Don't allocate so many list entries that the 32-bit ID could
|
||||
* overflow...
|
||||
*/
|
||||
if(UNLIKELY(VECTOR_SIZE(device->EffectList) >= 1<<25))
|
||||
{
|
||||
almtx_unlock(&device->EffectLock);
|
||||
return NULL;
|
||||
}
|
||||
lidx = (ALsizei)VECTOR_SIZE(device->EffectList);
|
||||
VECTOR_PUSH_BACK(device->EffectList, empty_sublist);
|
||||
sublist = &VECTOR_BACK(device->EffectList);
|
||||
sublist->FreeMask = ~U64(0);
|
||||
sublist->Effects = al_calloc(16, sizeof(ALeffect)*64);
|
||||
if(UNLIKELY(!sublist->Effects))
|
||||
{
|
||||
VECTOR_POP_BACK(device->EffectList);
|
||||
almtx_unlock(&device->EffectLock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
slidx = 0;
|
||||
effect = sublist->Effects + slidx;
|
||||
}
|
||||
|
||||
memset(effect, 0, sizeof(*effect));
|
||||
InitEffectParams(effect, AL_EFFECT_NULL);
|
||||
|
||||
/* Add 1 to avoid effect ID 0. */
|
||||
effect->id = ((lidx<<6) | slidx) + 1;
|
||||
|
||||
sublist->FreeMask &= ~(U64(1)<<slidx);
|
||||
almtx_unlock(&device->EffectLock);
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
static void FreeEffect(ALCdevice *device, ALeffect *effect)
|
||||
{
|
||||
ALuint id = effect->id - 1;
|
||||
ALsizei lidx = id >> 6;
|
||||
ALsizei slidx = id & 0x3f;
|
||||
|
||||
memset(effect, 0, sizeof(*effect));
|
||||
|
||||
VECTOR_ELEM(device->EffectList, lidx).FreeMask |= U64(1) << slidx;
|
||||
}
|
||||
|
||||
ALvoid ReleaseALEffects(ALCdevice *device)
|
||||
{
|
||||
ALsizei i;
|
||||
for(i = 0;i < device->EffectMap.size;i++)
|
||||
EffectSubList *sublist = VECTOR_BEGIN(device->EffectList);
|
||||
EffectSubList *subend = VECTOR_END(device->EffectList);
|
||||
size_t leftover = 0;
|
||||
for(;sublist != subend;++sublist)
|
||||
{
|
||||
ALeffect *temp = device->EffectMap.values[i];
|
||||
device->EffectMap.values[i] = NULL;
|
||||
ALuint64 usemask = ~sublist->FreeMask;
|
||||
while(usemask)
|
||||
{
|
||||
ALsizei idx = CTZ64(usemask);
|
||||
ALeffect *effect = sublist->Effects + idx;
|
||||
|
||||
// Release effect structure
|
||||
FreeThunkEntry(temp->id);
|
||||
memset(temp, 0, sizeof(ALeffect));
|
||||
al_free(temp);
|
||||
memset(effect, 0, sizeof(*effect));
|
||||
++leftover;
|
||||
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
sublist->FreeMask = ~usemask;
|
||||
}
|
||||
if(leftover > 0)
|
||||
WARN("(%p) Deleted "SZFMT" Effect%s\n", device, leftover, (leftover==1)?"":"s");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user