MDX 끄는데 오래 걸릴 때
| DirectX, 개발, 프로그래밍 | 2008.11.13 02:31 |
진행 중인 프로젝트의 클라이언트가 끌 때 시간이 오래 걸리는 현상이 나타났다.
또 한 가지 발견한 사실은 클라이언트를 오래 켜 놓을 수록 끄는데 시간이 오래 걸린다는 것.
어디서 시간을 잡아먹나 찾아보니 그래픽 Device 객체를 Dispose하는 곳이었다.
어디선가 자원의 릭이 발생하고 있을 거란 생각만 어렴풋이.
일단 이유는 모르겠지만 PresentationInterval을 Immediate에서 Default로 바꾸니
끄는 속도가 원래대로 빨라진 것 같았다. 덩실덩실 춤을 췄다.
... 근데 오래 켜 놓으니 그래도 끄는데 느리다 -_-; 흐음. 왜 그러지.
중요한 건 이 게임 프로젝트 말고 지금 졸업 논문 구현하고 있는 프로그램에서도
똑같은 현상이 벌어지고 있더란 말이지 (...)
렌더링 루프를 주석처리 해놓고 돌려보면 바로바로 잘 꺼지는데
렌더링을 하면 얄짤없이 끄는데 한참 걸린다.
렌더링 루프 안에서 어느 부분이 문제인지 부분부분 알아가다가
구글에 일단 이런 저런 키워드로 검색을 해봤다.
보통 도움이 안 되는 질문 글만 우글거리는 포럼에 웬일로 답이 적혀있었다(!)
렌더타겟 바꾼다고 Surface 받아왔으면 Dispose를 꼭 해줘야 한다는 것이었다.
두 프로그램 다 쉐도우 매핑 방식으로 그림자 찍는다고 텍스쳐를 렌더타겟으로
잡는 부분이 있었다. 일단 원래 렌더타겟(기본 그래픽 메모리)을 잠시 임시 변수로 잡아놓고
텍스쳐를 타겟으로 설정한 후 할 짓 다 한 다음에 임시 변수에 넣어둔 렌더타겟으로 다시
복구시키는 방법이었는데 여기서 임시 변수에 넣어둔 애가 자동으로 없어지는 애가 아닌 것이다!
C#은 원래 메모리 할당, 삭제에 대해 신경 안 써도 되게 Managed를 보장하는 놈이라
끌 때를 제외하면 전혀 자원 해제에 대한 경계심 없이 프로그래밍을 하게 되는데
그러다보니 이렇게 위험(...)한 DirectX에게 허를 찔린 듯.
GetRenderTarget이랑 DepthStencilSurface로 받아와서
임시 변수에 넣어뒀던 Surface를 렌더링 끝날 때 해제시켜주니 잘 꺼진다.
...
프로그램이 "와~! 이제 빨리 꺼진다~!!"하고 좋아하는 것도 참 웃기는 일이야.
뒷 이야기.
진짜 원인을 파악하고 나서야 이해가 된 것.
PresentationInterval는 하드웨어가 허용하는 최대한의 스피드로 렌더링 할 것이냐
아니면 모니터의 최대속도에 맞춰 렌더링할 것이냐를 바꾸는 거였는데 이게
Immediate일 땐 렌더링 과정을 굉장히 빠른 속도로 많이 거치면서 허공에 떠다니는
Surface가 많아져버렸던 것이다. Default로 바뀌면서 천천히 루프를 돌게 되고
집 잃은 Surface가 만들어지는 속도가 줄어들어서 끌 때 상대적으로 빨리 꺼졌던 것.
어찌됐든 떠다니는 자원들은 계속 생기고 얘네들은 Device가 Dispose 될 때
열심히 잡으러 다니나보다. 그러니까 거기서 시간을 엄청 잡아먹게 되고.
