improvements to video/audio threading
This commit is contained in:
parent
ebb974cbe5
commit
a9519239d4
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Reference in a new issue