本当にとある実験です。ま、それはおいておいて。
特定条件で正しく動作していないプログラムがあり、それを修正する方法を考え出したまではいいのですが・・・。
これ、対応できるように変更すると以下のような問題が起こります。対応はGDI描画部のみなのですが。
- (GDIでの描画時で)拡大処理にDirectX系を使うことができない。無理に使おうとすると負荷が2倍以上にふくれあがる
- (GDIでの描画時で)ソフトウェア描画であっても特定条件下で負荷が異常に増大することがある
- (たぶん)別のアプリで対応ができなくなるパターンができる
と、対応ルーチンを書いて問題になるな~ということでちょっと修正リリースを思いとどまっています。
ちょっとプログラムチックになりますが、これの原因がやっぱりある「お行儀の悪いプログラム」にあります。
今回のパターンは「取得した描画オブジェクトを解放することなく使い回している(毎フレームGetDC~ReleaseDCではなく、初期化時にGetDCしたデバイスコンテキストを使い続けている)」というものです。
使い終わったら解放するのが作法だと思って解放時に拡大描画ルーチンを仕込んでいるのですが、それが見事にスルーされたわけです。
何ともふしだらなプログラムですよね。
さて、この件はどうするのが正しいのでしょうか。
面倒なのが「GetDCしたまま放置」=「GetDCによるロックが発生したまま次のGetDCあるいはBeginPaintでデバイスコンテキストを返す必要」というこれにあります。
DirectX系では多重ロックはサポートされていない(GetDCを行っているときにもう一度GetDCを行うとエラーを返す)のと、サーフェイスとしての描画時にすべてのロックが解除されている必要がある(GetDC状態を何らかの手段でいったん取り除く)のがポイントです。