]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[two-step] Add fade to progress animation
authorRay Strode <rstrode@redhat.com>
Sat, 2 May 2009 04:36:28 +0000 (00:36 -0400)
committerRay Strode <rstrode@redhat.com>
Wed, 20 May 2009 21:27:53 +0000 (17:27 -0400)
One issue with the two-step plugin is that during the initial boot
progress the frames can be updated several seconds apart from each
other.  This can look jumpy.  We can now optionally fade between
the frames to make the experience be a little smoother.

src/libplybootsplash/ply-progress-animation.c
src/libplybootsplash/ply-progress-animation.h
src/plugins/splash/two-step/plugin.c

index 3c006deaa045e4d55806d5f15f88af6bf683c7fd..9f3fbf2f65fcc3cb2d3a873786c199d6981dbf91 100644 (file)
@@ -57,19 +57,26 @@ struct _ply_progress_animation
   char *image_dir;
   char *frames_prefix;
 
+  ply_progress_animation_transition_t transition;
+  double transition_duration;
+
   ply_window_t            *window;
   ply_frame_buffer_t      *frame_buffer;
   ply_frame_buffer_area_t  area;
   ply_frame_buffer_area_t  frame_area;
 
   double percent_done;
+  int previous_frame_number;
+
+  double transition_start_time;
 
   uint32_t is_hidden : 1;
+  uint32_t is_transitioning : 1;
 };
 
 ply_progress_animation_t *
 ply_progress_animation_new (const char *image_dir,
-                    const char *frames_prefix)
+                            const char *frames_prefix)
 {
   ply_progress_animation_t *progress_animation;
 
@@ -91,10 +98,20 @@ ply_progress_animation_new (const char *image_dir,
   progress_animation->frame_area.y = 0;
   progress_animation->frame_area.width = 0;
   progress_animation->frame_area.height = 0;
+  progress_animation->previous_frame_number = 0;
 
   return progress_animation;
 }
 
+void
+ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
+                                       ply_progress_animation_transition_t transition,
+                                       double                    duration)
+{
+  progress_animation->transition = transition;
+  progress_animation->transition_duration = duration;
+}
+
 static void
 ply_progress_animation_remove_frames (ply_progress_animation_t *progress_animation)
 {
@@ -136,7 +153,7 @@ ply_progress_animation_draw (ply_progress_animation_t *progress_animation)
   int number_of_frames;
   int frame_number;
   ply_image_t * const * frames;
-  uint32_t *frame_data;
+  uint32_t *previous_frame_data, *frame_data;
 
   if (progress_animation->is_hidden)
     return;
@@ -154,6 +171,14 @@ ply_progress_animation_draw (ply_progress_animation_t *progress_animation)
   if (progress_animation->frame_area.width > 0)
     draw_background (progress_animation);
 
+  if (progress_animation->previous_frame_number != frame_number &&
+      progress_animation->transition != PLY_PROGRESS_ANIMATION_TRANSITION_NONE &&
+      progress_animation->transition_duration > 0.0)
+    {
+      progress_animation->is_transitioning = true;
+      progress_animation->transition_start_time = ply_get_timestamp ();
+    }
+
   frames = (ply_image_t * const *) ply_array_get_elements (progress_animation->frames);
 
   progress_animation->frame_area.x = progress_animation->area.x;
@@ -162,11 +187,42 @@ ply_progress_animation_draw (ply_progress_animation_t *progress_animation)
   progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]);
   frame_data = ply_image_get_data (frames[frame_number]);
 
