From: Hans de Goede Date: Wed, 7 Nov 2018 19:27:08 +0000 (+0100) Subject: two-step: Speed up background-tile drawing on HiDPI screens X-Git-Tag: 0.9.5~84^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e10ed13fffb59b7a7656227c8f77b93310c160cd;p=thirdparty%2Fplymouth.git two-step: Speed up background-tile drawing on HiDPI screens 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 --- diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c index efdcaa90..65586f94 100644 --- a/src/plugins/splash/two-step/plugin.c +++ b/src/plugins/splash/two-step/plugin.c @@ -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;