<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">On Friday 10 April 2009, LukasT.dev@gmail.com wrote:<br>
&gt; &gt; I don't share your analysis of the problem :/ In the callgrind you give,<br>
&gt; &gt; the creation of selection and objects isn't visible at all. The main cost<br>
&gt; &gt; I see is the computation of exactBounds (and worse here, we pay it<br>
&gt; &gt; twice). One might note, that those exactBounds aren't needed in this<br>
&gt; &gt; case, since we allready know the extent of the function.<br>
&gt;<br>
&gt; Which function? Can you describe it more? I would implement it, but I don't<br>
&gt; see what you see..You are standing on the shoulders of giants?<br>
&gt; Can you take me there? :)<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>If you look at fillPainterPath, you can see the cost is divided in two <br>
functions:<br>
KisPaintDevice::applySelectionMask<br>
QPainter::fillRect<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>The first function represent 56% of the total cost, and most of what is done <br>
inside of that function can be avoided in our case. We don't need the call to <br>
exactBounds (we allready know it, 38%), and we don't need the crop (the paint <br>
device allready have the correct dimension, 17.80%). So basically we would <br>
just have to transfer the selection mask from "polygonMaskImage" to "polygon".<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>There is an other possible improvement, since we only create <br>
"polygonMaskImage" to apply on the "polygon" paint device, we can also edit <br>
directly the alpha channel of polygon.  So instead of <br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>            KisRectIterator rectIt = polygonMask-&gt;createRectIterator(x, y, rectWidth, rectHeight);<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>            while (!rectIt.isDone()) {<br>
                (*rectIt.rawData()) = qRed(polygonMaskImage.pixel(rectIt.x() - x, rectIt.y() - y));<br>
                ++rectIt;<br>
            }<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>You can do:<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>            KisRectIterator rectIt = polygon-&gt;createRectIterator(x, y, rectWidth, rectHeight);<br>
            <br>
            while (!rectIt.isDone()) {<br>
                    polygon-&gt;colorSpace()-&gt;applyAlphaU8Mask(pixelIt.rawData(), qRed(polygonMaskImage.pixel(rectIt.x() - x, rectIt.y() - y)), 1);<br>
                  ++rectIt;<br>
            }<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>And then remove all reference to polygonMask.<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>&gt; &gt; An other area of improvement could be to not use the QPainter, and to<br>
&gt; &gt; directly fill the mask, there is most likely going to be a huge speed up<br>
&gt; &gt; as well, since QPainter::fillRect is to general for our purpose.<br>
&gt;<br>
&gt; How would you fill it then? Using what class?<br>
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.<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>Hope it's more clear now :)<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p>-- <br>
Cyrille Berger<br>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; -qt-user-state:0;"><br></p></body></html>