-  ply_frame_buffer_fill_with_argb32_data (progress_animation->frame_buffer,
-                                          &progress_animation->frame_area, 0, 0,
-                                          frame_data);
+  if (progress_animation->is_transitioning)
+    {
+      double now;
+      double fade_percentage;
+      double fade_out_opacity;
+      now = ply_get_timestamp ();
+
+      fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration;
+
+      if (fade_percentage >= 1.0)
+        progress_animation->is_transitioning = false;
+      fade_percentage = CLAMP (fade_percentage, 0.0, 1.0);
+
+      previous_frame_data = ply_image_get_data (frames[frame_number - 1]);
+      if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER)
+        fade_out_opacity = 1.0;
+      else
+        fade_out_opacity = 1.0 - fade_percentage;
+
+      ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer,
+                                                         &progress_animation->frame_area, 0, 0,
+                                                         previous_frame_data, fade_out_opacity);
+      ply_frame_buffer_fill_with_argb32_data_at_opacity (progress_animation->frame_buffer,
+                                                         &progress_animation->frame_area, 0, 0,
+                                                         frame_data, fade_percentage);
+    }
+  else
+    {
+      ply_frame_buffer_fill_with_argb32_data (progress_animation->frame_buffer,
+                                              &progress_animation->frame_area, 0, 0,
+                                              frame_data);
+    }
 
   ply_frame_buffer_unpause_updates (progress_animation->frame_buffer);
+
+  progress_animation->previous_frame_number = frame_number;
 }
 
 static bool
index 2d337f83cfffe2279c4c118360313f4b1440730a..f199187fdc22003772510f80d85b46feee2fbfb4 100644 (file)
 
 typedef struct _ply_progress_animation ply_progress_animation_t;
 
+typedef enum
+{
+  PLY_PROGRESS_ANIMATION_TRANSITION_NONE,
+  PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER,
+  PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE,
+} ply_progress_animation_transition_t;
+
 #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
 ply_progress_animation_t *ply_progress_animation_new (const char *image_dir,
                                                       const char *frames_prefix);
 void ply_progress_animation_free (ply_progress_animation_t *progress_animation);
 
 bool ply_progress_animation_load (ply_progress_animation_t *progress_animation);
+void ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
+                                            ply_progress_animation_transition_t transition,
+                                            double                    duration);
 void ply_progress_animation_show (ply_progress_animation_t *progress_animation,
                                   ply_window_t             *window,
                                   long                      x,
index 0d32d58e9f39b8930a41e75aa3947245b16b7a34..88f2355a4553e7d4322d7c1cce8af05864ab1a80 100644 (file)
@@ -94,6 +94,9 @@ struct _ply_boot_splash_plugin
   double animation_vertical_alignment;
   char *animation_dir;
 
+  ply_progress_animation_transition_t transition;
+  double transition_duration;
+
   uint32_t background_start_color;
   uint32_t background_end_color;
 
@@ -114,6 +117,8 @@ create_plugin (ply_key_file_t *key_file)
   ply_boot_splash_plugin_t *plugin;
   char *image_dir, *image_path;
   char *alignment;
+  char *transition;
+  char *transition_duration;
   char *color;
 
   srand ((int) ply_get_timestamp ());
@@ -151,6 +156,25 @@ create_plugin (ply_key_file_t *key_file)
     plugin->animation_vertical_alignment = .5;
   free (alignment);
 
+
+  plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_NONE;
+  transition = ply_key_file_get_value (key_file, "two-step", "Transition");
+  if (transition != NULL)
+    {
+      if (strcmp (transition, "fade-over") == 0)
+        plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER;
+      else if (strcmp (transition, "cross-fade") == 0)
+        plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE;
+    }
+  free (transition);
+
+  transition_duration = ply_key_file_get_value (key_file, "two-step", "TransitionDuration");
+  if (transition_duration != NULL)
+    plugin->transition_duration = strtod (transition_duration, NULL);
+  else
+    plugin->transition_duration = 0.0;
+  free (transition_duration);
+
   color = ply_key_file_get_value (key_file, "two-step", "BackgroundStartColor");
 
   if (color != NULL)
@@ -471,6 +495,9 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
                                          "throbber-");
   plugin->progress_animation = ply_progress_animation_new (plugin->animation_dir,
                                                            "progress-");
+  ply_progress_animation_set_transition (plugin->progress_animation,
+                                         plugin->transition,
+                                         plugin->transition_duration);
 
   ply_trace ("loading lock image");
   if (!ply_image_load (plugin->lock_image))