複数のバッファリング
複数のバッファリング
複数のバッファリングは、複数のフレームバッファーを使用する方法です。基本的には、次のように動作します。複数のバッファを有効にすると画面と描画操作に使用される1つまたは複数のバックバッファに画像を生成するディスプレイコントローラによって使用されるフロントバッファがあります。描画操作を完了した後のバックバッファが表示されてフロントバッファになる。
2つのバッファ、1つのフロントおよび1つのバックバッファと、それは通常、2つのバックバッファと、それが"トリプルバッファリング"と呼ばれる1つのフロントバッファーで、"ダブルバッファリング"と呼ばれています。
一般的には、いくつかの望ましくない影響を回避することができる方法です。
- 項目によって画面の項目を描画するの可視プロセス。
- 描画操作をオーバーラップによる影響を点滅。
- 垂直ブランキング期間外の操作を記述することによって引き起こされる影響を引き裂く。
次のセクションでは、要件がemWinと"ダブルバッファリング"に対する"トリプルバッファリング"の利点を設定する方法について、この機能を使用できるように、それが動作する方法を詳細に説明しています。さらにそれは"複数のバッファリング"を自動的に使用するオプションのウィンドウマネージャを設定する方法を説明します。
どのように動作する
複数のバッファは、ディスプレイがこれまでに既に完全に描画操作が処理中である場合であっても、レンダリングされた画面が表示されているので、複数のフレームバッファを使用することです。フロントバッファの現在の内容を描画するプロセスを開始するときにバックバッファにコピーされます。その後、すべての描画操作は、このバックバッファで有効になります。描画操作が完了した後、バックバッファはフロントバッファになる。バックバッファを作ることは目に見えるフロントバッファは、通常はフレームバッファの開始アドレスは、ディスプレイコントローラのレジスタの変更が必要です。
今では、ディスプレイはディスプレイコントローラのアプリケーションによって継続的に更新さbeeingされていることを考慮すべきである。1秒間に60回。各期間の後に通常はVSYNC信号として知られている垂直syncronisation信号がある。バックバッファを作るために最高の瞬間は、新しいフロントバッファはこの信号です。考慮しない場合VSYNC信号引き裂く効果が発生する可能性があります。
ティアリング効果:
ダブルバッファリング
ダブルバッファリングで唯一の2つのバッファが用意されています:One前面および1つのバックバッファ。描画操作を開始するときに、フロントバッファの現在の内容は、バックバッファにコピーされます。操作の完了後にバックバッファが表示されてフロントバッファになるはず。
としてディスプレイコントローラのVSYNC信号に反応してこれを行うための最高の瞬間の上に説明した。ここでトリプルのバフ- eringに対してダブルバッファリングの欠点が明らかにされます:どちらのフレームバッファの開始アドレスは、描画操作の終了時または次のVSYNC信号まで待った後にすぐに変更されます。これは、ティアリングの影響が生じる可能性があることを意味したり、パフォーマンスが原因次のVSYNC信号を待つのが遅くなります。
トリプルバッファリング
One前面2背面バッファ:名として使用できる3つのバッファが存在する意味。描画操作を開始するときに、フロントバッファの現在の内容は、最初のバックバッファにコピーされます。操作の完了後にバックバッファが表示されてフロントバッファになるはず。二重緩衝液に反して、すぐにバッファを切り替える必要はありません。新しいフロントバッファに切り替えは、割り込みサービスルーチン(ISR)によって達成することができるディスプレイcontollerの次のVSYNC信号で行うことができる。複数のフレームバッファーに対応することができるディスプレイコントローラのほとんどは、割り込みソースとしてVSYNC信号を提供しています。ISR内で保留中のフロントバッファは見えるようになります。保留中のフロントバッファは見えるようになるまでは、さらに描画操作には使用されません。保留中のフロントバッファが見えるようになる前にさらに描画- INGの操作が開始されている場合は秒、ONDのバックバッファは、描画操作に使用されます。新しいバッファは、VSYNC信号を待ってまで準備ができている場合、それは新しい保留フロントバッファなどになります。これは、常に書き込み操作に対するフロントバッファを保護します。
それは次のフレームを描画するときに、いくつかのDIS -プレイコントローラ上での表示バッファの開始アドレスを変更するだけ効果がかかることに言及すべきである。この場合、ISRのないソリューションは、ISRなく同様に動作します。アドレスを変更すると、直接effektかかる場合にのみ、ISRは、影響を引き裂く回避するために必要です。
要件
次のリストは、複数のバッファを使用するための要件を示しています。
- ディスプレイコントローラは、複数のフレームバッファーをサポートする必要があります。
- 複数のフレームバッファのための十分なビデオメモリが利用可能になります。
- 涙の効果を回避する必要がある場合、それは最高のパフォーマンスを達成するために推奨されているディスプレイコントローラとトリプルバッファリングのVSYNC信号に反応することができるはずです。
制限事項
残念ながらそれは、複数のバッファのサポートと一緒に仮想画面を使用することはできません。
コンフィギュレーション
一般的に変更する必要のあるコンフィグレーションファイルのLCDConf.c、ディスプレイの設定ルーチンLCD_X_Config()とドライバのコールバック関数のLCD_X_DisplayDriver()の2のルーチンがあります。
LCD_X_Config()
基本的に一つのことはここで行われる必要があります:複数のバッファの使用を有効にする。
基本的な設定
ディスプレイドライバのデバイスを作成する前に行う必要がある最初の事はCON -見つけ出すことです複数のバッファインタフェースを。これは通常、LCD_X_Config()で行われます。それは厳密に次のコードスニペットに示すように、ディスプレイドライバのデバイスを作成する前に複数のバッファリングを有効にするために必要です。
/ / / /セットのディスプレイドライバと色変換/ / GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER、COLOR_CONVERSION、0、0);ボイドLCD_X_Configは(ボイド){/ / / / / / GUI_MULTIBUF_Configを(NUM_BUFFERS)multibuffering初期化... }
バッファをコピーするためのカスタムコールバックルーチン
さらにバッファをコピーするためのコールバックルーチンを設定することができます。として、それがバックバッファへの電流のフロントバッファの内容をコピーするために必要とされる描画操作の開始時に上記で説明した。通常は、単純なmemcpyを操作は、これを実行するために使用されます。しかし、例えば使用するディスプレイコントローラは、それがコピーオペラ - エーションに使用するために必要なことができるコピー操作を実行することができるならBitBLTエンジンで構成されている場合。またはDMAベースのルーチンは、コピー操作を行うために使用する必要があります。これらのケースでは、カスタム定義されたコールバック関数は、この操作に使用することができます。これは、次のコードスニペットに示すように、ディスプレイドライバのデバイスを作成した後にインストールすることができます。
静的ボイド_CopyBuffer(int型LayerIndex、int型IndexSrc、int型IndexDst){unsigned longのbufferSizeは、AddrSrc、AddrDst; / / / /一つのフレームバッファのサイズを計算する/ / bufferSizeは=(XSIZE * YSIZE * BITSPERPIXEL)/ 8; / / / /元および宛先アドレスを計算する/ / AddrSrc = _VRamBaseAddr + bufferSizeは* IndexSrc; AddrDst = _VRamBaseAddr + bufferSizeは* IndexDst、memcpyを((void *)をAddrDst、(void *)をAddrSrc、bufferSizeは);}ボイドLCD_X_Config(ボイド){/ / / / /セットのディスプレイドライバと色変換/ / GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER、COLOR_CONVERSION、0、0); / / / /セットのコピー操作/ / LCD_SetDevFunc(のカスタムコールバック関数/ / / / / GUI_MULTIBUF_Configを(NUM_BUFFERS)multibuffering初期化0、LCD_DEVFUNC_COPYBUFFER、(ボイド(*)())_ CopyBuffer);}
単純なmemcpyを()操作は、ドライバのデフォルトの動作であるため、上記のサンプルの実装は通常、意味をなさないことに注意してください。それは使用する必要のあるすべてのアクセラレーションのオプションがある場合は、カスタムコールバック関数を使用するためにのみ意味を持ちます。
LCD_X_DisplayDriver()
描画のプロセスが完了した後、バックバッファは見えるようになります。ディスプレイドライバはディスプレイドライバのコールバック関数にLCD_X_SHOWBUFFERコマンドを送信します。コールバック関数は、コマンドに反応することがあり、バッファが見えるようになることを確認する必要があります。これは、どちらかのISRによって、または直接、ディスプレイコントローラのフレームバッファの開始アドレスに右のアドレスを書き込むことにより行うことができます。
ISRとの
次のコードスニペットは、サンプル実装を示しています。
静的ボイド_ISR_EndOfFrame(ボイド){unsigned longのADDR、bufferSizeは、(_PendingBufferが> = 0){/ / / /与えられたバッファのアドレスを計算する場合/ / bufferSizeは=(XSIZE * YSIZE * BITSPERPIXEL)/ 8; ADDR = _VRamBaseAddr + bufferSizeは* pDataに - >インデックス/ / / /バッファが/ / GUI_MULTIBUF_Confirm(_PendingBuffer)表示されていることを確認して送信; _PendingBuffer = -1;}} intはLCD_X_DisplayDriver / / / / / / AT91C_LCDC_BA1 = ADDR与えられたバッファが見えるよう(符号なしLayerIndex、符号なしCmdを、無効* P){スイッチ(CMD){ケースLCD_X_SHOWBUFFER:LCD_X_SHOWBUFFER_INFO * pDataに、pDataに=(LCD_X_SHOWBUFFER_INFO *)のp; / / / /バッファのインデックスはISR / / _PendingBufferで使用されることを忘れないでください= pDataは、 >インデックス、休憩、... }}
上記の実装は次のVSYNC信号で実行されるISRの存在を前提としています。
ISRなし
代わりに利用可能なISRがない場合にはアドレスが引き裂く効果が発生する可能性があることを発見利点を直接設定することができます。次のコードスニペットは、サンプル実装を示しています。
int型LCD_X_DisplayDriver(符号なしLayerIndex、符号なしCmdを、無効* P){unsigned longのADDR、bufferSizeは、スイッチ(CMD){... ケースLCD_X_SHOWBUFFER:LCD_X_SHOWBUFFER_INFO * pDataに、pDataに=(LCD_X_SHOWBUFFER_INFO *)のp; / / / /与えられたバッファのアドレスを計算/ / bufferSizeは=(XSIZE * YSIZE * BITSPERPIXEL)/ 8; ADDR = _VRamBaseAddr + bufferSizeは* pDataに - >インデックス; / / / / / / AT91C_LCDC_BA1与えられたバッファを可視にする= ADDR; / / / /バッファが/ / GUI_MULTIBUF_Confirm(pDataを - >インデックス)表示されていることを確認送信、休憩、... }}
WMと、複数のバッファの自動使用
オプションのウィンドウマネージャ(WM)が自動的に複数のバッファ機能を使用することができます。関数WM_MULTIBUF_Enableは()この機能を有効にするために使用することができます。無効な勝利 - ダウズを再描画する前にバックバッファにWM第一のスイッチを有効にした場合。すべての無効なウィンドウを描画した後、新しい画面が見えるようになります。これは、ウィンドウが画面のウィンドウを描画するプロセスを隠します。
複数のバッファAPI
次の表は、複数のバッファのサポートの使用可能なルーチンを示します。
ルーチン | 説明 |
---|---|
基本的な機能 | |
GUI_MULTIBUF_Begin() | ニーズは、描画操作を開始する前に呼び出されます。 |
GUI_MULTIBUF_BeginEx() | パラメータLayerIndex以外は上記と同じ。 |
GUI_MULTIBUF_Config() | 複数のバッファの使用を設定するために呼び出す必要があります。 |
GUI_MULTIBUF_ConfigEx() | パラメータLayerIndex以外は上記と同じ。 |
GUI_MULTIBUF_Confirm() | 保留中のフロントバッファは見えるようになった直後に呼び出す必要があります。 |
GUI_MULTIBUF_ConfirmEx() | パラメータLayerIndex以外は上記と同じ。 |
GUI_MULTIBUF_End() | ニーズは、描画操作を完了した後で呼び出されます。 |
GUI_MULTIBUF_EndEx() | パラメータLayerIndex以外は上記と同じ。 |
GUI_MULTIBUF_GetNumBuffers() | 使用するバッファーの数を返します。 |
GUI_MULTIBUF_GetNumBuffersEx() | パラメータLayerIndex以外は上記と同じ。 |
オプションのウィンドウマネージャの機能 | |
WM_MULTIBUF_Enable() | オプションのWMで、複数のバッファの自動使用が有効または無効にします。 |