Reply
Thread Tools
Posts: 341 | Thanked: 57 times | Joined on Nov 2009
#1
Hello all ... I needed some help in trying to optimize this code portion ... Basically here's the thing .. I'm making this 'calligraphy pen' which gives the calligraphy effect by simply drawing a lot of adjacent slanted lines ... The problem is this: When I update the draw region using update() after every single draw of a slanted line, the output is correct, in the sense that updates are done in a timely manner, so that everything 'drawn' using the pen is immediately 'seen' the drawing.. however, because a *lot* (100s of them) of updates are done, the program slows down a little when run on the N900 ...

When I try to do a little optimization by running update after drawing *all* the slanted lines (so that all lines are updated onto the drawing board through a single update() ), the output is ... odd .... That is, immediately after drawing the lines, they lines seem broken (they have vacant patches where the drawing should have happened as well) ... however, if I trigger a redrawing of the form window (say, by changing the size of the form), the broken patches are immediately fixed !! When I run this program on my N900, it gets the initial broken output and stays like that, since I don't know how to enforce a redraw in this case ...

Here is the first 'optimized' code and output (partially correct/incorrect)

Code:
void Canvas::drawLineTo(const QPoint &endPoint)
{
    QPainter painter(&image);
    painter.setPen(QPen(Qt::black,1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    int fx=0,fy=0,k=0;
    qPoints.clear();
    connectingPointsCalculator2(qPoints,lastPoint.x(),lastPoint.y(),endPoint.x(),endPoint.y());
    int i=0;
    int x,y;
    for(i=0;i<qPoints.size();i++)
    {
        x=qPoints.at(i).x();
        y=qPoints.at(i).y();
        painter.setPen(Qt::black);
        painter.drawLine(x-5,y-5,x+5,y+5); // Drawing slanted lines
    }
    //Updating only once after many draws:
    update (QRect(QPoint(lastPoint.x()-5,lastPoint.y()-5), QPoint(endPoint.x()+5,endPoint.y()+5)).normalized());

    modified = true;
    lastPoint = endPoint;
}
Image right after scribbling on screen:



Image after slightly re-adjusting the window size:



Here is the second un-optimized code (its output is correct right after drawing, just like in the second picture above):

Code:
void Canvas::drawLineTo(const QPoint &endPoint)
{
    QPainter painter(&image);
    painter.setPen(QPen(Qt::black,1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    int fx=0,fy=0,k=0;
    qPoints.clear();
    connectingPointsCalculator2(qPoints,lastPoint.x(),lastPoint.y(),endPoint.x(),endPoint.y());
    int i=0;
    int x,y;
    for(i=0;i<qPoints.size();i++)
    {
        x=qPoints.at(i).x();
        y=qPoints.at(i).y();
        painter.setPen(Qt::black);
        painter.drawLine(x-5,y-5,x+5,y+5); // Drawing slanted lines
        //Updating repeatedly during the for loop:
        update(QRect(QPoint(x-5,y-5), QPoint(x+5,y+5)).normalized());//.adjusted(-rad,-rad,rad,rad));
    }
    modified = true;
    int rad = (myPenWidth / 2) + 2;
    lastPoint = endPoint;
}
Can anyone see what the issue might be ?
 
Posts: 190 | Thanked: 129 times | Joined on Mar 2010 @ Bavaria, Germany
#2
Without thinking a lot about it:

You could try to paint into a QPixmap. Store your points and only append them to the pixmap. Only if the widget is resized, you'll generate a new pixmap or resize it.
That would consume some (not a lot) memory and stops your n900 from slowing down. Maybe it even helps with the update problems.

EDIT: Oops, just saw you seem to already draw onto a image ...

Last edited by gri; 2010-06-14 at 20:10.
 
mikec's Avatar
Posts: 1,366 | Thanked: 1,185 times | Joined on Jan 2006
#3
are you running full screen on the n900?
__________________
N900_Email_Options Wiki Page
 
Posts: 52 | Thanked: 8 times | Joined on Apr 2010
#4
another way to optimize the code would be not to draw millions of lines. Update less often, then draw batches of lines from the previous update position to the current update position. You would only really see the down side if you were to draw really fast.

A way to limit the amount of updates is to limit it by time rather than system speed.
 

The Following User Says Thank You to Jaso333 For This Useful Post:
Posts: 726 | Thanked: 345 times | Joined on Apr 2010 @ Sweden
#5
It looks like you update too small a region. Just to try that, update the whole drawing area after drawing all the small lines. If this changes the behaviour, you've found the problem.
 
Posts: 341 | Thanked: 57 times | Joined on Nov 2009
#6
Alright here's one thing I did .. I found the min and max of x and y processed in my for-loop and used these values to perform just one update after the for loop, like so:

update(QRect(QPoint(minX-5, minY-5), QPoint(maxX+5, maxY+5)).normalized());

Good thing is it now works on my PC ... with just one update after the for loop, it still runs fine on the PC ... however when I run it on the N900, the result isn't good ... When drawing 100% vertical lines, no matter how fast, they are always solid, with no 'breaks' .. however when I draw horizontal of even semi-horizontal lines, there are breaks, even if I draw the line very slowly
 
Posts: 341 | Thanked: 57 times | Joined on Nov 2009
#7
The issue is somehow related to updating the display when drawing horizontal stuff ... When drawing vertical lines, no matter how fast, they're always solid, but horizontal lines are always broken, unless you are absolutely drawing at snail speed ..

Here's a picture from my N900:



Originally Posted by mikec View Post
are you running full screen on the n900?
Well right now its running in semi-fullscreen mode .. only the top bar is showing ... How do I switch to 100% fullscreen ? I doubt this will solve the issue though ..

Originally Posted by Joorin View Post
It looks like you update too small a region. Just to try that, update the whole drawing area after drawing all the small lines. If this changes the behaviour, you've found the problem.
Just tried this too .. Same result as before .. A little slower though ..
 
Posts: 61 | Thanked: 43 times | Joined on Aug 2008
#8
I think you still don't calculate changed area correctly. Try drawing from right to left and see if that works. Or draw a circle to see when updating works.

And I think you don't need to set pen black for every slanted line you draw.

Last edited by harriva; 2010-06-15 at 10:00.
 

The Following User Says Thank You to harriva For This Useful Post:
Posts: 341 | Thanked: 57 times | Joined on Nov 2009
#9
Well I tried even updating the entire are as well .. doesn't make any difference ... The problem in horizontal drawing is for both right to left and left to right .. If I draw the circle, the vertical parts of it would be OK, but the horizontal parts would have a problem ..

Setting the pen black was just a hiccup :P

The connectingPointsCalculator function gives me all the points between to coordinates .. about each of these the slanted lines are calculated .. I've checked the working for this function too, to see if it gives wrong results in horizontal cases or something .. but this is fine too .. Also, since the problem only exists when running the code on N900, it leads me to believe that maybe the updating/repainting procedure is different for the N900 than for PC ... Would double buffering help here ?
 
Venemo's Avatar
Posts: 1,296 | Thanked: 1,773 times | Joined on Aug 2009 @ Budapest, Hungary
#10
Originally Posted by ahmadka View Post
[...]

Can anyone see what the issue might be ?
StackOverflow might be a good place to ask.
 
Reply


 
Forum Jump


All times are GMT. The time now is 03:25.