aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c52
-rw-r--r--Alc/ALu.c16
-rw-r--r--OpenAL32/Include/alMain.h5
3 files changed, 55 insertions, 18 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index c969fd95..1274b824 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1123,6 +1123,7 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
{
ALuint attrIdx, reqStereoSources;
ALCcontext *ALContext;
+ void *temp;
SuspendContext(NULL);
@@ -1137,7 +1138,7 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
g_eLastContextError = ALC_NO_ERROR;
// Current implementation only allows one Context per Device
- if(device->Context)
+ if(device->NumContexts > 0)
{
alcSetError(ALC_INVALID_VALUE);
ProcessContext(NULL);
@@ -1214,6 +1215,15 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
device->Bs2b = NULL;
}
+ temp = realloc(device->Contexts, (device->NumContexts+1) * sizeof(*device->Contexts));
+ if(!temp)
+ {
+ alcSetError(ALC_OUT_OF_MEMORY);
+ ProcessContext(NULL);
+ return NULL;
+ }
+ device->Contexts = temp;
+
ALContext = calloc(1, sizeof(ALCcontext));
if(!ALContext)
{
@@ -1222,10 +1232,10 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
return NULL;
}
+ device->Contexts[device->NumContexts++] = ALContext;
ALContext->Device = device;
- InitContext(ALContext);
- device->Context = ALContext;
+ InitContext(ALContext);
ALContext->next = g_pContextList;
g_pContextList = ALContext;
@@ -1245,10 +1255,27 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
{
ALCcontext **list;
+ ALuint i;
if (IsContext(context))
{
- ALCdevice_StopPlayback(context->Device);
+ ALCdevice *Device = context->Device;
+
+ if(Device->NumContexts == 1)
+ ALCdevice_StopPlayback(Device);
+
+ SuspendContext(NULL);
+
+ for(i = 0;i < Device->NumContexts-1;i++)
+ {
+ if(Device->Contexts[i] == context)
+ {
+ memmove(&Device->Contexts[i], &Device->Contexts[i+1],
+ (Device->NumContexts-i-1) * sizeof(*Device->Contexts));
+ break;
+ }
+ }
+ Device->NumContexts--;
// Lock context
SuspendContext(context);
@@ -1268,8 +1295,6 @@ ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
ReleaseALAuxiliaryEffectSlots(context);
}
- context->Device->Context = NULL;
-
list = &g_pContextList;
while(*list != context)
list = &(*list)->next;
@@ -1279,6 +1304,7 @@ ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
// Unlock context
ProcessContext(context);
+ ProcessContext(NULL);
ExitContext(context);
@@ -1473,6 +1499,9 @@ ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
device->Bs2b = NULL;
device->szDeviceName = NULL;
+ device->Contexts = NULL;
+ device->NumContexts = 0;
+
//Set output format
device->Frequency = GetConfigValueInt(NULL, "frequency", SWMIXER_OUTPUT_RATE);
if(device->Frequency == 0)
@@ -1564,12 +1593,13 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
ProcessContext(NULL);
- if(pDevice->Context)
+ if(pDevice->NumContexts > 0)
{
#ifdef _DEBUG
- AL_PRINT("alcCloseDevice(): destroying 1 Context\n");
+ AL_PRINT("alcCloseDevice(): destroying %u Context(s)\n", pDevice->NumContexts);
#endif
- alcDestroyContext(pDevice->Context);
+ while(pDevice->NumContexts > 0)
+ alcDestroyContext(pDevice->Contexts[0]);
}
ALCdevice_ClosePlayback(pDevice);
@@ -1606,6 +1636,10 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
pDevice->Bs2b = NULL;
free(pDevice->szDeviceName);
+ pDevice->szDeviceName = NULL;
+
+ free(pDevice->Contexts);
+ pDevice->Contexts = NULL;
//Release device structure
memset(pDevice, 0, sizeof(ALCdevice));
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 49ac2ad8..c7a6d361 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1203,7 +1203,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALeffectslot *ALEffectSlot;
ALCcontext *ALContext;
int fpuState;
- ALuint i;
+ ALuint i, c;
SuspendContext(NULL);
@@ -1226,9 +1226,9 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
/* Clear mixing buffer */
memset(DryBuffer, 0, SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat));
- ALContext = device->Context;
- if(ALContext)
+ for(c = 0;c < device->NumContexts;c++)
{
+ ALContext = device->Contexts[c];
MixSomeSources(ALContext, DryBuffer, SamplesToDo);
/* effect slot processing */
@@ -1378,13 +1378,15 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALvoid aluHandleDisconnect(ALCdevice *device)
{
- if(device->Context)
+ ALuint i;
+
+ for(i = 0;i < device->NumContexts;i++)
{
ALsource *source;
- SuspendContext(device->Context);
+ SuspendContext(device->Contexts[i]);
- source = device->Context->Source;
+ source = device->Contexts[i]->Source;
while(source)
{
if(source->state == AL_PLAYING)
@@ -1405,7 +1407,7 @@ ALvoid aluHandleDisconnect(ALCdevice *device)
}
source = source->next;
}
- ProcessContext(device->Context);
+ ProcessContext(device->Contexts[i]);
}
device->Connected = ALC_FALSE;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 861019ef..f10744ed 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -247,8 +247,9 @@ struct ALCdevice_struct
// Dry path buffer mix
float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS];
- // Context created on this device
- ALCcontext *Context;
+ // Contexts created on this device
+ ALCcontext **Contexts;
+ ALuint NumContexts;
BackendFuncs *Funcs;
void *ExtraData; // For the backend's use