安全でない C# と 2D レンダリング用のポインター、良いのか悪いのか?
質問
DirectX 9 をラップし、2D ピクセル レベルの描画を実行するための簡略化されたインターフェイスを提供する C# コントロールを作成しています。.NET では、このコードを安全でないコード ブロックでラップし、安全でないコードを許可するオプションを使用してコンパイルする必要があります。
表面全体をロックし、ロックされたメモリ領域へのポインタを返します。その後、「単純な」ポインター演算を使用してピクセル データを直接書き込むことができます。これのパフォーマンステストを行ったところ、私が知っている他の「安全な」方法よりも速度が大幅に向上していることがわかりました。
これは、C# .NET アプリケーションで個々のピクセルを操作する最も速い方法ですか?もっと良い、より安全な方法はあるでしょうか?ポインタ操作を必要としない同様に高速なアプローチがあれば、それを使用することを好みます。
(今は 2008 年なので、私たちは皆 DirectX 3D を使用しているはずです。 OpenGL, など。ただし、このコントロールは 2D ピクセル レンダリング専用に使用され、3D レンダリングは必要ありません。)
解決
安全でないポインターを使用することは、C# で直接メモリ操作を行う最も速い方法です (Marshal ラッパー関数を使用するよりも確実に高速です)。
ちょっと興味があるのですが、どのような 2D 描画操作を実行しようとしていますか?
私が質問したのは、ピクセル レベルの操作を行うために DirectX サーフェスをロックすると、DirectX を使用することで得られると期待されるハードウェア アクセラレーションの利点のほとんどが無効になるためです。また、ターミナル サービス (リモート デスクトップ) 経由で使用する場合、DirectX デバイスは初期化に失敗するため、そのシナリオではコントロールは使用できなくなります (これは重要ではないかもしれません)。
DirectX は、大きな三角形を描画したり、イメージを変換したり (テクスチャを四角形にマッピングしたり) する場合には大きな効果を発揮しますが、単一ピクセルの操作ではそれほど優れたパフォーマンスを発揮しません。
.NET の領域に留まり、LockBits を使用し、返された BitmapData オブジェクト内の安全でないポインタを介してピクセルに直接アクセスすることで、Bitmap オブジェクトを表面として動作させる 1 つの代替方法があります。
他のヒント
はい、それがおそらく一番早い方法です。
数年前、私は 2 つの 1024x1024 画像をピクセル レベルで比較する必要がありました。get-pixel メソッドには 2 分かかり、安全でないスキャンには 0.01 秒かかりました。
私もそのような性質のものを高速化するために unsafe を使用しました。控えめに言っても、パフォーマンスの向上は劇的です。ここで重要なのは、unsafe は、自分が何をしているのかを知っている限り、必要のない可能性のある多くの機能を無効にするということです。
また、チェックしてください ダイレクトドロー. 。DirectX の 2D グラフィックス コンポーネントです。本当に速いです。
私は最近、シン クライアント アプリ (C#) の 1 つ用に単純なヒストグラム コントロールを作成するという任務を与えられました。私が分析していた画像は約 1200x1200 で、同じルートをたどる必要がありました。問題なく一度描画させることはできましたが、コントロールのサイズを変更する必要がありました。私はそれを避けようとしましたが、生の記憶そのものにアクセスする必要がありました。
標準の .NET クラスを使用することが不可能とは言いませんが、最終的にはあまり機能しませんでした。