diff options
author | chaviw <chaviw@google.com> | 2021-08-20 12:15:48 -0500 |
---|---|---|
committer | Rob Carr <racarr@google.com> | 2021-11-24 23:38:34 +0000 |
commit | e97e296c811d16a3169c99b2b9e14a25cc245356 (patch) | |
tree | fe269f7cb38cb43c81e8e77427568eda92c21f00 /libs/hwui/renderthread/DrawFrameTask.cpp | |
parent | 27cef855be711db25d8664977de3c92a4ef8c1ea (diff) |
Rework blast sync callback model
The previous code waited for a frame complete callback from hwui before
notifying WMS that a draw had occurred. However, frame complete callback
was not guaranteed to get called since it only invokes a callback if a
draw actually occured. VRI really needs a signal that RT has completed,
since it just needs to know that a draw was possible so it can notify
WMS that the RT completed its pass.
Instead, rename frameCompleteCallback to frameCommitCallback since that
API is exposed to a public API when a frame was actually drawn.
Create a new callback, frameCompleteCallback, that is invoked when the
draw has completed, regardless if a frame was actually drawn.
When the frameCompleteCallback is invoked, VRI can check to see if a new
frame actually drew. VRI can call into BBQ to see if the frame acquired
matches the frame that was attempted to draw. If so, VRI can wait on a
transaction callback. If not, it can allow VRI to continue. In either case,
it will notify WMS that the draw has finished.
Test: Split over and over
Bug: 195262673
Bug: 193634619
Change-Id: I24dd19ab2746be3fc33e597761abf8c5249f8b5b
Merged-In: I24dd19ab2746be3fc33e597761abf8c5249f8b5b
Diffstat (limited to 'libs/hwui/renderthread/DrawFrameTask.cpp')
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index e7081df2b558..94aedd0f43be 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -150,16 +150,18 @@ void DrawFrameTask::run() { canUnblockUiThread = syncFrameState(info); canDrawThisFrame = info.out.canDrawThisFrame; - if (mFrameCompleteCallback) { - mContext->addFrameCompleteListener(std::move(mFrameCompleteCallback)); - mFrameCompleteCallback = nullptr; + if (mFrameCommitCallback) { + mContext->addFrameCommitListener(std::move(mFrameCommitCallback)); + mFrameCommitCallback = nullptr; } } // Grab a copy of everything we need CanvasContext* context = mContext; - std::function<void(int64_t)> callback = std::move(mFrameCallback); + std::function<void(int64_t)> frameCallback = std::move(mFrameCallback); + std::function<void()> frameCompleteCallback = std::move(mFrameCompleteCallback); mFrameCallback = nullptr; + mFrameCompleteCallback = nullptr; int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)]; int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)]; int64_t frameStartTime = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameStartTime)]; @@ -170,9 +172,9 @@ void DrawFrameTask::run() { } // Even if we aren't drawing this vsync pulse the next frame number will still be accurate - if (CC_UNLIKELY(callback)) { + if (CC_UNLIKELY(frameCallback)) { context->enqueueFrameWork( - [callback, frameNr = context->getFrameNumber()]() { callback(frameNr); }); + [frameCallback, frameNr = context->getFrameNumber()]() { frameCallback(frameNr); }); } nsecs_t dequeueBufferDuration = 0; @@ -189,6 +191,10 @@ void DrawFrameTask::run() { context->waitOnFences(); } + if (CC_UNLIKELY(frameCompleteCallback)) { + std::invoke(frameCompleteCallback); + } + if (!canUnblockUiThread) { unblockUiThread(); } |