Technical Note TN2133

Coalesced Updates

Improving drawing performance by taking advantage of coalesced updates.

Coalesced Updates
How does this affect applications?
What tools can I use to tell if an application is being affected by coalesced updates?
Recommendations
Document Revision History

Coalesced Updates

Mac OS X 10.4 introduces a new behavior of coalescing updates that enables Quartz to more efficiently update the frame buffer during each display refresh. In addition to increasing system efficiency, coalescing updates improves visual consistency and eliminates "tearing" during scrolling and animation. To coalesce updates, the Quartz window server composites all window buffers into a single offscreen frame buffer before flushing it to the screen. When your application issues a command to flush, the system doesn't actually flush that content until the next available display refresh. This allows all updates for multiple applications to happen at the same time. Window server operations (window resize or move, for example) are handled in the same manner—coalesced into a system-wide screen update.

How does this affect applications?

The majority of applications gain the benefit of coalesced updates, however, there are some situations where it can cause performance regressions. Regressions tend to fall into two categories:

What tools can I use to tell if an application is being affected by coalesced updates?

If an application that has been built and linked on Mac OS X 10.4 and later is spending more time drawing than the same application built and linked on a previous system, then it is probably being affected by coalesced updates. There are two tools that can be used to verify if an application is or isn't being affected by coalesced updates, Quartz Debug and Instruments.

Quartz Debug

Quartz Debug is a debugging tool for the Quartz graphics system with several powerful features to help you identify a number of graphics display and performance problems. Once the Mac OS X developer tools have been installed, the Quartz Debug application is located in: /Developer/Applications/Performance Tools/. To see the affect of effects of coalesced updates on applications, including CFM applications and applications linked on systems previous to 10.4, enable forced beam synchronization in Quartz Debug. An application that is being affected by coalesced updates will have a lowered frame rate when beam synchronization is enabled than when beam synchronization is disabled, and often will have increased CPU usage. To learn more about using Quartz Debug to see the effect of coalesced updates see Q&A 1234, Debugging Graphics with QuartzDebug.

Instruments

Instruments is a profiling tool included with the Mac OS X developer tools distribution. Instruments can be used to profile an application and see if too much time is being spent in drawing operations, signaling that an application is having its updates coalesced. Once the Mac OS X developer tools have been installed, the Instruments profiling tool is located on the system at: /Developer/Applications/. If needed, use Quartz Debug to force beam synchronization then, in Instruments, sample your application using the "Time Profiler" instrument. If you see time more time spent in the CGContext drawing operations than you do with beam synchronization disabled, your application is having its updates coalesced.

To learn more about using Instruments for profiling please see the Instruments User Guide.

Recommendations

To applications, this doesn't really change what they should be doing; it just enforces what has been recommended in the past.

General recommendations

  • Flush once per update event.

  • Consider periodic updates when live resizing and scrolling, and if needed draw lower quality results.

  • While an application can get the current screen's refresh rate, the recommendation is to assume a refresh rate of 60 Hz.

  • Applications in general shouldn't draw or flush faster than the user can see. Most animations only need a refresh rate of 30 fps, if an animation needs to update more often, then a timer should be used to limit animation rates to the refresh rate or less.

  • Avoid, if possible, the functions that request an immediate flush to the screen. Applications drawing with Quartz should use CGContextSynchronize rather than CGContextFlush.

  • In Cocoa use NSView's setNeedsDisplay: to request an update for a view instead of the more immediate display:, and in Carbon's HIToolBox use HIViewSetNeedsDisplay or HIViewSetNeedsDisplayInRegion instead of the immediate HIWindowFlush.

Best Practices

  • In drawing routines, do all calculations then draw, minimizing the amount of time between first touching the context and being done with it. In windows that have complex drawing routines, this will minimize the time waiting for a context that is being flushed to be released for more drawing.

  • It is a good idea for animations and screen updates to be time based and frame-limited in order to work best with coalesced updates. That is, they must make a fixed amount of progress per unit of time, rather than per frame, and they must not attempt to run at a rate greater than the refresh rate.

  • Applications that are displaying more than a single animation at a time in one window need to arrange for all animations in a window to run off of the same timer, updating in the same round in the runloop, and flushing together.

  • Decouple your visualization engine from your data engine so that neither engine will impede the other. Avoid network or disk access that would block the UI.

A last resort

If your application cannot adopt any of the above solutions, it is possible to disable coalesced updates for your application. To disable coalesced updates for your application, set the key CGDisableCoalescedUpdates to the CFBoolean value of true in your Info.plist dictionary as shown in Listing 1. This key will only disable coalesced updates for applications running on Mac OS X 10.4.4 or later.

Listing 1  Using CGDisableCoalescedUpdates, in an applications Info.plist, to disable coalesced updates on 10.4.4 and later.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>GraphicsApp</string>
    <key>CFBundleName</key>
    <string>GraphicsApp</string>
         ...
         <key>CGDisableCoalescedUpdates</key>
         <true/>
         ...
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleSignature</key>
    <string>grap</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
</dict>
</plist>


Document Revision History


DateNotes
2010-08-31

Editorial. Grammar and spelling fixes.

2006-01-20

Changed the CGDisableCoalescedUpdates key's value in the Info.plist listing to a CFBoolean true.

2006-01-12

New document that describes how to achieve the maximum frame rate in your Mac OS X application