aboutsummaryrefslogtreecommitdiffstats
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
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.
-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();