Loading include/gui/BufferQueue.h +7 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceTexture.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> #include <utils/String8.h> Loading Loading @@ -218,7 +219,8 @@ public: // // Note that the dependencies on EGL will be removed once we switch to using // the Android HW Sync HAL. status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence); status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence = Fence::NO_FENCE); // consumerConnect connects a consumer to the BufferQueue. Only one // consumer may be connected, and when that consumer disconnects the Loading Loading @@ -378,6 +380,10 @@ private: // on a compile-time option) set to a new sync object in updateTexImage. EGLSyncKHR mFence; // mReleaseFence is a fence which must signal before the contents of // the buffer associated with this buffer slot may be overwritten. sp<Fence> mReleaseFence; // Indicates whether this buffer has been seen by a consumer yet bool mAcquireCalled; Loading include/gui/SurfaceTexture.h +15 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,14 @@ public: // target texture belongs is bound to the calling thread. status_t updateTexImage(); // setReleaseFence stores a fence file descriptor that will signal when the // current buffer is no longer being read. This fence will be returned to // the producer when the current buffer is released by updateTexImage(). // Multiple fences can be set for a given buffer; they will be merged into // a single union fence. The SurfaceTexture will close the file descriptor // when finished with it. void setReleaseFence(int fenceFd); // setBufferCountServer set the buffer count. If the client has requested // a buffer count using setBufferCount, the server-buffer count will // take effect once the client sets the count back to zero. Loading Loading @@ -349,6 +357,13 @@ private: // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based // on a compile-time option) set to a new sync object in updateTexImage. EGLSyncKHR mFence; // mReleaseFence is a fence which will signal when the buffer // associated with this buffer slot is no longer being used by the // consumer and can be overwritten. The buffer can be dequeued before // the fence signals; the producer is responsible for delaying writes // until it signals. sp<Fence> mReleaseFence; }; // mEglDisplay is the EGLDisplay with which this SurfaceTexture is currently Loading include/ui/Fence.h +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ class Fence : public LightRefBase<Fence>, public Flattenable { public: static const sp<Fence> NO_FENCE; // Construct a new Fence object with an invalid file descriptor. This // should be done when the Fence object will be set up by unflattening Loading libs/gui/Android.mk +5 −4 Original line number Diff line number Diff line Loading @@ -25,14 +25,15 @@ LOCAL_SRC_FILES:= \ CpuConsumer.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libcutils \ libEGL \ libGLESv2 \ libhardware \ libhardware_legacy \ libsync \ libui \ libEGL \ libGLESv2 \ libutils \ LOCAL_MODULE:= libgui Loading libs/gui/BufferQueue.cpp +17 −4 Original line number Diff line number Diff line Loading @@ -307,6 +307,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, status_t returnFlags(OK); EGLDisplay dpy = EGL_NO_DISPLAY; EGLSyncKHR fence = EGL_NO_SYNC_KHR; sp<Fence> releaseFence; { // Scope for the lock Mutex::Autolock lock(mMutex); Loading @@ -318,7 +319,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, usage |= mConsumerUsageBits; int found = -1; int foundSync = -1; int dequeuedCount = 0; bool tryAgain = true; while (tryAgain) { Loading Loading @@ -369,7 +369,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, // look for a free buffer to give to the client found = INVALID_BUFFER_SLOT; foundSync = INVALID_BUFFER_SLOT; dequeuedCount = 0; for (int i = 0; i < mBufferCount; i++) { const int state = mSlots[i].mBufferState; Loading @@ -393,7 +392,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, bool isOlder = mSlots[i].mFrameNumber < mSlots[found].mFrameNumber; if (found < 0 || isOlder) { foundSync = i; found = i; } } Loading Loading @@ -484,6 +482,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, mSlots[buf].mGraphicBuffer = graphicBuffer; mSlots[buf].mRequestBufferCalled = false; mSlots[buf].mFence = EGL_NO_SYNC_KHR; mSlots[buf].mReleaseFence.clear(); mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; Loading @@ -491,7 +490,9 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, dpy = mSlots[buf].mEglDisplay; fence = mSlots[buf].mFence; releaseFence = mSlots[buf].mReleaseFence; mSlots[buf].mFence = EGL_NO_SYNC_KHR; mSlots[buf].mReleaseFence.clear(); } // end lock scope if (fence != EGL_NO_SYNC_KHR) { Loading @@ -507,6 +508,16 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, eglDestroySyncKHR(dpy, fence); } if (releaseFence.get()) { int err = releaseFence->wait(1000); if (err == -ETIME) { ALOGE("dequeueBuffer: timeout waiting for release fence"); } else if (err != NO_ERROR) { ALOGE("dequeueBuffer: error waiting for sync fence: %d", err); } releaseFence.clear(); } ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); Loading Loading @@ -846,6 +857,7 @@ void BufferQueue::freeBufferLocked(int i) { eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence); mSlots[i].mFence = EGL_NO_SYNC_KHR; } mSlots[i].mReleaseFence.clear(); } void BufferQueue::freeAllBuffersLocked() { Loading Loading @@ -896,7 +908,7 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer) { } status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence) { EGLSyncKHR fence, const sp<Fence>& releaseFence) { ATRACE_CALL(); ATRACE_BUFFER_INDEX(buf); Loading @@ -908,6 +920,7 @@ status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, mSlots[buf].mEglDisplay = display; mSlots[buf].mFence = fence; mSlots[buf].mReleaseFence = releaseFence; // The buffer can now only be released if its in the acquired state if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { Loading Loading
include/gui/BufferQueue.h +7 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceTexture.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> #include <utils/String8.h> Loading Loading @@ -218,7 +219,8 @@ public: // // Note that the dependencies on EGL will be removed once we switch to using // the Android HW Sync HAL. status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence); status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence = Fence::NO_FENCE); // consumerConnect connects a consumer to the BufferQueue. Only one // consumer may be connected, and when that consumer disconnects the Loading Loading @@ -378,6 +380,10 @@ private: // on a compile-time option) set to a new sync object in updateTexImage. EGLSyncKHR mFence; // mReleaseFence is a fence which must signal before the contents of // the buffer associated with this buffer slot may be overwritten. sp<Fence> mReleaseFence; // Indicates whether this buffer has been seen by a consumer yet bool mAcquireCalled; Loading
include/gui/SurfaceTexture.h +15 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,14 @@ public: // target texture belongs is bound to the calling thread. status_t updateTexImage(); // setReleaseFence stores a fence file descriptor that will signal when the // current buffer is no longer being read. This fence will be returned to // the producer when the current buffer is released by updateTexImage(). // Multiple fences can be set for a given buffer; they will be merged into // a single union fence. The SurfaceTexture will close the file descriptor // when finished with it. void setReleaseFence(int fenceFd); // setBufferCountServer set the buffer count. If the client has requested // a buffer count using setBufferCount, the server-buffer count will // take effect once the client sets the count back to zero. Loading Loading @@ -349,6 +357,13 @@ private: // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based // on a compile-time option) set to a new sync object in updateTexImage. EGLSyncKHR mFence; // mReleaseFence is a fence which will signal when the buffer // associated with this buffer slot is no longer being used by the // consumer and can be overwritten. The buffer can be dequeued before // the fence signals; the producer is responsible for delaying writes // until it signals. sp<Fence> mReleaseFence; }; // mEglDisplay is the EGLDisplay with which this SurfaceTexture is currently Loading
include/ui/Fence.h +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ class Fence : public LightRefBase<Fence>, public Flattenable { public: static const sp<Fence> NO_FENCE; // Construct a new Fence object with an invalid file descriptor. This // should be done when the Fence object will be set up by unflattening Loading
libs/gui/Android.mk +5 −4 Original line number Diff line number Diff line Loading @@ -25,14 +25,15 @@ LOCAL_SRC_FILES:= \ CpuConsumer.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libcutils \ libEGL \ libGLESv2 \ libhardware \ libhardware_legacy \ libsync \ libui \ libEGL \ libGLESv2 \ libutils \ LOCAL_MODULE:= libgui Loading
libs/gui/BufferQueue.cpp +17 −4 Original line number Diff line number Diff line Loading @@ -307,6 +307,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, status_t returnFlags(OK); EGLDisplay dpy = EGL_NO_DISPLAY; EGLSyncKHR fence = EGL_NO_SYNC_KHR; sp<Fence> releaseFence; { // Scope for the lock Mutex::Autolock lock(mMutex); Loading @@ -318,7 +319,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, usage |= mConsumerUsageBits; int found = -1; int foundSync = -1; int dequeuedCount = 0; bool tryAgain = true; while (tryAgain) { Loading Loading @@ -369,7 +369,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, // look for a free buffer to give to the client found = INVALID_BUFFER_SLOT; foundSync = INVALID_BUFFER_SLOT; dequeuedCount = 0; for (int i = 0; i < mBufferCount; i++) { const int state = mSlots[i].mBufferState; Loading @@ -393,7 +392,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, bool isOlder = mSlots[i].mFrameNumber < mSlots[found].mFrameNumber; if (found < 0 || isOlder) { foundSync = i; found = i; } } Loading Loading @@ -484,6 +482,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, mSlots[buf].mGraphicBuffer = graphicBuffer; mSlots[buf].mRequestBufferCalled = false; mSlots[buf].mFence = EGL_NO_SYNC_KHR; mSlots[buf].mReleaseFence.clear(); mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; Loading @@ -491,7 +490,9 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, dpy = mSlots[buf].mEglDisplay; fence = mSlots[buf].mFence; releaseFence = mSlots[buf].mReleaseFence; mSlots[buf].mFence = EGL_NO_SYNC_KHR; mSlots[buf].mReleaseFence.clear(); } // end lock scope if (fence != EGL_NO_SYNC_KHR) { Loading @@ -507,6 +508,16 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, eglDestroySyncKHR(dpy, fence); } if (releaseFence.get()) { int err = releaseFence->wait(1000); if (err == -ETIME) { ALOGE("dequeueBuffer: timeout waiting for release fence"); } else if (err != NO_ERROR) { ALOGE("dequeueBuffer: error waiting for sync fence: %d", err); } releaseFence.clear(); } ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); Loading Loading @@ -846,6 +857,7 @@ void BufferQueue::freeBufferLocked(int i) { eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence); mSlots[i].mFence = EGL_NO_SYNC_KHR; } mSlots[i].mReleaseFence.clear(); } void BufferQueue::freeAllBuffersLocked() { Loading Loading @@ -896,7 +908,7 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer) { } status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence) { EGLSyncKHR fence, const sp<Fence>& releaseFence) { ATRACE_CALL(); ATRACE_BUFFER_INDEX(buf); Loading @@ -908,6 +920,7 @@ status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display, mSlots[buf].mEglDisplay = display; mSlots[buf].mFence = fence; mSlots[buf].mReleaseFence = releaseFence; // The buffer can now only be released if its in the acquired state if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { Loading