ほとんどのハードウェアアクセラレーションGUIライブラリがどのように機能するかについて、いくつかの調査を行っています。ここでは、実際にはそれらのレンダリングバックエンドのみに関心があります。私は、自分自身をある種のサイドプロジェクトとして書き、書くための最良の方法を理解しようとしています。ここでは、過度に凝った機能ではなく、究極のパフォーマンスを目指しています。プリミティブ、テキスト、アニメーションを描けるようになりたいです。
私が知っているいくつかの優れたライブラリーは、Qt、Skia、およびCairoです(ただし、HWAの状況が何であるかはわかりません)。私はまた、きちんとしたフォローがあるように見える小さなライブラリーであるNanoVGを見ました。私はNanoVGでまともなパフォーマンスを達成することができませんでした...
私を驚かせた唯一のことは、これらのライブラリすべてが「ペイント」の概念を利用しているようであり、各プリミティブ形状が最初から何度も描かれているように見えることです。つまり、APIからは、形状がGPUで「オブジェクト」として作成されたかのように表示されず、用語が何であれ、そこに残されて「自動」でレンダリングされるわけではありません。言い換えると、それらは、いくつかの大きなループで再描画されるためにGPUのメモリに残されません。詳しく説明すると、描画する必要がある各ie長方形に対して、その長方形をレンダリングするためだけにOpenGL状態全体が設定され、その後再び破棄されるようです。これらのレンダリングされた形状は、少なくとも最終的な宛先でレンダリングされているように見えますが、GPUはシーン全体を構成できます。
これらのライブラリが機能することを期待していた方法は、実際にシーン全体をGPUに保存することです(恐ろしい用語を除きます)。たとえば、プリミティブは三角測量されてメモリに残され、その後、複雑なプロセスを使用してシーンのメインレンダリングループが作成されます。さらに、属性を更新したり、プリミティブを削除または追加するためのメカニズムが配置されます。これはかなり漠然とした説明ですが、あなたはアイデアを理解していると思います。
私が今聞きたいのは、「保存」アプローチと比較して「ペイント」アプローチにパフォーマンス上の利点があるかどうかです(ここでも、これらに適切な名前があるかどうかわかりません...)。おそらく、ある種の複雑なキャッシングメカニズムですか?それとも、これで作業する方がはるかに簡単ですか?
「保存」アプローチではGPUでより多くのメモリを使用する可能性がありますが、「ペイント」アプローチに必要なすべてのOpenGL呼び出しはそれほど高価ではありませんか?レンダリングされた形状をキャッシュすることでこれを補正できるかもしれないと思いますが、GPUは、特に通信を考慮して、CPUに比べてこのような一度限りの(またはあまり規則的でない)ラスタライゼーションを実行するときに非常に大きなメリットを提供しますオーバーヘッド?また、この通信のオーバーヘッドは、フレームごとに描画を行わなければならないときに、アニメーションに深刻な問題を引き起こしませんか?
NanoVGに内部キャッシングメカニズムがないことは確かであり、これがかなり劣ったパフォーマンスの原因であると思います。一方、Qtは優れたパフォーマンスを持っているように見えるので、正しく動作しているはずです。グーグルもスキアを上手く利用できるようだ。
PS。私はあらゆる種類の専門家ではなく、つい最近OpenGLを学び始めました。
編集:私が考えたもう1つの可能性は、おそらく「描画」アプローチが純粋にメモリの利点のために必要であると考えられたということですか?私が思うのは、これらのすべてのライブラリはもちろん別の時代に始まったものであり、組み込みプラットフォームもターゲットにしているため、GPUメモリはターゲット(ed)プラットフォームでは不足している可能性があり、使用量は可能な限り少ないためです。パフォーマンスよりも重要です。繰り返しになりますが、このような状況では、通信オーバーヘッドがCPUを上回っていることを考えると、フレームごとのGPUラスタライゼーションがCPUよりも優れているとは確信できません。
さらに、http://blog.qt.io/blog/2010/01/06/qt-graphics-and-performance-opengl/を読んだところ、Qtは実行時にプリペイントされたセグメントのシェーダーコードを実行時に「ペイント」する前にブレンドし、次に、OGLコンパイラーが実行時にコードを適切にインライン化することを期待しています。これは、OGLの初期化オーバーヘッドがさらに増えるように思えます...