Apple Developer Connection
高度な検索
Member Login ログイン | ご入会 ADC連絡先

Technical Note TN2133
一括更新

GPUでの作業





一括更新

Mac OS X 10.4では、一括更新という新しい動作が導入されており、これによりQuartzは、毎回のディスプレイ更新時にフレームバッファをより効率的に更新できます。システム効率の向上に加え、一括更新は視覚的な一貫性を改善しスクロールやアニメーション中の「ちらつき」を無くします。一括更新を行うために、Quartzウインドウサーバは、スクリーンにフラッシュする前にすべてのウインドウバッファを単独のオフスクリーンフレームバッファに取りまとめます。アプリケーションからフラッシュ命令が出されても、次に利用可能なディスプレイのリフレッシュがあるまでシステムは実際にはそのコンテンツをフラッシュしません。これによって、複数のアプリケーションのすべての更新を一度に実行できます。ウインドウサーバの処理(ウインドウのサイズ変更や移動など)は同じ方法で処理され、システム全体の1回のスクリーン更新に取りまとめられます。

先頭に戻る

アプリケーションへどんな影響がありますか?

一括更新によってアプリケーションのほとんどはメリットを得られます。とはいえ、パフォーマンスが低下する可能性のある状況がいくつかあります。パフォーマンス低下には、次のような2つのタイプがあります。

  • 過剰フラッシュ。ディスプレイのリフレッシュ間隔よりも短かい時間で描画とフラッシュを行うアプリケーションは、リフレッシュレートにまで抑えられます。理想としては、アプリケーションではディスプレイのリフレッシュよりも高速に描画処理すべきではありません。ユーザが見ることのないピクセルをディスプレイに描画するのは時間の無駄になってしまうからです。ウインドウが描画処理されフラッシュされると、ウインドウサーバからのアクセスに備えてバッファはロックされる必要があります。そのためアプリケーションはフラッシュがスクリーンに現れるまではバッファへの描画以外なら実行できます。アプリケーション側でフラッシュ後すぐに描画しようとすると、実際にフラッシュが完了するまでブロックされます。そのためアプリケーションはフレーム同期のタイミングを逃すと、同期まで待機しなければならなくなり、それまで次のフレーム描画を開始することができません。

  • 描画間隔の拡張。アニメーションの実行時に、描画ルーチンに費やす時間がスクリーンのリフレッシュに要する時間より長いと、アニメーションの速度はリフレッシュレートの数分の一に抑えられてしまいます。たとえば、仮にリフレッシュレートが60fpsでアニメーションが最大55fpsで実行できるとすると、30fpsにまで抑えられます。

先頭に戻る

一括更新によってアプリケーションへ影響があったかどうかを知るために使用できるツールはありますか?

10.4でビルドしてリンクしたアプリケーションが、以前のシステムでビルドしてリンクした同じアプリケーションよりも描画に時間がかかる場合、おそらく一括更新による影響です。アプリケーションが一括更新による影響を受けているかどうか確認するために使用できるツールが2つあります。Quartz DebugとSharkの2つです。

Quartz Debug

Quartz Debugは、グラフィックスの表示やパフォーマンスに関する各種の問題を突きとめるのに役立つ、いくつかの強力な機能を備えた、Quatrzグラフィックスシステム用のデバッグツールです。Mac OS Xのデベロッパツールをインストールすると、Quartz Debugアプリケーションはシステムの次の場所に置かれます:/Developer/Applications/Performance Tools/。CFMアプリケーションや10.4以前のシステムの上でリンクしたアプリケーションを含む、アプリケーションに対する一括更新の効果の影響を確認するには、Quartz Debugの強制ビーム同期(Force Beam Synchronization)を有効にします。一括更新による影響を受けるアプリケーションは、ビーム同期が無効なときよりもビーム同期が有効なときの方がフレームレートが低くなり、CPU使用率が上昇します。Quartz Debugを使用して一括更新の影響を確認する詳細についてはQ&A 1236「Debugging Graphics with QuartzDebug」を参照してください。

先頭に戻る

Shark

Sharkは、Mac OS Xのデベロッパツールの配布版に含まれているプロファイリングツールです。Sharkを使用して、アプリケーションをプロファイルし、描画処理に過剰な時間がかかっていればアプリケーションが一括更新されていることを確認することができます。Mac OS Xのデベロッパツールをインストールすると、Sharkプロファイリングツールはシステムの次の場所に置かれます:/Developer/Applications/Performance Tools/。必要があれば、Quartz Debugを使用してビーム同期を強制的に行うようにした後、Sharkで“Time Profile (All Thread States)”モードでアプリケーションをサンプリングします。ビーム同期を無効にして行った場合よりも、CGContextで多くの時間が描画処理にかかっている場合、アプリケーションでは一括更新が行われたことになります。

