2016-12-03 13 views
1

Ich möchte einen Screenshot des aktuellen Frames in OpenGL für die weitere Verarbeitung erstellen und ich versuche die Leistung von glReadPixels zu verbessern, indem PBO verwendet wird, um Framebuffer asynchron zu lesen.PBO auf Android verbessert nicht die Leistung von glReadPixels

Ich habe den Eindruck, dass glReadPixels nach GL_PIXEL_PACK_BUFFER ist verpflichtet, Puffer sollte sofort zurückkehren, aber es dauert tatsächlich ähnlich oder sogar mehr Zeit als nicht mit PBO.

Hier sind Beispiele meiner Codes:

// 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); 

Basierend auf this article könnte die Ursache für die Verlangsamung aufgrund der Umwandlung zwischen dem internen Format, das GL_BGRA sein kann, und Pixelübertragungsformat, das GL_RGBA ist in mein Code. Wenn das Übertragungsformat auf GL_RGB geändert wird, verringert sich die Latenzzeit von glReadPixels auf etwa 100 ms. Wenn ich jedoch den Puffer mit GLES30.glMapBufferRange abbilde, wird der Ausgabeframe nicht korrekt gerendert. Ich habe auch das Format GL_BGRA in GLES11Ext versucht, aber es wird GL_INVALID_OPERATION in glReadPixel verursachen.

Gibt es eine andere Möglichkeit, glReadPixels auf Android sofort zurück zu geben, damit PBO die Leistung verbessern kann?

+0

Könnte nur ein "Feature" der spezifischen OpenGL-Implementierung sein. Haben Sie das mit verschiedenen Geräten mit GPUs verschiedener Hersteller versucht? Übrigens wurde der Aufruf 'glReadPixels()' für PBOs schließlich zu den Java-Bindungen in der API-Stufe 24 hinzugefügt. –

+0

Wie Sie vorgeschlagen haben, stellt sich heraus, dass es sich um ein umsetzungsspezifisches Problem handelt. Die GPU, mit der ich ursprünglich getestet habe, ist Adreno 306. Wenn ich die gleichen Codes auf Samsung Note 4 (Adreno 420) teste, funktioniert es wie erwartet. Danke für deinen Rat und die Infos zu neuen glReadPixels Bindungen. –

+0

Qualcomm ist berüchtigt für das Blockieren von Anrufen, die asynchron sein sollten. –

Antwort

0

Wie Reto vorgeschlagen hat, handelt es sich um ein umsetzungsspezifisches Problem. Die GPU, mit der ich ursprünglich getestet habe, ist Adreno 306. Wenn ich die gleichen Codes auf Samsung Note 4 (Adreno 420) teste, funktioniert es wie erwartet. Es lohnt sich also immer, auf verschiedenen Geräten und GPUs für solche Probleme zu testen.

Verwandte Themen