当你的D3D11程序在全屏模式时,如果由于某种原因导致全屏模式被终止而转换到窗口模式,则有可能会造成ID3D11Device设备无法释放。
比如当一个窗口从另外的显示器拖到全屏显示显示器时,或者在全屏程序中弹出一个对话框时,都会造成程序退出全屏模式。
此时IDXGISwapChain的Present会返回DXGI_STATUS_OCCLUDED。正常情况下在Present后,ID3D11Device设备的引用计数会减少。但有时引用计数不变。这样的话就会造成资源的泄漏。
UINT GetRef( IUnknown * iun )
{
UINT nRef = 0;
if ( iun )
{
iun->AddRef();
nRef = iun->Release();
}
return nRef;
}
// ......
UINT nRef1 = GetRef( pd3dDevice );
HRESULT hr = pSwapChain->Present( 1, flags );
if ( DXGI_STATUS_OCCLUDED == h )
{
m_bOccluded = TRUE;
// ...
UINT2 nRef2 = GetRef( pd3dDevice );
if ( nRef2 != nRef1 - 1 )
{
// 此时说明 pd3dDevice 的一个引用没有被释放,因此在最后程序退出时无法完成ID3D11Device的释放。
// ...
}
// ...
}
// ...
//
// 现在的办法是在程序退出时强制释放ID3D11Device接口
//
UINT nRef = m_pd3dDevice->Release();
while ( nRef > 0 )
{
nRef = m_pd3dDevice->Release();
}