KisPainter::paintPolygon used in paintops

Cyrille Berger cberger at cberger.net
Sun Apr 12 13:00:05 CEST 2009


On Friday 10 April 2009, LukasT.dev at gmail.com wrote:
> > I don't share your analysis of the problem :/ In the callgrind you give,
> > the creation of selection and objects isn't visible at all. The main cost
> > I see is the computation of exactBounds (and worse here, we pay it
> > twice). One might note, that those exactBounds aren't needed in this
> > case, since we allready know the extent of the function.
>
> Which function? Can you describe it more? I would implement it, but I don't
> see what you see..You are standing on the shoulders of giants?
> Can you take me there? :)

If you look at fillPainterPath, you can see the cost is divided in two 
functions:
KisPaintDevice::applySelectionMask
QPainter::fillRect

The first function represent 56% of the total cost, and most of what is done 
inside of that function can be avoided in our case. We don't need the call to 
exactBounds (we allready know it, 38%), and we don't need the crop (the paint 
device allready have the correct dimension, 17.80%). So basically we would 
just have to transfer the selection mask from "polygonMaskImage" to "polygon".

There is an other possible improvement, since we only create 
"polygonMaskImage" to apply on the "polygon" paint device, we can also edit 
directly the alpha channel of polygon.  So instead of 

            KisRectIterator rectIt = polygonMask->createRectIterator(x, y, 
rectWidth, rectHeight);

            while (!rectIt.isDone()) {
                (*rectIt.rawData()) = qRed(polygonMaskImage.pixel(rectIt.x() - 
x, rectIt.y() - y));
                ++rectIt;
            }

You can do:

            KisRectIterator rectIt = polygon->createRectIterator(x, y, 
rectWidth, rectHeight);
            
            while (!rectIt.isDone()) {
	            polygon->colorSpace()->applyAlphaU8Mask(pixelIt.rawData(), 
qRed(polygonMaskImage.pixel(rectIt.x() - x, rectIt.y() - y)), 1);
                  ++rectIt;
            }

And then remove all reference to polygonMask.

> > An other area of improvement could be to not use the QPainter, and to
> > directly fill the mask, there is most likely going to be a huge speed up
> > as well, since QPainter::fillRect is to general for our purpose.
>
> How would you fill it then? Using what class?
When I first wrote the mail (or at least as far as I remember...), I thought it 
would be tricky... since I first thought that it was the fillPath and not 
fillRect the problem... ok back to the point, this should be ultra easy. 
QPainter::fillRect is just used to clean th QImage (which really makes me 
wonder why it is that slow... they might have improve that in Qt4.5 or it 
might be worth investigation...), so probably a call to 
QImage::fill(qRgba(OPACITY_TRANSPARENT, OPACITY_TRANSPARENT, 
OPACITY_TRANSPARENT, 255)) should be enough, and quiet cheap.

Hope it's more clear now :)

-- 
Cyrille Berger

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.kde.org/pipermail/kimageshop/attachments/20090412/d1833d41/attachment.htm 


More information about the kimageshop mailing list