S.F. Page

Programming,Music,etc...

音声ファイルから動画ファイルを生成する(65) – スワップチェインの部分更新

スワップチェインの部分更新

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利用には少し難しいかもしれない。