Painting Optimization

C

cronusf

I have a custom control that does some expensive painting operations
in 3D. When the user drags another window over the control, it gets
real slow because of all the repaints generated. This is because the
3D rendering code is in the OnPaint handler.

So what we'd like to do, is render to an offscreen surface, and just
copy the surface to the client area in situations like the user
dragging a window over the control. However, other things in the
control can cause a repaint where we want to actually redo the
rendering...like if the user rotates the object in 3D. In the mouse
move event, the control is refreshed with the new orientation.

I'm assuming that instead of refreshing the control in these
situations, we should update the offscreen surface and then force a
refresh to copy it from the offscreen surface to the client area. But
I am just wondering if there is another idea, or a strategy built into
the Forms framework for this type of thing.
 
P

Peter Duniho

I have a custom control that does some expensive painting operations
in 3D. When the user drags another window over the control, it gets
real slow because of all the repaints generated. This is because the
3D rendering code is in the OnPaint handler.

So what we'd like to do, is render to an offscreen surface, and just
copy the surface to the client area in situations like the user
dragging a window over the control. However, other things in the
control can cause a repaint where we want to actually redo the
rendering...like if the user rotates the object in 3D. In the mouse
move event, the control is refreshed with the new orientation.

I'm assuming that instead of refreshing the control in these
situations, we should update the offscreen surface and then force a
refresh to copy it from the offscreen surface to the client area. But
I am just wondering if there is another idea, or a strategy built into
the Forms framework for this type of thing.

I think your proposed solution is probably the best. Ideally, you'd just
be able to set the DoubleBuffered property of your form to "true" and let
..NET handle the rest. But my recollection is that it doesn't do any
optimizations with that; OnPaint() still winds up getting called for a
simple invalidation. (For good reason, actually...since the API doesn't
provide for any way to distinguish between something that's invalidated
because the underlying data changed and just because a portion of the
window has been revealed).

So, barring that kind of support, you're left rendering off-screen and
then copying to the window any time the window needs to be redrawn.

It's not a bad approach at all. It's a nice way of separating the
underlying model invalidation from the on-screen view invalidation and
should address the performance issues you're talking about (of course, you
will still have the same performance issues any time you _do_ need to
repeatedly redraw the underlying model, such as with mouse input...but
that's a completely different matter :) ).

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top