Patch: timed progressbar for plymouth-plugin-spinfinity | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] | |
Hi, This proof-of-concept patch adds a simple progress bar to plymouth's "Spinfinity" plugin. The progress bar uses an estimate of boot time - defaulting to 45 seconds if unknown - and runs from 0% to 100% over that interval. Furthermore, the patch measures how long it takes to boot and writes that value to /etc/boottime at plugin shutdown. (This is kind of a nice side-effect - we get actual *measured* boot speed data, rather than just "feels snappier!") There's an associated script, update-boottime, that crams /etc/boottime into your initrd, so this splash plugin can use *that* to more closely approximate the time required to boot. This is similar to the OS X "WaitingForLoginWindow" process. It's an effective placebo - startup *seems* faster with the progress bar, even though it's exactly the same. You can enable it by adding 'timebar:1' to the boot commandline. This will make it run in linear-time mode - the progress bar moves linearly from 0% to 100%. Using 'timebar:2' modifies the percentage calculation to use an exponential function - this makes the bar run faster at first, then slow as it approaches 100%. This makes startup seem even faster. Seriously! The bar (and its implementation) are kind of ugly right now, but again - this is just a proof-of-concept. I think people get impatient with spinners after ~15s or so, so I think it's probably worth the effort to add something like this. Don't underestimate the *perceived* difference in startup speed - or at least the feeling that it's actually Doing Something during those ~40-50 seconds it takes system(s) to start. Try it yourself. See if you think it makes a difference. If people ask, I'll generate some binary packages of the 'timebar' plugin for people to test out, but I wanted to give you all a look at the code (and a chance to discuss the concept) first. -w
Attachment:
update-boottime
Description: application/shellscript
diff -up plymouth-0.5.0/src/splash-plugins/spinfinity/plugin.c.timebar plymouth-0.5.0/src/splash-plugins/spinfinity/plugin.c
--- plymouth-0.5.0/src/splash-plugins/spinfinity/plugin.c.timebar 2008-06-21 00:13:43.000000000 -0400
+++ plymouth-0.5.0/src/splash-plugins/spinfinity/plugin.c 2008-07-17 13:30:51.000000000 -0400
@@ -18,6 +18,7 @@
* 02111-1307, USA.
*
* Written by: Ray Strode <rstrode@xxxxxxxxxx>
+ * Will Woods <wwoods@xxxxxxxxxx>
*/
#include "config.h"
@@ -58,6 +59,16 @@
#define FRAMES_PER_SECOND 30
#endif
+#ifndef BAR_HEIGHT
+#define BAR_HEIGHT 16
+#endif
+
+#ifndef DEFAULT_BOOTTIME
+#define DEFAULT_BOOTTIME 45.0
+#endif
+
+#define BOOTTIME_FILE "/etc/boottime"
+
typedef struct
{
int number_of_bullets;
@@ -68,7 +79,7 @@ struct _ply_boot_splash_plugin
{
ply_event_loop_t *loop;
ply_frame_buffer_t *frame_buffer;
- ply_frame_buffer_area_t box_area, lock_area, logo_area;
+ ply_frame_buffer_area_t box_area, lock_area, logo_area, bar_area;
ply_image_t *logo_image;
ply_image_t *bullet_image;
ply_image_t *lock_image;
@@ -79,6 +90,11 @@ struct _ply_boot_splash_plugin
entry_t *entry;
ply_throbber_t *throbber;
+ double boottime;
+ double starttime;
+ double waittime;
+ unsigned bar_mode; /* XXX remove when we decide on a mode */
+
ply_answer_t *pending_password_answer;
};
@@ -88,6 +104,7 @@ static void draw_password_entry (ply_boo
ply_boot_splash_plugin_t *
create_plugin (void)
{
+ FILE *fh;
ply_boot_splash_plugin_t *plugin;
srand ((int) ply_get_timestamp ());
@@ -102,6 +119,36 @@ create_plugin (void)
plugin->throbber = ply_throbber_new (PLYMOUTH_IMAGE_DIR "spinfinity",
"throbber-");
+ plugin->starttime = ply_get_timestamp ();
+ plugin->boottime = DEFAULT_BOOTTIME;
+ /* We should be reading from the initrd at this point */
+ fh = fopen(BOOTTIME_FILE,"r");
+ if (fh != NULL) {
+ int r;
+ r = fscanf (fh,"%lf",&plugin->boottime);
+ /* Don't need to check the return value - if this failed we still have
+ * the default BOOTTIME value, which was set above */
+ fclose (fh);
+ }
+ /* XXX REMOVE THIS WHEN WE DECIDE ON A PROPER METHOD */
+ plugin->bar_mode = 0; /* Default to "off" */
+ fh = fopen("/proc/cmdline","r");
+ if (fh != NULL) {
+ char cmdline[1024];
+ size_t r;
+ r = fread(cmdline,sizeof(char),sizeof(cmdline),fh);
+ fclose(fh);
+ if (r > 0) {
+ if (strstr(cmdline,"timebar:0") != NULL) /* No bar */
+ plugin->bar_mode = 0;
+ else if (strstr(cmdline,"timebar:1") != NULL) /* Linear bar */
+ plugin->bar_mode = 1;
+ else if (strstr(cmdline,"timebar:2") != NULL) /* Exponential bar */
+ plugin->bar_mode = 2;
+ }
+ }
+ /* XXX END TEST CODE */
+
return plugin;
}
@@ -132,6 +179,7 @@ entry_free (entry_t *entry)
void
destroy_plugin (ply_boot_splash_plugin_t *plugin)
{
+ FILE *boottime;
if (plugin == NULL)
return;
@@ -141,6 +189,15 @@ destroy_plugin (ply_boot_splash_plugin_t
ply_image_free (plugin->box_image);
ply_image_free (plugin->lock_image);
ply_throbber_free (plugin->throbber);
+
+ ply_trace ("writing boottime");
+ /* At this point we should have a real rootfs */
+ boottime = fopen (BOOTTIME_FILE,"w");
+ if (boottime != NULL) {
+ fprintf (boottime,"%.1f\n", (ply_get_timestamp () - plugin->starttime));
+ fclose (boottime);
+ }
+
free (plugin);
}
@@ -177,6 +234,52 @@ draw_logo (ply_boot_splash_plugin_t *plu
}
static void
+draw_bar (ply_boot_splash_plugin_t *plugin)
+{
+ long width, height;
+ double fraction;
+
+ height = BAR_HEIGHT; /* TODO: configurable */
+
+ ply_frame_buffer_get_size (plugin->frame_buffer, &plugin->bar_area);
+ plugin->bar_area.x = 0; /* possibly unnecessary, but hey.. can't hurt */
+ plugin->bar_area.y = plugin->bar_area.height - BAR_HEIGHT;
+ plugin->bar_area.height = BAR_HEIGHT;
+ /* XXX Remove when we decide on a mode */
+ if (plugin->bar_mode == 1)
+ fraction = (ply_get_timestamp () - plugin->starttime) / plugin->boottime;
+ else /* Shouldn't get here unless bar_mode is > 0 */
+ /* Fun made-up smoothing function to make the growth asymptotic:
+ * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */
+ fraction = 1.0-pow(2.0,-pow(ply_get_timestamp () - plugin->starttime,1.45)/plugin->boottime);
+ width = (long) (plugin->bar_area.width * fraction);
+ if (width < 0)
+ width = 0;
+ if (width < plugin->bar_area.width)
+ plugin->bar_area.width = width;
+ ply_frame_buffer_pause_updates (plugin->frame_buffer);
+ draw_background (plugin, &plugin->bar_area);
+ ply_frame_buffer_fill_with_hex_color (plugin->frame_buffer,
+ &plugin->bar_area,
+ 0xffffff); /* white */
+ ply_frame_buffer_unpause_updates (plugin->frame_buffer);
+}
+
+static void
+animate_bar (ply_boot_splash_plugin_t *plugin)
+{
+ assert (plugin != NULL);
+ assert (plugin->loop != NULL);
+ if (plugin->bar_mode == 0)
+ return;
+ draw_bar (plugin);
+ ply_event_loop_watch_for_timeout(plugin->loop,
+ 1.0 / FRAMES_PER_SECOND,
+ (ply_event_loop_timeout_handler_t)
+ animate_bar, plugin);
+}
+
+static void
start_animation (ply_boot_splash_plugin_t *plugin)
{
@@ -197,6 +300,7 @@ start_animation (ply_boot_splash_plugin_
plugin->window,
area.width / 2.0 - width / 2.0,
plugin->logo_area.y + plugin->logo_area.height + height / 2);
+ animate_bar (plugin);
}
static void
@@ -208,6 +312,9 @@ stop_animation (ply_boot_splash_plugin_t
assert (plugin->loop != NULL);
ply_throbber_stop (plugin->throbber);
+ ply_event_loop_stop_watching_for_timeout(plugin->loop,
+ (ply_event_loop_timeout_handler_t)
+ animate_bar, plugin);
#ifdef ENABLE_FADE_OUT
for (i = 0; i < 10; i++)
@@ -281,6 +388,7 @@ on_enter (ply_boot_splash_plugin_t *plug
plugin->entry = NULL;
}
+ plugin->starttime += (ply_get_timestamp() - plugin->waittime);
start_animation (plugin);
}
@@ -466,6 +574,7 @@ ask_for_password (ply_boot_splash_plugin
ply_answer_t *answer)
{
plugin->pending_password_answer = answer;
+ plugin->waittime = ply_get_timestamp ();
stop_animation (plugin);
show_password_entry (plugin);
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
-- Fedora-desktop-list mailing list Fedora-desktop-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/fedora-desktop-list
[Fedora Users] [Fedora Announce] [Fedora Legacy Announce] [Home] [Kernel] [Fedora Legacy] [Fedora Docs] [Fedora Config] [PAM] [Red Hat Development] [Red Hat 9 Bible] [Red Hat 9] [Big List of Linux Books] [Gimp] [Yosemite News]
![]() |
![]() |