[StartD2D-10] 디바이스 로스트( Device Lost ) 처리하기

DirectX 11 2011. 11. 23. 08:00 Posted by 알 수 없는 사용자

앞서 작성했던 예제 샘플들은 사실 완전한 상태의 코드가 아닙니다. ( 죄송...^^ )
바로 이 디바이스-로스트와 관련한 상황이 있어야, 안정성을 향상시킬 수 있습니다.

디바이스-로스트의 처리는 다음과 같은 절차를 진행해야 합니다.

1. 디바이스-로스트가 발생함을 체크
2. 디바이스 의존적 리소스를 모두 제거
3. 디바이스 의존적 리소스를 재할당


이 세가지를 처리하는 것이 디바이스-로스트 상황에 대처하는 것입니다.
Direct2D 의 리소스와 관련한 내용은
http://vsts2010.net/593 글에서 제가 언급했었습니다.^^

그러면 하나씩 살펴보겠습니다.
우리가 진행했던 일반적인 렌더링 작업은 아래와 같습니다.


여기서 우리의 첫번째 단계를 처리합니다.
바로 hr = ::g_ipRT->EndDraw(); 부분입니다.
EndDraw()는 렌더링 작업의 결과를 리턴합니다.
리턴 값이 D2DERR_RECREATE_TARGET 이면, 바로 디바이스-로스트 상황입니다.
이름에서 유추할 수 있듯이 "에러가 났으니, 다시 생성하라" 입니다.

이번에 제가 사용할 샘플은 바로 이전 시간에 했던 알파이미지를 렌더링하는 샘플입니다.
이 샘플에서 디바이스 의존적인 리소스는 렌더 타겟과 비트맵입니다.
이 샘플에서 디바이스-로스트 상황이 발생한다면,
렌더타겟과 비트맵 리소스는 메모리에서 제거했다가 다시 생성해 주어야 합니다.

그래서 이번 샘플에서는 이들 리소스를 한번에 생성/삭제 하는 함수를 만들었습니다.


그리고 또 하나 고려해야 하는 부분이 있습니다.
바로 윈도우 사이즈의 변경입니다.
이 경우는 디바이스-로스트가 발생하지는 않습니다만,
순간적으로 화면이 깜빡이는 현상을 보이게 됩니다.
이 곳에도 역시 적절한(?) 처리를 해야 합니다.


렌더타겟의 리사이즈 작업이 실패하면,
역시 디바이스 의존적 리소스들을 모두 제거해 버립니다.

이제 WM_PAINT 이벤트를 위와 관련된 작업들과 연계해서 수정해야 합니다.


렌더타겟이 없는 경우는 디바이스-로스트 상황이거나 초기화 상태로 인식하고,
관련된 리소스를 생성합니다.
그리고 렌더타겟의 CheckWindowState()를 통해서 해당 윈도우가 가려져 있는지를 체크하고,
가려져 있지 않다면 렌더링 작업을 수행합니다.

렌더링 작업의 마지막에는 디바이시 로스트 상황을 체크해서
디바이스 의존적 리소스를 제거하고 있습니다. ( 앞서 언급했었죠..^^ )

이제 샘플이 약간은 안정성이 향상되었습니다.^^
이상으로 디바이스-로스트와 관련한 작업을 마치겠습니다.^^