First phase in a DCQ optimization scheme (will have at least three phases)
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@558 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -87,4 +87,8 @@ extern TFB_DrawCommandQueue DrawCommandQueue;
|
||||
|
||||
void TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand);
|
||||
|
||||
void Lock_DCQ (int slots);
|
||||
|
||||
void Unlock_DCQ (void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -202,7 +202,7 @@ TFB_Draw_WaitForSignal (void)
|
||||
DrawCommand.image = 0;
|
||||
// We need to lock the mutex before enqueueing the DC to prevent races
|
||||
LockSignalMutex ();
|
||||
Lock_DCQ ();
|
||||
Lock_DCQ (1);
|
||||
TFB_BatchReset ();
|
||||
TFB_EnqueueDrawCommand(&DrawCommand);
|
||||
Unlock_DCQ();
|
||||
|
||||
@@ -46,8 +46,8 @@ TFB_DrawCommandQueue DrawCommandQueue;
|
||||
// locks to protect the Draw Command Queue. Lock is re-entrant to
|
||||
// allow livelock deterrence to be written much more cleanly.
|
||||
|
||||
void
|
||||
Lock_DCQ (void)
|
||||
static void
|
||||
_lock (void)
|
||||
{
|
||||
Uint32 current_thread = SDL_ThreadID ();
|
||||
if (DCQ_locking_thread != current_thread)
|
||||
@@ -59,6 +59,34 @@ Lock_DCQ (void)
|
||||
// fprintf (stderr, "DCQ_sem locking depth: %i\n", DCQ_locking_depth);
|
||||
}
|
||||
|
||||
// Wait for the queue to be emptied.
|
||||
static void
|
||||
TFB_WaitForSpace (int requested_slots)
|
||||
{
|
||||
int old_depth, i;
|
||||
fprintf (stderr, "DCQ overload (Size = %d, FullSize = %d, Requested = %d). Sleeping until renderer is done.\n", DrawCommandQueue.Size, DrawCommandQueue.FullSize, requested_slots);
|
||||
// Restore the DCQ locking level. I *think* this is
|
||||
// always 1, but...
|
||||
TFB_BatchReset ();
|
||||
old_depth = DCQ_locking_depth;
|
||||
for (i = 0; i < old_depth; i++)
|
||||
Unlock_DCQ ();
|
||||
WaitCondVar (RenderingCond);
|
||||
for (i = 0; i < old_depth; i++)
|
||||
_lock ();
|
||||
fprintf (stderr, "DCQ clear (Size = %d, FullSize = %d). Continuing.\n", DrawCommandQueue.Size, DrawCommandQueue.FullSize);
|
||||
}
|
||||
|
||||
void
|
||||
Lock_DCQ (int slots)
|
||||
{
|
||||
_lock ();
|
||||
while (DrawCommandQueue.FullSize >= DCQ_MAX - slots)
|
||||
{
|
||||
TFB_WaitForSpace (slots);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Unlock_DCQ (void)
|
||||
{
|
||||
@@ -103,7 +131,7 @@ Synchronize_DCQ (void)
|
||||
void
|
||||
TFB_BatchGraphics (void)
|
||||
{
|
||||
Lock_DCQ ();
|
||||
_lock ();
|
||||
DrawCommandQueue.Batching++;
|
||||
Unlock_DCQ ();
|
||||
}
|
||||
@@ -111,7 +139,7 @@ TFB_BatchGraphics (void)
|
||||
void
|
||||
TFB_UnbatchGraphics (void)
|
||||
{
|
||||
Lock_DCQ ();
|
||||
_lock ();
|
||||
if (DrawCommandQueue.Batching)
|
||||
{
|
||||
DrawCommandQueue.Batching--;
|
||||
@@ -126,29 +154,12 @@ TFB_UnbatchGraphics (void)
|
||||
void
|
||||
TFB_BatchReset (void)
|
||||
{
|
||||
Lock_DCQ ();
|
||||
_lock ();
|
||||
DrawCommandQueue.Batching = 0;
|
||||
Synchronize_DCQ ();
|
||||
Unlock_DCQ ();
|
||||
}
|
||||
|
||||
// Wait for the queue to be emptied.
|
||||
static void
|
||||
TFB_WaitForSpace (int requested_slots)
|
||||
{
|
||||
int old_depth, i;
|
||||
fprintf (stderr, "DCQ overload (Size = %d, FullSize = %d, Requested = %d). Sleeping until renderer is done.\n", DrawCommandQueue.Size, DrawCommandQueue.FullSize, requested_slots);
|
||||
// Restore the DCQ locking level. I *think* this is
|
||||
// always 1, but...
|
||||
TFB_BatchReset ();
|
||||
old_depth = DCQ_locking_depth;
|
||||
for (i = 0; i < old_depth; i++)
|
||||
Unlock_DCQ ();
|
||||
WaitCondVar (RenderingCond);
|
||||
for (i = 0; i < old_depth; i++)
|
||||
Lock_DCQ ();
|
||||
fprintf (stderr, "DCQ clear (Size = %d, FullSize = %d). Continuing.\n", DrawCommandQueue.Size, DrawCommandQueue.FullSize);
|
||||
}
|
||||
|
||||
// Draw Command Queue Stuff
|
||||
|
||||
@@ -170,11 +181,7 @@ TFB_DrawCommandQueue_Create()
|
||||
void
|
||||
TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
|
||||
{
|
||||
Lock_DCQ ();
|
||||
while (DrawCommandQueue.FullSize >= DCQ_MAX - 1)
|
||||
{
|
||||
TFB_WaitForSpace (1);
|
||||
}
|
||||
Lock_DCQ (1);
|
||||
DCQ[DrawCommandQueue.InsertionPoint] = *Command;
|
||||
DrawCommandQueue.InsertionPoint = (DrawCommandQueue.InsertionPoint + 1) % DCQ_MAX;
|
||||
DrawCommandQueue.FullSize++;
|
||||
@@ -185,7 +192,7 @@ TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
|
||||
int
|
||||
TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
|
||||
{
|
||||
Lock_DCQ ();
|
||||
_lock ();
|
||||
|
||||
if (DrawCommandQueue.Size == 0)
|
||||
{
|
||||
@@ -214,7 +221,7 @@ TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
|
||||
void
|
||||
TFB_DrawCommandQueue_Clear ()
|
||||
{
|
||||
Lock_DCQ ();
|
||||
_lock ();
|
||||
DrawCommandQueue.Size = 0;
|
||||
DrawCommandQueue.Front = 0;
|
||||
DrawCommandQueue.Back = 0;
|
||||
|
||||
@@ -19,7 +19,5 @@
|
||||
#ifndef DCQUEUE_H
|
||||
#define DCQUEUE_H
|
||||
|
||||
void Lock_DCQ (void);
|
||||
void Unlock_DCQ (void);
|
||||
|
||||
/* This is all in drawcmd.h now. */
|
||||
#endif
|
||||
|
||||
@@ -537,7 +537,7 @@ TFB_FlushGraphics () // Only call from main thread!!
|
||||
|
||||
if (DrawCommandQueue.Size > DCQ_FORCE_SLOWDOWN_SIZE)
|
||||
{
|
||||
Lock_DCQ ();
|
||||
Lock_DCQ (-1);
|
||||
livelock_deterrence = TRUE;
|
||||
}
|
||||
|
||||
@@ -559,7 +559,7 @@ TFB_FlushGraphics () // Only call from main thread!!
|
||||
// fprintf (stderr, "Initiating livelock deterrence!\n");
|
||||
livelock_deterrence = TRUE;
|
||||
|
||||
Lock_DCQ ();
|
||||
Lock_DCQ (-1);
|
||||
}
|
||||
|
||||
DC_image = (TFB_Image*) DC.image;
|
||||
|
||||
Reference in New Issue
Block a user