マルチスレッド処理の問題
マルチスレッド処理の問題
フルスクリーンの Microsoft® Direct3D® アプリケーションは、Direct3D ランタイムにウィンドウ ハンドルを提供する。このウィンドウはランタイムによってフックされる。これは、アプリケーションのウィンドウ メッセージ プロシージャに渡されたすべてのメッセージが、まず、Direct3D ランタイム独自のメッセージ処理プロシージャによって調べられることを意味する。
ディスプレイ モードの変更は、下位のオペレーティング システムに組み込まれたサポート ルーチンによって影響を受ける。モードが変更されると、システムは複数のメッセージをすべてのアプリケーションに送信する。Direct3D アプリケーションは、メッセージはウィンドウ プロシージャ スレッドで受信する。このスレッドは、IDirect3DDevice9::Reset または IDirect3D9::CreateDevice (またはディスプレイ モードを変更する場合がある IDirect3DDevice9 の最後の IUnknown::Release) を呼び出したスレッドと必ずしも同じではない。Direct3D ランタイムは、複数のクリティカル セクションを内部で保持する。少なくとも 1 つのクリティカル セクションが、IDirect3DDevice9::Reset または IDirect3D9::CreateDevice によるモード切り替えの後も保持されるので、これらのクリティカル セクションは、アプリケーションがモード変更に関連するウィンドウ メッセージを受信した後も保持される。
この設計は、暗にマルチスレッド アプリケーションを意図している。特に、アプリケーションはウィンドウ メッセージ処理スレッドを Direct3D スレッドから完全に分離しなければならない。1 つのスレッドでモード変更を行いながら、別のスレッドで Direct3D の呼び出しを行うアプリケーションは、デッドロックの危険性がある。
このような理由から、Direct3D では、IDirect3DDevice9::Reset、IDirect3D9::CreateDevice、IDirect3DDevice9::TestCooperativeLevel、または IDirect3DDevice9 の最後の Release の各メソッドは、ウィンドウ メッセージを処理するスレッドと同じスレッドからのみ呼び出すことができるように設計されている。