aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alAuxEffectSlot.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-03-04 15:11:17 -0800
committerChris Robinson <[email protected]>2018-03-08 17:48:21 -0800
commit9bd1678299433a1f569a0d7680a25fbf4de83450 (patch)
tree205735c9508fa3e3a73408145a62dc0e148efecd /OpenAL32/alAuxEffectSlot.c
parent19281868dce20d47344bd059b5f3c4af5264baaa (diff)
Fix adding to and removing from the active effect slots
It wasn't properly removing all duplicates on insertion, and didn't remove the first effect slot when removing them.
Diffstat (limited to 'OpenAL32/alAuxEffectSlot.c')
-rw-r--r--OpenAL32/alAuxEffectSlot.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 9ccfaa36..d4e6bf75 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -598,18 +598,29 @@ static void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontex
{
for(j = i;j != 0;)
{
- if(newarray->slot[i] == newarray->slot[--j])
+ if(UNLIKELY(newarray->slot[i] == newarray->slot[--j]))
+ {
+ newcount--;
+ for(j = i;j < newcount;j++)
+ newarray->slot[j] = newarray->slot[j+1];
+ i--;
break;
- }
- if(j != 0)
- {
- newcount--;
- for(j = i;j < newcount;j++)
- newarray->slot[j] = newarray->slot[j+1];
- i--;
+ }
}
}
- newarray->count = newcount;
+
+ /* Reallocate newarray if the new size ended up smaller from duplicate
+ * removal.
+ */
+ if(UNLIKELY(newcount < newarray->count))
+ {
+ struct ALeffectslotArray *tmpnewarray = al_calloc(DEF_ALIGN,
+ FAM_SIZE(struct ALeffectslotArray, slot, newcount));
+ memcpy(tmpnewarray, newarray, FAM_SIZE(struct ALeffectslotArray, slot, newcount));
+ al_free(newarray);
+ newarray = tmpnewarray;
+ newarray->count = newcount;
+ }
curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel);
while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1))
@@ -622,26 +633,29 @@ static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcon
struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots,
almemory_order_acquire);
struct ALeffectslotArray *newarray = NULL;
- ALsizei newcount = curarray->count - count;
ALCdevice *device = context->Device;
ALsizei i, j;
- assert(newcount >= 0);
- newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount));
- newarray->count = newcount;
- for(i = j = 0;i < newarray->count;)
+ /* Don't shrink the allocated array size since we don't know how many (if
+ * any) of the effect slots to remove are in the array.
+ */
+ newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, curarray->count));
+ newarray->count = 0;
+ for(i = 0;i < curarray->count;i++)
{
- ALeffectslot *slot = curarray->slot[j++];
- ALsizei k = count;
- while(k != 0)
+ /* Insert this slot into the new array only if it's not one to remove. */
+ ALeffectslot *slot = curarray->slot[i];
+ for(j = count;j != 0;)
{
- if(slot->id == slotids[--k])
- break;
+ if(slot->id == slotids[--j])
+ goto skip_ins;
}
- if(k == 0)
- newarray->slot[i++] = slot;
+ newarray->slot[newarray->count++] = slot;
+ skip_ins: ;
}
+ /* TODO: Could reallocate newarray now that we know it's needed size. */
+
curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel);
while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1))
althrd_yield();