Skip to content

Commit 8e63748

Browse files
Jim ShargoAndroid (Google) Code Review
authored andcommitted
Merge "bufferqueues: Move the gl fence wait from dequeue to releaseBuffer" into main
2 parents 11c4285 + 9084218 commit 8e63748

4 files changed

Lines changed: 59 additions & 12 deletions

File tree

libs/gui/BufferQueueConsumer.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
#define VALIDATE_CONSISTENCY()
2929
#endif
3030

31+
#define EGL_EGLEXT_PROTOTYPES
32+
#include <EGL/egl.h>
33+
#include <EGL/eglext.h>
34+
3135
#include <gui/BufferItem.h>
3236
#include <gui/BufferQueueConsumer.h>
3337
#include <gui/BufferQueueCore.h>
@@ -486,6 +490,27 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
486490
return BAD_VALUE;
487491
}
488492

493+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
494+
if (eglFence != EGL_NO_SYNC_KHR) {
495+
// Most platforms will be using native fences, so it's unlikely that we'll ever have to
496+
// process an eglFence. Ideally we can remove this code eventually. In the mean time, do our
497+
// best to wait for it so the buffer stays valid, otherwise return an error to the caller.
498+
//
499+
// EGL_SYNC_FLUSH_COMMANDS_BIT_KHR so that we don't wait forever on a fence that hasn't
500+
// shown up on the GPU yet.
501+
EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
502+
1000000000);
503+
if (result == EGL_FALSE) {
504+
BQ_LOGE("releaseBuffer: error %#x waiting for fence", eglGetError());
505+
return UNKNOWN_ERROR;
506+
} else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
507+
BQ_LOGE("releaseBuffer: timeout waiting for fence");
508+
return UNKNOWN_ERROR;
509+
}
510+
eglDestroySyncKHR(eglDisplay, eglFence);
511+
}
512+
#endif
513+
489514
sp<IProducerListener> listener;
490515
{ // Autolock scope
491516
std::lock_guard<std::mutex> lock(mCore->mMutex);
@@ -507,8 +532,10 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
507532
return BAD_VALUE;
508533
}
509534

535+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
510536
mSlots[slot].mEglDisplay = eglDisplay;
511537
mSlots[slot].mEglFence = eglFence;
538+
#endif
512539
mSlots[slot].mFence = releaseFence;
513540
mSlots[slot].mBufferState.release();
514541

libs/gui/BufferQueueCore.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,16 @@ void BufferQueueCore::clearBufferSlotLocked(int slot) {
262262
mSlots[slot].mFrameNumber = 0;
263263
mSlots[slot].mAcquireCalled = false;
264264
mSlots[slot].mNeedsReallocation = true;
265+
mSlots[slot].mFence = Fence::NO_FENCE;
265266

267+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
266268
// Destroy fence as BufferQueue now takes ownership
267269
if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
268270
eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
269271
mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
270272
}
271-
mSlots[slot].mFence = Fence::NO_FENCE;
272273
mSlots[slot].mEglDisplay = EGL_NO_DISPLAY;
274+
#endif
273275

274276
if (mLastQueuedSlot == slot) {
275277
mLastQueuedSlot = INVALID_BUFFER_SLOT;

libs/gui/BufferQueueProducer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,10 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
451451
}
452452

453453
status_t returnFlags = NO_ERROR;
454+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
454455
EGLDisplay eglDisplay = EGL_NO_DISPLAY;
455456
EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
457+
#endif
456458
bool attachedByConsumer = false;
457459

458460
sp<IConsumerListener> listener;
@@ -569,8 +571,10 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
569571
mSlots[found].mAcquireCalled = false;
570572
mSlots[found].mGraphicBuffer = nullptr;
571573
mSlots[found].mRequestBufferCalled = false;
574+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
572575
mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
573576
mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
577+
#endif
574578
mSlots[found].mFence = Fence::NO_FENCE;
575579
mCore->mBufferAge = 0;
576580
mCore->mIsAllocating = true;
@@ -595,14 +599,18 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
595599
found, buffer->width, buffer->height, buffer->format);
596600
}
597601

