はじめにQuickTime 6.4には、Windowsアプリケーションのスクリーン更新を向上させる新しいダブルバッファ機能が含まれています。この機能は、Mac OS X上と同様の、遅延フラッシュ方式を利用しています。また、QuickTimeのグラフィックスポートごとに完全なオフスクリーン(バック)バッファを提供しており、定期的に、または明示的なリクエストに応じて、バッファをスクリーンにフラッシュします。この方法には、クリッピング処理の向上や、UI要素の散発的なフラッシュの防止など、多くのメリットがあります。 もう少し詳しく説明します。 QuickTimeグラフィックスポートへの更新分のピクセルデータは、バックバッファに描画され、すぐにスクリーンに描画されるわけではありません。各ポートの「ダーティな」領域(変更された部分)は、フラッシュが実行されるまで蓄積され、フラッシュされた時点でダーティリージョン全体がスクリーンに描画されます。 重要:ムービーを描画するとき、またはムービーをアイドル状態にするときに、QuickTimeが自動的にダーティリージョンをスクリーンにフラッシュします。 また、必要な場合はアプリケーションで明示的にフラッシュを実行することもできます(「新しい機能」を参照)。 機能の使用は任意アプリケーションによっては、この機能を使用しないことも考えられるため、この機能の使用は任意です(後述の「重要事項」を参照)。 この機能を使用するには、Windowsアプリケーションでは、次に示すように起動時に リスト1:QuickTimeダブルバッファの有効化 // QuickTimeダブルバッファを有効にする InitializeQTML(kInitializeQTMLEnableDoubleBufferedSurface); この機能を有効にすると、QuickTimeは、要求元のアプリケーションに関連付けられているグラフィックスポートへのスクリーン更新に対して、自動的にダブルバッファ機能を使用します。 最も簡単な使い方アプリケーションが更新リージョンの特殊な処理を実行しない場合でも、上記のリスト1に示すように、この機能を単に有効にしておくこともできます。QuickTimeは、デフォルトではこの機能を使用し、通常のスクリーン更新操作のためにダーティリージョンの蓄積と基本的なフラッシュを実行します。場合によっては、APIをそれ以上使用する必要はありません。 新しいAPIの使用アプリケーションが更新リージョンの特殊な処理を実行する場合は、この機能を利用するために新しいダブルバッファAPIを使用する必要があります。このセクションでは、これらのAPIについて簡単に説明します。 新しいフラグkInitializeQTMLEnableDoubleBufferedSurface
kQTMLNoDoubleBufferPort
新しい機能以下の新しいAPIを使用すると、ポートに蓄積されるダーティリージョン( QTMLAddRgnToDirtyRgn QTMLAddRectToDirtyRgn QTMLAddNativeRgnToDirtyRgn QTMLAddRgnToDirtyRgn(GrafPtr port, RgnHandle *dirtyRgn) QTMLAddRectToDirtyRgn(GrafPtr port, Rect *dirtyRect) QTMLAddNativeRgnToDirtyRgn(GrafPtr port, void *dirtyHRGN) 上記の新しいAPIは以下の用途に使用します。
注:上記の呼び出しは、最小限の変換処理で、コードに都合の良い方法でダーティリージョンを追加できるようにするために用意されています。対象となる更新処理に適した呼び出しを使用してください。 QTMLFlushDirtyPorts すべてのダーティポートを1つずつ確認し、それらのダーティリージョンをスクリーンにフラッシュします。この呼び出しは、特定のポートのバックバッファをスクリーンと同期する必要があるために実行されるフラッシュではなく、定期的な全体のフラッシュに使用することを目的としています。 QTMLFlushDirtyPorts() QTMLFlushPortDirtyRgn 指定されたポートのダーティリージョンをスクリーンにフラッシュします。この呼び出しは、 QTMLFlushPortDirtyRgn(GrafPtr port) QTMLGetBackbufferHDC GDIによるバックバッファへのアクセスを可能にします。呼び出し元は、 QTMLGetBackbufferHDC(GrafPtr port, HDC *backBufferHDC) QTMLReleaseBackbufferHDC GDIによるバックバッファへのアクセスを可能にします。呼び出し元は、バックバッファのうちダーティになった領域をQuickTimeに知らせるために、バックバッファ QTMLReleaseBackbufferHDC(GrafPtr port, HDC *backBufferHDC) 重要事項アプリケーションでは、QTMLとWindowsによる単一ウインドウへの描画を組み合わせて、互いを上書きし合うようなことは避けてください。Windowsが所有するウインドウ内でQTMLが所有する領域に、子 アプリケーションで考慮すべきもう1つ重要なことは、 一般に、ポートへの描画方法は次の4つのカテゴリに分類され、それぞれ少しずつ動作が異なります。 QuickTimeQuickTimeによる描画では、ムービーに関連付けられているポートに、ムービーがビジュアル要素を描画する処理が伴います。このタイプの描画では、ダブルバッファが有効な場合はバックバッファへ描画され、ダーティリージョンがポートに自動的に追加されて、スクリーンにフラッシュされます。 QuickDrawQuickDraw呼び出しを使って実行される描画は、ポートに適切なダーティリージョンを自動的に追加しますが、スクリーンに自動的にはフラッシュされません(これが行われるのは、スクリーンへ1回blitするだけで多数のQuickDrawレンダリングを実行できるようにするためです。スクリーンフラッシュは呼び出しの後で明示的に、またはタイマによって定期的に行う必要があります。 GDIポートに描画するには、GDIを使用して、 PixMapへの直接アクセスポートを慎重にロックすることにより、 あらゆる新しい機能の場合と同様に、ダブルバッファ機能を使用する一方で、古いQuickTimeバージョンとの下位互換性も維持したい場合は、アプリケーションの起動時に必ずQuickTimeのバージョンをチェックして、以前のQuickTimeバージョンで新しいAPIを使用しないでください。これらの呼び出しはQuickTime 6.4まで機能します。 以下のコードに、QuickTimeバージョンを取得する方法を示します。 リスト2:QuickTimeバージョンの取得
{
/* インストールされているQuickTimeのバージョンをチェックする */
long version;
OSErr result;
result = Gestalt(gestaltQuickTime,&version);
if ((result == noErr) && (version >= 0x06408000))
{
/* バージョン6.4以降を使用する */
}
}
例例1 オフスクリーンバッファにはウインドウの有効な表現がすでに存在するため、この動作を選択するアプリケーションは、 リスト3:Windows更新リージョンをポートのダーティリージョンに追加し、ポートをスクリーンにフラッシュ
case WM_PAINT:
{
RgnHandle macUpdateRgn = nil;
HRGN winUpdateRgn = CreateRectRgn(0,0,0,0);
macUpdateRgn = NewRgn();
BeginUpdate((GrafPtr) moviePort);
// アプリケーションで更新リージョンの特殊な処理を実行する場合は、
// Mac更新リージョンを取得する。特殊な処理をしない場合は、
// これをスキップできる。
MacCopyRgn(moviePort->visRgn, macUpdateRgn);
EndUpdate((GrafPtr) moviePort);
// (MacUpdateRgnに応じて、または何らかの理由で)
// アプリケーションで実行したい新しい描画がある場合は、
// ここで実行する。この描画は
// バックバッファで実行され、この呼び出しの終わりに
// スクリーンにフラッシュされる。
// Windows更新リージョンを取得する
GetUpdateRgn(hWnd, winUpdateRgn, FALSE);
// BeginPaint/EndPaintを呼び出して、更新リージョンをクリアする
BeginPaint (hWnd, &ps);
EndPaint(hWnd, &ps);
// ポートのダーティリージョンに、Windowsが更新の必要を示す
// リージョンを追加する。これによって、
// 2つの和集合をバックバッファから次のフラッシュのスクリーンに
// コピーできる。
QTMLAddNativeRgnToDirtyRgn((GrafPtr) moviePort, winUpdateRgn);
DeleteObject(winUpdateRgn);
// ダーティリージョン全体をスクリーンにフラッシュする
QTMLFlushPortDirtyRgn((GrafPtr) moviePort);
}
例2 長い一連の描画操作を結合し、最後に1回フラッシュを使用して、それらをすべて同時に表示すると都合がよい場合があります。次の例では、まずQuickDrawを使用して一連の縮小矩形を描画し、次にGDIを使用してバックバッファ リスト4:長い一連の描画操作を結合し、1回のフラッシュでそれらをすべて同時に表示
{
Rect myRect;
Pattern currentPattern;
myRect.top = myRect.left = 0;
myRect.bottom = myRect.right = 200;
SetPort(myWindowPort);
// この描画はQuickDrawを使って実行する。
// QuickDraw描画操作は、
// 影響のあったエリアをポートに
// 蓄積されたダーティリージョンに
// 自動的に追加する。
while (myRect.top < 50) {
// パターンを入れ替える
currentPattern =
(currentPattern == pattern1) ? pattern2 : pattern1;
// 現在の矩形を別のパターンで塗りつぶす
MacFillRect(myRect, currentPattern);
// 矩形をほんの少し縮小する。
MacInsetRect(myRect, 10, 10);
}
{
RECT winRect;
HDC backbufferHDC = NULL;
// ポートに関するバックバッファのHDCを取得する
QTMLGetBackbufferHDC(myWindowPort, &backbufferHDC);
// 上記のQuickDrawレンダリングを止めた場所に
// Windows RECTを作成する
winRect.top = myRect.top;
winRect.left = myRect.left;
winRect.bottom = myRect.bottom;
winRect.right = myRect.right;
// さらに別の矩形を塗りつぶす
FillRect(backbufferHDC, &winRect, hBrush);
// このバックバッファHDCを解放する必要がある。
QTMLReleaseBackbufferHDC(myWindowPort, &backbufferHDC);
// この描画はバックバッファに直接実行されるため、
// ダーティリージョンをポートに追加する必要がある。
QTMLAddRectToDirtyRgn(myWindowPort, & myRect);
}
// ここで、先へ進んで、すべての描画をスクリーンにフラッシュする
QTMLFlushPortDirtyRgn(myWindowPort);
}
ドキュメント改訂履歴
掲載日:2005-10-18 | ||||||||||
|