From 1f05c0eb100aa086725ded0fb7c342b505cfe4c5 Mon Sep 17 00:00:00 2001 From: skeezix Date: Fri, 4 Nov 2011 14:36:59 -0400 Subject: [PATCH] mmenu: background loading icons works nicely .. pretty fast, doesn't impact user speed much conf: setting bg icon loading to default on in the deployment mmenu.conf conf: did not yet set default to loading .desktops, still using .pnd for mmenu discovery .. overall a net speedup due to bg icon load, but even faster with .desktop --- deployment/etc/pandora/conf/mmenu.conf | 2 +- lib/pnd_desktop.c | 2 - minimenu/mmenu.c | 3 +- minimenu/mmenu.conf | 4 +- minimenu/mmui.c | 139 +++++++++++++++++++------ 5 files changed, 111 insertions(+), 39 deletions(-) diff --git a/deployment/etc/pandora/conf/mmenu.conf b/deployment/etc/pandora/conf/mmenu.conf index e56afed..7f9543b 100644 --- a/deployment/etc/pandora/conf/mmenu.conf +++ b/deployment/etc/pandora/conf/mmenu.conf @@ -19,7 +19,7 @@ skin_confname mmskin.conf pndrun /usr/pandora/scripts:./testdata/scripts # searchpath to locate "pnd_run.sh"; why aren't I looking in /etc/pandora/conf/apps for this? load_previews_now 0 # if >0, will try to load preview pics from pnds at boot time, not defer till later load_previews_later 1 # if >0, will try to load preview pics sometime (see defer_timer_ms as well) -load_icons_later 0 # if >0, will try to load icons after grid is showing, not during app scanning +load_icons_later 1 # if >0, will try to load icons after grid is showing, not during app scanning defer_icon_us 100000 # when background loading icons (load_icons_later), time between icon loadsa threaded_preview 0 # if 1, will try to load the preview in background, to avoid slowing up navigation loglevel 0 # 0 is debug, lots of crap; 3 is better, means 'errors only'. Output may screw up the wrapper! diff --git a/lib/pnd_desktop.c b/lib/pnd_desktop.c index 77d363a..d8c67c8 100644 --- a/lib/pnd_desktop.c +++ b/lib/pnd_desktop.c @@ -921,8 +921,6 @@ pnd_disco_t *pnd_parse_dotdesktop ( char *ddpath, unsigned int flags ) { p -> object_filename = strdup ( source ); } - fprintf ( stderr, "object %s /// src %s /// %s /// %s\n", ddpath, source, p -> object_path, p -> object_filename ); - // return disco-t return ( p ); } diff --git a/minimenu/mmenu.c b/minimenu/mmenu.c index 27b4e49..1c39c99 100644 --- a/minimenu/mmenu.c +++ b/minimenu/mmenu.c @@ -662,12 +662,13 @@ void applications_scan ( void ) { pnd_log ( pndn_debug, "Found pnd applications, and caching icons:\n" ); pnd_disco_t *iter = pnd_box_get_head ( g_active_apps ); unsigned int itercount = 0; + unsigned loadlater = pnd_conf_get_as_int_d ( g_conf, "minimenu.load_icons_later", 0 ); while ( iter ) { //pnd_log ( pndn_debug, " App: '%s'\n", IFNULL(iter->title_en,"No Name") ); // update cachescreen // ... every 5 filenames, just to avoid slowing it too much - if ( itercount % 5 == 0 ) { + if ( loadlater == 0 && itercount % 5 == 0 ) { ui_cachescreen ( 0 /* clear screen */, IFNULL(iter->title_en,"No Name") ); } diff --git a/minimenu/mmenu.conf b/minimenu/mmenu.conf index 64aa4c5..3902a21 100644 --- a/minimenu/mmenu.conf +++ b/minimenu/mmenu.conf @@ -19,12 +19,12 @@ skin_confname mmskin.conf pndrun /usr/pandora/scripts:./testdata/scripts # searchpath to locate "pnd_run.sh"; why aren't I looking in /etc/pandora/conf/apps for this? load_previews_now 0 # if >0, will try to load preview pics from pnds at boot time, not defer till later load_previews_later 0 # if >0, will try to load preview pics sometime (see defer_timer_ms as well) -load_icons_later 0 # if >0, will try to load icons after grid is showing, not during app scanning +load_icons_later 1 # if >0, will try to load icons after grid is showing, not during app scanning defer_icon_us 100000 # when background loading icons (load_icons_later), time between icon loadsa threaded_preview 0 # if 1, will try to load the preview in background, to avoid slowing up navigation loglevel 0 # 0 is debug, lots of crap; 3 is better, means 'errors only'. Output may screw up the wrapper! x11_present_sh /bin/pidof X # command to invoke to determine if X11 is running or not; expects a number on X is present. -disco_pnds 0 # if nonzero, will do application discovery on pnd-files +disco_pnds 1 # if nonzero, will do application discovery on pnd-files disco_dotdesktop 1 # if nonzero, will do application discovery on .desktop files disco_dotdesktop_all 0 # if nonzero, will include non-libpnd .desktop; if 0, just libpnd (pnd-found by pndnotifyd) will be included desktop_apps 1 # search the pnd standard desktop searchpath for apps diff --git a/minimenu/mmui.c b/minimenu/mmui.c index 25a9f3b..d0e0ce5 100644 --- a/minimenu/mmui.c +++ b/minimenu/mmui.c @@ -51,6 +51,10 @@ #define CHANGED_EVERYTHING (1<<4) /* redraw it all! */ unsigned int render_mask = CHANGED_EVERYTHING; +SDL_Thread *g_icon_thread = NULL; +unsigned char g_icon_thread_stop = 0; /* if !0 means thread should stop and maim app may block until it goes back to 0.. */ +unsigned char g_icon_thread_busy = 0; /* if !0 means thread is running right now */ + #define MIMETYPE_EXE "/usr/bin/file" /* check for file type prior to invocation */ /* SDL @@ -91,6 +95,8 @@ unsigned char ui_detail_hidden = 0; // if >0, detail panel is hidden static SDL_Surface *ui_scale_image ( SDL_Surface *s, unsigned int maxwidth, int maxheight ); // height -1 means ignore static int ui_selected_index ( void ); +static void ui_start_defered_icon_thread ( void ); +static void ui_stop_defered_icon_thread ( void ); unsigned char ui_setup ( void ) { @@ -1986,6 +1992,10 @@ void ui_push_ltrigger ( void ) { return; } + if ( g_icon_thread_busy ) { + ui_stop_defered_icon_thread(); + } + if ( ui_category > 0 ) { ui_category--; category_fs_restock ( g_categories [ ui_category ] ); @@ -2014,6 +2024,7 @@ void ui_push_ltrigger ( void ) { ui_rows_scrolled_down = 0; render_mask |= CHANGED_CATEGORY; + ui_start_defered_icon_thread(); return; } @@ -2025,6 +2036,10 @@ void ui_push_rtrigger ( void ) { return; } + if ( g_icon_thread_busy ) { + ui_stop_defered_icon_thread(); + } + unsigned int screen_width = ui_display_context.screen_width; unsigned int tab_width = pnd_conf_get_as_int ( g_conf, "tabs.tab_width" ); @@ -2053,6 +2068,7 @@ void ui_push_rtrigger ( void ) { ui_rows_scrolled_down = 0; render_mask |= CHANGED_CATEGORY; + ui_start_defered_icon_thread(); return; } @@ -2620,6 +2636,7 @@ void ui_touch_act ( unsigned int x, unsigned int y ) { render_mask |= CHANGED_CATEGORY; // rescan the dir category_fs_restock ( g_categories [ ui_category ] ); + ui_start_defered_icon_thread(); } break; @@ -2673,7 +2690,8 @@ int ui_threaded_timer ( pnd_disco_t *p ) { while ( 1 ) { // pause... - sleep ( delay_s ); + //sleep ( delay_s ); + SDL_Delay ( delay_s * 1000 ); // .. trigger SD check SDL_Event e; @@ -2708,20 +2726,8 @@ unsigned char ui_threaded_defered_preview ( pnd_disco_t *p ) { return ( 0 ); } -SDL_Thread *g_icon_thread = NULL; void ui_post_scan ( void ) { - // if deferred icon load, kick off the thread now - if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.load_icons_later", 0 ) == 1 ) { - - g_icon_thread = SDL_CreateThread ( (void*)ui_threaded_defered_icon, NULL ); - - if ( ! g_icon_thread ) { - pnd_log ( pndn_error, "ERROR: Couldn't create icon thread\n" ); - } - - } // deferred icon load - // reset view ui_selected = NULL; ui_rows_scrolled_down = 0; @@ -2764,43 +2770,72 @@ void ui_post_scan ( void ) { // redraw all render_mask |= CHANGED_EVERYTHING; + // if deferred icon load, kick off the thread now + if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.load_icons_later", 0 ) == 1 ) { + ui_start_defered_icon_thread(); + } // deferred icon load + return; } unsigned char ui_threaded_defered_icon ( void *p ) { extern pnd_box_handle g_active_apps; - pnd_box_handle h = g_active_apps; unsigned char maxwidth, maxheight; maxwidth = pnd_conf_get_as_int_d ( g_conf, "grid.icon_max_width", 50 ); maxheight = pnd_conf_get_as_int_d ( g_conf, "grid.icon_max_height", 50 ); - pnd_disco_t *iter = pnd_box_get_head ( h ); + pnd_disco_t *iter; + + g_icon_thread_busy = 1; + + // work at it in order within current category - while ( iter ) { + mm_appref_t *refiter = g_categories [ ui_category ] -> refs; + while ( refiter && ! g_icon_thread_stop ) { + iter = refiter -> ref; - // cache it - if ( iter -> pnd_icon_pos && - ! cache_icon ( iter, maxwidth, maxheight ) ) + // has an icon that is not already cached? + if ( ( iter -> pnd_icon_pos ) || + ( iter -> icon && iter -> object_flags & PND_DISCO_CUSTOM1 ) + ) { - pnd_log ( pndn_warning, " Couldn't load icon: '%s'\n", IFNULL(iter->title_en,"No Name") ); - } else { + + // try to cache it? + if ( ! cache_icon ( iter, maxwidth, maxheight ) ) { + //pnd_log ( pndn_warning, " Couldn't load icon: '%s'\n", IFNULL(iter->title_en,"No Name") ); - // trigger that we completed - SDL_Event e; - bzero ( &e, sizeof(SDL_Event) ); - e.type = SDL_USEREVENT; - e.user.code = sdl_user_finishedicon; - SDL_PushEvent ( &e ); + } else { - //pnd_log ( pndn_warning, " Finished deferred load icon: '%s'\n", IFNULL(iter->title_en,"No Name") ); - usleep ( pnd_conf_get_as_int_d ( g_conf, "minimenu.defer_icon_us", 50000 ) ); + // trigger that we completed + SDL_Event e; + bzero ( &e, sizeof(SDL_Event) ); + e.type = SDL_USEREVENT; + e.user.code = sdl_user_finishedicon; + SDL_PushEvent ( &e ); - } + //pnd_log ( pndn_warning, " Finished deferred load icon: '%s'\n", IFNULL(iter->title_en,"No Name") ); + //usleep ( pnd_conf_get_as_int_d ( g_conf, "minimenu.defer_icon_us", 50000 ) ); - // next - iter = pnd_box_get_next ( iter ); - } // while + } + + // avoid churn + iter -> pnd_icon_pos = 0; + if ( iter -> icon ) { + free ( iter -> icon ); + iter -> icon = NULL; + } + + // let user do something.. + SDL_Delay ( 200 ); + + } // has icon + + refiter = refiter -> next; + } + + // mark as done + g_icon_thread_busy = 0; return ( 0 ); } @@ -3184,6 +3219,7 @@ void ui_revealscreen ( void ) { // redraw tabs render_mask |= CHANGED_CATEGORY; + ui_start_defered_icon_thread(); return; } @@ -4230,3 +4266,40 @@ char *ui_pick_custom_category ( unsigned char mode ) { return ( foo ); } + +void ui_start_defered_icon_thread ( void ) { + + if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.load_icons_later", 0 ) == 0 ) { + return; + } + + if ( g_icon_thread_busy ) { + //fprintf ( stderr, "REM: Waiting for thread to stop..\n" ); + ui_stop_defered_icon_thread(); + } + + //fprintf ( stderr, "WARN: Starting new icon caching thread..\n" ); + g_icon_thread = SDL_CreateThread ( (void*)ui_threaded_defered_icon, NULL ); + + if ( ! g_icon_thread ) { + pnd_log ( pndn_error, "ERROR: Couldn't create icon thread\n" ); + } + + return; +} + +void ui_stop_defered_icon_thread ( void ) { + time_t started = time ( NULL ); + + // ask thread to stop, then wait for it (if two run at same time, or if we change + // category content under neath it, could be bad..) + g_icon_thread_stop = 1; + while ( g_icon_thread_busy ) { + time ( NULL ); // spin + } + g_icon_thread_stop = 0; + + fprintf ( stderr, "REM: Thread stoppage took %u seconds.\n", (int) ( time ( NULL ) - started ) ); + + return; +} -- 2.39.2