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