Hi, On Wed, Feb 06, 2008 at 01:13:30PM +0100, Johannes Hofmann wrote:
Hi Jorge,
On Mon, Feb 04, 2008 at 07:31:29PM -0300, Jorge Arellano Cid wrote:
Well an experimental prototype was committed. The original idea here was to use this new API:
void Textblock::flush (bool asap) void FltkViewBase::queueDrawTotal (bool asap)
(asap = "As soon as possible")
and to call the function inmediately when "asap" is true and to otherwise delay to a tunable number of seconds.
After some tests it showed extraordinarily effective. For instance testing with the "All" directory from:
http://chlamydia.fs.ei.tum.de/pub/DragonFly/packages/stable/DragonFly-1.10.1...
it was roughly using 2 to 3 times less CPU (in my notebook) than using the FltkPlatform::generalIdle() throttling patch.
Some glitches remained, and while I was working on it, the test server above went down... :(
I got a big surprise when after some more tests, it worked quite well when ignoring everything but calls with asap=true ! :-)
For instance, now the code reads:
void FltkViewBase::queueDrawTotal (bool asap) { static time_t lastRedraw = 0;
//if (asap || time(0) > lastRedraw + 2) { if (asap) { redraw (DAMAGE_EXPOSE); lastRedraw = time(0); } }
If I understand this correctly, the patch now is equivalent to removing the calls to queueDrawTotal(), where asap == false, right?
Right. But the idea is to queue when asap == false, and to set a delayed draw that is user adjustable in seconds (e.g. 0, 0.5, 1, 3, ...).
With this patch I see missing screen updates e.g. when resizing the window.
Yes some glitches remain. There's still a need to add a few queueDrawTotal(true) calls in necessary places so this is solved. Once this is done, the amount of CPU usage decreases dramatically and the user can choose a refresh rate.
First let me explain how I think the drawing and relayout is designed in dillo2. Please correct me if I'm wrong.
Oh, I didn't design it so we're both exploring this area.
* Frequent redraws are good if they update the visible content. E.g. when loading a page over a slow line. Immediate feedback to the user is a great feature of dillo. The screen flickering can be avoided with some double buffer mechanism.
Choosing refresh_delay=0 would give immediate feedback. refresh_delay=3 could yield low CPU usage and very good performance. e.g. as place commented:
You can try with the new patch.
dillo-fltk immediate /* clear_double_buffer(); */ dillo-fltk 0:06 clear_double_buffer();
* queueResize() calls are put into the code whenever the layout might have changed without worrying too much about performance. To make this efficient, queueResize() or queueDrawTotal() just remembers drawing or resizing should be done at some time in the future.
It looks like, but there are also some unimplemented functions like startDrawing (), finishDrawing(), and flush(). Maybe they were discarded, myabe left for future implementation, or left for a second design-pass.
* The idle function mechanism then does the actual work of resizing or redrawing. This way many calls to queueResize() can cause many resize operations, or they can be combined to just single resize depending on when the idle functions are called. When loading the same page, dillo can update the screen frequently if enough CPU is available, or less often, if CPU time is not available.
I think this is an excellent concept :-)
:)
So what do we need to do?
* Make the concept work properly. Here I think we need to improve the code where the idle functions are called so that multiple redraws are really combined especially if there is no CPU available.
* Of course we still should reconsider each call to queueDrawTotal() or queueResize() and verify whether it is really necessary. However I think we should favor correctness over speed. That means, whenever the layout might have changed, we must call queueResize().
Sure. The patch is not complete. After adding the missing flushes it should work OK. And refresh_delay would help to set the desired behaviour.
* It would be nice, if we could decide whether a resizing widget affects the layout that is currently visible, so that we could avoid redrawing in this case. This would avoid redrawing when loading very long pages as the DragonFly package list. But I don't think this is easy.
Back in 2005 we needed to test the prototype quickly, so it was reasonable to simply add, for instance, a queuedrawTotal() call when only a queuedraw() was needed and to postpone clipping until the basics were working. I believe this is what is asking for a review now.
Also we should agree on what we actually want to optimize. I don't think CPU usage or number of redraws are enough. Instead dillo should be usable and "feel fast" on fast and slow or loaded systems (if CPU is available, why not use it?).
I believe we can have it all! (as explained above). -- Cheers Jorge.-