Loading libs/gui/BufferQueueConsumer.cpp +5 −21 Original line number Diff line number Diff line Loading @@ -477,9 +477,14 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence) { #else status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, EGLDisplay eglDisplay, EGLSyncKHR eglFence) { #endif ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); Loading @@ -493,27 +498,6 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, return BAD_VALUE; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) if (eglFence != EGL_NO_SYNC_KHR) { // Most platforms will be using native fences, so it's unlikely that we'll ever have to // process an eglFence. Ideally we can remove this code eventually. In the mean time, do our // best to wait for it so the buffer stays valid, otherwise return an error to the caller. // // EGL_SYNC_FLUSH_COMMANDS_BIT_KHR so that we don't wait forever on a fence that hasn't // shown up on the GPU yet. EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 1000000000); if (result == EGL_FALSE) { BQ_LOGE("releaseBuffer: error %#x waiting for fence", eglGetError()); return UNKNOWN_ERROR; } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { BQ_LOGE("releaseBuffer: timeout waiting for fence"); return UNKNOWN_ERROR; } eglDestroySyncKHR(eglDisplay, eglFence); } #endif sp<IProducerListener> listener; { // Autolock scope std::lock_guard<std::mutex> lock(mCore->mMutex); Loading libs/gui/ConsumerBase.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -656,9 +656,13 @@ status_t ConsumerBase::addReleaseFenceLocked(int slot, return OK; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t ConsumerBase::releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer) { #else status_t ConsumerBase::releaseBufferLocked( int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { #endif if (mAbandoned) { CB_LOGE("releaseBufferLocked: ConsumerBase is abandoned!"); return NO_INIT; Loading @@ -675,8 +679,12 @@ status_t ConsumerBase::releaseBufferLocked( CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64, slot, mSlots[slot].mFrameNumber); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, mSlots[slot].mFence); #else status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, display, eglFence, mSlots[slot].mFence); #endif if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT) { freeBufferLocked(slot); } Loading libs/gui/GLConsumer.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -417,18 +417,18 @@ void GLConsumer::onSlotCountChanged(int slotCount) { } #endif status_t GLConsumer::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer, #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t GLConsumer::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { // release the buffer if it hasn't already been discarded by the // BufferQueue. This can happen, for example, when the producer of this // buffer has reallocated the original buffer slot after this buffer // was acquired. status_t err = ConsumerBase::releaseBufferLocked( buf, graphicBuffer, display, eglFence); status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence); mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; return err; } #endif status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease) Loading Loading @@ -490,9 +490,14 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t status = releaseBufferLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer()); #else status_t status = releaseBufferLocked( mCurrentTexture, mCurrentTextureImage->graphicBuffer(), mEglDisplay, mEglSlots[mCurrentTexture].mEglFence); #endif if (status < NO_ERROR) { GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); Loading @@ -501,10 +506,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->display = mEglDisplay; pendingRelease->fence = mEglSlots[mCurrentTexture].mEglFence; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->isPending = true; } } Loading Loading @@ -744,6 +746,11 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { return err; } } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) // Basically all clients are using native fence syncs. If they aren't, we lose nothing // by waiting here, because the alternative can cause deadlocks (b/339705065). glFinish(); #else EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to Loading Loading @@ -773,6 +780,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { } glFlush(); mEglSlots[mCurrentTexture].mEglFence = fence; #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) } } Loading libs/gui/IGraphicBufferConsumer.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,12 @@ public: return callRemote<Signature>(Tag::ATTACH_BUFFER, slot, buffer); } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t releaseBuffer(int buf, uint64_t frameNumber, const sp<Fence>& releaseFence) override { using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&); return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence); } #else status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)), Loading @@ -92,6 +98,7 @@ public: using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&); return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence); } #endif status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override { using Signature = decltype(&IGraphicBufferConsumer::consumerConnect); Loading libs/gui/include/gui/BufferQueueConsumer.h +7 −4 Original line number Diff line number Diff line Loading @@ -65,13 +65,14 @@ public: // any references to the just-released buffer that it might have, as if it // had received a onBuffersReleased() call with a mask set for the released // buffer. // // Note that the dependencies on EGL will be removed once we switch to using // the Android HW Sync HAL. #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) virtual status_t releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence) override; #else virtual status_t releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, EGLDisplay display, EGLSyncKHR fence); #endif // connect connects a consumer to the BufferQueue. Only one // consumer may be connected, and when that consumer disconnects the // BufferQueue is placed into the "abandoned" state, causing most Loading Loading @@ -167,6 +168,7 @@ public: // dump our state in a String status_t dumpState(const String8& prefix, String8* outResult) const override; #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) // Functions required for backwards compatibility. // These will be modified/renamed in IGraphicBufferConsumer and will be // removed from this class at that time. See b/13306289. Loading @@ -176,6 +178,7 @@ public: const sp<Fence>& releaseFence) { return releaseBuffer(buf, frameNumber, releaseFence, display, fence); } #endif virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { Loading Loading
libs/gui/BufferQueueConsumer.cpp +5 −21 Original line number Diff line number Diff line Loading @@ -477,9 +477,14 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot, return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence) { #else status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, EGLDisplay eglDisplay, EGLSyncKHR eglFence) { #endif ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); Loading @@ -493,27 +498,6 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, return BAD_VALUE; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) if (eglFence != EGL_NO_SYNC_KHR) { // Most platforms will be using native fences, so it's unlikely that we'll ever have to // process an eglFence. Ideally we can remove this code eventually. In the mean time, do our // best to wait for it so the buffer stays valid, otherwise return an error to the caller. // // EGL_SYNC_FLUSH_COMMANDS_BIT_KHR so that we don't wait forever on a fence that hasn't // shown up on the GPU yet. EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 1000000000); if (result == EGL_FALSE) { BQ_LOGE("releaseBuffer: error %#x waiting for fence", eglGetError()); return UNKNOWN_ERROR; } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { BQ_LOGE("releaseBuffer: timeout waiting for fence"); return UNKNOWN_ERROR; } eglDestroySyncKHR(eglDisplay, eglFence); } #endif sp<IProducerListener> listener; { // Autolock scope std::lock_guard<std::mutex> lock(mCore->mMutex); Loading
libs/gui/ConsumerBase.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -656,9 +656,13 @@ status_t ConsumerBase::addReleaseFenceLocked(int slot, return OK; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t ConsumerBase::releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer) { #else status_t ConsumerBase::releaseBufferLocked( int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { #endif if (mAbandoned) { CB_LOGE("releaseBufferLocked: ConsumerBase is abandoned!"); return NO_INIT; Loading @@ -675,8 +679,12 @@ status_t ConsumerBase::releaseBufferLocked( CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64, slot, mSlots[slot].mFrameNumber); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, mSlots[slot].mFence); #else status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, display, eglFence, mSlots[slot].mFence); #endif if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT) { freeBufferLocked(slot); } Loading
libs/gui/GLConsumer.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -417,18 +417,18 @@ void GLConsumer::onSlotCountChanged(int slotCount) { } #endif status_t GLConsumer::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer, #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t GLConsumer::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence) { // release the buffer if it hasn't already been discarded by the // BufferQueue. This can happen, for example, when the producer of this // buffer has reallocated the original buffer slot after this buffer // was acquired. status_t err = ConsumerBase::releaseBufferLocked( buf, graphicBuffer, display, eglFence); status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence); mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; return err; } #endif status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, PendingRelease* pendingRelease) Loading Loading @@ -490,9 +490,14 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t status = releaseBufferLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer()); #else status_t status = releaseBufferLocked( mCurrentTexture, mCurrentTextureImage->graphicBuffer(), mEglDisplay, mEglSlots[mCurrentTexture].mEglFence); #endif if (status < NO_ERROR) { GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); Loading @@ -501,10 +506,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->display = mEglDisplay; pendingRelease->fence = mEglSlots[mCurrentTexture].mEglFence; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->isPending = true; } } Loading Loading @@ -744,6 +746,11 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { return err; } } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) // Basically all clients are using native fence syncs. If they aren't, we lose nothing // by waiting here, because the alternative can cause deadlocks (b/339705065). glFinish(); #else EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to Loading Loading @@ -773,6 +780,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { } glFlush(); mEglSlots[mCurrentTexture].mEglFence = fence; #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) } } Loading
libs/gui/IGraphicBufferConsumer.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,12 @@ public: return callRemote<Signature>(Tag::ATTACH_BUFFER, slot, buffer); } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) status_t releaseBuffer(int buf, uint64_t frameNumber, const sp<Fence>& releaseFence) override { using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&); return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence); } #else status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)), Loading @@ -92,6 +98,7 @@ public: using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&); return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence); } #endif status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override { using Signature = decltype(&IGraphicBufferConsumer::consumerConnect); Loading
libs/gui/include/gui/BufferQueueConsumer.h +7 −4 Original line number Diff line number Diff line Loading @@ -65,13 +65,14 @@ public: // any references to the just-released buffer that it might have, as if it // had received a onBuffersReleased() call with a mask set for the released // buffer. // // Note that the dependencies on EGL will be removed once we switch to using // the Android HW Sync HAL. #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) virtual status_t releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence) override; #else virtual status_t releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, EGLDisplay display, EGLSyncKHR fence); #endif // connect connects a consumer to the BufferQueue. Only one // consumer may be connected, and when that consumer disconnects the // BufferQueue is placed into the "abandoned" state, causing most Loading Loading @@ -167,6 +168,7 @@ public: // dump our state in a String status_t dumpState(const String8& prefix, String8* outResult) const override; #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP) // Functions required for backwards compatibility. // These will be modified/renamed in IGraphicBufferConsumer and will be // removed from this class at that time. See b/13306289. Loading @@ -176,6 +178,7 @@ public: const sp<Fence>& releaseFence) { return releaseBuffer(buf, frameNumber, releaseFence, display, fence); } #endif virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { Loading