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