PDA

View Full Version : Why is drawText so terribly slow?



Ntoskrnl
29th July 2008, 13:47
Hello,
I'm trying to write a hex editor (or better, converting my win32 one to Qt). I'm using a QPixmap which needs often to be refreshed (imagine only the scrolling) the pixmap is later on painted (drawPixmap) to the widget. The problem is that it's terribly slow, really not acceptable. I would think that I'm doing something wrong, but lfhex when compiled is exactly just as slow (I compiled it on windows). The problem seems to be related to drawText, which seems to be the slow function. This is really a problem, since the scrolling acts way too slow, just like in lfhex. I hope I can work this out, otherwise I'm in serious trouble.
I even tried to avoid the pixmap approach and paint directly (lfhex does the same, without success) and it didn't change anything.
Could anyone please help me?
Thanks in advance

Ntoskrnl
29th July 2008, 17:39
I did some further testing, and it seems that the painting itself is slow. Not only drawText. Since I'm using a pixmap I set the PaintOnScreen attribute to disable double buffering (just thought it was worth mentioning in case someone thought this was the problem). The "repaint only what has to be repainted" can't help in this situation: when one scrolls the hex editor, everything needs to be repainted. Is it really possible that the painting is so slow? I can't make heads or tails of this.

aamer4yu
30th July 2008, 06:37
Pixmap for editor :O

Why dont u use QTextEdit ??

Ntoskrnl
30th July 2008, 09:42
Well, even if I paint directly and leave the double buffering to Qt, it doesn't make any difference. The normal Win32 approach is calling CreateCompatileBitmap and then painting the bmp on the device context. Using a text control to make a hex editor is generally the lazy developer approach. I wouldn't know how to obtain this control in a text editor:

http://ntoskr.nl/hexed.jpg

And even if I managed to recreate this view in a text control, why should I? The painting is most logical solution when writing a serious hex editor. I would rather understand why it doesn't work.

I provided a little demo for those who have the free 4.4 edition of Qt on Windows:

http://ntoskr.nl/hexed.zip

In this demo I'm using no double buffering, I PaintOnScreen and call repaint, rather than update to refresh the hex view. repaint, as the doc says, calls directly the paintEvent, while update optimizes against flickering and never overlaps. My concern is not flickering, it doesn't even come to flicker and I don't understand how the painting can be so slow. It's not even a complicate kind of drawing.

Has anyone an idea of what this could be related to?

Thanks!

pherthyl
30th July 2008, 20:21
>> The painting is most logical solution when writing a serious hex editor.

Is it? Don't you then lose all ability to interact with the text? Even if you don't plan to support editing, how will people copy and paste?

fullmetalcoder
30th July 2008, 22:20
drawText() is kinda slow because it reinitialize a couple of internal object (QTextEngine for instance) every time it is called. Avoid calling it for every character and try to batch text drawing (the longer the chunk of text to draw the better
drawing into a pixmap and then drawing this pixmap on the screen is the WORST way to go. Inherit from QAbstractScrollArea and paint directly on the viewport
if you are unsure about how to perform the actual drawing using this approach have a look at the code of text editor widget (don't use one but take inspiration from it...) such a QTextEdit or QCodeEdit (http://qcodeedit.edyuk.org)
you may also be interested in having a look at Oketa, the new hex editor of KDE 4

hope this helps

Ntoskrnl
30th July 2008, 23:45
Is it? Don't you then lose all ability to interact with the text? Even if you don't plan to support editing, how will people copy and paste?

Of course not, in my demo this ability isn't provided simply because I haven't finished the control (and won't since it's too slow). All serious hex editors do it this way, if you want to check a working version of the same control, check out the CFF Explorer (http://ntcore.com/exsuite.php). Everything is handled, mouse, keyboard, editing, selection etc. It's all about writing a control from scratch.

fullmetalcoder, thanks for the answer:


drawText() is kinda slow because it reinitialize a couple of internal object (QTextEngine for instance) every time it is called. Avoid calling it for every character and try to batch text drawing (the longer the chunk of text to draw the better

Yes, I noticed, but is really really slow still.


# drawing into a pixmap and then drawing this pixmap on the screen is the WORST way to go. Inherit from QAbstractScrollArea and paint directly on the viewport

This demo draws directly. I changed the behaviour just to try, but it doesn't help. Also, lfhex draws directly, but very slow.


# if you are unsure about how to perform the actual drawing using this approach have a look at the code of text editor widget (don't use one but take inspiration from it...) such a QTextEdit or QCodeEdit
# you may also be interested in having a look at Oketa, the new hex editor of KDE 4

Yes, I had already had a look at okteta sources. I cannot however try it, since I'm only running on Windows. I only tried lfhex and khexedit. KHexEdit I tried on bsd and it wasn't fast enough. Meanwhile lfhex was really painfully slow (just like my demo).

Today, I came up with another idea: using QGraphicsScene to implement the hex view. I only did a few tests, but it seems MUCH faster. I'm fairly new at using Qt (just a month), so I might be wrong.

fullmetalcoder
31st July 2008, 23:21
I graphics view turns out to be faster than normal widget drawing there MUST be something terribly WRONG with your code. I'd have given it a look but the archive only contains an exe (besides I'm running linux so I can't even check the speed).

pherthyl
1st August 2008, 20:15
Yes, I had already had a look at okteta sources. I cannot however try it, since I'm only running on Windows.

Okteta runs fine here.. Fast scrolling.


Today, I came up with another idea: using QGraphicsScene to implement the hex view. I only did a few tests, but it seems MUCH faster. I'm fairly new at using Qt (just a month), so I might be wrong.

This whole thread is silly without code. Obviously scrolling a window of text is not inherently slow, so there must be some issue in how you're doing it. Pretty much impossible to determine the issue with an exe that most people can't run. For all we know you're painting the thing pixel by pixel or something equally bizarre.