Send syncStatus and return FrameCommitCallback in FrameCallback
FrameCallback sends back the syncStatus and allows the caller to return
a FrameCommitCallback. This is so the caller can evaluate the results of
the sync and determine if it wants to continue waiting for a commit
callback. In cases, where the sync has failed, there will never be a
commit callback so the caller can avoid waiting.
This is partically helpful for VRI because it wants to sync with a frame
that will draw, but also doesn't want to get stuck indefinitely waiting
on the callback. VRI can check the syncStatus and only handle blast sync
and/or reportDraw when its determined that a draw will happen.
This allows VRI to remove frameCompleteCallback since it can now wait
until a buffer has drawn instead of when the vsync has completed. This makes
sure it waits on FrameDropped since that result indicates HWUI will draw on
the next vsync
Test: BlastSync
Bug: 200284684
Change-Id: Ic6e2f08ea21ac8a1634a3389c927fcb68ede3f7b
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index bd93a4f..27865b3 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -609,10 +609,19 @@
LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm,
env->NewGlobalRef(frameCallback));
- proxy->setFrameCallback([globalCallbackRef](int64_t frameNr) {
+ proxy->setFrameCallback([globalCallbackRef](int32_t syncResult,
+ int64_t frameNr) -> std::function<void(bool)> {
JNIEnv* env = getenv(globalCallbackRef->vm());
- env->CallVoidMethod(globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw,
- static_cast<jlong>(frameNr));
+ ScopedLocalRef<jobject> frameCommitCallback(
+ env, env->CallObjectMethod(
+ globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw,
+ static_cast<jint>(syncResult), static_cast<jlong>(frameNr)));
+ if (frameCommitCallback == nullptr) {
+ return nullptr;
+ }
+ sp<FrameCommitWrapper> wrapper =
+ sp<FrameCommitWrapper>::make(env, frameCommitCallback.get());
+ return [wrapper](bool didProduceBuffer) { wrapper->onFrameCommit(didProduceBuffer); };
});
}
}
@@ -623,7 +632,7 @@
if (!callback) {
proxy->setFrameCommitCallback(nullptr);
} else {
- sp<FrameCommitWrapper> wrapper = new FrameCommitWrapper{env, callback};
+ sp<FrameCommitWrapper> wrapper = sp<FrameCommitWrapper>::make(env, callback);
proxy->setFrameCommitCallback(
[wrapper](bool didProduceBuffer) { wrapper->onFrameCommit(didProduceBuffer); });
}
@@ -1003,8 +1012,9 @@
jclass frameCallbackClass = FindClassOrDie(env,
"android/graphics/HardwareRenderer$FrameDrawingCallback");
- gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
- "onFrameDraw", "(J)V");
+ gFrameDrawingCallback.onFrameDraw =
+ GetMethodIDOrDie(env, frameCallbackClass, "onFrameDraw",
+ "(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;");
jclass frameCommitClass =
FindClassOrDie(env, "android/graphics/HardwareRenderer$FrameCommitCallback");
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 94aedd0..8c98c72 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -158,7 +158,8 @@
// Grab a copy of everything we need
CanvasContext* context = mContext;
- std::function<void(int64_t)> frameCallback = std::move(mFrameCallback);
+ std::function<std::function<void(bool)>(int32_t, int64_t)> frameCallback =
+ std::move(mFrameCallback);
std::function<void()> frameCompleteCallback = std::move(mFrameCompleteCallback);
mFrameCallback = nullptr;
mFrameCompleteCallback = nullptr;
@@ -173,8 +174,13 @@
// Even if we aren't drawing this vsync pulse the next frame number will still be accurate
if (CC_UNLIKELY(frameCallback)) {
- context->enqueueFrameWork(
- [frameCallback, frameNr = context->getFrameNumber()]() { frameCallback(frameNr); });
+ context->enqueueFrameWork([frameCallback, context, syncResult = mSyncResult,
+ frameNr = context->getFrameNumber()]() {
+ auto frameCommitCallback = std::move(frameCallback(syncResult, frameNr));
+ if (frameCommitCallback) {
+ context->addFrameCommitListener(std::move(frameCommitCallback));
+ }
+ });
}
nsecs_t dequeueBufferDuration = 0;
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index e3ea802..8ad8abc 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -77,7 +77,7 @@
void run();
- void setFrameCallback(std::function<void(int64_t)>&& callback) {
+ void setFrameCallback(std::function<std::function<void(bool)>(int32_t, int64_t)>&& callback) {
mFrameCallback = std::move(callback);
}
@@ -126,7 +126,7 @@
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
- std::function<void(int64_t)> mFrameCallback;
+ std::function<std::function<void(bool)>(int32_t, int64_t)> mFrameCallback;
std::function<void(bool)> mFrameCommitCallback;
std::function<void()> mFrameCompleteCallback;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 430c4d3..026699c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -327,7 +327,8 @@
[this, cb = callback]() { mContext->setPrepareSurfaceControlForWebviewCallback(cb); });
}
-void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
+void RenderProxy::setFrameCallback(
+ std::function<std::function<void(bool)>(int32_t, int64_t)>&& callback) {
mDrawFrameTask.setFrameCallback(std::move(callback));
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 6d46be4..491dbd7 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -124,7 +124,7 @@
void setASurfaceTransactionCallback(
const std::function<bool(int64_t, int64_t, int64_t)>& callback);
void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback);
- void setFrameCallback(std::function<void(int64_t)>&& callback);
+ void setFrameCallback(std::function<std::function<void(bool)>(int32_t, int64_t)>&& callback);
void setFrameCommitCallback(std::function<void(bool)>&& callback);
void setFrameCompleteCallback(std::function<void()>&& callback);