1. UWP on Hololens에서의 resource leak 체크
UWP App은 명시적인 종료가 없으므로 리소스에 대한 leak체크가 쉽지 않다. 그래서 suspend이벤트나 아니면 임의의 버튼같은걸 만들어서 가상의 종료처리를 하고 이 시점에 leak체크를 하도록 하고 있다.
Hololens버전은 UWP앱이지만 일반적인 DirectX on UWP앱과는 차이가 있다.
swapchain을 사용하지 않는다.
즉 일반적인 UWP앱은 swapChainPanel이라는 XAML 객체를 가지고 있고 이 녀석과 D3D가 연결된다. interop을 하며 서로 ref count를 증가시킨다.
Hololens버전의 경우 Windows::Graphics::Holographic::HolographicCamera^ 객체로부터 frame buffer를 얻어서 D3D에서 RenderTargetView를 만든다. 따라서 D3D객체와 Windows::Graphics::Holographic::HolographicCamera^ 객체는 서로의 ref count를 증가시킨다. Windows::Graphics::Holographic::HolographicCamera^ 객체를 완전히 해제해야 D3D측의 ref count가 감소한다.
아직까지 이 부분을 아직 제대로 처리하지 못하고 있었다. 최소한의 기능구현이 급하다보니 우선순위상 뒤로 미뤄뒀었다. 필수적인 기능들은 다 구현했으므로 이제 종료(?)처리를 제대로 하도록 코드를 수정했다.
Resource leak체크의 최종단계는 ID3D11Device::Release() 호출시 0이 리턴되는지 확인하는 것이다. 만약 D3D리소스 혹은 Windows::Graphics::Holographic::HolographicCamera^객체가 해제되지 않았다면 0보다 큰 값을 리턴할 것이다.
Windows::Graphics::Holographic::HolographicCamera^객체가 해제되지 않았다면 다른 Hololens관련 객체들도 해제되지 않았을 것이다.
다음의 Hololens관련 객체들이 D3DDevice를 해제하기 전에 먼저 확실히 해제해야한다.
Windows::Graphics::Holographic::HolographicSpace^ , Windows::Graphics::Holographic::HolographicFrame^ ,
Windows::Graphics::Holographic::HolographicCamera^
ref class객체라서 ref count를 직접 볼수 없지만 다음과 같은 방법으로 ref count를 확인할 수 있다.
ULONG GetRefCount(IUnknown* pObj) { pObj->AddRef(); ULONG ref = pObj->Release(); return ref; }
//Windows::Graphics::Holographic::HolographicSpace^ m_holoGraphics; IInspectable* pHoloGraphics = reinterpret_cast<IInspectable*>(m_holoGraphics); ULONG ref_count_graphics = GetRefCount(pHoloGraphics);
D3DDevice를 해제하기 직전에 Windows::Graphics::Holographic::HolographicSpace^객체가 1인 상태면 된다. 그래야 D3DDevice::Release()했을때 서로의 ref count를 감소시키고 0으로 리턴되는 결과를 확인할 수 있다.
2. CameraAdded, CameraRemoved 이벤트 처리
앱이 응답하지 않거나 하면 CameraRemoved이벤트가 발생하는데 이것도 처리해줘야한다. 앱이 다시 응답하면 이후에 CameraAdded가 발생한다. 참고로 디버깅할때 브레이크 포인트 찍어놓고 있으면 흔히 발생한다.
이 이벤트는 다음과 같은 수순으로 발생하고 처리한다.
- 최초에 앱이 초기화 되고 나면 CameraAdded이벤트가 날라오고 여기서 Hololens로부터 프레임버퍼를 얻을 수 있다. 이걸로 D3D의 RenderTargetView를 만든다.
- 앱이 응답하지 않거나 기타 다른이유로 CameraRemoved이벤트가 날라온다. 이 시점에서 Hololens의 프레임버퍼는 더 이상 사용할 수 없다. 따라서 Hololens로부터 받은 프레임버퍼로 얻은 RTV를 해제해야한다. D3D디바이스의 lost상태가 아니므로 프레임버퍼와 관련된 리소스만 해제하면 된다. Texture나 Vertex Buffer와 같은 리소스는 그대로 둔다.
- 다시 앱이 응답 가능하게 되면 CameraAdded이벤트가 날라온다. Hololens로부터 프레임버퍼를 얻어서 D3D의 RTV를 만든다. 이제부터 다시 렌더링 가능.