2016-12-03 8 views
1

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がパフォーマンスを向上させることができるのですか?

+0

特定のOpenGL実装の「機能」に過ぎないかもしれません。さまざまなベンダーのGPUを使用して、さまざまなデバイスでこれを試しましたか?ところで、PBOの 'glReadPixels()'呼び出しは、APIレベル24のJavaバインディングに最終的に追加されました。 –

+0

あなたが示唆したように、実装固有の問題であることが判明しました。私が最初にテストしていたGPUはAdreno 306です。私がSamsung Note 4(Adreno 420)で同じコードをテストすると、期待どおりに動作します。あなたのアドバイスと新しいglReadPixelsバインディングの情報をありがとう。 –

+0

クアルコムは、非同期でなければならないコールをブロックすることで有名です。 –

答えて

0

Retoが示唆しているように、実装固有の問題であることが判明しました。私が最初にテストしていたGPUはAdreno 306です。私がSamsung Note 4(Adreno 420)で同じコードをテストすると、期待どおりに動作します。このような種類の問題については、さまざまなデバイスやGPUでテストすることが常に価値があります。

関連する問題