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 <hdegoede@redhat.com>
This commit is contained in:
Hans de Goede 2018-11-07 20:27:08 +01:00
parent 9f3aff2e7c
commit e10ed13fff

View 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;