diff options
author | 2021-08-20 16:28:35 -0700 | |
---|---|---|
committer | 2021-10-11 16:46:01 -0700 | |
commit | 403a05bc88c5aa6671adcf4214c2a531f77ac2a4 (patch) | |
tree | f5d93d3b2d3815af4f7d5db4fb67936fa33ac5de /services/surfaceflinger/TransactionCallbackInvoker.cpp | |
parent | 5795d387464674f24e842ac2ea3477507748b5de (diff) |
Second Patch for async RenderEngine
- pass a vector of <LayerSettings> instead of a vector of pointers to
drawLayers function to ensure lifecycle safety.
- capture all local variables to call drawLayerInternals in the render
engine thread to avoid of pointers being invalidated if it takes long
time to pop mFunctions calls.
- change renderScreenImplLocked return type as a shared_future
object to unblock SF main thread for screen capture events.
- block region sampling thread only when SF main thread hasn't
completed capture screen event.
Bug: 180657548
Test: SurfaceFlinger_test, android.hardware.graphics.composer@2.2-vts, libcompositionengine_test, librenderengine_test, libsurfaceflinger_unittest pass
Change-Id: I615f2927d30524988fb12df22fe331e7217c3058
Diffstat (limited to 'services/surfaceflinger/TransactionCallbackInvoker.cpp')
-rw-r--r-- | services/surfaceflinger/TransactionCallbackInvoker.cpp | 32 |
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, |