FlushGraphics now tracks and wakes each thread individually, lessening

the stuttering when multiple threads are performing Flush operations.

Also, a number of comments have been reworked for accuracy.


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@527 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2003-01-03 12:14:19 +00:00
parent af999b15ea
commit 578cf23ba3
12 changed files with 149 additions and 19 deletions
+1
View File
@@ -1,4 +1,5 @@
Changes towards version 0.2: Changes towards version 0.2:
- FlushGraphics now waits and notifies on a per-thread level
- No longer using SHGetFolderPath on Windows - SvdB - No longer using SHGetFolderPath on Windows - SvdB
- Key repeat is now enabled when typing text, from slayne - Key repeat is now enabled when typing text, from slayne
- Capital letter bug in new input code fixed, from slayne - Capital letter bug in new input code fixed, from slayne
-4
View File
@@ -78,10 +78,6 @@ Implementation bugs (low priority):
- 3D planet view when entering orbit is now done, but there's some things - 3D planet view when entering orbit is now done, but there's some things
which could make it look nicer, like better slave shield and removing which could make it look nicer, like better slave shield and removing
occasional pops/discontinuities occasional pops/discontinuities
- Rotation and zooming isn't now as smooth as before after condition
variable DCQ patch
- This is because of the fact that all FlushGraphics routines wait on
one lone condition variable -- we need one per thread, effectively.
- Transitions (crossfades) aren't perhaps correctly done always, syncing - Transitions (crossfades) aren't perhaps correctly done always, syncing
might be wrong etc. might be wrong etc.
- Condition variable DCQ patch should have fixed this. Confirm? - Condition variable DCQ patch should have fixed this. Confirm?
+4
View File
@@ -651,6 +651,10 @@ SOURCE=..\sc2code\libs\threads\thrcommon.c
SOURCE=..\sc2code\libs\threads\thrcommon.h SOURCE=..\sc2code\libs\threads\thrcommon.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\sc2code\libs\threads\condbank.c
# End Source File
# End Group # End Group
# Begin Group "time" # Begin Group "time"
@@ -109,6 +109,7 @@ typedef struct tfb_drawcommand
BOOLEAN UsePalette; BOOLEAN UsePalette;
int BlendNumerator; int BlendNumerator;
int BlendDenominator; int BlendDenominator;
DWORD thread;
} TFB_DrawCommand; } TFB_DrawCommand;
// Queue Stuff // Queue Stuff
@@ -54,12 +54,10 @@ UninitGraphics () // Also probably empty
} }
// Batch/UnbatchGraphics: These routines appear to be used to ensure /* Batching and Unbatching functions. A "Batch" is a collection of
// that the screen doesn't update with a half-drawn region. This can DrawCommands that will never be flipped to the screen half-rendered.
// be implemented in all sorts of ways - I've chosen to fold it into BatchGraphics and UnbatchGraphics function vaguely like a non-blocking
// our DrawCommandQueue, for the most part. These just forward to recursive lock to do this respect. */
// the TFB_ versions in dcqueue.c. They may also make continuity_break
// redundant, but I haven't tested that yet. --Michael
void void
BatchGraphics (void) BatchGraphics (void)
{ {
@@ -72,6 +70,9 @@ UnbatchGraphics (void)
TFB_UnbatchGraphics (); TFB_UnbatchGraphics ();
} }
/* Sleeps this thread until all Draw Commands queued by that thread have
been processed. */
void void
FlushGraphics (void) FlushGraphics (void)
{ {
@@ -80,7 +81,7 @@ FlushGraphics (void)
DrawCommand.Type = TFB_DRAWCOMMANDTYPE_FLUSHGRAPHICS; DrawCommand.Type = TFB_DRAWCOMMANDTYPE_FLUSHGRAPHICS;
DrawCommand.image = 0; DrawCommand.image = 0;
TFB_EnqueueDrawCommand(&DrawCommand); TFB_EnqueueDrawCommand(&DrawCommand);
WaitCondVar (RenderingCond); WaitForSignal ();
} }
void void
+2 -1
View File
@@ -223,7 +223,8 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
{ {
return; return;
} }
DrawCommand->thread = CurrentThreadID ();
if (DrawCommand->Type <= TFB_DRAWCOMMANDTYPE_COPYFROMOTHERBUFFER if (DrawCommand->Type <= TFB_DRAWCOMMANDTYPE_COPYFROMOTHERBUFFER
&& TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE) && TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
{ {
@@ -737,7 +737,8 @@ TFB_FlushGraphics () // Only call from main thread!!
break; break;
case TFB_DRAWCOMMANDTYPE_FLUSHGRAPHICS: case TFB_DRAWCOMMANDTYPE_FLUSHGRAPHICS:
// done = TRUE; // done = TRUE;
TFB_SwapBuffers (); // TFB_SwapBuffers ();
SignalThread (DC.thread);
break; break;
case TFB_DRAWCOMMANDTYPE_SKIPGRAPHICS: case TFB_DRAWCOMMANDTYPE_SKIPGRAPHICS:
TFB_DrawCommandQueue_Clear (); TFB_DrawCommandQueue_Clear ();
+7 -1
View File
@@ -65,7 +65,8 @@
extern void InitThreadSystem (void); extern void InitThreadSystem (void);
extern void UnInitThreadSystem (void); extern void UnInitThreadSystem (void);
extern void init_cond_bank (void);
extern void uninit_cond_bank (void);
typedef int (*ThreadFunction) (void *); typedef int (*ThreadFunction) (void *);
@@ -130,5 +131,10 @@ extern void WaitCondVar (CondVar);
extern void SignalCondVar (CondVar); extern void SignalCondVar (CondVar);
extern void BroadcastCondVar (CondVar); extern void BroadcastCondVar (CondVar);
extern DWORD CurrentThreadID (void);
extern void WaitForSignal (void);
extern void SignalThread (DWORD);
#endif /* _THREADLIB_H */ #endif /* _THREADLIB_H */
+1 -1
View File
@@ -1,2 +1,2 @@
uqm_SUBDIRS="sdl" uqm_SUBDIRS="sdl"
uqm_CFILES="thrcommon.c" uqm_CFILES="condbank.c thrcommon.c"
+110
View File
@@ -0,0 +1,110 @@
//Copyright Paul Reiche, Fred Ford. 1992-2002
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* This defines the Condition Variable Bank. Individual threads may
sleep until they are signaled by their Thread ID. If the Condition
Variable Bank is exhausted (unlikely!) it will wait on the DCQ's
condition variable. This may produce stuttering. */
#include <stdio.h>
#include "starcon.h"
#include "libs/threadlib.h"
/* The Condition Variable Bank. */
#define CONDVAR_BANK_SIZE 10
static Semaphore bank_sem;
static struct {
CondVar var;
DWORD id;
int used;
} bank[CONDVAR_BANK_SIZE];
void
init_cond_bank ()
{
int i;
bank_sem = CreateSemaphore (1, "CondVar Bank Semaphore");
for (i = 0; i < CONDVAR_BANK_SIZE; i++)
{
bank[i].var = CreateCondVar ();
bank[i].id = bank[i].used = 0;
}
}
void
uninit_cond_bank ()
{
int i;
for (i = 0; i < CONDVAR_BANK_SIZE; i++)
{
DestroyCondVar (bank[i].var);
}
DestroySemaphore (bank_sem);
}
void
WaitForSignal ()
{
int i;
int index = -1;
DWORD me = CurrentThreadID ();
SetSemaphore (bank_sem);
for (i = 0; i < CONDVAR_BANK_SIZE; i++)
{
if (!bank[i].used)
{
index = i;
break;
}
}
if (index == -1)
{
/* The bank is full! */
fprintf(stderr, "Condvar bank is full, %ul is waiting on DCQ.", me);
ClearSemaphore (bank_sem);
WaitCondVar (RenderingCond);
}
else
{
bank[i].used = 1;
bank[i].id = me;
ClearSemaphore (bank_sem);
WaitCondVar (bank[i].var);
}
}
void
SignalThread (DWORD id)
{
int i;
SetSemaphore (bank_sem);
for (i = 0; i < CONDVAR_BANK_SIZE; i++)
{
if (bank[i].used && bank[i].id == id)
{
bank[i].id = bank[i].used = 0;
SignalCondVar (bank[i].var);
break;
}
}
ClearSemaphore (bank_sem);
}
@@ -86,14 +86,16 @@ typedef SDL_cond *NativeCondVar;
#define NativeCreateCondVar() \ #define NativeCreateCondVar() \
SDL_CreateCond () SDL_CreateCond ()
#define NativeDestroyCondVar(condvar) \ #define NativeDestroyCondVar(condvar) \
SDL_DestroyCond((condvar)) SDL_DestroyCond ((condvar))
#define NativeWaitCondVar(condvar) \ #define NativeWaitCondVar(condvar) \
SDLWrapper_WaitCondVar((condvar)) SDLWrapper_WaitCondVar ((condvar))
#define NativeSignalCondVar(condvar) \ #define NativeSignalCondVar(condvar) \
SDL_CondSignal((condvar)) SDL_CondSignal ((condvar))
#define NativeBroadcastCondVar(condvar) \ #define NativeBroadcastCondVar(condvar) \
SDL_CondBroadcast((condvar)) SDL_CondBroadcast ((condvar))
#define NativeCurrentThreadID() \
SDL_ThreadID ()
#endif /* _SDLTHREAD_H */ #endif /* _SDLTHREAD_H */
+7
View File
@@ -89,11 +89,13 @@ InitThreadSystem (void)
signal(SIGUSR1, SigUSR1Handler); signal(SIGUSR1, SigUSR1Handler);
#endif #endif
NativeInitThreadSystem (); NativeInitThreadSystem ();
init_cond_bank ();
} }
void void
UnInitThreadSystem (void) UnInitThreadSystem (void)
{ {
uninit_cond_bank ();
NativeUnInitThreadSystem (); NativeUnInitThreadSystem ();
#ifdef PROFILE_THREADS #ifdef PROFILE_THREADS
signal(SIGUSR1, SIG_DFL); signal(SIGUSR1, SIG_DFL);
@@ -602,3 +604,8 @@ void BroadcastCondVar (CondVar cv)
{ {
NativeBroadcastCondVar (cv); NativeBroadcastCondVar (cv);
} }
DWORD CurrentThreadID ()
{
return (DWORD)NativeThreadID ();
}