From abe9a86b4a227a1846cd043d28d0e9bc47a24992 Mon Sep 17 00:00:00 2001 From: gewlitys Date: Tue, 10 Sep 2002 20:41:18 +0000 Subject: [PATCH] threading patch git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@29 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/sc2code/libs/graphics/gfx_common.h | 3 +- sc2/src/sc2code/libs/graphics/sdl/3do_blt.c | 152 ++++++++++-------- sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c | 6 + .../sc2code/libs/graphics/sdl/sdl_common.c | 72 +++++++-- .../sc2code/libs/graphics/sdl/sdl_common.h | 4 +- sc2/src/sc2code/libs/input/sdl/input.c | 3 +- sc2/src/starcon2.c | 9 +- 7 files changed, 157 insertions(+), 92 deletions(-) diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.h b/sc2/src/sc2code/libs/graphics/gfx_common.h index a586f1cce..d203a6bd0 100644 --- a/sc2/src/sc2code/libs/graphics/gfx_common.h +++ b/sc2/src/sc2code/libs/graphics/gfx_common.h @@ -44,6 +44,7 @@ enum // flags for TFB_InitGraphics #define TFB_GFXFLAGS_FULLSCREEN (1<<0) #define TFB_GFXFLAGS_BILINEAR_FILTERING (1<<1) +#define TFB_GFXFLAGS_SHOWFPS (1<<2) int TFB_InitGraphics (int driver, int flags, int width, int height, int bpp); int TFB_CreateGamePlayThread (); @@ -106,7 +107,7 @@ typedef struct tfb_drawcommandqueue { int Front; int Back; - int Size; + volatile int Size; } TFB_DrawCommandQueue; TFB_DrawCommandQueue *TFB_DrawCommandQueue_Create (); diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c b/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c index 3dabc8051..817975e04 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c @@ -38,6 +38,9 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) } img = (TFB_Image *) ((BYTE *) SrcFramePtr + SrcFramePtr->DataOffs); + + if (SDL_mutexP(img->mutex)) + printf("blt(): couldn't lock img->mutex\n"); if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE) { @@ -46,92 +49,87 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) // DrawCommand = HMalloc (sizeof (TFB_DrawCommand)); - if (DrawCommand) + DrawCommand->Type = TFB_DRAWCOMMANDTYPE_IMAGE; + DrawCommand->x = pClipRect->corner.x - + GetFrameHotX (_CurFramePtr); + DrawCommand->y = pClipRect->corner.y - + GetFrameHotY (_CurFramePtr); + DrawCommand->w = img->SurfaceSDL->clip_rect.w; + DrawCommand->h = img->SurfaceSDL->clip_rect.h; + + if (gscale != 0 && gscale != 256) { - DrawCommand->Type = TFB_DRAWCOMMANDTYPE_IMAGE; - DrawCommand->x = pClipRect->corner.x - - GetFrameHotX (_CurFramePtr); - DrawCommand->y = pClipRect->corner.y - - GetFrameHotY (_CurFramePtr); - DrawCommand->w = img->SurfaceSDL->clip_rect.w; - DrawCommand->h = img->SurfaceSDL->clip_rect.h; + DrawCommand->x += (GetFrameHotX (SrcFramePtr) * + ((1 << 8) - gscale)) >> 8; + DrawCommand->y += (GetFrameHotY (SrcFramePtr) * + ((1 << 8) - gscale)) >> 8; + DrawCommand->w = (DrawCommand->w * gscale) >> 8; + DrawCommand->h = (DrawCommand->h * gscale) >> 8; - if (gscale != 0 && gscale != 256) + if (img->ScaledImg) { - DrawCommand->x += (GetFrameHotX (SrcFramePtr) * - ((1 << 8) - gscale)) >> 8; - DrawCommand->y += (GetFrameHotY (SrcFramePtr) * - ((1 << 8) - gscale)) >> 8; - DrawCommand->w = (DrawCommand->w * gscale) >> 8; - DrawCommand->h = (DrawCommand->h * gscale) >> 8; - - if (img->ScaledImg) + if (img->scale != gscale) { - if (img->scale != gscale) - { - SDL_FreeSurface(img->ScaledImg); - img->ScaledImg = NULL; - } + SDL_FreeSurface(img->ScaledImg); + img->ScaledImg = NULL; } + } - if (!img->ScaledImg) + if (!img->ScaledImg) + { + // Atleast melee zooming and planet surfaces will use this + + // NOTE: Planet surfaces maybe causes memory leaks, + // I haven't currently seen DELETEIMAGE executed to them at all. + // Also, we might want to change the way they are implemented, as + // currently the scaled img is like 1936x600x32bit so it takes + // much memory and is perhaps too slow to process on slower systems. + // -Mika + + SDL_Surface *new_surf; + + img->scale = gscale; + new_surf = zoomSurface (img->DrawableImg, gscale / 256.0f, + gscale / 256.0f, SMOOTHING_OFF); + + if (new_surf) { - // Atleast melee zooming and planet surfaces will use this + img->ScaledImg = TFB_DisplayFormatAlpha (new_surf); - // NOTE: Planet surfaces maybe causes memory leaks, - // I haven't currently seen DELETEIMAGE executed to them at all. - // Also, we might want to change the way they are implemented, as - // currently the scaled img is like 1936x600x32bit so it takes - // much memory and is perhaps too slow to process on slower systems. - // -Mika - - // TODO: does this need mutexes? - - SDL_Surface *new_surf; - - img->scale = gscale; - new_surf = zoomSurface (img->DrawableImg, gscale / 256.0f, - gscale / 256.0f, SMOOTHING_OFF); - - if (new_surf) + if (img->ScaledImg) { - img->ScaledImg = TFB_DisplayFormatAlpha (new_surf); - - if (img->ScaledImg) - { - SDL_FreeSurface(new_surf); - } - else - { - printf("blt(): TFB_DisplayFormatAlpha failed\n"); - img->ScaledImg = new_surf; - } + SDL_FreeSurface(new_surf); } else { - printf("blt(): zoomSurface failed\n"); + printf("blt(): TFB_DisplayFormatAlpha failed\n"); + img->ScaledImg = new_surf; } } + else + { + printf("blt(): zoomSurface failed\n"); + } } - - DrawCommand->image = (TFB_ImageStruct*) img; //TFB_Image - - if (GetPrimType (PrimPtr) == STAMPFILL_PRIM) - { - DWORD c32k; - - c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index - DrawCommand->r = (c32k >> (10 - (8 - 5))) & 0xF8; - DrawCommand->g = (c32k >> (5 - (8 - 5))) & 0xF8; - DrawCommand->b = (c32k << (8 - 5)); - } - - DrawCommand->Qualifier = (TYPE_GET (GetFrameParentDrawable ( - SrcFramePtr)->FlagsAndIndex) >> FTYPE_SHIFT) & - MAPPED_TO_DISPLAY; - - TFB_EnqueueDrawCommand(DrawCommand); } + + DrawCommand->image = (TFB_ImageStruct*) img; //TFB_Image + + if (GetPrimType (PrimPtr) == STAMPFILL_PRIM) + { + DWORD c32k; + + c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index + DrawCommand->r = (c32k >> (10 - (8 - 5))) & 0xF8; + DrawCommand->g = (c32k >> (5 - (8 - 5))) & 0xF8; + DrawCommand->b = (c32k << (8 - 5)); + } + + DrawCommand->Qualifier = (TYPE_GET (GetFrameParentDrawable ( + SrcFramePtr)->FlagsAndIndex) >> FTYPE_SHIFT) & + MAPPED_TO_DISPLAY; + + TFB_EnqueueDrawCommand(DrawCommand); } else { @@ -141,6 +139,9 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) dst_img = ((TFB_Image *) ((BYTE *) _CurFramePtr + _CurFramePtr->DataOffs)); + if (SDL_mutexP(dst_img->mutex)) + printf("blt(): couldn't lock dst_img->mutex\n"); + SDL_SrcRect.x = (short) img->SurfaceSDL->clip_rect.x; SDL_SrcRect.y = (short) img->SurfaceSDL->clip_rect.y; SDL_SrcRect.w = (short) img->SurfaceSDL->clip_rect.w; @@ -159,7 +160,13 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) ); dst_img->dirty = TRUE; + + if (SDL_mutexV(dst_img->mutex)) + printf("blt(): couldn't unlock dst_img->mutex\n"); } + + if (SDL_mutexV(img->mutex)) + printf("blt(): couldn't unlock img->mutex\n"); } static void @@ -212,6 +219,9 @@ fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) img = ((TFB_Image *) ((BYTE *) _CurFramePtr + _CurFramePtr->DataOffs)); + if (SDL_mutexP(img->mutex)) + printf("fillrect_blt(): couldn't lock img->mutex\n"); + SDLRect.x = (short) (pClipRect->corner.x - GetFrameHotX (_CurFramePtr)); SDLRect.y = (short) (pClipRect->corner.y - @@ -223,6 +233,8 @@ fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) img->dirty = TRUE; + if (SDL_mutexV(img->mutex)) + printf("fillrect_blt(): couldn't unlock img->mutex\n"); } } diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c b/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c index 21b90b79a..72aa454f3 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c @@ -293,6 +293,12 @@ SleepTask (DWORD wake_time) { DWORD t; + if (wake_time == 0) + { + SDL_Delay (5); + return (GetTimeCounter ()); + } + t = GetTimeCounter (); if (wake_time <= t) SDL_Delay (0); diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index cfdb5d30d..69de93a90 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -28,6 +28,7 @@ SDL_Surface *SDL_Video; SDL_Surface *SDL_Screen; SDL_Surface *ExtraScreen; +BOOLEAN ShowFPS = FALSE; volatile int continuity_break; @@ -54,6 +55,9 @@ TFB_InitGraphics (int driver, int flags, int width, int height, int bpp) SDL_EnableUNICODE (1); SDL_WM_SetCaption (TFB_WINDOW_CAPTION, NULL); + if (flags & TFB_GFXFLAGS_SHOWFPS) + ShowFPS = TRUE; + //if (flags & TFB_GFXFLAGS_FULLSCREEN) // SDL_ShowCursor (SDL_DISABLE); @@ -132,6 +136,7 @@ TFB_LoadImage (SDL_Surface *img) float y_scale = (float)ScreenHeightActual / ScreenHeight; myImage = (TFB_Image*) HMalloc (sizeof (TFB_Image)); + myImage->mutex = SDL_CreateMutex(); myImage->dirty = FALSE; myImage->ScaledImg = NULL; @@ -238,33 +243,56 @@ TFB_DisplayFormatAlpha (SDL_Surface *surface) return SDL_DisplayFormatAlpha (surface); } +void +TFB_ComputeFPS () +{ + static Uint32 last_time = 0, fps_counter = 0; + Uint32 current_time, delta_time; + + current_time = SDL_GetTicks (); + delta_time = current_time - last_time; + last_time = current_time; + + fps_counter += delta_time; + if (fps_counter > 1000) + { + fps_counter = 0; + printf ("fps %.2f\n",1.0 / (delta_time / 1000.0)); + } +} + void TFB_FlushGraphics () // Only call from main thread!! { int semval; - Uint32 this_flush; - static Uint32 last_flush = 0; - this_flush = SDL_GetTicks (); - if (this_flush - last_flush < 1000 / 100) - return; - - semval = SDL_SemTryWait (GraphicsSem); - if (semval != 0 && !continuity_break) - return; - - continuity_break = 0; if (DrawCommandQueue == 0 || DrawCommandQueue->Size == 0) { - if (semval == 0) - SDL_SemPost (GraphicsSem); + SDL_Delay(5); return; } - last_flush = this_flush; + if (!continuity_break) { + // TODO: a more optimal way of getting the lock on GraphicsSem.. + // cannot currently use SDL_SemWait because it would break + // the usage of continuity_break + + semval = SDL_SemWaitTimeout (GraphicsSem, 100); + if (semval != 0 && !continuity_break) + return; + continuity_break = 0; + + if (semval == 0) + SDL_SemPost (GraphicsSem); + } + else + { + continuity_break = 0; + } + + if (ShowFPS) + TFB_ComputeFPS (); - if (semval == 0) - SDL_SemPost (GraphicsSem); while (DrawCommandQueue->Size > 0) { @@ -280,6 +308,9 @@ TFB_FlushGraphics () // Only call from main thread!! } DC_image = (TFB_Image*) DC->image; + if (DC_image) + if (SDL_mutexP(DC_image->mutex)) + printf("TFB_FlushGraphics(): couldn't lock DC_image->mutex\n"); switch (DC->Type) { @@ -413,9 +444,18 @@ TFB_FlushGraphics () // Only call from main thread!! SDL_FreeSurface (DC_image->ScaledImg); } + if (SDL_mutexV(DC_image->mutex)) + printf("TFB_FlushGraphics(): couldn't unlock DC_image->mutex (DELETEIMAGE)\n"); + SDL_DestroyMutex (DC_image->mutex); + HFree (DC_image); + DC_image = 0; break; } + + if (DC_image) + if (SDL_mutexV(DC_image->mutex)) + printf("TFB_FlushGraphics(): couldn't unlock DC_image->mutex\n"); TFB_DeallocateDrawCommand (DC); } diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h index 2a6bc51ee..9b2842662 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h @@ -33,6 +33,7 @@ extern SDL_Surface *SDL_Screen; extern SDL_Surface *ExtraScreen; extern volatile int continuity_break; +extern BOOLEAN ShowFPS; void ScreenOrigin (FRAME Display, COORD sx, COORD sy); void LoadDisplay (PDISPLAY_INTERFACE *pDisplay); @@ -45,8 +46,9 @@ typedef struct tfb_image SDL_Surface *ScaledImg; int scale; // used with ScaledImg BOOLEAN dirty; // true if DrawableImg needs to be created again + SDL_mutex *mutex; UBYTE pad[sizeof(TFB_ImageStruct)-sizeof(SDL_Surface*)-sizeof(SDL_Surface*)- - sizeof(SDL_Surface*)-sizeof(int)-sizeof(BOOLEAN)]; + sizeof(SDL_Surface*)-sizeof(int)-sizeof(BOOLEAN)-sizeof(SDL_mutex*)]; } TFB_Image; TFB_Image *TFB_LoadImage (SDL_Surface *img); diff --git a/sc2/src/sc2code/libs/input/sdl/input.c b/sc2/src/sc2code/libs/input/sdl/input.c index 7e74a5a05..7c7eae37e 100644 --- a/sc2/src/sc2code/libs/input/sdl/input.c +++ b/sc2/src/sc2code/libs/input/sdl/input.c @@ -89,7 +89,8 @@ TFB_InitInput (int driver, int flags) void ProcessKeyboardEvent(const SDL_Event *Event) { - if(Event->key.keysym.sym == SDLK_BACKQUOTE) + if(Event->key.keysym.sym == SDLK_BACKQUOTE || + Event->key.keysym.sym == SDLK_WORLD_7) { exit(0); } diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index ff4576387..b37a1f084 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -49,17 +49,20 @@ main (int argc, char *argv[]) else if (!strcmp(argv[i],"-opengl")) { gfxdriver = TFB_GFXDRIVER_SDL_OPENGL; - gfxflags |= TFB_GFXFLAGS_BILINEAR_FILTERING; } - else if (!strcmp(argv[i],"-linear")) + else if (!strcmp(argv[i],"-bilinear")) { - gfxflags &= ~TFB_GFXFLAGS_BILINEAR_FILTERING; + gfxflags |= TFB_GFXFLAGS_BILINEAR_FILTERING; } else if (!strcmp(argv[i],"-frequency")) { i++; sscanf(argv[i],"%d",&frequency); } + else if (!strcmp(argv[i],"-fps")) + { + gfxflags |= TFB_GFXFLAGS_SHOWFPS; + } } TFB_InitGraphics (gfxdriver, gfxflags, width, height, bpp);