All drawing into windows in Mac OS X is double-buffered unless you explicitly request otherwise. When you draw content into the graphics port (GrafPort
) of a window, you are actually drawing into the offscreen drawing buffer associated with the window. The content being drawn does not appear onscreen until QDFlushPortBuffer
is called.
The Carbon Event Manager calls QDFlushPortBuffer
at the following times:
An event is retrieved—the event can be retrieved either by a call to WaitNextEvent
or by an event handler returning control to the Carbon Event Manager.
A Human Interface Toolbox routine must draw some content—this usually happens when routines such as TEIdle
or TEClick
are called
The buffer is not flushed when QuickDraw drawing routines (such as LineTo
, FrameRect
, and CopyBits
) are called or when controls are drawn. In nearly all cases, there should be no need for your application to flush the port buffer explicitly. Instead, simply let the system flush the buffer at event retrieval time. Flushing the port buffer frequently can significantly impact performance. If you absolutely must flush the buffer explicitly, make sure to coalesce your content drawing operations together and then flush the port buffer once.
The following guidelines detail how you should deal with the performance implications of Mac OS X window buffering:
Avoid triple buffering. If your application maintains an offscreen graphics world (GWorld) for each window or if it buffers the window contents during drawing, be sure to disable or conditionalize such code. Buffering in this manner serves no purpose on Mac OS X other than to inefficiently occupy extra memory and slow down window drawing.
Let the system flush the window to screen. A set of small window buffer flushes generally requires significantly more time to complete than one large window buffer flush. The best thing to do is to wait for the system to flush the buffer at event loop time. If you cannot wait for the system to flush the port buffer, a good tactic is to wait until a set of small flushes have accumulated and then flush it. Avoid flushing after every call to FrameRect
, LineTo
or CopyBits
. Instead, flush when all content is drawn.
Disable control updates while changing attributes. When changing the attributes of a large number of controls, you should consider using SetControlVisibility
on the root control to prevent redundant drawing. All Control Manager functions that alter the appearance of a control immediately cause the control to be redrawn in the window buffer. Although the window buffer is not flushed to screen until QDFlushPortBuffer
is called, rendering controls still takes time, especially given the computationally expensive nature of the Aqua user interface.
Eliminate implicit window buffer locking by QuickDraw. Locking the port buffer explicitly before a sequence of QuickDraw calls prevents QuickDraw from creating a lock for each individual call. See “Improving QuickDraw Performance” for more information.
© 2003, 2006 Apple Computer, Inc. All Rights Reserved. (Last updated: 2006-04-04)