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_RECTANGLE,
TFB_DRAWCOMMANDTYPE_IMAGE,
TFB_DRAWCOMMANDTYPE_FILLEDIMAGE,
TFB_DRAWCOMMANDTYPE_COPY,
TFB_DRAWCOMMANDTYPE_COPYTOIMAGE,
@@ -31,6 +32,7 @@ enum
TFB_DRAWCOMMANDTYPE_SCISSORENABLE,
TFB_DRAWCOMMANDTYPE_SCISSORDISABLE,
TFB_DRAWCOMMANDTYPE_SETPALETTE,
TFB_DRAWCOMMANDTYPE_DELETEIMAGE,
TFB_DRAWCOMMANDTYPE_SENDSIGNAL,
};
@@ -46,14 +48,14 @@ typedef struct tfb_drawcommand
int r;
int g;
int b;
TFB_Palette Palette[256];
BOOLEAN UsePalette;
BOOLEAN UseScaling;
int index;
int BlendNumerator;
int BlendDenominator;
DWORD thread;
SCREEN srcBuffer;
SCREEN destBuffer;
BOOLEAN UsePalette;
BOOLEAN UseScaling;
} 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);
}
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
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)
{
int i;
int i, changed;
Lock_DCQ(257);
changed = 0;
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;
}
else
{
Lock_DCQ (1);
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.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);
}
@@ -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_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_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_DeleteImage (TFB_ImageStruct *img);
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!!
+21 -14
View File
@@ -44,12 +44,12 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
{
int x, y;
BOOLEAN scaled, paletted;
BOOLEAN scaled, paletted, filled;
TFB_Palette palette[256];
x = pClipRect->corner.x - GetFrameHotX (_CurFramePtr);
y = pClipRect->corner.y - GetFrameHotY (_CurFramePtr);
scaled = FALSE;
scaled = filled = FALSE;
if (gscale != 0 && gscale != 256)
{
@@ -118,7 +118,7 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
if (GetPrimType (PrimPtr) == STAMPFILL_PRIM)
{
int i, r, g, b;
int r, g, b;
DWORD c32k;
c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index
@@ -126,14 +126,11 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
g = (c32k >> (5 - (8 - 5))) & 0xF8;
b = (c32k << (8 - 5)) & 0xF8;
for (i = 0; i < 256; ++i)
{
palette[i].r = r;
palette[i].g = g;
palette[i].b = b;
}
paletted = TRUE;
palette[0].r = r;
palette[0].g = g;
palette[0].b = b;
filled = TRUE;
}
else
{
@@ -145,9 +142,19 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
}
UnlockMutex (img->mutex);
TFB_Draw_Image ((TFB_ImageStruct *)img, x, y, scaled,
(paletted ? palette : NULL),
TFB_SCREEN_MAIN);
if (filled)
{
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
{
+1 -9
View File
@@ -22,6 +22,7 @@
#include "libs/threadlib.h"
#include "SDL_thread.h"
#include "libs/graphics/drawcmd.h"
#include "libs/graphics/sdl/dcqueue.h"
Semaphore DCQ_sem;
@@ -29,15 +30,6 @@ Semaphore DCQ_sem;
static int DCQ_locking_depth = 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_DrawCommandQueue DrawCommandQueue;
+31 -1
View File
@@ -19,5 +19,35 @@
#ifndef 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
+54 -25
View File
@@ -39,6 +39,8 @@ SDL_Rect TransitionClipRect;
int GfxFlags = 0;
static TFB_Palette palette[256];
int
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)
// SDL_ShowCursor (SDL_DISABLE);
TFB_FlushPaletteCache ();
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
TFB_FlushGraphics () // Only call from main thread!!
{
@@ -568,6 +548,21 @@ TFB_FlushGraphics () // Only call from main thread!!
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:
{
SDL_Rect targetRect;
@@ -592,7 +587,7 @@ TFB_FlushGraphics () // Only call from main thread!!
{
if (DC.UsePalette)
{
SDL_SetColors (surf, (SDL_Color*)DC.Palette, 0, 256);
SDL_SetColors (surf, (SDL_Color*)palette, 0, 256);
}
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);
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;
}
case TFB_DRAWCOMMANDTYPE_LINE: