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 TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand);
|
||||||
|
|
||||||
|
void Lock_DCQ (int slots);
|
||||||
|
|
||||||
|
void Unlock_DCQ (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ TFB_Draw_WaitForSignal (void)
|
|||||||
DrawCommand.image = 0;
|
DrawCommand.image = 0;
|
||||||
// We need to lock the mutex before enqueueing the DC to prevent races
|
// We need to lock the mutex before enqueueing the DC to prevent races
|
||||||
LockSignalMutex ();
|
LockSignalMutex ();
|
||||||
Lock_DCQ ();
|
Lock_DCQ (1);
|
||||||
TFB_BatchReset ();
|
TFB_BatchReset ();
|
||||||
TFB_EnqueueDrawCommand(&DrawCommand);
|
TFB_EnqueueDrawCommand(&DrawCommand);
|
||||||
Unlock_DCQ();
|
Unlock_DCQ();
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ TFB_DrawCommandQueue DrawCommandQueue;
|
|||||||
// locks to protect the Draw Command Queue. Lock is re-entrant to
|
// locks to protect the Draw Command Queue. Lock is re-entrant to
|
||||||
// allow livelock deterrence to be written much more cleanly.
|
// allow livelock deterrence to be written much more cleanly.
|
||||||
|
|
||||||
void
|
static void
|
||||||
Lock_DCQ (void)
|
_lock (void)
|
||||||
{
|
{
|
||||||
Uint32 current_thread = SDL_ThreadID ();
|
Uint32 current_thread = SDL_ThreadID ();
|
||||||
if (DCQ_locking_thread != current_thread)
|
if (DCQ_locking_thread != current_thread)
|
||||||
@@ -59,6 +59,34 @@ Lock_DCQ (void)
|
|||||||
// fprintf (stderr, "DCQ_sem locking depth: %i\n", DCQ_locking_depth);
|
// 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
|
void
|
||||||
Unlock_DCQ (void)
|
Unlock_DCQ (void)
|
||||||
{
|
{
|
||||||
@@ -103,7 +131,7 @@ Synchronize_DCQ (void)
|
|||||||
void
|
void
|
||||||
TFB_BatchGraphics (void)
|
TFB_BatchGraphics (void)
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
_lock ();
|
||||||
DrawCommandQueue.Batching++;
|
DrawCommandQueue.Batching++;
|
||||||
Unlock_DCQ ();
|
Unlock_DCQ ();
|
||||||
}
|
}
|
||||||
@@ -111,7 +139,7 @@ TFB_BatchGraphics (void)
|
|||||||
void
|
void
|
||||||
TFB_UnbatchGraphics (void)
|
TFB_UnbatchGraphics (void)
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
_lock ();
|
||||||
if (DrawCommandQueue.Batching)
|
if (DrawCommandQueue.Batching)
|
||||||
{
|
{
|
||||||
DrawCommandQueue.Batching--;
|
DrawCommandQueue.Batching--;
|
||||||
@@ -126,29 +154,12 @@ TFB_UnbatchGraphics (void)
|
|||||||
void
|
void
|
||||||
TFB_BatchReset (void)
|
TFB_BatchReset (void)
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
_lock ();
|
||||||
DrawCommandQueue.Batching = 0;
|
DrawCommandQueue.Batching = 0;
|
||||||
Synchronize_DCQ ();
|
Synchronize_DCQ ();
|
||||||
Unlock_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
|
// Draw Command Queue Stuff
|
||||||
|
|
||||||
@@ -170,11 +181,7 @@ TFB_DrawCommandQueue_Create()
|
|||||||
void
|
void
|
||||||
TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
|
TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
Lock_DCQ (1);
|
||||||
while (DrawCommandQueue.FullSize >= DCQ_MAX - 1)
|
|
||||||
{
|
|
||||||
TFB_WaitForSpace (1);
|
|
||||||
}
|
|
||||||
DCQ[DrawCommandQueue.InsertionPoint] = *Command;
|
DCQ[DrawCommandQueue.InsertionPoint] = *Command;
|
||||||
DrawCommandQueue.InsertionPoint = (DrawCommandQueue.InsertionPoint + 1) % DCQ_MAX;
|
DrawCommandQueue.InsertionPoint = (DrawCommandQueue.InsertionPoint + 1) % DCQ_MAX;
|
||||||
DrawCommandQueue.FullSize++;
|
DrawCommandQueue.FullSize++;
|
||||||
@@ -185,7 +192,7 @@ TFB_DrawCommandQueue_Push (TFB_DrawCommand* Command)
|
|||||||
int
|
int
|
||||||
TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
|
TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
_lock ();
|
||||||
|
|
||||||
if (DrawCommandQueue.Size == 0)
|
if (DrawCommandQueue.Size == 0)
|
||||||
{
|
{
|
||||||
@@ -214,7 +221,7 @@ TFB_DrawCommandQueue_Pop (TFB_DrawCommand *target)
|
|||||||
void
|
void
|
||||||
TFB_DrawCommandQueue_Clear ()
|
TFB_DrawCommandQueue_Clear ()
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
_lock ();
|
||||||
DrawCommandQueue.Size = 0;
|
DrawCommandQueue.Size = 0;
|
||||||
DrawCommandQueue.Front = 0;
|
DrawCommandQueue.Front = 0;
|
||||||
DrawCommandQueue.Back = 0;
|
DrawCommandQueue.Back = 0;
|
||||||
|
|||||||
@@ -19,7 +19,5 @@
|
|||||||
#ifndef DCQUEUE_H
|
#ifndef DCQUEUE_H
|
||||||
#define DCQUEUE_H
|
#define DCQUEUE_H
|
||||||
|
|
||||||
void Lock_DCQ (void);
|
/* This is all in drawcmd.h now. */
|
||||||
void Unlock_DCQ (void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ TFB_FlushGraphics () // Only call from main thread!!
|
|||||||
|
|
||||||
if (DrawCommandQueue.Size > DCQ_FORCE_SLOWDOWN_SIZE)
|
if (DrawCommandQueue.Size > DCQ_FORCE_SLOWDOWN_SIZE)
|
||||||
{
|
{
|
||||||
Lock_DCQ ();
|
Lock_DCQ (-1);
|
||||||
livelock_deterrence = TRUE;
|
livelock_deterrence = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,7 +559,7 @@ TFB_FlushGraphics () // Only call from main thread!!
|
|||||||
// fprintf (stderr, "Initiating livelock deterrence!\n");
|
// fprintf (stderr, "Initiating livelock deterrence!\n");
|
||||||
livelock_deterrence = TRUE;
|
livelock_deterrence = TRUE;
|
||||||
|
|
||||||
Lock_DCQ ();
|
Lock_DCQ (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DC_image = (TFB_Image*) DC.image;
|
DC_image = (TFB_Image*) DC.image;
|
||||||
|
|||||||
Reference in New Issue
Block a user