diff --git a/fiv-browser.c b/fiv-browser.c index 7759c3a..345913b 100644 --- a/fiv-browser.c +++ b/fiv-browser.c @@ -254,8 +254,12 @@ draw_row(FivBrowser *self, cairo_t *cr, const Row *row) border.top + extents.height + border.bottom); } - gtk_render_background( - style, cr, border.left, border.top, extents.width, extents.height); + // Performance optimization--specifically targeting the checkerboard. + if (cairo_image_surface_get_format(item->entry->thumbnail) != + CAIRO_FORMAT_RGB24) { + gtk_render_background(style, cr, border.left, border.top, + extents.width, extents.height); + } gtk_render_frame(style, cr, 0, 0, border.left + extents.width + border.right, @@ -306,8 +310,9 @@ rescale_thumbnail(cairo_surface_t *thumbnail, double row_height) int projected_width = round(scale_x * width); int projected_height = round(scale_y * height); + cairo_format_t cairo_format = cairo_image_surface_get_format(thumbnail); cairo_surface_t *scaled = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, projected_width, projected_height); + cairo_format, projected_width, projected_height); // pixman can take gamma into account when scaling, unlike Cairo. struct pixman_f_transform xform_floating; @@ -315,7 +320,8 @@ rescale_thumbnail(cairo_surface_t *thumbnail, double row_height) // PIXMAN_a8r8g8b8_sRGB can be used for gamma-correct results, // but it's an incredibly slow transformation - pixman_format_code_t format = PIXMAN_a8r8g8b8; + pixman_format_code_t format = + cairo_format == CAIRO_FORMAT_RGB24 ? PIXMAN_x8r8g8b8 : PIXMAN_a8r8g8b8; pixman_image_t *src = pixman_image_create_bits(format, width, height, (uint32_t *) cairo_image_surface_get_data(thumbnail), diff --git a/fiv-io.c b/fiv-io.c index 7b83a09..a78d9c9 100644 --- a/fiv-io.c +++ b/fiv-io.c @@ -2366,9 +2366,15 @@ read_spng_thumbnail( } struct spng_ihdr ihdr = {}; + struct spng_trns trns = {}; spng_get_ihdr(ctx, &ihdr); + bool may_be_translucent = !spng_get_trns(ctx, &trns) || + ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA || + ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA; + cairo_surface_t *surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, ihdr.width, ihdr.height); + may_be_translucent ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, + ihdr.width, ihdr.height); cairo_status_t surface_status = cairo_surface_status(surface); if (surface_status != CAIRO_STATUS_SUCCESS) { @@ -2396,10 +2402,7 @@ read_spng_thumbnail( } // pixman can be mildly abused to do this operation, but it won't be faster. - struct spng_trns trns = {}; - if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA || - ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA || - !spng_get_trns(ctx, &trns)) { + if (may_be_translucent) { for (size_t i = size / sizeof *data; i--; ) { const uint8_t *unit = (const uint8_t *) &data[i]; uint32_t a = unit[3],