Remove RenderEngine::flush from latchBuffer()
Fence fd will be owned by SurfaceFlinger to be propagated down to
latchBuffer for merging sync fences. We can't store the fd at the
Layer-level & flush on every draw() invocation for some reason (I don't
fully understand what the gl driver does under the hood, but from what
it looks like file descriptors are reused when the command stream is
flushed too often which causes a memory leak when a buffer's sync fence
is merged), so we'll let SF backend store the flush fence for the
previous frame.
Bug: 116277151
Change-Id: I7901b0178aa0f11505650bf5e1df6f085a5d93bf
Test: SurfaceFlinger_test, libsurfaceflinger_unittest, go/wm-smoke
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 91948ae..f499f06 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -147,7 +147,8 @@
status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const DispSync& dispSync,
bool* autoRefresh, bool* queuedBuffer,
- uint64_t maxFrameNumber) {
+ uint64_t maxFrameNumber,
+ const sp<Fence>& releaseFence) {
ATRACE_CALL();
BLC_LOGV("updateTexImage");
Mutex::Autolock lock(mMutex);
@@ -198,7 +199,7 @@
}
// Release the previous buffer.
- err = updateAndReleaseLocked(item, &mPendingRelease);
+ err = updateAndReleaseLocked(item, &mPendingRelease, releaseFence);
if (err != NO_ERROR) {
return err;
}
@@ -278,14 +279,15 @@
}
status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,
- PendingRelease* pendingRelease) {
+ PendingRelease* pendingRelease,
+ const sp<Fence>& releaseFence) {
status_t err = NO_ERROR;
int slot = item.mSlot;
// Do whatever sync ops we need to do before releasing the old slot.
if (slot != mCurrentTexture) {
- err = syncForReleaseLocked();
+ err = syncForReleaseLocked(releaseFence);
if (err != NO_ERROR) {
// Release the buffer we just acquired. It's not safe to
// release the old buffer, so instead we just drop the new frame.
@@ -367,19 +369,19 @@
return doFenceWaitLocked();
}
-status_t BufferLayerConsumer::syncForReleaseLocked() {
+status_t BufferLayerConsumer::syncForReleaseLocked(const sp<Fence>& releaseFence) {
BLC_LOGV("syncForReleaseLocked");
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- if (mRE.useNativeFenceSync()) {
- base::unique_fd fenceFd = mRE.flush();
- if (fenceFd == -1) {
+ if (mRE.useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
+ // TODO(alecmouri): fail further upstream if the fence is invalid
+ if (!releaseFence->isValid()) {
BLC_LOGE("syncForReleaseLocked: failed to flush RenderEngine");
return UNKNOWN_ERROR;
}
- sp<Fence> fence(new Fence(std::move(fenceFd)));
- status_t err = addReleaseFenceLocked(mCurrentTexture,
- mCurrentTextureImage->graphicBuffer(), fence);
+ status_t err =
+ addReleaseFenceLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer(),
+ releaseFence);
if (err != OK) {
BLC_LOGE("syncForReleaseLocked: error adding release fence: "
"%s (%d)",