aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alBuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32/alBuffer.c')
-rw-r--r--OpenAL32/alBuffer.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index 9e4249ec..b2302933 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -51,9 +51,9 @@ static ALsizei SanitizeAlignment(enum UserFmtType type, ALsizei align);
#define FORMAT_MASK 0x00ffffff
-#define CONSTRUCT_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_PRESERVE_DATA_BIT_SOFT)
+#define CONSTRUCT_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_PRESERVE_DATA_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT)
#define INVALID_FORMAT_MASK ~(FORMAT_MASK | CONSTRUCT_FLAGS)
-#define MAP_ACCESS_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)
AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
@@ -232,18 +232,18 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei
WriteLock(&albuf->lock);
if(((access&AL_MAP_READ_BIT_SOFT) && !(albuf->Access&AL_MAP_READ_BIT_SOFT)) ||
- ((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)))
+ ((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)) ||
+ ((access&AL_MAP_PERSISTENT_BIT_SOFT) && !(albuf->Access&AL_MAP_PERSISTENT_BIT_SOFT)))
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done);
if(offset < 0 || offset >= albuf->OriginalSize ||
length <= 0 || length > albuf->OriginalSize - offset)
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done);
- if(ReadRef(&albuf->ref) != 0 || albuf->MappedAccess != 0)
+ if(albuf->MappedAccess != 0 ||
+ (!(access&AL_MAP_PERSISTENT_BIT_SOFT) && ReadRef(&albuf->ref) != 0))
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, unlock_done);
retval = (ALbyte*)albuf->data + offset;
albuf->MappedAccess = access;
- if((access&AL_MAP_WRITE_BIT_SOFT) && !(access&AL_MAP_READ_BIT_SOFT))
- memset(retval, 0x55, length);
unlock_done:
WriteUnlock(&albuf->lock);
@@ -281,6 +281,43 @@ done:
ALCcontext_DecRef(context);
}
+AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, ALsizei length)
+{
+ ALCdevice *device;
+ ALCcontext *context;
+ ALbuffer *albuf;
+
+ context = GetContextRef();
+ if(!context) return;
+
+ device = context->Device;
+ LockBuffersRead(device);
+ if((albuf=LookupBuffer(device, buffer)) == NULL)
+ SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
+
+ WriteLock(&albuf->lock);
+ if(albuf->MappedAccess == 0 || !(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT))
+ alSetError(context, AL_INVALID_OPERATION);
+ /* TODO: Should check mapped range. */
+ else if(offset < 0 || offset >= albuf->OriginalSize ||
+ length <= 0 || length > albuf->OriginalSize - offset)
+ alSetError(context, AL_INVALID_VALUE);
+ 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);
+
+done:
+ UnlockBuffersRead(device);
+ ALCcontext_DecRef(context);
+}
+
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length)
{
enum UserFmtChannels srcchannels = UserFmtMono;