From: Christopher Barker <Chris.B<arker@no...> - 2008-04-11 17:03:09
Darren Dale wrote:
> I reverted the changes, so we still have an unnecessary call to draw in some
> cases, but at least everything should work.
There are similar issues with the wx back-end (see the recent thread).
The proposed patch to wx should be tested in interactive mode. If it
works, then maybe it can be ported to QT. If it doesn't then this makes
it quite clear that some re-factoring is needed:
As I looked through the wx code, I found it to be a bit of a jumbled
mess of blitting and drawing and... It looks like it has grown out of a
simpler system, with various patches to fix things that didn't work,
eventually ending up with "re-draw every time you paint", which should
work (and does), but really kills the whole idea of double buffering.
Anyway, it should be structured something like:
In the Paint handler:
Only a blit of the buffer bitmap -- that it, ever. In the case of the
Agg back-ends, I don't know if there should be both the Agg bitmap and a
native (wx, qt, or gtk) bitmap -- I suppose that's a function of how
fast it is to go from agg to native bitmap -- I think this can be now
done on wx without any data copying, so it should be fast enough. If
not, then the native and agg bitmaps should always be kept in sync.
When should the bitmap be re-drawn?
1) On a Size event -- so a Size event handler needs to call
canvas.draw() (is that right?)
2) when the users code or MPL asks for a re-draw -- this is the
canvas.draw() call, I think.
It should be as simple as that! Or are there other times that the bitmap
needs to be re-drawn?
One complication -- when the canvas is re-drawn due to a user action,
the screen needs to be updated, so we need a "blit the bitmap to the
screen now" call, which would be made after every canvas.draw() call,
unless it's a SaveFig or printing call. On wx, the theory is that you
can call Refresh() and Update(), which will trigger a Paint event.
However, I've found that that sometimes doesn't happen right away --
it's fast enough for common use, but not for animation, so I suggest
that there be a BlitNow() method that uses a wx.ClientDC to blit the
bitmap. I don't know about QT or GTK.
I have noticed a bunch of code that computes the damaged region of the
window, so that only that part gets blitted -- in theory that's a nice
optimization, but in practice, I've found that bltting the whole window
is plenty fast, so there's little point.
I wish I had more time to work on this...
Christopher Barker, Ph.D.
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception