DCQ optimization (Phase 2 of 3)

This has dropped the .bss segment of the final binary by nearly 16MB.


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@562 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2003-01-18 03:17:06 +00:00
parent 9f76511706
commit e5aa5677a4
7 changed files with 187 additions and 54 deletions
+5 -3
View File
@@ -24,6 +24,7 @@ enum
TFB_DRAWCOMMANDTYPE_LINE, TFB_DRAWCOMMANDTYPE_LINE,
TFB_DRAWCOMMANDTYPE_RECTANGLE, TFB_DRAWCOMMANDTYPE_RECTANGLE,
TFB_DRAWCOMMANDTYPE_IMAGE, TFB_DRAWCOMMANDTYPE_IMAGE,
TFB_DRAWCOMMANDTYPE_FILLEDIMAGE,
TFB_DRAWCOMMANDTYPE_COPY, TFB_DRAWCOMMANDTYPE_COPY,
TFB_DRAWCOMMANDTYPE_COPYTOIMAGE, TFB_DRAWCOMMANDTYPE_COPYTOIMAGE,
@@ -31,6 +32,7 @@ enum
TFB_DRAWCOMMANDTYPE_SCISSORENABLE, TFB_DRAWCOMMANDTYPE_SCISSORENABLE,
TFB_DRAWCOMMANDTYPE_SCISSORDISABLE, TFB_DRAWCOMMANDTYPE_SCISSORDISABLE,
TFB_DRAWCOMMANDTYPE_SETPALETTE,
TFB_DRAWCOMMANDTYPE_DELETEIMAGE, TFB_DRAWCOMMANDTYPE_DELETEIMAGE,
TFB_DRAWCOMMANDTYPE_SENDSIGNAL, TFB_DRAWCOMMANDTYPE_SENDSIGNAL,
}; };
@@ -46,14 +48,14 @@ typedef struct tfb_drawcommand
int r; int r;
int g; int g;
int b; int b;
TFB_Palette Palette[256]; int index;
BOOLEAN UsePalette;
BOOLEAN UseScaling;
int BlendNumerator; int BlendNumerator;
int BlendDenominator; int BlendDenominator;
DWORD thread; DWORD thread;
SCREEN srcBuffer; SCREEN srcBuffer;
SCREEN destBuffer; SCREEN destBuffer;
BOOLEAN UsePalette;
BOOLEAN UseScaling;
} TFB_DrawCommand; } TFB_DrawCommand;
+71 -2
View File
@@ -100,6 +100,40 @@ TFB_Draw_Rect (PRECT rect, int r, int g, int b, SCREEN dest)
TFB_EnqueueDrawCommand (&DC); TFB_EnqueueDrawCommand (&DC);
} }
void
TFB_Draw_SetPalette (int index, int r, int g, int b)
{
TFB_DrawCommand DC;
DC.Type = TFB_DRAWCOMMANDTYPE_SETPALETTE;
DC.r = r;
DC.g = g;
DC.b = b;
DC.index = index;
DC.image = 0;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC);
}
/* This value is protected by the DCQ's lock. */
static int _localpal[256][3];
void
TFB_FlushPaletteCache ()
{
int i;
Lock_DCQ (-1);
for (i = 0; i < 256; i++)
{
_localpal[i][0] = -1;
_localpal[i][1] = -1;
_localpal[i][2] = -1;
}
Unlock_DCQ ();
}
void void
TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette *palette, SCREEN dest) TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette *palette, SCREEN dest)
{ {
@@ -113,15 +147,29 @@ TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette
if (palette != NULL) if (palette != NULL)
{ {
int i; int i, changed;
Lock_DCQ(257);
changed = 0;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
DC.Palette[i] = palette[i]; if ((_localpal[i][0] != palette[i].r) ||
(_localpal[i][1] != palette[i].g) ||
(_localpal[i][2] != palette[i].b))
{
changed++;
_localpal[i][0] = palette[i].r;
_localpal[i][1] = palette[i].g;
_localpal[i][2] = palette[i].b;
TFB_Draw_SetPalette (i, palette[i].r, palette[i].g,
palette[i].b);
}
} }
// if (changed) { fprintf (stderr, "Actually changing palette! "); }
DC.UsePalette = TRUE; DC.UsePalette = TRUE;
} }
else else
{ {
Lock_DCQ (1);
DC.UsePalette = FALSE; DC.UsePalette = FALSE;
} }
@@ -129,6 +177,27 @@ TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette
DC.BlendNumerator = BlendNumerator; DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator; DC.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC);
Unlock_DCQ ();
}
void
TFB_Draw_FilledImage (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, int r, int g, int b, SCREEN dest)
{
TFB_DrawCommand DC;
DC.Type = TFB_DRAWCOMMANDTYPE_FILLEDIMAGE;
DC.image = img;
DC.x = x;
DC.y = y;
DC.UseScaling = scaled;
DC.r = r;
DC.g = g;
DC.b = b;
DC.destBuffer = dest;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC); TFB_EnqueueDrawCommand (&DC);
} }
@@ -93,9 +93,13 @@ void TFB_Draw_Line (int x1, int y1, int x2, int y2, int r, int g, int b, SCREEN
void TFB_Draw_Rect (PRECT rect, int r, int g, int b, SCREEN dest); void TFB_Draw_Rect (PRECT rect, int r, int g, int b, SCREEN dest);
void TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette *palette, SCREEN dest); void TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette *palette, SCREEN dest);
void TFB_Draw_Copy (PRECT r, SCREEN src, SCREEN dest); void TFB_Draw_Copy (PRECT r, SCREEN src, SCREEN dest);
void TFB_Draw_FilledImage (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, int r, int g, int b, SCREEN dest);
void TFB_Draw_CopyToImage (TFB_ImageStruct *img, PRECT lpRect, SCREEN src); void TFB_Draw_CopyToImage (TFB_ImageStruct *img, PRECT lpRect, SCREEN src);
void TFB_Draw_DeleteImage (TFB_ImageStruct *img); void TFB_Draw_DeleteImage (TFB_ImageStruct *img);
void TFB_Draw_WaitForSignal (void); void TFB_Draw_WaitForSignal (void);
void TFB_Draw_SetPalette (int index, int r, int g, int b);
void TFB_FlushPaletteCache (void);
void TFB_FlushGraphics (void); // Only call from main thread!! void TFB_FlushGraphics (void); // Only call from main thread!!
+21 -14
View File
@@ -44,12 +44,12 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE) if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
{ {
int x, y; int x, y;
BOOLEAN scaled, paletted; BOOLEAN scaled, paletted, filled;
TFB_Palette palette[256]; TFB_Palette palette[256];
x = pClipRect->corner.x - GetFrameHotX (_CurFramePtr); x = pClipRect->corner.x - GetFrameHotX (_CurFramePtr);
y = pClipRect->corner.y - GetFrameHotY (_CurFramePtr); y = pClipRect->corner.y - GetFrameHotY (_CurFramePtr);
scaled = FALSE; scaled = filled = FALSE;
if (gscale != 0 && gscale != 256) if (gscale != 0 && gscale != 256)
{ {
@@ -118,7 +118,7 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
if (GetPrimType (PrimPtr) == STAMPFILL_PRIM) if (GetPrimType (PrimPtr) == STAMPFILL_PRIM)
{ {
int i, r, g, b; int r, g, b;
DWORD c32k; DWORD c32k;
c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index
@@ -126,14 +126,11 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
g = (c32k >> (5 - (8 - 5))) & 0xF8; g = (c32k >> (5 - (8 - 5))) & 0xF8;
b = (c32k << (8 - 5)) & 0xF8; b = (c32k << (8 - 5)) & 0xF8;
for (i = 0; i < 256; ++i) palette[0].r = r;
{ palette[0].g = g;
palette[i].r = r; palette[0].b = b;
palette[i].g = g;
palette[i].b = b; filled = TRUE;
}
paletted = TRUE;
} }
else else
{ {
@@ -145,9 +142,19 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
} }
UnlockMutex (img->mutex); UnlockMutex (img->mutex);
TFB_Draw_Image ((TFB_ImageStruct *)img, x, y, scaled, if (filled)
(paletted ? palette : NULL), {
TFB_SCREEN_MAIN); TFB_Draw_FilledImage ((TFB_ImageStruct *)img, x, y,
scaled, palette[0].r,
palette[0].g, palette[0].b,
TFB_SCREEN_MAIN);
}
else
{
TFB_Draw_Image ((TFB_ImageStruct *)img, x, y, scaled,
(paletted ? palette : NULL),
TFB_SCREEN_MAIN);
}
} }
else else
{ {
+1 -9
View File
@@ -22,6 +22,7 @@
#include "libs/threadlib.h" #include "libs/threadlib.h"
#include "SDL_thread.h" #include "SDL_thread.h"
#include "libs/graphics/drawcmd.h" #include "libs/graphics/drawcmd.h"
#include "libs/graphics/sdl/dcqueue.h"
Semaphore DCQ_sem; Semaphore DCQ_sem;
@@ -29,15 +30,6 @@ Semaphore DCQ_sem;
static int DCQ_locking_depth = 0; static int DCQ_locking_depth = 0;
static Uint32 DCQ_locking_thread = 0; static Uint32 DCQ_locking_thread = 0;
// Maximum size of the DCQ. The larger the DCQ, the larger frameskips
// become tolerable before initiating livelock deterrence and game
// slowdown. Other constants for controlling the frameskip/slowdown
// balance may be found in sdl_common.c near TFB_FlushGraphics.
#ifdef DCQ_OF_DOOM
#define DCQ_MAX 512
#else
#define DCQ_MAX 16384
#endif
TFB_DrawCommand DCQ[DCQ_MAX]; TFB_DrawCommand DCQ[DCQ_MAX];
TFB_DrawCommandQueue DrawCommandQueue; TFB_DrawCommandQueue DrawCommandQueue;
+31 -1
View File
@@ -19,5 +19,35 @@
#ifndef DCQUEUE_H #ifndef DCQUEUE_H
#define DCQUEUE_H #define DCQUEUE_H
/* This is all in drawcmd.h now. */ // Maximum size of the DCQ. The larger the DCQ, the larger frameskips
// become tolerable before initiating livelock deterrence and game
// slowdown. Other constants for controlling the frameskip/slowdown
// balance may be found in sdl_common.c near TFB_FlushGraphics.
// Livelock deterrance constants. Because the entire screen is rarely
// refreshed, we may not drop draw commands on the floor with abandon.
// Furthermore, if the main program is queuing commands at a speed
// comparable to our processing of the commands, we never finish and
// the game freezes. Thus, if the queue starts out larger than
// DCQ_FORCE_SLOWDOWN_SIZE, or DCQ_LIVELOCK_MAX commands find
// themselves being processed in one go, livelock deterrence is
// enabled, and TFB_FlushGraphics locks the DCQ until it has processed
// all entries. If batched but pending commands exceed DCQ_FORCE_BREAK_SIZE,
// a continuity break is performed. This will effectively slow down the
// game logic, a fate we seek to avoid - however, it seems to be unavoidable
// on slower machines. Even there, it's seems nonexistent outside of
// communications screens. --Michael
#ifdef DCQ_OF_DOOM
#define DCQ_MAX 512
#define DCQ_FORCE_SLOWDOWN_SIZE 128
#define DCQ_FORCE_BREAK_SIZE 512
#define DCQ_LIVELOCK_MAX 256
#else
#define DCQ_MAX 16384
#define DCQ_FORCE_SLOWDOWN_SIZE 4096
#define DCQ_FORCE_BREAK_SIZE 16384
#define DCQ_LIVELOCK_MAX 4096
#endif
#endif #endif
+54 -25
View File
@@ -39,6 +39,8 @@ SDL_Rect TransitionClipRect;
int GfxFlags = 0; int GfxFlags = 0;
static TFB_Palette palette[256];
int int
TFB_InitGraphics (int driver, int flags, int width, int height, int bpp) TFB_InitGraphics (int driver, int flags, int width, int height, int bpp)
{ {
@@ -76,6 +78,8 @@ TFB_InitGraphics (int driver, int flags, int width, int height, int bpp)
//if (flags & TFB_GFXFLAGS_FULLSCREEN) //if (flags & TFB_GFXFLAGS_FULLSCREEN)
// SDL_ShowCursor (SDL_DISABLE); // SDL_ShowCursor (SDL_DISABLE);
TFB_FlushPaletteCache ();
return 0; return 0;
} }
@@ -467,30 +471,6 @@ TFB_ComputeFPS ()
} }
} }
// Livelock deterrance constants. Because the entire screen is rarely
// refreshed, we may not drop draw commands on the floor with abandon.
// Furthermore, if the main program is queuing commands at a speed
// comparable to our processing of the commands, we never finish and
// the game freezes. Thus, if the queue starts out larger than
// DCQ_FORCE_SLOWDOWN_SIZE, or DCQ_LIVELOCK_MAX commands find
// themselves being processed in one go, livelock deterrence is
// enabled, and TFB_FlushGraphics locks the DCQ until it has processed
// all entries. If batched but pending commands exceed DCQ_FORCE_BREAK_SIZE,
// a continuity break is performed. This will effectively slow down the
// game logic, a fate we seek to avoid - however, it seems to be unavoidable
// on slower machines. Even there, it's seems nonexistent outside of
// communications screens. --Michael
#ifdef DCQ_OF_DOOM
#define DCQ_FORCE_SLOWDOWN_SIZE 128
#define DCQ_FORCE_BREAK_SIZE 512
#define DCQ_LIVELOCK_MAX 256
#else
#define DCQ_FORCE_SLOWDOWN_SIZE 1024
#define DCQ_FORCE_BREAK_SIZE 4096
#define DCQ_LIVELOCK_MAX 2048
#endif
void void
TFB_FlushGraphics () // Only call from main thread!! TFB_FlushGraphics () // Only call from main thread!!
{ {
@@ -568,6 +548,21 @@ TFB_FlushGraphics () // Only call from main thread!!
switch (DC.Type) switch (DC.Type)
{ {
case TFB_DRAWCOMMANDTYPE_SETPALETTE:
{
int index = DC.index;
if (index < 0 || index > 255)
{
fprintf(stderr, "DCQ panic: Tried to set palette #%i", index);
}
else
{
palette[index].r = DC.r & 0xFF;
palette[index].g = DC.g & 0xFF;
palette[index].b = DC.b & 0xFF;
}
break;
}
case TFB_DRAWCOMMANDTYPE_IMAGE: case TFB_DRAWCOMMANDTYPE_IMAGE:
{ {
SDL_Rect targetRect; SDL_Rect targetRect;
@@ -592,7 +587,7 @@ TFB_FlushGraphics () // Only call from main thread!!
{ {
if (DC.UsePalette) if (DC.UsePalette)
{ {
SDL_SetColors (surf, (SDL_Color*)DC.Palette, 0, 256); SDL_SetColors (surf, (SDL_Color*)palette, 0, 256);
} }
else else
{ {
@@ -602,6 +597,40 @@ TFB_FlushGraphics () // Only call from main thread!!
TFB_BlitSurface(surf, NULL, SDL_Screens[DC.destBuffer], &targetRect, DC.BlendNumerator, DC.BlendDenominator); TFB_BlitSurface(surf, NULL, SDL_Screens[DC.destBuffer], &targetRect, DC.BlendNumerator, DC.BlendDenominator);
break;
}
case TFB_DRAWCOMMANDTYPE_FILLEDIMAGE:
{
SDL_Rect targetRect;
SDL_Surface *surf;
int i;
TFB_Palette pal[256];
if (DC_image == 0)
{
fprintf (stderr, "TFB_FlushGraphics(): error, DC_image == 0\n");
break;
}
targetRect.x = DC.x;
targetRect.y = DC.y;
if (DC.UseScaling)
surf = DC_image->ScaledImg;
else
surf = DC_image->NormalImg;
for (i = 0; i < 256; i++)
{
pal[i].r = DC.r;
pal[i].g = DC.g;
pal[i].b = DC.b;
}
SDL_SetColors (surf, (SDL_Color*)pal, 0, 256);
TFB_BlitSurface(surf, NULL, SDL_Screens[DC.destBuffer], &targetRect, DC.BlendNumerator, DC.BlendDenominator);
break; break;
} }
case TFB_DRAWCOMMANDTYPE_LINE: case TFB_DRAWCOMMANDTYPE_LINE: