スワップチェインの部分更新
DXGI 1.2からDirty RectangleとScroll Areaがサポートされた。詳細は「Enhancing presentation with the flip model, dirty rectangles, and scrolled areas」にであるが、絵だけ引用すると
となっている。これにより、更新が必要な部分のみを描画し、更新矩形およびスクロール矩形を指定することで一つ前のフレームのうち更新されていない矩形と合成が行われる。フレームの更新シーケンスは下図のようになっている。「Enhancing presentation with the flip model, dirty rectangles, and scrolled areas」から引用である。
コードの実装例は下記の通り。Present1()メソッドに更新矩形の情報を渡すだけである。
DXGI_PRESENT_PARAMETERS parameters = {};
MARGINS& m = window_.margins();
RECT srect[1] = { { m.cxLeftWidth + GetSystemMetrics(SM_CXBORDER), m.cyTopHeight, window_.width() - (m.cxLeftWidth + m.cxRightWidth), window_.height() - (m.cyTopHeight) } };
parameters.DirtyRectsCount = 1;
parameters.pDirtyRects = srect;
parameters.pScrollRect = nullptr;
parameters.pScrollOffset = nullptr;
HRESULT hr = dxgi_swap_chain_->Present1(1, 0, &parameters);
if (hr == DXGI_ERROR_INVALID_CALL){
parameters.DirtyRectsCount = 0;
parameters.pDirtyRects = nullptr;
hr = dxgi_swap_chain_->Present1(1, 0, &parameters);
}
if (FAILED(hr)){
restore_swapchain_and_dependent_resources();
}
この機能を使用するにはスワップチェインをDXGI_SWAP_EFFECT_FLIP_SEQUENTIALで作成しておかなくてはならない。さらにスワップチェイン生成後の1回目のPrensent1()は部分描画ではなく全画面に描画しておかないといけない。そうしないとエラーとなってしまう。上記のコードではDXGI_ERROR_INVALID_CALLのときはDirtyRectsを無効化し、全画面を再描画するように試みるようにしている。
うまく使えば描画にかけるコストを下げることができるけれども、UI利用には少し難しいかもしれない。