threaded start-up for fonts
This commit is contained in:
parent
f6f55f4337
commit
9b700c72b5
2 changed files with 147 additions and 7 deletions
|
|
@ -14,6 +14,9 @@ http://www.newbreedsoftware.com/tuxpaint/
|
|||
-----------------------
|
||||
* Splash screen appears earlier, along with the version info and cursor.
|
||||
|
||||
* Normal start-up time reduced by 11.4 seconds by splitting out font
|
||||
loading into a separate thread. You only wait if you want the text tool.
|
||||
(450 MHz Mac G4, 7200 RPM ATA disk, about 200 font files)
|
||||
|
||||
* Stamp tool improvements:
|
||||
------------------------
|
||||
|
|
|
|||
151
src/tuxpaint.c
151
src/tuxpaint.c
|
|
@ -38,6 +38,11 @@
|
|||
#define VIDEO_BPP 32 // might be fastest, if conversion funcs removed
|
||||
|
||||
|
||||
// plan to rip this out as soon as it is considered stable
|
||||
#ifndef NO_THREADS
|
||||
#define THREADED_FONTS
|
||||
#endif
|
||||
|
||||
/* Method for printing images: */
|
||||
|
||||
#define PRINTMETHOD_PS /* Direct to PostScript */
|
||||
|
|
@ -301,6 +306,23 @@ extern char* g_win32_getlocale(void);
|
|||
#define FNAME_EXTENSION ".bmp"
|
||||
#endif
|
||||
|
||||
#if defined(THREADED_FONTS) || defined(THREADED_STAMPS)
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_mutex.h"
|
||||
#else
|
||||
#define SDL_CreateThread(fn,vp) (void*)(long)(fn(vp))
|
||||
#define SDL_WaitThread(tid,rcp) do{(void)tid;(void)rcp;}while(0)
|
||||
#define SDL_Thread int
|
||||
#define SDL_mutex int
|
||||
#define SDL_CreateMutex() 0 // creates in released state
|
||||
#define SDL_DestroyMutex(lock)
|
||||
#define SDL_mutexP(lock) // take lock
|
||||
#define SDL_mutexV(lock) // release lock
|
||||
#endif
|
||||
|
||||
static SDL_Thread *font_thread;
|
||||
static volatile long font_thread_done;
|
||||
|
||||
#include "tools.h"
|
||||
#include "titles.h"
|
||||
#include "colors.h"
|
||||
|
|
@ -1745,7 +1767,10 @@ static void parse_font_style(style_info *si)
|
|||
if(!stumped)
|
||||
{
|
||||
stumped=1;
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("Font style parser stumped by \"%s\".\n", si->style);
|
||||
#endif
|
||||
}
|
||||
sp++; // bad: an unknown character
|
||||
}
|
||||
|
|
@ -1769,6 +1794,8 @@ static void groupfonts_range(style_info **base, int count)
|
|||
int boldmap[4] = {-1,-1,-1,-1};
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
if(count<1 || count>4)
|
||||
{
|
||||
printf("\n::::::: %d styles in %s:\n",count, base[0]->family);
|
||||
|
|
@ -1778,6 +1805,7 @@ while(i--)
|
|||
printf(" %s\n", base[i]->style);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
i = count;
|
||||
while(i--)
|
||||
|
|
@ -1880,16 +1908,22 @@ printf(" %s\n", base[i]->style);
|
|||
int b = boldmap[base[i]->boldness];
|
||||
if(b==-1)
|
||||
{
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("too many boldness levels, discarding: %s, %s\n", base[i]->family, base[i]->style);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
int spot = b ? TTF_STYLE_BOLD : 0;
|
||||
spot += base[i]->italic ? TTF_STYLE_ITALIC : 0;
|
||||
if(fi->filename[spot])
|
||||
{
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("duplicates, discarding: %s, %s\n", base[i]->family, base[i]->style);
|
||||
printf("b %d, spot %d\n", b, spot);
|
||||
printf("occupancy %p %p %p %p\n", fi->filename[0], fi->filename[1], fi->filename[2], fi->filename[3]);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
fi->filename[spot] = strdup(base[i]->filename);
|
||||
|
|
@ -1994,7 +2028,10 @@ static void groupfonts(void)
|
|||
qsort(user_font_families, num_font_families, sizeof user_font_families[0], compar_fontscore);
|
||||
if(user_font_families[0]->score < 0)
|
||||
printf("sorted the wrong way, or all fonts were crap\n");
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("Trim starting with %d families\n", num_font_families);
|
||||
#endif
|
||||
while(num_font_families>1 && user_font_families[num_font_families-1]->score < 0)
|
||||
{
|
||||
i = --num_font_families;
|
||||
|
|
@ -2012,7 +2049,10 @@ static void groupfonts(void)
|
|||
free(user_font_families[i]);
|
||||
user_font_families[i] = NULL;
|
||||
}
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("Trim ending with %d families\n", num_font_families);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2261,6 +2301,38 @@ static int charsize(char c);
|
|||
#define USEREVENT_TEXT_UPDATE 1
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __powerpc__
|
||||
// Ticks at 1/4 the memory bus clock (24.907667 MHz on Albert's Mac Cube)
|
||||
// This is good for 80-second diff or 160-second total.
|
||||
#define CLOCK_ASM(tbl) asm volatile("mftb %0" : "=r" (tbl))
|
||||
#define CLOCK_TYPE unsigned long
|
||||
#ifndef CLOCK_SPEED
|
||||
#warning Benchmark times are based on a 99.63 MHz memory bus.
|
||||
#define CLOCK_SPEED 24907667.0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
// get 6.25 MHz out of a 200 MHz Pentium-MMX
|
||||
#define CLOCK_ASM(tbl) asm volatile("rdtsc" : "=A" (tbl))
|
||||
#define CLOCK_TYPE unsigned long long
|
||||
#ifndef
|
||||
#warning Benchmark times are based on a 450 MHz CPU.
|
||||
#define CLOCK_SPEED 450000000.0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_ASM
|
||||
#warning No idea how to read CPU cycles for you, sorry.
|
||||
#define CLOCK_ASM(tbl)
|
||||
#define CLOCK_TYPE unsigned long
|
||||
#define CLOCK_SPEED 1000000000.0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* --- MAIN --- */
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
|
|
@ -2268,9 +2340,28 @@ int main(int argc, char * argv[])
|
|||
/* Set up locale support */
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
CLOCK_TYPE time1;
|
||||
CLOCK_ASM(time1);
|
||||
|
||||
/* Set up! */
|
||||
setup(argc, argv);
|
||||
|
||||
#if 0
|
||||
while(!font_thread_done)
|
||||
{
|
||||
// FIXME: should respond to quit events
|
||||
// FIXME: should have a read-depends memory barrier around here
|
||||
show_progress_bar();
|
||||
SDL_Delay(20);
|
||||
}
|
||||
SDL_WaitThread(font_thread, NULL);
|
||||
#endif
|
||||
|
||||
CLOCK_TYPE time2;
|
||||
CLOCK_ASM(time2);
|
||||
|
||||
printf("Start-up time: %.3f\n", (double)(time2-time1)/CLOCK_SPEED);
|
||||
|
||||
// Let the user know we're (nearly) ready now
|
||||
do_setcursor(cursor_arrow);
|
||||
playsound(0, SND_HARP, 1);
|
||||
|
|
@ -2766,9 +2857,10 @@ static void mainloop(void)
|
|||
update_screen_rect(&r_tools);
|
||||
|
||||
playsound(1, SND_CLICK, 0);
|
||||
|
||||
draw_tux_text(tool_tux[cur_tool], tool_tips[cur_tool], 1);
|
||||
|
||||
|
||||
// FIXME: this "if" is just plain gross
|
||||
if(cur_tool != TOOL_TEXT)
|
||||
draw_tux_text(tool_tux[cur_tool], tool_tips[cur_tool], 1);
|
||||
|
||||
/* Draw items for this tool: */
|
||||
|
||||
|
|
@ -2809,6 +2901,24 @@ static void mainloop(void)
|
|||
}
|
||||
else if (cur_tool == TOOL_TEXT)
|
||||
{
|
||||
if(!font_thread_done)
|
||||
{
|
||||
draw_colors(COLORSEL_DISABLE);
|
||||
draw_none();
|
||||
update_screen_rect(&r_toolopt);
|
||||
update_screen_rect(&r_ttoolopt);
|
||||
draw_tux_text(TUX_WAIT, "This is a slow computer with lots of fonts...", 1);
|
||||
while(!font_thread_done)
|
||||
{
|
||||
// FIXME: should respond to quit events
|
||||
// FIXME: should have a read-depends memory barrier around here
|
||||
show_progress_bar();
|
||||
SDL_Delay(20);
|
||||
}
|
||||
// FIXME: should kill this in any case
|
||||
SDL_WaitThread(font_thread, NULL);
|
||||
}
|
||||
draw_tux_text(tool_tux[cur_tool], tool_tips[cur_tool], 1);
|
||||
cur_thing = cur_font;
|
||||
num_things = num_font_families;
|
||||
thing_scroll = &font_scroll;
|
||||
|
|
@ -6167,7 +6277,10 @@ static int charset_works(TTF_Font *font, const char *s)
|
|||
SDL_Surface *tmp_surf = TTF_RenderUTF8_Blended(font, c, black);
|
||||
if(!tmp_surf)
|
||||
{
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("could not render \"%s\" font\n", TTF_FontFaceFamilyName(font));
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
surfs[count++] = tmp_surf;
|
||||
|
|
@ -6310,7 +6423,11 @@ static void tp_ftw(char *restrict const dir, unsigned dirlen, int rsrc,
|
|||
}
|
||||
|
||||
closedir(d);
|
||||
#if 1
|
||||
#ifndef THREADED_FONTS
|
||||
show_progress_bar();
|
||||
#endif
|
||||
#endif
|
||||
dir[dirlen] = '\0'; // repair it (clobbered for stat() call above)
|
||||
|
||||
if(file_names)
|
||||
|
|
@ -6347,7 +6464,11 @@ static void loadfont_callback(const char *restrict const dir, unsigned dirlen, t
|
|||
{
|
||||
while(i--)
|
||||
{
|
||||
#if 1
|
||||
#ifndef THREADED_FONTS
|
||||
show_progress_bar();
|
||||
#endif
|
||||
#endif
|
||||
int loadable = 0;
|
||||
const char *restrict const cp = strchr(files[i].str, '.');
|
||||
if(cp)
|
||||
|
|
@ -6411,13 +6532,19 @@ static void loadfont_callback(const char *restrict const dir, unsigned dirlen, t
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("Font missing critical chars: %s, %s, %s\n", files[i].str, family, style);
|
||||
#endif
|
||||
}
|
||||
TTF_CloseFont(font);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// THREADED_FONTS
|
||||
printf("could not open %s\n", files[i].str);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
free(files[i].str);
|
||||
|
|
@ -6635,9 +6762,10 @@ static void load_stamps(void)
|
|||
|
||||
|
||||
|
||||
static void load_user_fonts(void)
|
||||
static int load_user_fonts(void *vp)
|
||||
{
|
||||
char * homedirdir;
|
||||
(void)vp; // junk passed by threading library
|
||||
|
||||
loadfonts(DATA_PREFIX "fonts");
|
||||
|
||||
if (!no_system_fonts)
|
||||
|
|
@ -6671,11 +6799,15 @@ static void load_user_fonts(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
homedirdir = get_fname("fonts");
|
||||
char *homedirdir = get_fname("fonts");
|
||||
loadfonts(homedirdir);
|
||||
free(homedirdir);
|
||||
|
||||
groupfonts();
|
||||
|
||||
font_thread_done = 1;
|
||||
// FIXME: need a memory barrier here
|
||||
return 0; // useless, wanted by threading library
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -7456,6 +7588,9 @@ static void setup(int argc, char * argv[])
|
|||
|
||||
do_setcursor(cursor_watch);
|
||||
|
||||
font_thread = SDL_CreateThread(load_user_fonts, NULL);
|
||||
|
||||
// continuing on with the rest of the cursors...
|
||||
|
||||
cursor_hand = get_cursor(hand_bits, hand_mask_bits,
|
||||
hand_width, hand_height,
|
||||
|
|
@ -7697,9 +7832,11 @@ static void setup(int argc, char * argv[])
|
|||
|
||||
locale_font = load_locale_font(medium_font,18);
|
||||
|
||||
#if 0
|
||||
// put elsewhere for THREADED_FONTS
|
||||
/* Load user fonts, for the text tool */
|
||||
load_user_fonts();
|
||||
|
||||
#endif
|
||||
|
||||
if (!dont_load_stamps)
|
||||
load_stamps();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue