DCQ optimization - phase 3 of 3

Replaced one big struct with tagged-union structure


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@564 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2003-01-18 20:15:12 +00:00
parent c26c318c7b
commit f585650073
5 changed files with 243 additions and 171 deletions
+1
View File
@@ -1,4 +1,5 @@
Changes towards version 0.2:
- Optimized DCQ to be much smaller and faster
- Added stat data in outfit screen (use --font=pc) - from Nic
- Added fixed introx.mod, from fOSSiL
- Fixed Orz .mod file, from fOSSiL
+80 -15
View File
@@ -37,27 +37,92 @@ enum
TFB_DRAWCOMMANDTYPE_SENDSIGNAL,
};
typedef struct tfb_drawcommand
typedef struct tfb_dc_line
{
int x1, y1, x2, y2;
int r, g, b;
SCREEN destBuffer;
} TFB_DrawCommand_Line;
typedef struct tfb_dc_rect
{
int x, y, w, h;
int r, g, b;
SCREEN destBuffer;
} TFB_DrawCommand_Rect;
typedef struct tfb_dc_img
{
int Type;
int x;
int y;
int w;
int h;
TFB_ImageStruct *image;
int r;
int g;
int b;
int index;
int BlendNumerator;
int BlendDenominator;
DWORD thread;
SCREEN srcBuffer;
int x, y;
int BlendNumerator, BlendDenominator;
SCREEN destBuffer;
BOOLEAN UsePalette;
BOOLEAN UseScaling;
} TFB_DrawCommand;
} TFB_DrawCommand_Image;
typedef struct tfb_dc_filledimg
{
TFB_ImageStruct *image;
int x, y;
int r, g, b;
int BlendNumerator, BlendDenominator;
SCREEN destBuffer;
BOOLEAN UseScaling;
} TFB_DrawCommand_FilledImage;
typedef struct tfb_dc_copy
{
int x, y, w, h;
int BlendNumerator, BlendDenominator;
SCREEN srcBuffer, destBuffer;
} TFB_DrawCommand_Copy;
typedef struct tfb_dc_copyimg
{
TFB_ImageStruct *image;
int x, y, w, h;
int BlendNumerator, BlendDenominator;
SCREEN srcBuffer;
} TFB_DrawCommand_CopyToImage;
typedef struct tfb_dc_scissor
{
int x, y, w, h;
} TFB_DrawCommand_Scissor;
typedef struct tfb_dc_setpal
{
int index;
int r, g, b;
} TFB_DrawCommand_SetPalette;
typedef struct tfb_dc_delimg
{
TFB_ImageStruct *image;
} TFB_DrawCommand_DeleteImage;
typedef struct tfb_dc_signal
{
DWORD thread;
} TFB_DrawCommand_SendSignal;
typedef struct tfb_drawcommand
{
int Type;
union {
TFB_DrawCommand_Line line;
TFB_DrawCommand_Rect rect;
TFB_DrawCommand_Image image;
TFB_DrawCommand_FilledImage filledimage;
TFB_DrawCommand_Copy copy;
TFB_DrawCommand_CopyToImage copytoimage;
TFB_DrawCommand_Scissor scissor;
TFB_DrawCommand_SetPalette setpalette;
TFB_DrawCommand_DeleteImage deleteimage;
TFB_DrawCommand_SendSignal sendsignal;
} data;
} TFB_DrawCommand;
// Queue Stuff
+56 -71
View File
@@ -51,19 +51,14 @@ TFB_Draw_Line (int x1, int y1, int x2, int y2, int r, int g, int b, SCREEN dest)
TFB_DrawCommand DC;
DC.Type = TFB_DRAWCOMMANDTYPE_LINE;
DC.x = x1;
DC.y = y1;
DC.w = x2;
DC.h = y2;
DC.r = r;
DC.g = g;
DC.b = b;
DC.image = 0;
DC.UsePalette = FALSE;
DC.destBuffer = dest;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
DC.data.line.x1 = x1;
DC.data.line.y1 = y1;
DC.data.line.x2 = x2;
DC.data.line.y2 = y2;
DC.data.line.r = r;
DC.data.line.g = g;
DC.data.line.b = b;
DC.data.line.destBuffer = dest;
TFB_EnqueueDrawCommand (&DC);
}
@@ -83,19 +78,14 @@ TFB_Draw_Rect (PRECT rect, int r, int g, int b, SCREEN dest)
}
DC.Type = TFB_DRAWCOMMANDTYPE_RECTANGLE;
DC.x = rect->corner.x;
DC.y = rect->corner.y;
DC.w = rect->extent.width;
DC.h = rect->extent.height;
DC.r = r;
DC.g = g;
DC.b = b;
DC.image = 0;
DC.UsePalette = FALSE;
DC.destBuffer = dest;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
DC.data.rect.x = rect->corner.x;
DC.data.rect.y = rect->corner.y;
DC.data.rect.w = rect->extent.width;
DC.data.rect.h = rect->extent.height;
DC.data.rect.r = r;
DC.data.rect.g = g;
DC.data.rect.b = b;
DC.data.rect.destBuffer = dest;
TFB_EnqueueDrawCommand (&DC);
}
@@ -106,13 +96,10 @@ 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;
DC.data.setpalette.r = r;
DC.data.setpalette.g = g;
DC.data.setpalette.b = b;
DC.data.setpalette.index = index;
TFB_EnqueueDrawCommand (&DC);
}
@@ -140,10 +127,10 @@ TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette
TFB_DrawCommand DC;
DC.Type = TFB_DRAWCOMMANDTYPE_IMAGE;
DC.image = img;
DC.x = x;
DC.y = y;
DC.UseScaling = scaled;
DC.data.image.image = img;
DC.data.image.x = x;
DC.data.image.y = y;
DC.data.image.UseScaling = scaled;
if (palette != NULL)
{
@@ -165,17 +152,17 @@ TFB_Draw_Image (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, TFB_Palette
}
}
// if (changed) { fprintf (stderr, "Actually changing palette! "); }
DC.UsePalette = TRUE;
DC.data.image.UsePalette = TRUE;
}
else
{
Lock_DCQ (1);
DC.UsePalette = FALSE;
DC.data.image.UsePalette = FALSE;
}
DC.destBuffer = dest;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
DC.data.image.destBuffer = dest;
DC.data.image.BlendNumerator = BlendNumerator;
DC.data.image.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC);
Unlock_DCQ ();
@@ -187,16 +174,16 @@ TFB_Draw_FilledImage (TFB_ImageStruct *img, int x, int y, BOOLEAN scaled, int r,
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;
DC.data.filledimage.image = img;
DC.data.filledimage.x = x;
DC.data.filledimage.y = y;
DC.data.filledimage.UseScaling = scaled;
DC.data.filledimage.r = r;
DC.data.filledimage.g = g;
DC.data.filledimage.b = b;
DC.data.filledimage.destBuffer = dest;
DC.data.filledimage.BlendNumerator = BlendNumerator;
DC.data.filledimage.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC);
}
@@ -207,15 +194,15 @@ TFB_Draw_CopyToImage (TFB_ImageStruct *img, PRECT lpRect, SCREEN src)
TFB_DrawCommand DC;
DC.Type = TFB_DRAWCOMMANDTYPE_COPYTOIMAGE;
DC.x = lpRect->corner.x;
DC.y = lpRect->corner.y;
DC.w = lpRect->extent.width;
DC.h = lpRect->extent.height;
DC.image = img;
DC.srcBuffer = src;
DC.data.copytoimage.x = lpRect->corner.x;
DC.data.copytoimage.y = lpRect->corner.y;
DC.data.copytoimage.w = lpRect->extent.width;
DC.data.copytoimage.h = lpRect->extent.height;
DC.data.copytoimage.image = img;
DC.data.copytoimage.srcBuffer = src;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
DC.data.copytoimage.BlendNumerator = BlendNumerator;
DC.data.copytoimage.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC);
}
@@ -235,16 +222,15 @@ TFB_Draw_Copy (PRECT r, SCREEN src, SCREEN dest)
}
DC.Type = TFB_DRAWCOMMANDTYPE_COPY;
DC.x = r->corner.x;
DC.y = r->corner.y;
DC.w = r->extent.width;
DC.h = r->extent.height;
DC.image = 0;
DC.srcBuffer = src;
DC.destBuffer = dest;
DC.data.copy.x = r->corner.x;
DC.data.copy.y = r->corner.y;
DC.data.copy.w = r->extent.width;
DC.data.copy.h = r->extent.height;
DC.data.copy.srcBuffer = src;
DC.data.copy.destBuffer = dest;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
DC.data.copy.BlendNumerator = BlendNumerator;
DC.data.copy.BlendDenominator = BlendDenominator;
TFB_EnqueueDrawCommand (&DC);
}
@@ -257,7 +243,7 @@ TFB_Draw_DeleteImage (TFB_ImageStruct *img)
TFB_DrawCommand DC;
DC.Type = TFB_DRAWCOMMANDTYPE_DELETEIMAGE;
DC.image = img;
DC.data.deleteimage.image = img;
TFB_EnqueueDrawCommand (&DC);
}
@@ -268,7 +254,6 @@ TFB_Draw_WaitForSignal (void)
{
TFB_DrawCommand DrawCommand;
DrawCommand.Type = TFB_DRAWCOMMANDTYPE_SENDSIGNAL;
DrawCommand.image = 0;
// We need to lock the mutex before enqueueing the DC to prevent races
LockSignalMutex ();
Lock_DCQ (1);
+16 -15
View File
@@ -231,7 +231,9 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
return;
}
DrawCommand->thread = CurrentThreadID ();
if (DrawCommand->Type == TFB_DRAWCOMMANDTYPE_SENDSIGNAL)
DrawCommand->data.sendsignal.thread = CurrentThreadID ();
if (DrawCommand->Type <= TFB_DRAWCOMMANDTYPE_COPYTOIMAGE
&& TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
{
@@ -250,20 +252,19 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
scissor_rect = _pCurContext->ClipRect;
DC.Type = scissor_rect.extent.width
? (DC.x = scissor_rect.corner.x,
DC.y=scissor_rect.corner.y,
DC.w=scissor_rect.extent.width,
DC.h=scissor_rect.extent.height),
TFB_DRAWCOMMANDTYPE_SCISSORENABLE
: TFB_DRAWCOMMANDTYPE_SCISSORDISABLE;
DC.image = 0;
DC.UsePalette = FALSE;
DC.BlendNumerator = BlendNumerator;
DC.BlendDenominator = BlendDenominator;
if (scissor_rect.extent.width)
{
DC.Type = TFB_DRAWCOMMANDTYPE_SCISSORENABLE;
DC.data.scissor.x = scissor_rect.corner.x;
DC.data.scissor.y = scissor_rect.corner.y;
DC.data.scissor.w = scissor_rect.extent.width;
DC.data.scissor.h = scissor_rect.extent.height;
}
else
{
DC.Type = TFB_DRAWCOMMANDTYPE_SCISSORDISABLE;
}
TFB_EnqueueDrawCommand(&DC);
}
}
+90 -70
View File
@@ -525,7 +525,6 @@ TFB_FlushGraphics () // Only call from main thread!!
while (!done)
{
TFB_DrawCommand DC;
TFB_Image *DC_image;
if (!TFB_DrawCommandQueue_Pop (&DC))
{
@@ -542,24 +541,20 @@ TFB_FlushGraphics () // Only call from main thread!!
Lock_DCQ (-1);
}
DC_image = (TFB_Image*) DC.image;
if (DC_image)
LockMutex (DC_image->mutex);
switch (DC.Type)
{
case TFB_DRAWCOMMANDTYPE_SETPALETTE:
{
int index = DC.index;
int index = DC.data.setpalette.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;
palette[index].r = DC.data.setpalette.r & 0xFF;
palette[index].g = DC.data.setpalette.g & 0xFF;
palette[index].b = DC.data.setpalette.b & 0xFF;
}
break;
}
@@ -567,25 +562,26 @@ TFB_FlushGraphics () // Only call from main thread!!
{
SDL_Rect targetRect;
SDL_Surface *surf;
TFB_Image *DC_image = (TFB_Image *)DC.data.image.image;
if (DC_image == 0)
{
fprintf (stderr, "TFB_FlushGraphics(): error, DC_image == 0\n");
fprintf (stderr, "DCQ ERROR: IMAGE passed null image ptr\n");
break;
}
targetRect.x = DC.x;
targetRect.y = DC.y;
LockMutex (DC_image->mutex);
targetRect.x = DC.data.image.x;
targetRect.y = DC.data.image.y;
if (DC.UseScaling)
if (DC.data.image.UseScaling)
surf = DC_image->ScaledImg;
else
surf = DC_image->NormalImg;
if (surf->format->palette)
{
if (DC.UsePalette)
if (DC.data.image.UsePalette)
{
SDL_SetColors (surf, (SDL_Color*)palette, 0, 256);
}
@@ -595,7 +591,8 @@ 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.data.image.destBuffer], &targetRect, DC.data.image.BlendNumerator, DC.data.image.BlendDenominator);
UnlockMutex (DC_image->mutex);
break;
}
@@ -605,32 +602,33 @@ TFB_FlushGraphics () // Only call from main thread!!
SDL_Surface *surf;
int i;
TFB_Palette pal[256];
TFB_Image *DC_image = (TFB_Image *)DC.data.filledimage.image;
if (DC_image == 0)
{
fprintf (stderr, "TFB_FlushGraphics(): error, DC_image == 0\n");
fprintf (stderr, "DCQ ERROR: FILLEDIMAGE passed null image ptr\n");
break;
}
LockMutex (DC_image->mutex);
targetRect.x = DC.x;
targetRect.y = DC.y;
targetRect.x = DC.data.filledimage.x;
targetRect.y = DC.data.filledimage.y;
if (DC.UseScaling)
if (DC.data.filledimage.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;
pal[i].r = DC.data.filledimage.r;
pal[i].g = DC.data.filledimage.g;
pal[i].b = DC.data.filledimage.b;
}
SDL_SetColors (surf, (SDL_Color*)pal, 0, 256);
TFB_BlitSurface(surf, NULL, SDL_Screens[DC.destBuffer], &targetRect, DC.BlendNumerator, DC.BlendDenominator);
TFB_BlitSurface(surf, NULL, SDL_Screens[DC.data.filledimage.destBuffer], &targetRect, DC.data.filledimage.BlendNumerator, DC.data.filledimage.BlendDenominator);
UnlockMutex (DC_image->mutex);
break;
}
case TFB_DRAWCOMMANDTYPE_LINE:
@@ -641,15 +639,20 @@ TFB_FlushGraphics () // Only call from main thread!!
PutPixelFn screen_plot;
screen_plot = putpixel_for (SDL_Screen);
color = SDL_MapRGB (SDL_Screen->format, DC.r, DC.g, DC.b);
color = SDL_MapRGB (SDL_Screen->format, DC.data.line.r, DC.data.line.g, DC.data.line.b);
x1 = DC.x;
x2 = DC.w;
y1 = DC.y;
y2 = DC.h;
x1 = DC.data.line.x1;
x2 = DC.data.line.x2;
y1 = DC.data.line.y1;
y2 = DC.data.line.y2;
SDL_GetClipRect(SDL_Screen, &r);
/* Danger, Will Robinson! This code
looks VERY suspicious. It will end
up changing the slope of the
line! */
if (x1 < r.x)
x1 = r.x;
else if (x1 > r.x + r.w)
@@ -670,30 +673,30 @@ TFB_FlushGraphics () // Only call from main thread!!
else if (y2 > r.y + r.h)
y2 = r.y + r.h;
SDL_LockSurface (SDL_Screens[DC.destBuffer]);
line (x1, y1, x2, y2, color, screen_plot, SDL_Screens[DC.destBuffer]);
SDL_UnlockSurface (SDL_Screens[DC.destBuffer]);
SDL_LockSurface (SDL_Screens[DC.data.line.destBuffer]);
line (x1, y1, x2, y2, color, screen_plot, SDL_Screens[DC.data.line.destBuffer]);
SDL_UnlockSurface (SDL_Screens[DC.data.line.destBuffer]);
break;
}
case TFB_DRAWCOMMANDTYPE_RECTANGLE:
{
SDL_Rect r;
r.x = DC.x;
r.y = DC.y;
r.w = DC.w;
r.h = DC.h;
r.x = DC.data.rect.x;
r.y = DC.data.rect.y;
r.w = DC.data.rect.w;
r.h = DC.data.rect.h;
SDL_FillRect(SDL_Screens[DC.destBuffer], &r, SDL_MapRGB(SDL_Screen->format, DC.r, DC.g, DC.b));
SDL_FillRect(SDL_Screens[DC.data.rect.destBuffer], &r, SDL_MapRGB(SDL_Screen->format, DC.data.rect.r, DC.data.rect.g, DC.data.rect.b));
break;
}
case TFB_DRAWCOMMANDTYPE_SCISSORENABLE:
{
SDL_Rect r;
r.x = DC.x;
r.y = DC.y;
r.w = DC.w;
r.h = DC.h;
r.x = DC.data.scissor.x;
r.y = DC.data.scissor.y;
r.w = DC.data.scissor.w;
r.h = DC.data.scissor.h;
SDL_SetClipRect(SDL_Screen, &r);
break;
@@ -704,50 +707,67 @@ TFB_FlushGraphics () // Only call from main thread!!
case TFB_DRAWCOMMANDTYPE_COPYTOIMAGE:
{
SDL_Rect src, dest;
src.x = dest.x = DC.x;
src.y = dest.y = DC.y;
src.w = DC.w;
src.h = DC.h;
TFB_Image *DC_image = (TFB_Image *)DC.data.copytoimage.image;
if (DC_image == 0)
{
fprintf (stderr, "DCQ ERROR: COPYTOIMAGE passed null image ptr\n");
break;
}
LockMutex (DC_image->mutex);
src.x = dest.x = DC.data.copytoimage.x;
src.y = dest.y = DC.data.copytoimage.y;
src.w = DC.data.copytoimage.w;
src.h = DC.data.copytoimage.h;
dest.x = 0;
dest.y = 0;
TFB_BlitSurface(SDL_Screens[DC.srcBuffer], &src, DC_image->NormalImg, &dest, DC.BlendNumerator, DC.BlendDenominator);
TFB_BlitSurface(SDL_Screens[DC.data.copytoimage.srcBuffer], &src, DC_image->NormalImg, &dest, DC.data.copytoimage.BlendNumerator, DC.data.copytoimage.BlendDenominator);
UnlockMutex (DC_image->mutex);
break;
}
case TFB_DRAWCOMMANDTYPE_COPY:
{
SDL_Rect src, dest;
src.x = dest.x = DC.x;
src.y = dest.y = DC.y;
src.w = DC.w;
src.h = DC.h;
src.x = dest.x = DC.data.copy.x;
src.y = dest.y = DC.data.copy.y;
src.w = DC.data.copy.w;
src.h = DC.data.copy.h;
TFB_BlitSurface(SDL_Screens[DC.srcBuffer], &src, SDL_Screens[DC.destBuffer], &dest, DC.BlendNumerator, DC.BlendDenominator);
TFB_BlitSurface(SDL_Screens[DC.data.copy.srcBuffer], &src, SDL_Screens[DC.data.copy.destBuffer], &dest, DC.data.copy.BlendNumerator, DC.data.copy.BlendDenominator);
break;
}
case TFB_DRAWCOMMANDTYPE_DELETEIMAGE:
SDL_FreeSurface (DC_image->NormalImg);
{
TFB_Image *DC_image = (TFB_Image *)DC.data.deleteimage.image;
if (DC_image == 0)
{
fprintf (stderr, "DCQ ERROR: DELETEIMAGE passed null image ptr\n");
break;
}
LockMutex (DC_image->mutex);
SDL_FreeSurface (DC_image->NormalImg);
if (DC_image->ScaledImg) {
//fprintf (stderr, "DELETEIMAGE to ScaledImg %x, size %d %d\n",DC_image->ScaledImg,DC_image->ScaledImg->w,DC_image->ScaledImg->h);
SDL_FreeSurface (DC_image->ScaledImg);
if (DC_image->ScaledImg) {
SDL_FreeSurface (DC_image->ScaledImg);
}
if (DC_image->Palette)
HFree (DC_image->Palette);
UnlockMutex (DC_image->mutex);
DestroyMutex (DC_image->mutex);
HFree (DC_image);
break;
}
if (DC_image->Palette)
HFree (DC_image->Palette);
UnlockMutex (DC_image->mutex);
DestroyMutex (DC_image->mutex);
HFree (DC_image);
DC_image = 0;
break;
case TFB_DRAWCOMMANDTYPE_SENDSIGNAL:
SignalThread (DC.thread);
SignalThread (DC.data.sendsignal.thread);
break;
}
if (DC_image)
UnlockMutex (DC_image->mutex);
}
if (livelock_deterrence)