最初にアプリケーションについて簡単に説明します。一度に最大48台のカメラを表示できる映像セキュリティソフトです。各ビデオ ストリームは独自の Windows HDC を取得しますが、すべて共有 OpenGL コンテキストを使用します。OpenGL でかなり良いパフォーマンスが得られ、Windows/Linux/Mac で動作します。内部では、コンテキストは wxWidgets 2.8 wxGLCanvas を使用して作成されますが、それが問題とは何の関係もないと思います。
では、本題です。同じカメラを 48 個のウィンドウすべてに表示するとします。これは基本的に、30fps のみをデコードしていることを意味します (別のスレッドで実行されます) が、画像からデコードを取り除くために最大 1440fps を表示します。私は PBO を使用して画像を転送しています。ピクセル シェーダーとマルチテクスチャリングがサポートされているかどうかに応じて、GPU で YUV->RGB 変換を行うためにそれらを使用する場合があります。次に、クワッドを使用してテクスチャを配置し、SwapBuffers を呼び出します。すべての OpenGL 呼び出しは、UI スレッドから発生します。また、CPU で YUV->RGB 変換を試み、GL_RGBA および GL_BGRA テクスチャの使用を台無しにしましたが、すべての形式でほぼ同じパフォーマンスが得られます。問題は、可能な 1440 fps のうち約 1000 fps しか得られないことです (fps で測定すべきではないことはわかっていますが、ただし、このシナリオでは簡単です)。上記のシナリオでは、320x240 (YUV420) ビデオを使用していますが、これはおよそ 110MB/秒です。1280x720 カメラを使用すると、フレームレートはほぼ同じで、ほぼ 1.3GB/秒になります。これは、テクスチャのアップロード速度ではないことを示しています。CPU で YUV->RGB 変換とスケーリングを行い、Windows DC を使用してペイントすると、完全な 1440fps を簡単に取得できます。
言及すべきもう 1 つのことは、wglSwapIntervalEXT を使用して、ビデオ カードと OpenGL の両方で vsync を無効にしたことです。また、報告されている OpenGL エラーはありません。ただし、非常に眠いアプリケーションをプロファイルするために使用すると、ほとんどの時間が SwapBuffers で費やされているようです。この問題は、複数の HDC の使用または SwapBuffers のどこかでの使用に何らかの形で関連していると想定していますが、自分が行っていることを他にどのように行うかはわかりません。
私は OpenGL の専門家ではないので、何か提案や何かあれば、ぜひ聞きたいです。私がやっていることが間違っているように聞こえる場合、または同じことをより効率的に達成できる方法がある場合は、それを聞いてみたいです.
行われているすべての OpenGL 呼び出しをよりよく理解するための glIntercept ログへのリンクを次に示します。
単純な RGB: https://docs.google.com/open?id=0BzGMib6CGH4TdUdlcTBYMHNTRnM
シェーダー YUV: https://docs.google.com/open?id=0BzGMib6CGH4TSDJTZGxDanBwS2M
プロファイリング情報: プロファイリング後、いくつかの冗長な状態変化が報告されましたが、これには驚きませんでした。私はそれらをすべて排除しましたが、私が期待していた顕著なパフォーマンスの違いは見られませんでした. レンダリング ループごとに 34 の状態変更があり、非推奨の関数をいくつか使用しています。これらを解決する頂点配列の使用を検討します。ただし、レンダリング ループごとに 1 つのクワッドを実行しているだけなので、これによるパフォーマンスへの影響はあまり期待できません。また、OpenGL 1.4 のみであると思われるかなり古い Intel チップセット ドライバーをサポートする必要があるため、すべてを取り除いてすべての VBO に移行したくはありません。
私が本当に興味を持ち、それまで思いもよらなかったことは、各コンテキストが独自のフロント バッファーとバック バッファーを持っていることです。コンテキストを 1 つしか使用していないため、前の HDC レンダー呼び出しは、スワップが発生する前にバック バッファーへの書き込みを終了する必要があります。その後、次のコンテキストがバック バッファーへの書き込みを再開できます。複数のコンテキストを使用する方が本当に効率的でしょうか? または、代わりにテクスチャ (私が思うに FBO) へのレンダリングを検討し、1 つのコンテキストを使用し続ける必要がありますか?
編集: 元の説明では、複数の OpenGL コンテキストの使用について言及されていましたが、間違っていました。1 つの OpenGL コンテキストと複数の HDC しか使用していません。EDIT2: gDEBugger でプロファイリングした後にいくつかの情報を追加しました。