[Digikam-devel] Speed issues in rendering the selection

Alex Gontmakher gsasha at cs.technion.ac.il
Tue Aug 16 13:56:51 BST 2005


Hi all,

I've been working on integration of my selector code into the Image 
Editor, and I've stumbled at the following issue.

The problem is, the code was way too irresponsive to my taste. In the 
existing SVN version, the image is rendered by tiles, and you could see 
these tiles being painted on the screen. In my version, the updates are 
done more continuously, with the result that you don't see the changes 
until everything is re-rendered.

This makes such things like starting the selection (which repaints the 
whole viewport in white shading) look very irresponsive - almost a 
second passes until you see the screen change.

I have traced the problem to the slowness of blending of the image 
itself with the white color of the shading (or with the histogram). This 
operation is quite slow in Imlib, and is downright horrible in Qt 
(although, Qt4 might be better). Actually, in QT it appears to rely on 
the X's blending implementation, which could be accelerated by the 
graphic card, but isn't on my computer (a Thinkpad R40).

My point is that the general blending is unnecessary general for our 
case - it assumes that each pixel has its own alpha value. In our case, 
we know that the alpha is constant, and can even select an easy one, 
like 50%.

To test this out, I wrote my own blending implementation that blends 
QImages with the alpha of 0.5. It is very fast - it does no if's and 
multiplications, and works on whole words. I used this implementation to 
perform the selection shading, and the result is nice - all the 
selection operations become snappy. Take a look:

static void shadeRect(QImage& image, QRect rect)
{
  QRgb add = qRgba(0x7f,0x7f,0x7f,0x00);
  QRgb mask = qRgba(0xfe,0xfe,0xfe,0xfe);

  rect = rect.intersect(image.rect());
  for (int r=rect.top(); r<rect.bottom(); ++r) {
    QRgb* line = (QRgb*)image.scanLine(r);
    int left = rect.left();
    int right = rect.right();
    for (int c=left; c<right; ++c) {
      line[c] = ((line[c] & mask) >> 1) + add;
    }
  }
}

Now the problem is, this code works only for QImages (for which the 
pixels are available for direct manipulation), and not for QPixmaps. 
This makes the code ugly in several places:

1. You cannot define a painter on QImage. As a result, I cannot use 
functions like drawRect() to draw the selection border and corners, and 
would have to do that manually, pixel-by-pixel. YUCK.
2. The current ImLibInterface can paint on pixmaps only, not on QImages. 
Currently, I convert the QPixmaps to QImages after they're painted, and 
cache the QImages. However, this is ugly and it involves an unnecessary 
round-trip to the X server.

Now what can be done about it (assuming we decide we want it to be fast, 
snappy and flicker-free):

   1. We can put up with the ugliness of the above solution, probably
      fixing up the ImlibInterface to draw on QImages.
   2. We can make the shading of the selection optional, and turn it on
      only for computers which have the appropriate acceleration of
      alpha blending. Selection is, of course, extremely fast when only
      the frame is drawn. Note though that this doesn't help with the
      histogram, which still needs to be blended (well, unless it is
      finally moved into the sidebar).
      Not that I know if such acceleration actually exists in X drivers
      or how to detect its presence.

Any comments?

I attach the patch that does this - it's far from being done, but demoes 
the speed of the selection rendering.

Alex
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/digikam-devel/attachments/20050816/ad15937a/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: selector_with_qimage.diff
Type: text/x-patch
Size: 86330 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/digikam-devel/attachments/20050816/ad15937a/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gsasha.vcf
Type: text/x-vcard
Size: 175 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/digikam-devel/attachments/20050816/ad15937a/attachment.vcf>


More information about the Digikam-devel mailing list