Sharkを使ったプロファイリングの詳細については、Apple Developer Connectionsのパフォーマンスページ(http://developer.apple.com/performance/)を参照してください。

先頭に戻る

推奨事項

アプリケーションについては、実際のところ、するべきことはこれまでと変わりません。単に従来推奨されてきたことを適用するだけです。

一般的な推奨事項

  • 更新イベントごとに1回フラッシュします。

  • サイズ変更やスクロールを行うときには定期的な更新を意識し、必要なら品質結果を低くして描画します。

  • アプリケーションでは現在のスクリーンのリフレッシュレートを取得できますが、リフレッシュレートは60fpsと想定することを推奨します。

  • アプリケーションでは、通常、ユーザが見えない速度で描画やフラッシュをすべきではありません。アニメーションのほとんどは30fpsのリフレッシュレートで十分です。仮にアニメーションをもっと頻繁に更新する必要がある場合は、タイマを使ってリフレッシュレート以下にアニメーションレートを制限するようにします。

  • 可能ならば、スクリーンに対する即時のフラッシュを要求する関数の使用は避けます。Quartzを使って描画を行うアプリケーションではCGContextFlushよりもCGContextSynchronizeを使用するようにします。

  • Cocoaでは、すぐに表示するdisplay:よりも、NSViewsetNeedsDisplay:を使って表示の更新を要求するようにします。CarbonのHIToolBoxでは、HIWindowFlushよりもHIViewSetNeedsDisplayまたはHIViewSetNeedsDisplayInRegionを使用するようにします。

先頭に戻る

ベストプラクティス

  • 描画ルーチンでは、計算をすべてしてから描画を行うことで、コンテキストの処理開始から処理の終了までの時間を短縮します。複雑な描画ルーチンを持ったウインドウでは、これで、フラッシュ中のコンテキストが解放されて描画できるようになるまで待機する時間が短縮されます。

  • 一括更新で最適な動作をするように、アニメーションと画面更新を時間に基づくようにしてフレームを制限することは良い考えです。つまり、フレームごとではなく時間単位ごとに処理が一定して進展するようにして、リフレッシュレートよりも高速に動作するようにすべきではありません。

  • 1つのウインドウに一度に複数のアニメーションを表示するアプリケーションは、ウインドウ内のすべてのアニメーションを調整して、共通のタイマに基づいて動作するようにし、実行ループの同じ周回で更新して同時にフラッシュするようにする必要があります。

  • 視覚化エンジンとデータエンジンを分離し、どちらのエンジンももう一方を妨げないようにします。UIをブロックしてしまうネットワークやディスクのアクセスを回避します。

先頭に戻る

最後の手段

上記のいずれの方法もアプリケーションで採用できない場合は、アプリケーションの一括更新を無効にできます。アプリケーションの一括更新を無効にするには、リスト1に示すように、Info.plistディクショナリのキーCGDisableCoalescedUpdatesにCFBoolean値trueを設定します。このキーは、Mac OS X 10.4.4以降で実行するアプリケーションの一括更新のみを無効にします。注:一括更新を無効にすることは、最後の手段としてのみお勧めします。無効にしても、システムではまだ、必要に応じてアプリケーションに対して更新を強制的に一括実行します。また、アプリケーションの一括更新を無効化すると、ウインドウ更新中の視覚的な正確さからちらつきに至るまで問題の原因になり得ます。

リスト1:アプリケーションのInfo.plistでCGDisableCoalescedUpdatesを使って、10.4.4以降の一括更新を無効にする

<?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>

重要:互換性を最大限に高めるために、10.4以前のシステムの上でリンクしたすべてのアプリケーション(10.4の上でリンクしているCFMアプリケーションを含む)では、フラッシュが単独で実行される場合、フラッシュ処理は一括更新サイクルに強制的に組み込まれません。ウインドウサーバを経由するすべてのアクセラレートされたサーフェスフラッシュは、一括更新サイクルを通じて実行されます。しかし、従来のアプリケーションまたはInfo.plistで一括更新を無効にしているアプリケーションによってフラッシュが実行されたときに、一括更新がすでに進行中の場合、そのフラッシュはその時点の一括更新に組み込まれます。つまり、視覚的な正確性を求める最新のアプリケーションは、フラッシュが早すぎる可能性のある従来のアプリケーションに優先するということです。

先頭に戻る

ドキュメント改訂履歴

日付メモ
2006-01-20Info.plistリストのCGDisableCoalescedUpdatesキー値をCFBoolean trueへ変更。
2006-01-12Mac OS Xアプリケーションで最大フレームレートを達成する方法。

掲載日: 2006-01-20




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.