summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>2019-10-12 08:58:23 +0200
committerEmmanuele Bassi <ebassi@gnome.org>2020-06-26 11:45:29 +0100
commit679e9ed7b056ec3b17921863b5c7d2873a43c3b3 (patch)
tree6aec31f93e2bf0d2b10642398a7c56183aa49e34 /gdk-pixbuf
parentc7eada6cac522d095fdd13770619d807ca538346 (diff)
downloadgdk-pixbuf-679e9ed7b056ec3b17921863b5c7d2873a43c3b3.tar.gz
pixops: Avoid division during alpha scaling
This patch significantly improves performance of gtksourceview-2.10.5 full-screen redraw on a 4K display with an alpha channel. Divisions by the common value 0xff0000 are converted into multiplications by an optimizing C compiler. For other values, 3 divisions are reduced to 1 division, 3 multiplications and some float-to-int conversions.
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/pixops/pixops.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
index a1c3c9bfd..623dbd09e 100644
--- a/gdk-pixbuf/pixops/pixops.c
+++ b/gdk-pixbuf/pixops/pixops.c
@@ -956,11 +956,20 @@ scale_pixel (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha,
{
if (src_has_alpha)
{
- if (a)
+ if (a == 0xff0000)
{
- dest[0] = r / a;
- dest[1] = g / a;
- dest[2] = b / a;
+ /* Division by a constant is converted into a multiplication by an optimizing C compiler */
+ dest[0] = r / 0xff0000;
+ dest[1] = g / 0xff0000;
+ dest[2] = b / 0xff0000;
+ dest[3] = 0xff0000 >> 16;
+ }
+ else if (a)
+ {
+ double a1 = 1.0 / a;
+ dest[0] = r * a1;
+ dest[1] = g * a1;
+ dest[2] = b * a1;
dest[3] = a >> 16;
}
else
@@ -991,6 +1000,7 @@ scale_line (int *weights, int n_x, int n_y, guchar *dest, int dest_x,
{
int x = x_init;
int i, j;
+ const int n_xy = n_x * n_y;
while (dest < dest_end)
{
@@ -998,7 +1008,7 @@ scale_line (int *weights, int n_x, int n_y, guchar *dest, int dest_x,
int *pixel_weights;
pixel_weights = weights +
- ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y;
+ ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_xy;
if (src_has_alpha)
{
@@ -1022,11 +1032,20 @@ scale_line (int *weights, int n_x, int n_y, guchar *dest, int dest_x,
}
}
- if (a)
+ if (a == 0xff0000)
+ {
+ /* Division by a constant is converted into a multiplication by an optimizing C compiler */
+ dest[0] = r / 0xff0000;
+ dest[1] = g / 0xff0000;
+ dest[2] = b / 0xff0000;
+ dest[3] = 0xff0000 >> 16;
+ }
+ else if (a)
{
- dest[0] = r / a;
- dest[1] = g / a;
- dest[2] = b / a;
+ double a1 = 1.0 / a;
+ dest[0] = r * a1;
+ dest[1] = g * a1;
+ dest[2] = b * a1;
dest[3] = a >> 16;
}
else