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 #define AUDIOSTACK 16384*2
static lwpq_t audioqueue; static lwpq_t audioqueue;
static lwp_t athread; static lwp_t athread = LWP_THREAD_NULL;
static Uint8 astack[AUDIOSTACK]; static Uint8 astack[AUDIOSTACK];
static bool stopaudio = false;
static int currentfreq;
/**************************************************************************** /****************************************************************************
* Audio Threading * Audio Threading
@ -53,10 +55,11 @@ static Uint8 astack[AUDIOSTACK];
static void * static void *
AudioThread (void *arg) AudioThread (void *arg)
{ {
LWP_InitQueue (&audioqueue);
while (1) while (1)
{ {
if(stopaudio)
break;
whichab ^= 1; whichab ^= 1;
memset(dma_buffers[whichab], 0, sizeof(dma_buffers[0])); memset(dma_buffers[whichab], 0, sizeof(dma_buffers[0]));
@ -92,7 +95,6 @@ AudioThread (void *arg)
} }
LWP_ThreadSleep (audioqueue); LWP_ThreadSleep (audioqueue);
} }
return NULL; return NULL;
} }
@ -107,10 +109,37 @@ DMACallback()
DCFlushRange (dma_buffers[whichab], sizeof(dma_buffers[0])); DCFlushRange (dma_buffers[whichab], sizeof(dma_buffers[0]));
AUDIO_InitDMA ((Uint32)dma_buffers[whichab], SAMPLES_PER_DMA_BUFFER*4); AUDIO_InitDMA ((Uint32)dma_buffers[whichab], SAMPLES_PER_DMA_BUFFER*4);
AUDIO_StartDMA (); AUDIO_StartDMA ();
LWP_ThreadSignal (audioqueue); 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) static int WIIAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
{ {
if (spec->freq != 32000 && spec->freq != 48000) 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[0], 0, sizeof(dma_buffers[0]));
memset(dma_buffers[1], 0, sizeof(dma_buffers[0])); memset(dma_buffers[1], 0, sizeof(dma_buffers[0]));
if (spec->freq == 32000) currentfreq = spec->freq;
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ); WII_AudioStart();
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();
return 1; return 1;
} }
@ -201,7 +222,6 @@ static SDL_AudioDevice *WIIAUD_CreateDevice(int devindex)
// Initialise the Wii side of the audio system // Initialise the Wii side of the audio system
AUDIO_Init(0); AUDIO_Init(0);
AUDIO_RegisterDMACallback(DMACallback);
/* Set the function pointers */ /* Set the function pointers */
this->OpenAudio = WIIAUD_OpenAudio; this->OpenAudio = WIIAUD_OpenAudio;

View file

@ -39,7 +39,7 @@
#include "SDL_wiievents_c.h" #include "SDL_wiievents_c.h"
static const char WIIVID_DRIVER_NAME[] = "wii"; static const char WIIVID_DRIVER_NAME[] = "wii";
static SDL_Thread * videothread = 0; static lwp_t videothread = LWP_THREAD_NULL;
static SDL_mutex * videomutex = 0; static SDL_mutex * videomutex = 0;
/*** SDL ***/ /*** SDL ***/
@ -60,7 +60,8 @@ static SDL_Rect* modes_descending[] =
unsigned int *xfb[2] = { NULL, NULL }; // Double buffered unsigned int *xfb[2] = { NULL, NULL }; // Double buffered
int whichfb = 0; // Switch 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 texturemem[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // GX texture
static unsigned char textureconvert[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // 565 mem static unsigned char textureconvert[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // 565 mem
@ -173,34 +174,61 @@ draw_square (Mtx v)
GX_End (); 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; static int quit_flip_thread = 0;
int flip_thread(void * arg) int flip_thread(void * arg)
{ {
while(1) while(1)
{ {
if (quit_flip_thread) if(quit_flip_thread == 2)
break; break;
whichfb ^= 1;
SDL_mutexP(videomutex);
// clear texture objects // clear texture objects
GX_InvVtxCache(); GX_InvVtxCache();
GX_InvalidateTexAll(); GX_InvalidateTexAll();
SDL_mutexP(videomutex);
// load texture into GX // load texture into GX
DCFlushRange(texturemem, TEXTUREMEM_SIZE); DCFlushRange(texturemem, TEXTUREMEM_SIZE);
GX_SetNumChans(1);
GX_LoadTexObj(&texobj, GX_TEXMAP0); GX_LoadTexObj(&texobj, GX_TEXMAP0);
draw_square(view); // render textured quad draw_square(view); // render textured quad
GX_CopyDisp(xfb[whichfb], GX_TRUE);
GX_DrawDone (); GX_DrawDone ();
GX_SetColorUpdate(GX_TRUE);
SDL_mutexV(videomutex); 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_SetNextFramebuffer(xfb[whichfb]);
VIDEO_Flush(); VIDEO_Flush();
VIDEO_WaitVSync(); VIDEO_WaitVSync();
@ -212,7 +240,7 @@ static void
SetupGX() SetupGX()
{ {
Mtx44 p; Mtx44 p;
int df = 1; int df = 1; // deflicker on/off
GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1); GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1);
GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight); GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight);
@ -220,7 +248,7 @@ SetupGX()
GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight); GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight); 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_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR);
@ -230,6 +258,7 @@ SetupGX()
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE); GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate (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 guOrtho(p, 480/2, -(480/2), -(640/2), 640/2, 100, 1000); // matrix, t, b, l, r, n, f
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC); GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
@ -238,10 +267,10 @@ SetupGX()
static void static void
StartVideoThread() StartVideoThread()
{ {
if(videothread == 0) if(videothread == LWP_THREAD_NULL)
{ {
quit_flip_thread = 0; 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() void WII_VideoStop()
{ {
quit_flip_thread = 1; quit_flip_thread = 1;
SDL_WaitThread(videothread, NULL); LWP_JoinThread(videothread, NULL);
videothread = 0; videothread = LWP_THREAD_NULL;
} }
void WII_VideoQuit(_THIS) void WII_VideoQuit(_THIS)