Improve error reporting for buffers

This commit is contained in:
Chris Robinson
2018-01-26 00:13:03 -08:00
parent 6ae7fc5df1
commit fbafbe6272
+270 -263
View File
@@ -54,7 +54,7 @@ static ALsizei SanitizeAlignment(enum UserFmtType type, ALsizei align);
#define INVALID_STORAGE_MASK ~(AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_PRESERVE_DATA_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT)
#define MAP_READ_WRITE_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT)
#define MAP_ACCESS_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT)
#define INVALID_MAP_FLAGS ~(AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT)
AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
@@ -66,9 +66,8 @@ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
if(!context) return;
if(!(n >= 0))
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d buffers", n);
for(cur = 0;cur < n;cur++)
alSetError(context, AL_INVALID_VALUE, "Generating %d buffers", n);
else for(cur = 0;cur < n;cur++)
{
ALbuffer *buffer = NewBuffer(context);
if(!buffer)
@@ -80,7 +79,6 @@ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
buffers[cur] = buffer->id;
}
done:
ALCcontext_DecRef(context);
}
@@ -97,22 +95,29 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
device = context->Device;
LockBuffersWrite(device);
if(!(n >= 0))
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d buffers", n);
if(UNLIKELY(n < 0))
{
alSetError(context, AL_INVALID_VALUE, "Deleting %d buffers", n);
goto done;
}
for(i = 0;i < n;i++)
{
if(!buffers[i])
continue;
/* Check for valid Buffer ID */
/* Check for valid Buffer ID, and make sure it's not in use. */
if((ALBuf=LookupBuffer(device, buffers[i])) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffers[i]);
{
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffers[i]);
goto done;
}
if(ReadRef(&ALBuf->ref) != 0)
SETERR_GOTO(context, AL_INVALID_OPERATION, done, "Deleting in-use buffer %u",
buffers[i]);
{
alSetError(context, AL_INVALID_OPERATION, "Deleting in-use buffer %u", buffers[i]);
goto done;
}
}
for(i = 0;i < n;i++)
{
if((ALBuf=LookupBuffer(device, buffers[i])) != NULL)
@@ -161,24 +166,26 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!(size >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Negative storage size %d", size);
if(!(freq > 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid sample rate %d", freq);
if((flags&INVALID_STORAGE_MASK) != 0)
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid storage flags 0x%x",
flags&INVALID_STORAGE_MASK);
if((flags&AL_MAP_PERSISTENT_BIT_SOFT) && !(flags&MAP_READ_WRITE_FLAGS))
SETERR_GOTO(context, AL_INVALID_VALUE, done,
"Declaring persistently mapped storage without read or write access");
if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)
SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid format 0x%04x", format);
align = SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign));
if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid unpack alignment");
switch(srctype)
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(size < 0))
alSetError(context, AL_INVALID_VALUE, "Negative storage size %d", size);
else if(UNLIKELY(freq < 1))
alSetError(context, AL_INVALID_VALUE, "Invalid sample rate %d", freq);
else if(UNLIKELY((flags&INVALID_STORAGE_MASK) != 0))
alSetError(context, AL_INVALID_VALUE, "Invalid storage flags 0x%x",
flags&INVALID_STORAGE_MASK);
else if(UNLIKELY((flags&AL_MAP_PERSISTENT_BIT_SOFT) && !(flags&MAP_READ_WRITE_FLAGS)))
alSetError(context, AL_INVALID_VALUE,
"Declaring persistently mapped storage without read or write access");
else if(UNLIKELY(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE))
alSetError(context, AL_INVALID_ENUM, "Invalid format 0x%04x", format);
else if(UNLIKELY((align=SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign))) < 1))
alSetError(context, AL_INVALID_VALUE, "Invalid unpack alignment");
else
{
switch(srctype)
{
case UserFmtUByte:
case UserFmtShort:
case UserFmtFloat:
@@ -195,15 +202,16 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const
case UserFmtMSADPCM:
framesize = ((align-2)/2 + 7) * ChannelsFromUserFmt(srcchannels);
break;
}
if((size%framesize) != 0)
alSetError(context, AL_INVALID_VALUE,
"Data size %d is not a multiple of frame size %d (%d unpack alignment)",
size, framesize, align);
else
LoadData(context, albuf, freq, size/framesize*align, srcchannels, srctype, data, align,
flags);
}
if((size%framesize) != 0)
alSetError(context, AL_INVALID_VALUE, "Data size %d is not a multiple of frame size %d",
size, framesize);
else
LoadData(context, albuf, freq, size/framesize*align, srcchannels, srctype, data, align,
flags);
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -220,47 +228,49 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if((access&~MAP_ACCESS_FLAGS) != 0)
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid map flags 0x%x",
access&~MAP_ACCESS_FLAGS);
if(!(access&MAP_READ_WRITE_FLAGS))
SETERR_GOTO(context, AL_INVALID_VALUE, done,
"Mapping buffer without read or write access");
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY((access&INVALID_MAP_FLAGS) != 0))
alSetError(context, AL_INVALID_VALUE, "Invalid map flags 0x%x", access&INVALID_MAP_FLAGS);
else if(UNLIKELY(!(access&MAP_READ_WRITE_FLAGS)))
alSetError(context, AL_INVALID_VALUE, "Mapping buffer %u without read or write access",
buffer);
else
{
ALbitfieldSOFT unavailable;
WriteLock(&albuf->lock);
unavailable = (albuf->Access^access) & access;
if(UNLIKELY(ReadRef(&albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT)))
alSetError(context, AL_INVALID_OPERATION,
"Mapping in-use buffer %u without persistent mapping", buffer);
else if(UNLIKELY(albuf->MappedAccess != 0))
alSetError(context, AL_INVALID_OPERATION, "Mapping already-mapped buffer %u", buffer);
else if(UNLIKELY((unavailable&AL_MAP_READ_BIT_SOFT)))
alSetError(context, AL_INVALID_VALUE,
"Mapping buffer %u for reading without read access", buffer);
else if(UNLIKELY((unavailable&AL_MAP_WRITE_BIT_SOFT)))
alSetError(context, AL_INVALID_VALUE,
"Mapping buffer %u for writing without write access", buffer);
else if(UNLIKELY((unavailable&AL_MAP_PERSISTENT_BIT_SOFT)))
alSetError(context, AL_INVALID_VALUE,
"Mapping buffer %u persistently without persistent access", buffer);
else if(UNLIKELY(offset < 0 || offset >= albuf->OriginalSize ||
length <= 0 || length > albuf->OriginalSize - offset))
alSetError(context, AL_INVALID_VALUE, "Mapping invalid range %d+%d for buffer %u",
offset, length, buffer);
else
{
retval = (ALbyte*)albuf->data + offset;
albuf->MappedAccess = access;
albuf->MappedOffset = offset;
albuf->MappedSize = length;
}
WriteLock(&albuf->lock);
if(ReadRef(&albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT))
SETERR_GOTO(context, AL_INVALID_OPERATION, unlock_done,
"Mapping in-use buffer without persistent mapping");
if(albuf->MappedAccess != 0)
SETERR_GOTO(context, AL_INVALID_OPERATION, unlock_done, "Mapping already-mapped buffer");
if((access&AL_MAP_READ_BIT_SOFT) && !(albuf->Access&AL_MAP_READ_BIT_SOFT))
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done,
"Mapping buffer for reading without read access");
if((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT))
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done,
"Mapping buffer for writing without write access");
if((access&AL_MAP_PERSISTENT_BIT_SOFT) && !(albuf->Access&AL_MAP_PERSISTENT_BIT_SOFT))
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done,
"Mapping buffer persistently without persistent access");
if(offset < 0 || offset >= albuf->OriginalSize ||
length <= 0 || length > albuf->OriginalSize - offset)
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Mapping invalid range %d+%d",
offset, length);
retval = (ALbyte*)albuf->data + offset;
albuf->MappedAccess = access;
albuf->MappedOffset = offset;
albuf->MappedSize = length;
unlock_done:
WriteUnlock(&albuf->lock);
done:
WriteUnlock(&albuf->lock);
}
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
ALCcontext_DecRef(context);
return retval;
}
@@ -276,21 +286,22 @@ AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer)
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
WriteLock(&albuf->lock);
if(albuf->MappedAccess == 0)
alSetError(context, AL_INVALID_OPERATION, "Unmapping an unmapped buffer %u", buffer);
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else
{
albuf->MappedAccess = 0;
albuf->MappedOffset = 0;
albuf->MappedSize = 0;
WriteLock(&albuf->lock);
if(albuf->MappedAccess == 0)
alSetError(context, AL_INVALID_OPERATION, "Unmapping unmapped buffer %u", buffer);
else
{
albuf->MappedAccess = 0;
albuf->MappedOffset = 0;
albuf->MappedSize = 0;
}
WriteUnlock(&albuf->lock);
}
WriteUnlock(&albuf->lock);
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -305,29 +316,32 @@ AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, A
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
WriteLock(&albuf->lock);
if(albuf->MappedAccess == 0 || !(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT))
alSetError(context, AL_INVALID_OPERATION, "Flushing buffer %u not mapped for writing",
buffer);
else if(offset < albuf->MappedOffset || offset >= albuf->MappedOffset+albuf->MappedSize ||
length <= 0 || length > albuf->MappedOffset+albuf->MappedSize-offset)
alSetError(context, AL_INVALID_VALUE, "Flushing an invalid range %d+%d", offset, length);
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else
{
/* FIXME: Need to use some method of double-buffering for the mixer and
* app to hold separate memory, which can be safely transfered
* asynchronously. Currently we just say the app shouldn't write where
* OpenAL's reading, and hope for the best...
*/
ATOMIC_THREAD_FENCE(almemory_order_seq_cst);
WriteLock(&albuf->lock);
if(UNLIKELY(!(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT)))
alSetError(context, AL_INVALID_OPERATION,
"Flushing buffer %u while not mapped for writing", buffer);
else if(UNLIKELY(offset < albuf->MappedOffset ||
offset >= albuf->MappedOffset+albuf->MappedSize ||
length <= 0 || length > albuf->MappedOffset+albuf->MappedSize-offset))
alSetError(context, AL_INVALID_VALUE, "Flushing invalid range %d+%d on buffer %u",
offset, length, buffer);
else
{
/* FIXME: Need to use some method of double-buffering for the mixer
* and app to hold separate memory, which can be safely transfered
* asynchronously. Currently we just say the app shouldn't write
* where OpenAL's reading, and hope for the best...
*/
ATOMIC_THREAD_FENCE(almemory_order_seq_cst);
}
WriteUnlock(&albuf->lock);
}
WriteUnlock(&albuf->lock);
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -338,71 +352,85 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons
ALCdevice *device;
ALCcontext *context;
ALbuffer *albuf;
ALsizei byte_align;
ALsizei frame_size;
ALsizei num_chans;
ALsizei align;
void *dst;
context = GetContextRef();
if(!context) return;
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)
SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid format 0x%04x", format);
WriteLock(&albuf->lock);
align = SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign));
if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Invalid unpack alignment");
if((long)srcchannels != (long)albuf->FmtChannels || srctype != albuf->OriginalType)
SETERR_GOTO(context, AL_INVALID_ENUM, unlock_done,
"Unpacking data with mismatched format");
if(align != albuf->OriginalAlign)
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done,
"Unpacking data with mismatched alignment");
if(albuf->MappedAccess != 0)
SETERR_GOTO(context, AL_INVALID_OPERATION, unlock_done,
"Unpacking data into mapped buffer");
num_chans = ChannelsFromFmt(albuf->FmtChannels);
frame_size = num_chans * BytesFromFmt(albuf->FmtType);
if(albuf->OriginalType == UserFmtIMA4)
byte_align = ((align-1)/2 + 4) * num_chans;
else if(albuf->OriginalType == UserFmtMSADPCM)
byte_align = ((align-2)/2 + 7) * num_chans;
else
byte_align = align * frame_size;
if(offset < 0 || length < 0 || offset > albuf->OriginalSize ||
length > albuf->OriginalSize-offset)
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Invalid data sub-range %d+%d",
offset, length);
if((offset%byte_align) != 0 || (length%byte_align) != 0)
SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Invalid sub-range alignment");
/* offset -> byte offset, length -> sample count */
offset = offset/byte_align * frame_size;
length = length/byte_align * albuf->OriginalAlign;
dst = (ALbyte*)albuf->data + offset;
if(srctype == UserFmtIMA4 && albuf->FmtType == FmtShort)
Convert_ALshort_ALima4(dst, data, num_chans, length, align);
else if(srctype == UserFmtMSADPCM && albuf->FmtType == FmtShort)
Convert_ALshort_ALmsadpcm(dst, data, num_chans, length, align);
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE))
alSetError(context, AL_INVALID_ENUM, "Invalid format 0x%04x", format);
else
{
assert((long)srctype == (long)albuf->FmtType);
memcpy(dst, data, length*frame_size);
ALsizei unpack_align, align;
ALsizei byte_align;
ALsizei frame_size;
ALsizei num_chans;
void *dst;
WriteLock(&albuf->lock);
unpack_align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign);
align = SanitizeAlignment(srctype, unpack_align);
if(UNLIKELY(align < 1))
alSetError(context, AL_INVALID_VALUE, "Invalid unpack alignment %d", unpack_align);
else if(UNLIKELY((long)srcchannels != (long)albuf->FmtChannels ||
srctype != albuf->OriginalType))
alSetError(context, AL_INVALID_ENUM, "Unpacking data with mismatched format");
else if(UNLIKELY(align != albuf->OriginalAlign))
alSetError(context, AL_INVALID_VALUE,
"Unpacking data with alignment %u does not match original alignment %u",
align, albuf->OriginalAlign);
else if(UNLIKELY(albuf->MappedAccess != 0))
alSetError(context, AL_INVALID_OPERATION, "Unpacking data into mapped buffer %u",
buffer);
else
{
num_chans = ChannelsFromFmt(albuf->FmtChannels);
frame_size = num_chans * BytesFromFmt(albuf->FmtType);
if(albuf->OriginalType == UserFmtIMA4)
byte_align = ((align-1)/2 + 4) * num_chans;
else if(albuf->OriginalType == UserFmtMSADPCM)
byte_align = ((align-2)/2 + 7) * num_chans;
else
byte_align = align * frame_size;
if(UNLIKELY(offset < 0 || length < 0 || offset > albuf->OriginalSize ||
length > albuf->OriginalSize-offset))
alSetError(context, AL_INVALID_VALUE, "Invalid data sub-range %d+%d on buffer %u",
offset, length, buffer);
else if(UNLIKELY((offset%byte_align) != 0))
alSetError(context, AL_INVALID_VALUE,
"Sub-range offset %d is not a multiple of frame size %d (%d unpack alignment)",
offset, byte_align, align);
else if(UNLIKELY((length%byte_align) != 0))
alSetError(context, AL_INVALID_VALUE,
"Sub-range length %d is not a multiple of frame size %d (%d unpack alignment)",
length, byte_align, align);
else
{
/* offset -> byte offset, length -> sample count */
offset = offset/byte_align * align * frame_size;
length = length/byte_align * align;
dst = (ALbyte*)albuf->data + offset;
if(srctype == UserFmtIMA4 && albuf->FmtType == FmtShort)
Convert_ALshort_ALima4(dst, data, num_chans, length, align);
else if(srctype == UserFmtMSADPCM && albuf->FmtType == FmtShort)
Convert_ALshort_ALmsadpcm(dst, data, num_chans, length, align);
else
{
assert((long)srctype == (long)albuf->FmtType);
memcpy(dst, data, length*frame_size);
}
}
}
WriteUnlock(&albuf->lock);
}
unlock_done:
WriteUnlock(&albuf->lock);
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -473,17 +501,15 @@ AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(va
device = context->Device;
LockBuffersRead(device);
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
switch(param)
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer float property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -498,17 +524,15 @@ AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(v
device = context->Device;
LockBuffersRead(device);
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
switch(param)
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-float property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -523,18 +547,17 @@ AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *v
device = context->Device;
LockBuffersRead(device);
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!values))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer float-vector property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -550,31 +573,29 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value)
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
switch(param)
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else switch(param)
{
case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
if(!(value >= 0))
SETERR_GOTO(context, AL_INVALID_VALUE, done,
"Buffer unpack block alignment %d is invalid", value);
ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value);
if(UNLIKELY(value < 0))
alSetError(context, AL_INVALID_VALUE, "Invalid unpack block alignment %d", value);
else
ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value);
break;
case AL_PACK_BLOCK_ALIGNMENT_SOFT:
if(!(value >= 0))
SETERR_GOTO(context, AL_INVALID_VALUE, done,
"Buffer pack block alignment %d is invalid", value);
ATOMIC_STORE_SEQ(&albuf->PackAlign, value);
if(UNLIKELY(value < 0))
alSetError(context, AL_INVALID_VALUE, "Invalid pack block alignment %d", value);
else
ATOMIC_STORE_SEQ(&albuf->PackAlign, value);
break;
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -588,16 +609,16 @@ AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(val
if(!context) return;
device = context->Device;
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
switch(param)
LockBuffersRead(device);
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-integer property 0x%04x", param);
}
UnlockBuffersRead(device);
done:
ALCcontext_DecRef(context);
}
@@ -624,30 +645,25 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!values))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
case AL_LOOP_POINTS_SOFT:
WriteLock(&albuf->lock);
if(ReadRef(&albuf->ref) != 0)
if(UNLIKELY(ReadRef(&albuf->ref) != 0))
alSetError(context, AL_INVALID_OPERATION, "Modifying in-use buffer %u's loop points",
buffer);
else if(UNLIKELY(values[0] >= values[1] || values[0] < 0 || values[1] > albuf->SampleLen))
alSetError(context, AL_INVALID_VALUE, "Invalid loop point range %d -> %d o buffer %u",
values[0], values[1], buffer);
else
{
WriteUnlock(&albuf->lock);
SETERR_GOTO(context, AL_INVALID_OPERATION, done,
"Modifying in-use buffer loop points");
albuf->LoopStart = values[0];
albuf->LoopEnd = values[1];
}
if(values[0] >= values[1] || values[0] < 0 ||
values[1] > albuf->SampleLen)
{
WriteUnlock(&albuf->lock);
SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid loop point range %d -> %d",
values[0], values[1]);
}
albuf->LoopStart = values[0];
albuf->LoopEnd = values[1];
WriteUnlock(&albuf->lock);
break;
@@ -655,9 +671,8 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val
alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer-vector property 0x%04x",
param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -673,18 +688,17 @@ AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *val
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!value))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer float property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -699,19 +713,17 @@ AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *valu
device = context->Device;
LockBuffersRead(device);
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!value1 || !value2 || !value3)
SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!value1 || !value2 || !value3))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-float property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -733,18 +745,17 @@ AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *valu
device = context->Device;
LockBuffersRead(device);
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!values))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer float-vector property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -760,11 +771,11 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!value))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
case AL_FREQUENCY:
*value = albuf->Frequency;
@@ -796,9 +807,8 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -813,19 +823,17 @@ AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1
device = context->Device;
LockBuffersRead(device);
if(LookupBuffer(device, buffer) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!value1 || !value2 || !value3)
SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY(LookupBuffer(device, buffer) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!value1 || !value2 || !value3))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
default:
alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-integer property 0x%04x", param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -856,11 +864,11 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer);
if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer");
switch(param)
if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL))
alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
else if(UNLIKELY(!values))
alSetError(context, AL_INVALID_VALUE, "NULL pointer");
else switch(param)
{
case AL_LOOP_POINTS_SOFT:
ReadLock(&albuf->lock);
@@ -873,9 +881,8 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values
alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer-vector property 0x%04x",
param);
}
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
@@ -963,7 +970,7 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei
* usage, and reporting the real size could cause problems for apps that
* use AL_SIZE to try to get the buffer's play length.
*/
if(newsize <= INT_MAX-15)
if(LIKELY(newsize <= INT_MAX-15))
newsize = (newsize+15) & ~0xf;
if(newsize != ALBuf->BytesAlloc)
{