Hi Sebastian, this patch is obsolete, as fltk does all that for us: The void Widget::redraw(const Rectangle& r) method marks a rectangle for later redraw. See my followup mail for a much shorter patch that does the same thing. It's already in cvs. I will try to summarize how fltk handles redraws (as I have understood it so far): * Redraw requests from the program itself or from the outside (expose events) are accumulated by fltk and will result in a later call to the draw() methods of the various widgets. Information about what is to be drawn is passed via a bitmap that can be accessed using Widget::damage() and via the current clipping region. * A program can require redraws using void Widget::redraw(const Rectangle& r). In this case fltk ensures, that r will not be clipped during a subsequent draw(). * A program can require redraws using void Widget::redraw(uchar c). In this case fltk ensures, that at least the bits that are on in c will be turned on in the damage() bitmap during a subsequent draw(). This pretty simple mechanism is used by fltk code itself to avoid unnecessary redraws. Here are some examples: * The void Group::draw_child(Widget& w) method looks at the current clip region and returns immediately if w is clipped. * If a widget notices that it needs redrawing (e.g. a button that has been pushed) it will set a flag in its own damage() bitmap and then call redraw(DAMAGE_CHILD). If then at drawing time just the DAMAGE_CHILD bit is on in the global damage() bitmap, Group calls the draw() methods of all those child widgets that have indicated that they need a redraw in their on damage() bitmap. All other widgets will not redraw. * ScrollGroup uses the DAMAGE_SCROLL bit in damage() to indicate that a redraw is necessary because of a scroll movement. If this is the only bit in damage() at drawing time, an optimized aproach is used for redrawing: The part of the screen that was already visible before the scroll movement will be copied to the new position and only the rest is actually redrawn. Some of these methods are already used in the current cvs-version of dw2: * void FltkViewBase::draw () only calls theLayout->expose () for the not clipped area. * If just DAMAGE_CHILD is on in damage(), FltkViewBase::draw () lets Group::draw() draw those child widgets that have requested a redraw. * void FltkViewBase::queueDraw (core::Rectangle *area) uses void Widget::redraw(const Rectangle& r) to request redrawing only for a specific area. * void FltkViewport::draw () uses the same mechanism as ScrollGroup to optimize redraws that are necessary because of scroll movements. Cheers, Johannes On Sun, Nov 18, 2007 at 09:22:43PM +0100, Sebastian Geerken wrote:
Hi Johannes,
I'm glad that someone is dealing with this problem. I'll write more about it, here just some first remarks, after only taking a glance at this and other patches.
On Fri, Nov 09, Johannes Hofmann wrote:
Hi,
this patch adds set(), isEmpty(), and merge() methods to core::Rectangle. These methods are then used to maintain a rectangle that contains all screen areas for which a redraw was requested. When fltk really draws to the screen, the drawing is limited to this area. The most obvious improvement is visible on pages with very large images that take some time to load. While the image is loaded the rest of the page is no longer flickering - at least if there is no other stuff that requests complete redraws.
You may take a look at the old implementation (gtk-based, somewhere in dw_viewport.c), combining the areas of different redraw requests is already implemented there. Perhaps it is better to adopt the old code, which has been working for a while.
Some notes on the general problem. There are several cases when areas are to be redrawn, I hope this list is complete:
1. to react on expose events, 2. if a widget redraws itself, and 3. when scrolling.
Regarding the problem, how to restrict drawing to a minimum, case 1 is probably neglectable, since the number of expose events is mostly rather small (only when moving windows, changing there order etc.). It seems that the following code:
+ ::fltk::Rectangle rect (x(), y(), w(), h()); + if (d == DAMAGE_VALUE) {
may be used to distinguish it from the critical cases 2 and 3. For case 1, still the whole viewport is drawn, optimization should be secondary.
Sebastian
_______________________________________________ Dillo-dev mailing list Dillo-dev@dillo.org http://lists.auriga.wearlab.de/cgi-bin/mailman/listinfo/dillo-dev