OpenGLで現在のフレームのスクリーンショットを取得して、後で処理するために、PBOを使用して非同期にフレームバッファを読み込むことによってglReadPixelsのパフォーマンスを向上させようとしています。AndroidのPBOがglReadPixelsのパフォーマンスを改善しない
GL_PIXEL_PACK_BUFFERがバッファにバインドされた後のglReadPixelsが直ちに返されるという印象を受けていますが、実際にはPBOを使用しない場合と同じかそれ以上の時間がかかります。
はここに私のコードのサンプルである:
// Setup PBO
GLES30.glGenBuffers(nPbo, pboIndex, 0);
for(int i=0;i<nPbo; i++){
GLES30.glBindBuffer (GL_PIXEL_PACK_BUFFER, pboIndex[i]);
GLES30.glBufferData(GL_PIXEL_PACK_BUFFER, size, null,GL_STREAM_READ);
}
GLES30.glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
......
// For each frame, trigger async transfer of framebuffer to PBO.
// Note that I don't even map the PBO to memory yet
GLES30.glBindBuffer (GL_PIXEL_PACK_BUFFER, pboIndex[index]);
// The following is a JNI method to overload glReadPixels in GLES20.glReadPixels,
// to allow passing int offset to the last param in order to use PBO,
// and slowdown (around 500ms on my device) happens here
GLES3PBOReadPixelsFix.glReadPixelsPBO(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, 0);
GLES30.glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
this articleに基づいて、減速の原因はでGL_RGBAあるGL_BGRAとすることができる内部フォーマット間の変換、および画素転送形式にすることができ私のコード。転送フォーマットをGL_RGBに変更すると、glReadPixelsのレイテンシが約100msに短縮されますが、GLES30.glMapBufferRangeでバッファをマップすると、出力フレームが正しく表示されません。 GLES11ExtでGL_BGRA形式も試しましたが、glReadPixelでGL_INVALID_OPERATIONが発生します。
AndroidでglReadPixelsをすぐに返すようにする方法はありますか.PBOがパフォーマンスを向上させることができるのですか?
特定のOpenGL実装の「機能」に過ぎないかもしれません。さまざまなベンダーのGPUを使用して、さまざまなデバイスでこれを試しましたか?ところで、PBOの 'glReadPixels()'呼び出しは、APIレベル24のJavaバインディングに最終的に追加されました。 –
あなたが示唆したように、実装固有の問題であることが判明しました。私が最初にテストしていたGPUはAdreno 306です。私がSamsung Note 4(Adreno 420)で同じコードをテストすると、期待どおりに動作します。あなたのアドバイスと新しいglReadPixelsバインディングの情報をありがとう。 –
クアルコムは、非同期でなければならないコールをブロックすることで有名です。 –