[wxPython-users] Not quite understanding buffered DCs
Robin Dunn
robin at alldunn.com
Tue Dec 26 12:16:11 PST 2006
Jeffrey Barish wrote:
> I understand the principle behind buffered DCs: A buffered DC reduces
> flicker by accumulating the effects of many draw commands before blitting
> the final result to the screen in one operation. In Listing 6.1 of the
> book, there is a buffered DC for DrawLines and another for drawMotion to
> accumulate the effect of many DrawLine commands. But doesn't the actual
> drawing to the screen occur in OnPaint?
You can also paint outside of a EVT_PAINT handler by using a
wx.ClientDC[1]. In the example in the book this is what is done in
OnMotion. The new lines are drawn to the buffer and then the buffer
will be flushed to the wx.ClientDC.
> Isn't the drawing of individual
> elements already done by the time we get here? I'm thinking that the
> individual elements have already been rendered into the bitmap buffer, so
> the only thing that needs to happen in OnPaint is a blit of the bitmap to
> the screen.
True.
> No flicker there because everything gets drawn to the screen
> in one operation. I am thinking that the bitmap buffer provides the
> necessary buffering. Maybe I am confused about what the bitmap buffer
> does.
I think you've got a good handle on it.
>
> Moreover, it seems as if we don't really need a BufferedPaintDC in OnPaint,
> aside from the convenience of not having to spell out the blit operation,
> again because the screen update happens as the result of one blit
> operation.
It is all for convenience. That one line in the example replaces about
4 lines it would take to do it without a wx.BufferedPaintDC. In fact,
all of the buffered dc classes are entirely for convenience. You can do
everything they do yourself with just a bitmap, a MemoryDC and a
ClientDC or PaintDC.
> I can see a use for BufferedPaintDC in a program where all the drawing takes
> place in OnPaint. Without the buffering, individual elements would appear
> sequentially. But if the drawing is already done by the time we get to
> OnPaint, isn't the buffering superfluous?
I think what you are still missing is that:
1. There still needs to be a wx.PaintDC created, otherwise nothing will
be painted at all. The wx.BufferedPaintDC creates a wx.PaintDC
internally for you.
2. A side effect of creating a buffered dc is that the buffer bitmap
will be flushed to the real dc when the buffered dc is garbage collected.
So "wx.BufferedPaintDC(self, self.buffer)" will actually create a
PaintDC and a MemoryDC, select the bitmap into the memory DC and then
blit the memory DC to the paint DC.
[1] Although it is becoming a better practice to avoid using wx.ClientDC
and just call Refresh instead, and do all your painting from the
EVT_PAINT handler. This is because with the newer CoreGraphics API on
OS X "out of order repaints" is much more expensive of an operation.
It's possible that other platforms may move in this direction as well.
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
More information about the wxpython-users
mailing list