2017-05-07 31 views
2

我有DirectX11 UWP應用程序。我使用IDXGIFactory2::CreateSwapChainForCoreWindow和常用參數創建交換鏈。如何在UWP應用程序中減少全屏交換鏈表示延遲?

::DXGI_SWAP_CHAIN_DESC1 desc{}; 
desc.Width    = back_buffer_width; 
desc.Height    = back_buffer_height; 
desc.Format    = DXGI_FORMAT_B8G8R8A8_UNORM; 
desc.SampleDesc.Count = 1; 
desc.SampleDesc.Quality = 0; 
desc.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT; 
desc.BufferCount  = 2; 
desc.SwapEffect   = DXGI_SWAP_EFFECT_FLIP_DISCARD; 
desc.Flags    = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; 
desc.Scaling   = DXGI_SCALING_NONE; 
desc.AlphaMode   = DXGI_ALPHA_MODE_IGNORE; 
::Microsoft::WRL::ComPtr<::IDXGISwapChain1> p_swap_chain; 
Validate_OkResult 
(
    p_dxgi_factory->CreateSwapChainForCoreWindow 
    (
     p_d3d_device.Get() 
    , reinterpret_cast< ::IUnknown * >(h_window) // passing ::Windows::UI::Core::CoreWindow^
    , ::std::addressof(desc) 
    , nullptr 
    , &p_swap_chain 
    ) 
); 
Validate_OkResult(p_swap_chain->SetMaximumFrameLatency(1)); // 1 is minimum allowed value 

當我嘗試通過調用::IDXGISwapChain::SetFullscreenState它失敗DXGI_ERROR_NOT_CURRENTLY_AVAILABLE和我得到以下診斷,改變成全屏模式:

DXGI ERROR: IDXGISwapChain::SetFullscreenState: Core Window SwapChains cannot transition to fullscreen, as they are considered perpetually windowed. [ MISCELLANEOUS ERROR #163: ]

DXGI ERROR: IDXGISwapChain::SetFullscreenState: For modern applications, fullscreen is not available. All swapchains must be windowed. [ MISCELLANEOUS ERROR #206: ]

我想通了,我可以切換全屏模式使用ApplicationView

::Windows::UI::ViewManagement::ApplicationView^h_view(::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()); 
if(h_view->IsFullScreenMode) 
{ 
    h_view->ExitFullScreenMode(); 
} 
else 
{ 
    h_view->TryEnterFullScreenMode(); 
} 

然而,該方法僅隱藏任務欄上,隱藏窗框和最大化窗口。我認爲,在這種情況下,使用翻轉模式演示應該有可能獲得常規全屏交換鏈的低延遲優勢,但這看起來並不是兩項工作,而且交換鏈還在不斷合成。合成翻蓋仍然用於演示,並且呈現滯後仍與窗口模式下相同〜30ms。我是否需要完全禁用組合或者是否有其他方法來避免組合使用額外延遲?

回答

0

一些試驗後我設法找到一個解決方案:除了指針可視化反饋禁用系統的覆蓋將禁止在全屏模式和呈現合成將作爲獨立的翻轉進行。下面的代碼應該添加到::Windows::ApplicationModel::Core::IFrameworkView::SetWindow方法實現:

::Windows::UI::Input::PointerVisualizationSettings^h_visualization_settings{::Windows::UI::Input::PointerVisualizationSettings::GetForCurrentView()}; 
h_visualization_settings->IsContactFeedbackEnabled = false; 
h_visualization_settings->IsBarrelButtonFeedbackEnabled = false; 
::Windows::UI::ViewManagement::ApplicationView^h_view{::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView()}; 
h_view->FullScreenSystemOverlayMode = ::Windows::UI::ViewManagement::FullScreenSystemOverlayMode::Minimal; 

注意,它不完全禁用覆蓋,它只是顯示一個小酒吧:第一,用戶需要點擊顯示相應的覆蓋項目,如任務欄。

相關問題