OSDN Git Service

TextureView/GLES20Canvas: Support synchronous GLConsumers
authorEino-Ville Talvala <etalvala@google.com>
Thu, 19 Sep 2013 19:49:13 +0000 (12:49 -0700)
committerEino-Ville Talvala <etalvala@google.com>
Thu, 19 Sep 2013 20:43:42 +0000 (13:43 -0700)
Always update to the newest available frame from a GLConsumer.
Otherwise, with a synchronous queue, rendering can fall behind and
eventually deadlock with producer.

Bug: 10830400
Change-Id: I7f1d752c80ae5dac892a26d82e86806c27f5d955

core/jni/android_view_GLES20Canvas.cpp

index dc90da7..b720e73 100644 (file)
@@ -878,6 +878,23 @@ static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject cl
     sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
 
     if (surfaceTexture->updateTexImage() == NO_ERROR) {
+        int64_t frameNumber = surfaceTexture->getFrameNumber();
+        // If the GLConsumer queue is in synchronous mode, need to discard all
+        // but latest frame, using the frame number to tell when we no longer
+        // have newer frames to target. Since we can't tell which mode it is in,
+        // do this unconditionally.
+        int dropCounter = 0;
+        while (surfaceTexture->updateTexImage() == NO_ERROR) {
+            int64_t newFrameNumber = surfaceTexture->getFrameNumber();
+            if (newFrameNumber == frameNumber) break;
+            frameNumber = newFrameNumber;
+            dropCounter++;
+        }
+        #if DEBUG_RENDERER
+        if (dropCounter > 0) {
+            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
+        }
+        #endif
         surfaceTexture->getTransformMatrix(transform);
         GLenum renderTarget = surfaceTexture->getCurrentTextureTarget();