1

さらに処理するために OpenGL で現在のフレームのスクリーンショットを撮りたいのですが、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);

この記事に基づいて、スローダウンの原因は、GL_BGRA である可能性のある内部形式と、私のコードでは GL_RGBA であるピクセル転送形式との間の変換が原因である可能性があります。転送形式を GL_RGB に変更すると、glReadPixels のレイテンシが約 100 ミリ秒に短縮されますが、バッファを GLES30.glMapBufferRange でマップすると、出力フレームが正しくレンダリングされないように見えます。GLES11Ext で GL_BGRA フォーマットも試しましたが、glReadPixel で GL_INVALID_OPERATION が発生します。

Android で glReadPixels をすぐに返して、PBO のパフォーマンスを向上させる方法は他にありますか?

4

1 に答える 1

0

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

于 2016-12-06T06:11:47.530 に答える