DCQ is now statically allocated

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@399 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2002-12-10 20:20:24 +00:00
parent 2a711f2c9a
commit 07e268224f
7 changed files with 67 additions and 68 deletions
+4
View File
@@ -101,3 +101,7 @@ The bugs reported but not yet verified:
- In starmap, when any zone of influence is moving, the starmap cursor behaves badly - In starmap, when any zone of influence is moving, the starmap cursor behaves badly
(erases what it passes over). Leaving and returning to the starmap fixes it (erases what it passes over). Leaving and returning to the starmap fixes it
- Under FreeBSD, waiting on condition variables doesn't seem to
actually wait or hand control to the renderer, thus spinlocking and
crashing.
+2
View File
@@ -1,4 +1,6 @@
0.2: 0.2:
- Recoded the DCQ to not sit on the heap, added debugging info
- Fixed Outfit Starship and Shipyard graphics, from TDuck
- 3D planet is now zoomed randomly from any corner, from PhracturedBlue - 3D planet is now zoomed randomly from any corner, from PhracturedBlue
- Flagship thrusters and modules one-pixel place fix, from TDuck - Flagship thrusters and modules one-pixel place fix, from TDuck
- Earth topo map is now tinted as should, from PhracturedBlue - Earth topo map is now tinted as should, from PhracturedBlue
+3 -1
View File
@@ -101,9 +101,11 @@ Implementation bugs (low priority):
and removing occasional pops/discontinuities and removing occasional pops/discontinuities
- Rotation and zooming isn't now as smooth as before after condition - Rotation and zooming isn't now as smooth as before after condition
variable DCQ patch variable DCQ patch
- DrawCommandQueue is gratuitously dynamically allocated, should be static - 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?
Stuff still to do (large): Stuff still to do (large):
- add a Key Jamming program - add a Key Jamming program
+5 -7
View File
@@ -124,7 +124,7 @@ typedef struct tfb_drawcommandqueue
volatile int Size; volatile int Size;
} TFB_DrawCommandQueue; } TFB_DrawCommandQueue;
TFB_DrawCommandQueue *TFB_DrawCommandQueue_Create (void); void TFB_DrawCommandQueue_Create (void);
void TFB_BatchGraphics (void); void TFB_BatchGraphics (void);
@@ -132,15 +132,13 @@ void TFB_UnbatchGraphics (void);
void TFB_BatchReset (void); void TFB_BatchReset (void);
void TFB_DrawCommandQueue_Push (TFB_DrawCommandQueue* myQueue, void TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command);
TFB_DrawCommand* Command);
int TFB_DrawCommandQueue_Pop (TFB_DrawCommandQueue* myQueue, int TFB_DrawCommandQueue_Pop (TFB_DrawCommand* Command);
TFB_DrawCommand* Command);
void TFB_DrawCommandQueue_Clear (TFB_DrawCommandQueue* myQueue); void TFB_DrawCommandQueue_Clear (void);
extern TFB_DrawCommandQueue *DrawCommandQueue; extern TFB_DrawCommandQueue DrawCommandQueue;
// The TFB_Enqueue* functions are necessary, because only the // The TFB_Enqueue* functions are necessary, because only the
// main thread can draw to the window. // main thread can draw to the window.
@@ -35,11 +35,11 @@ InitGraphics (int argc, char* argv[], COUNT KbytesRequired)
{ {
BOOLEAN ret; BOOLEAN ret;
TFB_DrawCommandQueue_Create ();
LoadDisplay (&_pCurDisplay); LoadDisplay (&_pCurDisplay);
ActivateDisplay (); ActivateDisplay ();
DrawCommandQueue = TFB_DrawCommandQueue_Create ();
ret = TRUE; ret = TRUE;
return (ret); return (ret);
} }
+44 -51
View File
@@ -35,7 +35,7 @@ static Uint32 DCQ_locking_thread = 0;
#define DCQ_MAX 16384 #define DCQ_MAX 16384
TFB_DrawCommand DCQ[DCQ_MAX]; TFB_DrawCommand DCQ[DCQ_MAX];
TFB_DrawCommandQueue *DrawCommandQueue; TFB_DrawCommandQueue DrawCommandQueue;
// DCQ Synchronization: SDL-specific implementation of re-entrant // DCQ Synchronization: SDL-specific implementation of re-entrant
// locks to protect the Draw Command Queue. Lock is re-entrant to // locks to protect the Draw Command Queue. Lock is re-entrant to
@@ -78,20 +78,20 @@ Unlock_DCQ (void)
static void static void
Synchronize_DCQ (void) Synchronize_DCQ (void)
{ {
if (!DrawCommandQueue->Batching) if (!DrawCommandQueue.Batching)
{ {
int front = DrawCommandQueue->Front; int front = DrawCommandQueue.Front;
int back = DrawCommandQueue->InsertionPoint; int back = DrawCommandQueue.InsertionPoint;
DrawCommandQueue->Back = DrawCommandQueue->InsertionPoint; DrawCommandQueue.Back = DrawCommandQueue.InsertionPoint;
if (front <= back) if (front <= back)
{ {
DrawCommandQueue->Size = (back - front); DrawCommandQueue.Size = (back - front);
} }
else else
{ {
DrawCommandQueue->Size = (back + DCQ_MAX - front); DrawCommandQueue.Size = (back + DCQ_MAX - front);
} }
DrawCommandQueue->FullSize = DrawCommandQueue->Size; DrawCommandQueue.FullSize = DrawCommandQueue.Size;
} }
} }
@@ -99,7 +99,7 @@ void
TFB_BatchGraphics (void) TFB_BatchGraphics (void)
{ {
Lock_DCQ (); Lock_DCQ ();
DrawCommandQueue->Batching++; DrawCommandQueue.Batching++;
Unlock_DCQ (); Unlock_DCQ ();
} }
@@ -107,9 +107,9 @@ void
TFB_UnbatchGraphics (void) TFB_UnbatchGraphics (void)
{ {
Lock_DCQ (); Lock_DCQ ();
if (DrawCommandQueue->Batching) if (DrawCommandQueue.Batching)
{ {
DrawCommandQueue->Batching--; DrawCommandQueue.Batching--;
} }
Synchronize_DCQ (); Synchronize_DCQ ();
Unlock_DCQ (); Unlock_DCQ ();
@@ -122,43 +122,36 @@ void
TFB_BatchReset (void) TFB_BatchReset (void)
{ {
Lock_DCQ (); Lock_DCQ ();
DrawCommandQueue->Batching = 0; DrawCommandQueue.Batching = 0;
Synchronize_DCQ (); Synchronize_DCQ ();
Unlock_DCQ (); Unlock_DCQ ();
} }
// Draw Command Queue Stuff // Draw Command Queue Stuff
// TODO: Make this be statically allocated, too. We only ever have one DCQ, after all.
TFB_DrawCommandQueue* void
TFB_DrawCommandQueue_Create() TFB_DrawCommandQueue_Create()
{ {
TFB_DrawCommandQueue* myQueue; DrawCommandQueue.Back = 0;
DrawCommandQueue.Front = 0;
myQueue = (TFB_DrawCommandQueue*) HMalloc( DrawCommandQueue.InsertionPoint = 0;
sizeof(TFB_DrawCommandQueue)); DrawCommandQueue.Batching = 0;
DrawCommandQueue.FullSize = 0;
myQueue->Back = 0; DrawCommandQueue.Size = 0;
myQueue->Front = 0; DCQ_locking_depth = 0;
myQueue->InsertionPoint = 0; DCQ_locking_thread = 0;
myQueue->Batching = 0;
myQueue->FullSize = 0;
myQueue->Size = 0;
DCQ_sem = CreateSemaphore(1); DCQ_sem = CreateSemaphore(1);
return (myQueue);
} }
void void
TFB_DrawCommandQueue_Push (TFB_DrawCommandQueue* myQueue, TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
TFB_DrawCommand* Command)
{ {
Lock_DCQ (); Lock_DCQ ();
while (myQueue->FullSize >= DCQ_MAX - 1) while (DrawCommandQueue.FullSize >= DCQ_MAX - 1)
{ {
int old_depth, i; int old_depth, i;
fprintf (stderr, "DCQ overload (Size = %d). Sleeping until renderer is done.\n", myQueue->Size); fprintf (stderr, "DCQ overload (Size = %d). Sleeping until renderer is done.\n", DrawCommandQueue.Size);
// Restore the DCQ locking level. I *think* this is // Restore the DCQ locking level. I *think* this is
// always 1, but... // always 1, but...
old_depth = DCQ_locking_depth; old_depth = DCQ_locking_depth;
@@ -167,54 +160,54 @@ TFB_DrawCommandQueue_Push (TFB_DrawCommandQueue* myQueue,
WaitCondVar (RenderingCond); WaitCondVar (RenderingCond);
for (i = 0; i < old_depth; i++) for (i = 0; i < old_depth; i++)
Lock_DCQ (); Lock_DCQ ();
fprintf (stderr, "DCQ clear (Size = %d). Continuing.\n", myQueue->Size); fprintf (stderr, "DCQ clear (Size = %d). Continuing.\n", DrawCommandQueue.Size);
} }
DCQ[myQueue->InsertionPoint] = *Command; DCQ[DrawCommandQueue.InsertionPoint] = *Command;
myQueue->InsertionPoint = (myQueue->InsertionPoint + 1) % DCQ_MAX; DrawCommandQueue.InsertionPoint = (DrawCommandQueue.InsertionPoint + 1) % DCQ_MAX;
myQueue->FullSize++; DrawCommandQueue.FullSize++;
Synchronize_DCQ (); Synchronize_DCQ ();
Unlock_DCQ (); Unlock_DCQ ();
} }
int int
TFB_DrawCommandQueue_Pop (TFB_DrawCommandQueue *myQueue, TFB_DrawCommand *target) TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
{ {
Lock_DCQ (); Lock_DCQ ();
if (myQueue->Size == 0) if (DrawCommandQueue.Size == 0)
{ {
Unlock_DCQ (); Unlock_DCQ ();
return (0); return (0);
} }
if (myQueue->Front == myQueue->Back && myQueue->Size != DCQ_MAX) if (DrawCommandQueue.Front == DrawCommandQueue.Back && DrawCommandQueue.Size != DCQ_MAX)
{ {
fprintf (stderr, "Augh! Assertion failure in DCQ! Front == Back, Size != DCQ_MAX\n"); fprintf (stderr, "Augh! Assertion failure in DCQ! Front == Back, Size != DCQ_MAX\n");
myQueue->Size = 0; DrawCommandQueue.Size = 0;
Unlock_DCQ (); Unlock_DCQ ();
return (0); return (0);
} }
*target = DCQ[myQueue->Front]; *target = DCQ[DrawCommandQueue.Front];
myQueue->Front = (myQueue->Front + 1) % DCQ_MAX; DrawCommandQueue.Front = (DrawCommandQueue.Front + 1) % DCQ_MAX;
myQueue->Size--; DrawCommandQueue.Size--;
myQueue->FullSize--; DrawCommandQueue.FullSize--;
Unlock_DCQ (); Unlock_DCQ ();
return 1; return 1;
} }
void void
TFB_DrawCommandQueue_Clear (TFB_DrawCommandQueue *myQueue) TFB_DrawCommandQueue_Clear ()
{ {
Lock_DCQ (); Lock_DCQ ();
myQueue->Size = 0; DrawCommandQueue.Size = 0;
myQueue->Front = 0; DrawCommandQueue.Front = 0;
myQueue->Back = 0; DrawCommandQueue.Back = 0;
myQueue->Batching = 0; DrawCommandQueue.Batching = 0;
myQueue->FullSize = 0; DrawCommandQueue.FullSize = 0;
myQueue->InsertionPoint = 0; DrawCommandQueue.InsertionPoint = 0;
Unlock_DCQ (); Unlock_DCQ ();
} }
@@ -262,7 +255,7 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
} }
} }
TFB_DrawCommandQueue_Push (DrawCommandQueue, DrawCommand); TFB_DrawCommandQueue_Push (DrawCommand);
} }
#endif #endif
@@ -523,9 +523,9 @@ TFB_FlushGraphics () // Only call from main thread!!
BOOLEAN livelock_deterrence; BOOLEAN livelock_deterrence;
BOOLEAN done; BOOLEAN done;
// This is technically a locking violation on DrawCommandQueue->Size, // This is technically a locking violation on DrawCommandQueue.Size,
// but it is likely to not be very destructive. // but it is likely to not be very destructive.
if (DrawCommandQueue == 0 || DrawCommandQueue->Size == 0) if (DrawCommandQueue.Size == 0)
{ {
static int last_fade = 255; static int last_fade = 255;
static int last_transition = 255; static int last_transition = 255;
@@ -571,12 +571,12 @@ TFB_FlushGraphics () // Only call from main thread!!
commands_handled = 0; commands_handled = 0;
livelock_deterrence = FALSE; livelock_deterrence = FALSE;
if (DrawCommandQueue->FullSize > DCQ_FORCE_BREAK_SIZE) if (DrawCommandQueue.FullSize > DCQ_FORCE_BREAK_SIZE)
{ {
TFB_BatchReset (); TFB_BatchReset ();
} }
if (DrawCommandQueue->Size > DCQ_FORCE_SLOWDOWN_SIZE) if (DrawCommandQueue.Size > DCQ_FORCE_SLOWDOWN_SIZE)
{ {
Lock_DCQ (); Lock_DCQ ();
livelock_deterrence = TRUE; livelock_deterrence = TRUE;
@@ -588,14 +588,14 @@ TFB_FlushGraphics () // Only call from main thread!!
TFB_DrawCommand DC; TFB_DrawCommand DC;
TFB_Image *DC_image; TFB_Image *DC_image;
if (!TFB_DrawCommandQueue_Pop (DrawCommandQueue, &DC)) if (!TFB_DrawCommandQueue_Pop (&DC))
{ {
// the Queue is now empty. // the Queue is now empty.
break; break;
} }
++commands_handled; ++commands_handled;
if (!livelock_deterrence && commands_handled + DrawCommandQueue->Size > DCQ_LIVELOCK_MAX) if (!livelock_deterrence && commands_handled + DrawCommandQueue.Size > DCQ_LIVELOCK_MAX)
{ {
// fprintf (stderr, "Initiating livelock deterrence!\n"); // fprintf (stderr, "Initiating livelock deterrence!\n");
livelock_deterrence = TRUE; livelock_deterrence = TRUE;
@@ -768,7 +768,7 @@ TFB_FlushGraphics () // Only call from main thread!!
TFB_SwapBuffers (); TFB_SwapBuffers ();
break; break;
case TFB_DRAWCOMMANDTYPE_SKIPGRAPHICS: case TFB_DRAWCOMMANDTYPE_SKIPGRAPHICS:
TFB_DrawCommandQueue_Clear (DrawCommandQueue); TFB_DrawCommandQueue_Clear ();
} }
if (DC_image) if (DC_image)
UnlockMutex (DC_image->mutex); UnlockMutex (DC_image->mutex);