KisPainter::paintPolygon used in paintops
LukasT.dev@gmail.com
lukast.dev at gmail.com
Tue Sep 29 13:25:50 CEST 2009
On Sunday 12 April 2009 13:00:05 Cyrille Berger wrote:
> 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 :)
>
I'm back on this issue. Last time I did not put enough effort into this. Now
I'm more inspired.
if fillPainterPath there is
fillPainter.fillRect(fillRect, paintColor(), OPACITY_OPAQUE);
if fillRect in kis_fill_painter there
KoColor kc2(kc); // get rid of const
kc2.convertTo(device()->colorSpace());
We create QImage polygonMaskImage
and two QColor in fillRect, fillPath
so for every particle is created so much objects...Remember the easy
optimizations? [1] Maybe the easy solution would be to cache colors as much as
possible..
[1] http://wiki.koffice.org/index.php?title=Krita/Optimization
CyrilleB: I hope to catch you on IRC and you could mentor me to implement
improvements you mention...
More information about the kimageshop
mailing list