Optimize thumbnail rendering
Massive responsivity gains have been achieved here. Rescaling performance doesn't seem to be particularly affected.
This commit is contained in:
parent
63955e881d
commit
ada67f044a
|
@ -254,8 +254,12 @@ draw_row(FivBrowser *self, cairo_t *cr, const Row *row)
|
||||||
border.top + extents.height + border.bottom);
|
border.top + extents.height + border.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_render_background(
|
// Performance optimization--specifically targeting the checkerboard.
|
||||||
style, cr, border.left, border.top, extents.width, extents.height);
|
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,
|
gtk_render_frame(style, cr, 0, 0,
|
||||||
border.left + extents.width + border.right,
|
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_width = round(scale_x * width);
|
||||||
int projected_height = round(scale_y * height);
|
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_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.
|
// pixman can take gamma into account when scaling, unlike Cairo.
|
||||||
struct pixman_f_transform xform_floating;
|
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,
|
// PIXMAN_a8r8g8b8_sRGB can be used for gamma-correct results,
|
||||||
// but it's an incredibly slow transformation
|
// 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,
|
pixman_image_t *src = pixman_image_create_bits(format, width, height,
|
||||||
(uint32_t *) cairo_image_surface_get_data(thumbnail),
|
(uint32_t *) cairo_image_surface_get_data(thumbnail),
|
||||||
|
|
13
fiv-io.c
13
fiv-io.c
|
@ -2366,9 +2366,15 @@ read_spng_thumbnail(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spng_ihdr ihdr = {};
|
struct spng_ihdr ihdr = {};
|
||||||
|
struct spng_trns trns = {};
|
||||||
spng_get_ihdr(ctx, &ihdr);
|
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_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);
|
cairo_status_t surface_status = cairo_surface_status(surface);
|
||||||
if (surface_status != CAIRO_STATUS_SUCCESS) {
|
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.
|
// pixman can be mildly abused to do this operation, but it won't be faster.
|
||||||
struct spng_trns trns = {};
|
if (may_be_translucent) {
|
||||||
if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA ||
|
|
||||||
ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA ||
|
|
||||||
!spng_get_trns(ctx, &trns)) {
|
|
||||||
for (size_t i = size / sizeof *data; i--; ) {
|
for (size_t i = size / sizeof *data; i--; ) {
|
||||||
const uint8_t *unit = (const uint8_t *) &data[i];
|
const uint8_t *unit = (const uint8_t *) &data[i];
|
||||||
uint32_t a = unit[3],
|
uint32_t a = unit[3],
|
||||||
|
|
Loading…
Reference in New Issue