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 Change-Id: I24dd19ab2746be3fc33e597761abf8c5249f8b5b
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user