summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/TransactionCallbackInvoker.cpp
diff options
context:
space:
mode:
author Sally Qi <sallyqi@google.com> 2021-10-12 18:53:23 +0000
committer Sally Qi <sallyqi@google.com> 2021-10-14 21:26:26 -0700
commit59a9f506c7293fdee01482a4bb532df953600d4c (patch)
treed0e102a21a673d6b7eb9fed85cfd6a7376685193 /services/surfaceflinger/TransactionCallbackInvoker.cpp
parent08a97163caa30c57a8cbad571a358dd97a838e70 (diff)
Revert^2 "Second Patch for async RenderEngine"
Keep the change of Second Patch for async RenderEngine and fix the regression - remove the vector variables which is to store futureFence locally in BufferStateLayer to get avoid fd leaking - screenshots initiated from the app don't wait on the SF main thread. 2109270e74a18585aceffc94d1758cee47bb4175 Bug: 202843200 Bug: 202833127 Bug: 202808760 Test: Wembley PIN setting test, NexusLauncherOutOfProcTests Change-Id: I87847d01e2e330ddec88272cd8608f0b78c0a2cd
Diffstat (limited to 'services/surfaceflinger/TransactionCallbackInvoker.cpp')
-rw-r--r--services/surfaceflinger/TransactionCallbackInvoker.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index c1eb8966d1..8fbf0b4d07 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -154,6 +154,38 @@ status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>&
// destroyed the client side is dead and there won't be anyone to send the callback to.
sp<IBinder> surfaceControl = handle->surfaceControl.promote();
if (surfaceControl) {
+ sp<Fence> prevFence = nullptr;
+
+ for (const auto& futureStruct : handle->previousReleaseFences) {
+ sp<Fence> currentFence = sp<Fence>::make(dup(futureStruct.get().drawFence));
+ if (prevFence == nullptr && currentFence->getStatus() != Fence::Status::Invalid) {
+ prevFence = currentFence;
+ handle->previousReleaseFence = prevFence;
+ } else if (prevFence != nullptr) {
+ // If both fences are signaled or both are unsignaled, we need to merge
+ // them to get an accurate timestamp.
+ if (prevFence->getStatus() != Fence::Status::Invalid &&
+ prevFence->getStatus() == currentFence->getStatus()) {
+ char fenceName[32] = {};
+ snprintf(fenceName, 32, "%.28s", handle->name.c_str());
+ sp<Fence> mergedFence = Fence::merge(fenceName, prevFence, currentFence);
+ if (mergedFence->isValid()) {
+ handle->previousReleaseFence = mergedFence;
+ prevFence = handle->previousReleaseFence;
+ }
+ } else if (currentFence->getStatus() == Fence::Status::Unsignaled) {
+ // If one fence has signaled and the other hasn't, the unsignaled
+ // fence will approximately correspond with the correct timestamp.
+ // There's a small race if both fences signal at about the same time
+ // and their statuses are retrieved with unfortunate timing. However,
+ // by this point, they will have both signaled and only the timestamp
+ // will be slightly off; any dependencies after this point will
+ // already have been met.
+ handle->previousReleaseFence = currentFence;
+ }
+ }
+ }
+ handle->previousReleaseFences = {};
FrameEventHistoryStats eventStats(handle->frameNumber,
handle->gpuCompositionDoneFence->getSnapshot().fence,
handle->compositorTiming, handle->refreshStartTime,