improvements to video/audio threading

This commit is contained in:
dborth 2009-10-09 22:49:54 +00:00
parent ebb974cbe5
commit a9519239d4
2 changed files with 81 additions and 32 deletions

View file

@ -44,8 +44,10 @@ static Uint8 whichab = 0;
#define AUDIOSTACK 16384*2
static lwpq_t audioqueue;
static lwp_t athread;
static lwp_t athread = LWP_THREAD_NULL;
static Uint8 astack[AUDIOSTACK];
static bool stopaudio = false;
static int currentfreq;
/****************************************************************************
* Audio Threading
@ -53,10 +55,11 @@ static Uint8 astack[AUDIOSTACK];
static void *
AudioThread (void *arg)
{
LWP_InitQueue (&audioqueue);
while (1)
{
if(stopaudio)
break;
whichab ^= 1;
memset(dma_buffers[whichab], 0, sizeof(dma_buffers[0]));
@ -92,7 +95,6 @@ AudioThread (void *arg)
}
LWP_ThreadSleep (audioqueue);
}
return NULL;
}
@ -107,10 +109,37 @@ DMACallback()
DCFlushRange (dma_buffers[whichab], sizeof(dma_buffers[0]));
AUDIO_InitDMA ((Uint32)dma_buffers[whichab], SAMPLES_PER_DMA_BUFFER*4);
AUDIO_StartDMA ();
LWP_ThreadSignal (audioqueue);
}
void WII_AudioStop()
{
AUDIO_StopDMA ();
AUDIO_RegisterDMACallback(0);
stopaudio = true;
LWP_ThreadSignal(audioqueue);
LWP_JoinThread(athread, NULL);
LWP_CloseQueue (audioqueue);
athread = LWP_THREAD_NULL;
}
void WII_AudioStart()
{
if (currentfreq == 32000)
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ);
else
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
// startup conversion thread
stopaudio = false;
LWP_InitQueue (&audioqueue);
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 67);
// Start the first chunk of audio playing
AUDIO_RegisterDMACallback(DMACallback);
DMACallback();
}
static int WIIAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
if (spec->freq != 32000 && spec->freq != 48000)
@ -126,16 +155,8 @@ static int WIIAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
memset(dma_buffers[0], 0, sizeof(dma_buffers[0]));
memset(dma_buffers[1], 0, sizeof(dma_buffers[0]));
if (spec->freq == 32000)
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ);
else
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
// startup conversion thread
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 90);
// Start the first chunk of audio playing
DMACallback();
currentfreq = spec->freq;
WII_AudioStart();
return 1;
}
@ -201,7 +222,6 @@ static SDL_AudioDevice *WIIAUD_CreateDevice(int devindex)
// Initialise the Wii side of the audio system
AUDIO_Init(0);
AUDIO_RegisterDMACallback(DMACallback);
/* Set the function pointers */
this->OpenAudio = WIIAUD_OpenAudio;

View file

@ -39,7 +39,7 @@
#include "SDL_wiievents_c.h"
static const char WIIVID_DRIVER_NAME[] = "wii";
static SDL_Thread * videothread = 0;
static lwp_t videothread = LWP_THREAD_NULL;
static SDL_mutex * videomutex = 0;
/*** SDL ***/
@ -60,7 +60,8 @@ static SDL_Rect* modes_descending[] =
unsigned int *xfb[2] = { NULL, NULL }; // Double buffered
int whichfb = 0; // Switch
static GXRModeObj* vmode = 0;
GXRModeObj* vmode = 0;
u8 * screenTex = NULL; // screen capture
static unsigned char texturemem[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // GX texture
static unsigned char textureconvert[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // 565 mem
@ -173,34 +174,61 @@ draw_square (Mtx v)
GX_End ();
}
/****************************************************************************
* TakeScreenshot
*
* Copies the current screen into a GX texture
***************************************************************************/
static void TakeScreenshot()
{
int texSize = vmode->fbWidth * vmode->efbHeight * 4;
if(screenTex) free(screenTex);
screenTex = (u8 *)memalign(32, texSize);
if(screenTex == NULL) return;
GX_SetTexCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetTexCopyDst(vmode->fbWidth, vmode->efbHeight, GX_TF_RGBA8, GX_FALSE);
GX_CopyTex(screenTex, GX_FALSE);
GX_PixModeSync();
DCFlushRange(screenTex, texSize);
}
static int quit_flip_thread = 0;
int flip_thread(void * arg)
{
while(1)
{
if (quit_flip_thread)
if(quit_flip_thread == 2)
break;
whichfb ^= 1;
SDL_mutexP(videomutex);
// clear texture objects
GX_InvVtxCache();
GX_InvalidateTexAll();
SDL_mutexP(videomutex);
// load texture into GX
DCFlushRange(texturemem, TEXTUREMEM_SIZE);
GX_SetNumChans(1);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
draw_square(view); // render textured quad
GX_CopyDisp(xfb[whichfb], GX_TRUE);
GX_DrawDone ();
GX_SetColorUpdate(GX_TRUE);
SDL_mutexV(videomutex);
if (quit_flip_thread == 1)
{
quit_flip_thread = 2;
TakeScreenshot();
}
whichfb ^= 1;
GX_CopyDisp(xfb[whichfb], GX_TRUE);
VIDEO_SetNextFramebuffer(xfb[whichfb]);
VIDEO_Flush();
VIDEO_WaitVSync();
@ -212,7 +240,7 @@ static void
SetupGX()
{
Mtx44 p;
int df = 1;
int df = 1; // deflicker on/off
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
@ -220,7 +248,7 @@ SetupGX()
GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight);
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, (df == 1) ? GX_TRUE : GX_FALSE, vmode->vfilter); // deflicker ON only for filtered mode
GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, (df == 1) ? GX_TRUE : GX_FALSE, vmode->vfilter);
GX_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
@ -230,6 +258,7 @@ SetupGX()
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate (GX_TRUE);
GX_SetNumChans(1);
guOrtho(p, 480/2, -(480/2), -(640/2), 640/2, 100, 1000); // matrix, t, b, l, r, n, f
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
@ -238,10 +267,10 @@ SetupGX()
static void
StartVideoThread()
{
if(videothread == 0)
if(videothread == LWP_THREAD_NULL)
{
quit_flip_thread = 0;
videothread = SDL_CreateThread(flip_thread, NULL);
LWP_CreateThread (&videothread, flip_thread, NULL, NULL, 0, 68);
}
}
@ -730,8 +759,8 @@ void WII_VideoStart()
void WII_VideoStop()
{
quit_flip_thread = 1;
SDL_WaitThread(videothread, NULL);
videothread = 0;
LWP_JoinThread(videothread, NULL);
videothread = LWP_THREAD_NULL;
}
void WII_VideoQuit(_THIS)