我想獲取OpenGL中當前幀的屏幕截圖作進一步處理,並試圖通過使用PBO異步讀取幀緩衝區來提高glReadPixels的性能。安卓上的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_BGRA,並且,這是GL_RGBA在我的代碼。將傳輸格式更改爲GL_RGB會將glReadPixels的延遲降低到100ms左右,但是當我使用GLES30.glMapBufferRange映射緩衝區時,輸出幀看起來看起來不正確。我也嘗試了GLES11Ext中的GL_BGRA格式,但它會在glReadPixel中引起GL_INVALID_OPERATION。
是否有任何其他方式使Android上的glReadPixels立即返回,以便PBO可以提高性能?
可能只是特定OpenGL實現的「特徵」。您是否嘗試過使用各種設備與各種供應商提供的GPU?順便說一句,針對PBOs的「glReadPixels()」調用最終被添加到API級別24中的Java綁定中。 –
正如您所建議的那樣,它變成了一個實現特定的問題。我最初測試的GPU是Adreno 306.當我在Samsung Note 4(Adreno 420)上測試相同的代碼時,它按預期工作。感謝您的建議以及新的glReadPixels綁定信息。 –
高通公司在阻止應該異步的呼叫方面聲名狼借。 –