602+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
598603
eglDisplay = mSlots[found].mEglDisplay;
599604
eglFence = mSlots[found].mEglFence;
605+
#endif
600606
// Don't return a fence in shared buffer mode, except for the first
601607
// frame.
602608
*outFence = (mCore->mSharedBufferMode &&
603609
mCore->mSharedBufferSlot == found) ?
604610
Fence::NO_FENCE : mSlots[found].mFence;
611+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
605612
mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
613+
#endif
606614
mSlots[found].mFence = Fence::NO_FENCE;
607615

608616
// If shared buffer mode has just been enabled, cache the slot of the
@@ -691,6 +699,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
691699
returnFlags |= BUFFER_NEEDS_REALLOCATION;
692700
}
693701

702+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
694703
if (eglFence != EGL_NO_SYNC_KHR) {
695704
EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
696705
1000000000);
@@ -705,6 +714,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
705714
}
706715
eglDestroySyncKHR(eglDisplay, eglFence);
707716
}
717+
#endif
708718

709719
BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
710720
*outSlot,
@@ -908,7 +918,9 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot,
908918

909919
mSlots[*outSlot].mGraphicBuffer = buffer;
910920
mSlots[*outSlot].mBufferState.attachProducer();
921+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
911922
mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
923+
#endif
912924
mSlots[*outSlot].mFence = Fence::NO_FENCE;
913925
mSlots[*outSlot].mRequestBufferCalled = true;
914926
mSlots[*outSlot].mAcquireCalled = false;

libs/gui/include/gui/BufferSlot.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,26 +174,30 @@ struct BufferState {
174174
};
175175

176176
struct BufferSlot {
177-
178177
BufferSlot()
179-
: mGraphicBuffer(nullptr),
180-
mEglDisplay(EGL_NO_DISPLAY),
181-
mBufferState(),
182-
mRequestBufferCalled(false),
183-
mFrameNumber(0),
184-
mEglFence(EGL_NO_SYNC_KHR),
185-
mFence(Fence::NO_FENCE),
186-
mAcquireCalled(false),
187-
mNeedsReallocation(false) {
178+
: mGraphicBuffer(nullptr),
179+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
180+
mEglDisplay(EGL_NO_DISPLAY),
181+
#endif
182+
mBufferState(),
183+
mRequestBufferCalled(false),
184+
mFrameNumber(0),
185+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
186+
mEglFence(EGL_NO_SYNC_KHR),
187+
#endif
188+
mFence(Fence::NO_FENCE),
189+
mAcquireCalled(false),
190+
mNeedsReallocation(false) {
188191
}
189192

190193
// mGraphicBuffer points to the buffer allocated for this slot or is NULL
191194
// if no buffer has been allocated.
192195
sp<GraphicBuffer> mGraphicBuffer;
193196

197+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
194198
// mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
195199
EGLDisplay mEglDisplay;
196-
200+
#endif
197201
// mBufferState is the current state of this buffer slot.
198202
BufferState mBufferState;
199203

@@ -207,12 +211,14 @@ struct BufferSlot {
207211
// may be released before their release fence is signaled).
208212
uint64_t mFrameNumber;
209213

214+
#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
210215
// mEglFence is the EGL sync object that must signal before the buffer
211216
// associated with this buffer slot may be dequeued. It is initialized
212217
// to EGL_NO_SYNC_KHR when the buffer is created and may be set to a
213218
// new sync object in releaseBuffer. (This is deprecated in favor of
214219
// mFence, below.)
215220
EGLSyncKHR mEglFence;
221+
#endif
216222

217223
// mFence is a fence which will signal when work initiated by the
218224
// previous owner of the buffer is finished. When the buffer is FREE,

0 commit comments

Comments
 (0)