<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi all,<br>
<br>
I've been working on integration of my selector code into the Image
Editor, and I've stumbled at the following issue.<br>
<br>
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.<br>
<br>
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.<br>
<br>
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).<br>
<br>
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%.<br>
<br>
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:<br>
<br>
<tt>static void shadeRect(QImage& image, QRect rect)<br>
{<br>
  QRgb add = qRgba(0x7f,0x7f,0x7f,0x00);<br>
  QRgb mask = qRgba(0xfe,0xfe,0xfe,0xfe);<br>
<br>
  rect = rect.intersect(image.rect());<br>
  for (int r=rect.top(); r<rect.bottom(); ++r) {<br>
    QRgb* line = (QRgb*)image.scanLine(r);<br>
    int left = rect.left();<br>
    int right = rect.right();<br>
    for (int c=left; c<right; ++c) {<br>
      line[c] = ((line[c] & mask) >> 1) + add;<br>
    }<br>
  }<br>
}</tt><br>
<br>
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:<br>
<br>
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.<br>
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.<br>
<br>
Now what can be done about it (assuming we decide we want it to be
fast, snappy and flicker-free):<br>
<br>
<ol>
  <li>We can put up with the ugliness of the above solution, probably
fixing up the ImlibInterface to draw on QImages.</li>
  <li>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).<br>
Not that I know if such acceleration actually exists in X drivers or
how to detect its presence.</li>
</ol>
Any comments?<br>
<br>
I attach the patch that does this - it's far from being done, but
demoes the speed of the selection rendering.<br>
<br>
Alex<br>
</body>
</html>