While looking for ways to improve the KDE color selection dialog, I stumbled upon the slow rendering of the hue/saturation color gradient. Using a simple trick such gradients can be rendered using hardware facilities.
The goal is to render a two-dimensional gradient as depicted below. The current implementation allocates a properly sized QImage, and computes the RGB color values for each individual pixel.
Hue/saturation two-dimensional gradient
This requires, however, nearly hundred thousand conversions from HSV to RGB color values, and is the primary cause for the slowness of the dialog.
When looking at the resulting RGB values, you will notice that each row (“scanline”) is actually a one-dimensional linear gradient, so it could be rendered using QLinearGradient.
Looking further, you will also see that there is a linear gradient in each column. Such a gradient is called “bilinear”, but Qt does not offer a two-dimensional QGradient class.
The trick is to create this bilinear gradient by scaling up a very small QImage. The image you see above is actually only 7×2 pixels large. The image is then rendered to a larger QPixmap with scaling applied, so that possible hardware scaling can be used.
A requirement is that pixmap scaling supports bilinear interpolation. This mode, however, is even available with the software scaling algorithms built into Qt.