OSDN Git Service

libgui: Allow for pending releases in GLConsumer
authorDan Stoza <stoza@google.com>
Wed, 18 Nov 2015 01:00:45 +0000 (17:00 -0800)
committerDan Stoza <stoza@google.com>
Tue, 23 Feb 2016 01:40:36 +0000 (17:40 -0800)
Adds the ability for GLConsumer to record a pending release instead of
releasing the buffer immediately. This will be used by SurfaceFlinger
to latch a new buffer without having to immediately release the old
one, since it needs to get a fence from HWC before releasing.

Change-Id: I8cc3ce7d5ff80e2ea4b4d681b028db042352d229

include/gui/GLConsumer.h
libs/gui/GLConsumer.cpp

index 0e4acee..61f631f 100644 (file)
@@ -253,10 +253,25 @@ protected:
 
     static bool isExternalFormat(PixelFormat format);
 
+    struct PendingRelease {
+        PendingRelease() : isPending(false), currentTexture(-1),
+                graphicBuffer(), display(nullptr), fence(nullptr) {}
+
+        bool isPending;
+        int currentTexture;
+        sp<GraphicBuffer> graphicBuffer;
+        EGLDisplay display;
+        EGLSyncKHR fence;
+    };
+
     // This releases the buffer in the slot referenced by mCurrentTexture,
     // then updates state to refer to the BufferItem, which must be a
-    // newly-acquired buffer.
-    status_t updateAndReleaseLocked(const BufferItem& item);
+    // newly-acquired buffer. If pendingRelease is not null, the parameters
+    // which would have been passed to releaseBufferLocked upon the successful
+    // completion of the method will instead be returned to the caller, so that
+    // it may call releaseBufferLocked itself later.
+    status_t updateAndReleaseLocked(const BufferItem& item,
+            PendingRelease* pendingRelease = nullptr);
 
     // Binds mTexName and the current buffer to mTexTarget.  Uses
     // mCurrentTexture if it's set, mCurrentTextureImage if not.  If the
index e1abd45..70c3dfa 100644 (file)
@@ -370,7 +370,8 @@ status_t GLConsumer::releaseBufferLocked(int buf,
     return err;
 }
 
-status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
+status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item,
+        PendingRelease* pendingRelease)
 {
     status_t err = NO_ERROR;
 
@@ -432,14 +433,23 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
 
     // release old buffer
     if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
-        status_t status = releaseBufferLocked(
-                mCurrentTexture, mCurrentTextureImage->graphicBuffer(),
-                mEglDisplay, mEglSlots[mCurrentTexture].mEglFence);
-        if (status < NO_ERROR) {
-            GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
-                   strerror(-status), status);
-            err = status;
-            // keep going, with error raised [?]
+        if (pendingRelease == nullptr) {
+            status_t status = releaseBufferLocked(
+                    mCurrentTexture, mCurrentTextureImage->graphicBuffer(),
+                    mEglDisplay, mEglSlots[mCurrentTexture].mEglFence);
+            if (status < NO_ERROR) {
+                GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
+                        strerror(-status), status);
+                err = status;
+                // keep going, with error raised [?]
+            }
+        } else {
+            pendingRelease->currentTexture = mCurrentTexture;
+            pendingRelease->graphicBuffer =
+                    mCurrentTextureImage->graphicBuffer();
+            pendingRelease->display = mEglDisplay;
+            pendingRelease->fence = mEglSlots[mCurrentTexture].mEglFence;
+            pendingRelease->isPending = true;
         }
     }