]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
two-step: Speed up background-tile drawing on HiDPI screens
authorHans de Goede <hdegoede@redhat.com>
Wed, 7 Nov 2018 19:27:08 +0000 (20:27 +0100)
committerHans de Goede <hdegoede@redhat.com>
Tue, 27 Nov 2018 07:48:56 +0000 (08:48 +0100)
Before this commit background drawing on HiDPI screens is quite slow
and CPU intensive, because we do the interpolating scale, which does
a whole bunch of double-precision float operations for *each* pixel
for every frame we draw.

When using two-step with a background-tile on a Cherry Trail machine with
a HiDPI screen this results in the diskcrypt password entry being visible
laggy, I can type the password much faster then the bullets show up.

This also means we are pegging the CPU during boot, significantly slowing
down the boot.

This commit fixes this by creating the background_buffer at the screen's
device_scale and rotation, only doing the scaling once.

This commit further speeds things up by also doing the solid/gradient fill
of the background + the alpha blend of the tiled background-image once,
creating a solid background which allows us to hit the
ply_pixel_buffer_fill_with_buffer memcpy fast-path and avoids the need to
re-do the solid/gradient fill + alpha-blend each frame we render.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
src/plugins/splash/two-step/plugin.c

index efdcaa90e169f5ff5c72322e8f36c951f7c225eb..65586f9418a6bb53798bba45f4f30642809c39ed 100644 (file)
@@ -245,17 +245,38 @@ view_load_end_animation (view_t *view)
 static bool
 view_load (view_t *view)
 {
-        unsigned long screen_width, screen_height;
+        unsigned long screen_width, screen_height, screen_scale;
         ply_boot_splash_plugin_t *plugin;
+        ply_pixel_buffer_t *buffer;
 
         plugin = view->plugin;
 
         screen_width = ply_pixel_display_get_width (view->display);
         screen_height = ply_pixel_display_get_height (view->display);
 
+        buffer = ply_renderer_get_buffer_for_head(
+                        ply_pixel_display_get_renderer (view->display),
+                        ply_pixel_display_get_renderer_head (view->display));
+        screen_scale = ply_pixel_buffer_get_device_scale (buffer);
+
         if (plugin->background_tile_image != NULL) {
                 ply_trace ("tiling background to %lux%lu", screen_width, screen_height);
-                view->background_buffer = ply_pixel_buffer_tile (ply_image_get_buffer (plugin->background_tile_image), screen_width, screen_height);
+
+                /* Create a buffer at screen scale so that we only do the slow interpolating scale once */
+                view->background_buffer = ply_pixel_buffer_new (screen_width * screen_scale, screen_height * screen_scale);
+                ply_pixel_buffer_set_device_scale (view->background_buffer, screen_scale);
+
+                if (plugin->background_start_color != plugin->background_end_color)
+                        ply_pixel_buffer_fill_with_gradient (view->background_buffer, NULL,
+                                                             plugin->background_start_color,
+                                                             plugin->background_end_color);
+                else
+                        ply_pixel_buffer_fill_with_hex_color (view->background_buffer, NULL,
+                                                              plugin->background_start_color);
+
+                buffer = ply_pixel_buffer_tile (ply_image_get_buffer (plugin->background_tile_image), screen_width, screen_height);
+                ply_pixel_buffer_fill_with_buffer (view->background_buffer, buffer, 0, 0);
+                ply_pixel_buffer_free (buffer);
         }
 
         if (plugin->watermark_image != NULL) {
@@ -874,7 +895,9 @@ draw_background (view_t             *view,
         area.width = width;
         area.height = height;
 
-        if (plugin->background_start_color != plugin->background_end_color)
+        if (view->background_buffer != NULL)
+                ply_pixel_buffer_fill_with_buffer (pixel_buffer, view->background_buffer, 0, 0);
+        else if (plugin->background_start_color != plugin->background_end_color)
                 ply_pixel_buffer_fill_with_gradient (pixel_buffer, &area,
                                                      plugin->background_start_color,
                                                      plugin->background_end_color);
@@ -882,17 +905,6 @@ draw_background (view_t             *view,
                 ply_pixel_buffer_fill_with_hex_color (pixel_buffer, &area,
                                                       plugin->background_start_color);
 
-        if (view->background_buffer != NULL) {
-                uint32_t *data;
-                data = ply_pixel_buffer_get_argb32_data (view->background_buffer);
-
-                /* We must pass NULL as fill area, because the fill area
-                   must be sized as the image we're sourcing from, otherwise
-                   sampling does not work
-                */
-                ply_pixel_buffer_fill_with_argb32_data_with_clip (pixel_buffer, NULL, NULL, data);
-        }
-
         if (plugin->watermark_image != NULL) {
                 uint32_t *data;