Showing posts with label qt. Show all posts
Showing posts with label qt. Show all posts
Tuesday, September 30, 2008
Lazarus cross platform and cross widget set example
Today I read a news item on the Lazarus site about a SI_Browser, a simple DICOM viewer. I didn't know what DICOM was, but google led me to the wikipedia article about it.
At the bottom of the site, I found a familiar link about the MRIcron DICOM viewer. I knew MRIcron is built using Lazarus; Chris Rorden, the developer, has made and paid several successful bounties to support MRIcron and Lazarus.
The actual reason I write this post, is the installation page of MRIcron. MRIcron is a Lazarus application that really shows the strength of Lazarus cross platfrom and widget set support. Chris offers MRIcron in 8 differenent flavours:
Chris, thanks for showing the power of Lazarus.
At the bottom of the site, I found a familiar link about the MRIcron DICOM viewer. I knew MRIcron is built using Lazarus; Chris Rorden, the developer, has made and paid several successful bounties to support MRIcron and Lazarus.
The actual reason I write this post, is the installation page of MRIcron. MRIcron is a Lazarus application that really shows the strength of Lazarus cross platfrom and widget set support. Chris offers MRIcron in 8 differenent flavours:
- Windows (WinAPI widgetset)
- Linux
- 32-bit (QT widgetset)
- 32-bit (GTK1 widgetset)
- 32-bit (GTK2 widgetset)
- 64-bit (GTK1 widgetset)
- 64-bit (GTK2 widgetset)
- Macintosh OSX
- OSX 10.4 or later (Universal binary, Carbon widgetset)
- OSX 10.3 or earlier (PowerPC, GTK1 widgetset)
Chris, thanks for showing the power of Lazarus.
Saturday, September 29, 2007
Fight for Synedit speed under qt widgetset
One or two weeks ago our qt-ide was almost fine (if form designer was not taken into account) except one important detail - the speed of the unit editor. Yes, you were able to edit source, but the speed .... it was deadly slow. You could type a key and wait second or two before that key was printed in editor. So we started the fight for speed.
The core of the unit editor is the Synedit component. Lazarus uses an early version of Synedit but it is heavily changed for our needs (adopted, extended). Synedit is a TCustomControl, so it does all its painting and event handling itself. When I looked at the source for the first time, I found nothing criminal. A well done component which repaints only changed areas.
I tried to find out what piece of code makes the component so slow under qt. And I found that it is the qt QPainter.DrawText method. My first assumption was that in the OnPaint event we were repainting the whole Synedit, not only the changed area.
I checked how invalidateRect was done and there was no error - QWidget.Update(Rect) was called. My next assumption was that we were ignoring that Rect in the OnPaint event, but no - we did clip the paint area by that rect. What was it - a mystery?
I checked how clipping worked and found, that in DrawText the clipping was gone. The reason was in Synedit - it used double buffered painting and as result DrawText performed on a non clipped bitmap instead of a clipped window. Revision 12175 changed things. There was no more bitmap, but painting was still as slow as before.
My next assumption was that qt doesn't check the clipping region before DrawText. And bingo - manual check of clipping rect before DrawText gave us no bad speed (revision 12183). But cpu usage was very big in spite of the achieved speed. So something was still wrong, but what?
Zeljan noticed that caret eats too much cpu time. It was because of a not optimal use of timer and widget repainting. After fixing those things in revisions 12198-12200 there was not so high cpu rate as before.
I was already happy but Zeljan was at his best and found one more speed killer. That was our ExtTextOut implementation. ExtTextOut have 2 arguments related to text: Str - the text and Count - count of chars. We made the assumption that Pascal components pass Str arguments that are already trimmed to count chars, but this was not true (at least for Synedit). There were cases where count was equal to 1, but Length of Str equal to 300 (or 400 chars). After an appropriate patch (revisions 12201,12205)the speed of Synedit has become really fast.
Now qt-ide as fast as it should be.
The core of the unit editor is the Synedit component. Lazarus uses an early version of Synedit but it is heavily changed for our needs (adopted, extended). Synedit is a TCustomControl, so it does all its painting and event handling itself. When I looked at the source for the first time, I found nothing criminal. A well done component which repaints only changed areas.
I tried to find out what piece of code makes the component so slow under qt. And I found that it is the qt QPainter.DrawText method. My first assumption was that in the OnPaint event we were repainting the whole Synedit, not only the changed area.
I checked how invalidateRect was done and there was no error - QWidget.Update(Rect) was called. My next assumption was that we were ignoring that Rect in the OnPaint event, but no - we did clip the paint area by that rect. What was it - a mystery?
I checked how clipping worked and found, that in DrawText the clipping was gone. The reason was in Synedit - it used double buffered painting and as result DrawText performed on a non clipped bitmap instead of a clipped window. Revision 12175 changed things. There was no more bitmap, but painting was still as slow as before.
My next assumption was that qt doesn't check the clipping region before DrawText. And bingo - manual check of clipping rect before DrawText gave us no bad speed (revision 12183). But cpu usage was very big in spite of the achieved speed. So something was still wrong, but what?
Zeljan noticed that caret eats too much cpu time. It was because of a not optimal use of timer and widget repainting. After fixing those things in revisions 12198-12200 there was not so high cpu rate as before.
I was already happy but Zeljan was at his best and found one more speed killer. That was our ExtTextOut implementation. ExtTextOut have 2 arguments related to text: Str - the text and Count - count of chars. We made the assumption that Pascal components pass Str arguments that are already trimmed to count chars, but this was not true (at least for Synedit). There were cases where count was equal to 1, but Length of Str equal to 300 (or 400 chars). After an appropriate patch (revisions 12201,12205)the speed of Synedit has become really fast.
Now qt-ide as fast as it should be.
Subscribe to:
Comments (Atom)