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
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a8b21fb..9e2b6e0 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -759,6 +759,12 @@
private boolean mWaitForBlastSyncComplete = false;
/**
+ * Keeps track of the last frame number that was attempted to draw. Should only be accessed on
+ * the RenderThread.
+ */
+ private long mRtLastAttemptedDrawFrameNum = 0;
+
+ /**
* Keeps track of whether a traverse was triggered while the UI thread was paused. This can
* occur when the client is waiting on another process to submit the transaction that
* contains the buffer. The UI thread needs to wait on the callback before it can submit
@@ -3974,35 +3980,19 @@
}
/**
- * The callback will run on the render thread.
+ * Only call this on the UI Thread.
*/
- private HardwareRenderer.FrameCompleteCallback createFrameCompleteCallback(Handler handler,
- boolean reportNextDraw, ArrayList<Runnable> commitCallbacks) {
- return frameNr -> {
- if (DEBUG_BLAST) {
- Log.d(mTag, "Received frameCompleteCallback frameNum=" + frameNr);
- }
-
- handler.postAtFrontOfQueue(() -> {
- if (mNextDrawUseBlastSync) {
- // We don't need to synchronize mRtBLASTSyncTransaction here since we're
- // guaranteed that this is called after onFrameDraw and mNextDrawUseBlastSync
- // is only true when the UI thread is paused. Therefore, no one should be
- // modifying this object until the next vsync.
- mSurfaceChangedTransaction.merge(mRtBLASTSyncTransaction);
- }
-
- if (reportNextDraw) {
- // TODO: Use the frame number
- pendingDrawFinished();
- }
- if (commitCallbacks != null) {
- for (int i = 0; i < commitCallbacks.size(); i++) {
- commitCallbacks.get(i).run();
- }
- }
- });
- };
+ void clearBlastSync() {
+ mNextDrawUseBlastSync = false;
+ mWaitForBlastSyncComplete = false;
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "Scheduling a traversal=" + mRequestedTraverseWhilePaused
+ + " due to a previous skipped traversal.");
+ }
+ if (mRequestedTraverseWhilePaused) {
+ mRequestedTraverseWhilePaused = false;
+ scheduleTraversals();
+ }
}
/**
@@ -4012,30 +4002,86 @@
return mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled();
}
- private boolean addFrameCompleteCallbackIfNeeded() {
+ private boolean addFrameCompleteCallbackIfNeeded(boolean reportNextDraw) {
if (!isHardwareEnabled()) {
return false;
}
+ if (!mNextDrawUseBlastSync && !reportNextDraw) {
+ return false;
+ }
+
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "Creating frameCompleteCallback");
+ }
+
+ mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(() -> {
+ long frameNr = mBlastBufferQueue.getLastAcquiredFrameNum();
+ if (DEBUG_BLAST) {
+ Log.d(mTag, "Received frameCompleteCallback "
+ + " lastAcquiredFrameNum=" + frameNr
+ + " lastAttemptedDrawFrameNum=" + mRtLastAttemptedDrawFrameNum);
+ }
+
+ boolean frameWasNotDrawn = frameNr != mRtLastAttemptedDrawFrameNum;
+ // If frame wasn't drawn, clear out the next transaction so it doesn't affect the next
+ // draw attempt. The next transaction and transaction complete callback were only set
+ // for the current draw attempt.
+ if (frameWasNotDrawn) {
+ mBlastBufferQueue.setNextTransaction(null);
+ mBlastBufferQueue.setTransactionCompleteCallback(mRtLastAttemptedDrawFrameNum,
+ null);
+ }
+
+ mHandler.postAtFrontOfQueue(() -> {
+ if (mNextDrawUseBlastSync) {
+ // We don't need to synchronize mRtBLASTSyncTransaction here since we're
+ // guaranteed that this is called after onFrameDraw and mNextDrawUseBlastSync
+ // is only true when the UI thread is paused. Therefore, no one should be
+ // modifying this object until the next vsync.
+ mSurfaceChangedTransaction.merge(mRtBLASTSyncTransaction);
+ }
+
+ if (reportNextDraw) {
+ pendingDrawFinished();
+ }
+
+ if (frameWasNotDrawn) {
+ clearBlastSync();
+ }
+ });
+ });
+ return true;
+ }
+
+ private void addFrameCommitCallbackIfNeeded() {
+ if (!isHardwareEnabled()) {
+ return;
+ }
+
ArrayList<Runnable> commitCallbacks = mAttachInfo.mTreeObserver
.captureFrameCommitCallbacks();
- final boolean needFrameCompleteCallback =
- mNextDrawUseBlastSync || mReportNextDraw
- || (commitCallbacks != null && commitCallbacks.size() > 0);
- if (needFrameCompleteCallback) {
- if (DEBUG_BLAST) {
- Log.d(mTag, "Creating frameCompleteCallback"
- + " mNextDrawUseBlastSync=" + mNextDrawUseBlastSync
- + " mReportNextDraw=" + mReportNextDraw
- + " commitCallbacks size="
- + (commitCallbacks == null ? 0 : commitCallbacks.size()));
- }
- mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(
- createFrameCompleteCallback(mAttachInfo.mHandler, mReportNextDraw,
- commitCallbacks));
- return true;
+ final boolean needFrameCommitCallback =
+ (commitCallbacks != null && commitCallbacks.size() > 0);
+ if (!needFrameCommitCallback) {
+ return;
}
- return false;
+
+ if (DEBUG_DRAW) {
+ Log.d(mTag, "Creating frameCommitCallback"
+ + " commitCallbacks size=" + commitCallbacks.size());
+ }
+ mAttachInfo.mThreadedRenderer.setFrameCommitCallback(didProduceBuffer -> {
+ if (DEBUG_DRAW) {
+ Log.d(mTag, "Received frameCommitCallback didProduceBuffer=" + didProduceBuffer);
+ }
+
+ mHandler.postAtFrontOfQueue(() -> {
+ for (int i = 0; i < commitCallbacks.size(); i++) {
+ commitCallbacks.get(i).run();
+ }
+ });
+ });
}
private void addFrameCallbackIfNeeded() {
@@ -4065,6 +4111,8 @@
+ " Creating transactionCompleteCallback=" + nextDrawUseBlastSync);
}
+ mRtLastAttemptedDrawFrameNum = frame;
+
if (needsCallbackForBlur) {
mBlurRegionAggregator
.dispatchBlurTransactionIfNeeded(frame, blurRegionsForFrame, hasBlurUpdates);
@@ -4087,18 +4135,7 @@
if (DEBUG_BLAST) {
Log.d(mTag, "Received transactionCompleteCallback frameNum=" + frame);
}
- mHandler.postAtFrontOfQueue(() -> {
- mNextDrawUseBlastSync = false;
- mWaitForBlastSyncComplete = false;
- if (DEBUG_BLAST) {
- Log.d(mTag, "Scheduling a traversal=" + mRequestedTraverseWhilePaused
- + " due to a previous skipped traversal.");
- }
- if (mRequestedTraverseWhilePaused) {
- mRequestedTraverseWhilePaused = false;
- scheduleTraversals();
- }
- });
+ mHandler.postAtFrontOfQueue(this::clearBlastSync);
});
} else if (reportNextDraw) {
// If we need to report next draw, wait for adapter to flush its shadow queue
@@ -4124,8 +4161,9 @@
mIsDrawing = true;
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
- boolean usingAsyncReport = addFrameCompleteCallbackIfNeeded();
addFrameCallbackIfNeeded();
+ addFrameCommitCallbackIfNeeded();
+ boolean usingAsyncReport = addFrameCompleteCallbackIfNeeded(mReportNextDraw);
try {
boolean canUseAsync = draw(fullRedrawNeeded);
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index d4ae6d7..3e31b46 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -139,6 +139,11 @@
}
}
+static jlong nativeGetLastAcquiredFrameNum(JNIEnv* env, jclass clazz, jlong ptr) {
+ sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+ return queue->getLastAcquiredFrameNum();
+}
+
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
// clang-format off
@@ -151,7 +156,8 @@
{"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction},
{"nativeSetTransactionCompleteCallback",
"(JJLandroid/graphics/BLASTBufferQueue$TransactionCompleteCallback;)V",
- (void*)nativeSetTransactionCompleteCallback}
+ (void*)nativeSetTransactionCompleteCallback},
+ {"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
// clang-format on
};
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 36215ec..0e1360f 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -39,6 +39,7 @@
long frameNumber);
private static native void nativeSetTransactionCompleteCallback(long ptr, long frameNumber,
TransactionCompleteCallback callback);
+ private static native long nativeGetLastAcquiredFrameNum(long ptr);
/**
* Callback sent to {@link #setTransactionCompleteCallback(long, TransactionCompleteCallback)}
@@ -145,4 +146,7 @@
nativeMergeWithNextTransaction(mNativeObject, nativeTransaction, frameNumber);
}
+ public long getLastAcquiredFrameNum() {
+ return nativeGetLastAcquiredFrameNum(mNativeObject);
+ }
}
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 8894fa3..abdf1a2 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -388,7 +388,8 @@
*/
public @NonNull FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
@NonNull Runnable frameCommitCallback) {
- setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback));
+ nSetFrameCommitCallback(mNativeProxy,
+ didProduceBuffer -> executor.execute(frameCommitCallback));
return this;
}
@@ -609,6 +610,11 @@
}
/** @hide */
+ public void setFrameCommitCallback(FrameCommitCallback callback) {
+ nSetFrameCommitCallback(mNativeProxy, callback);
+ }
+
+ /** @hide */
public void setFrameCompleteCallback(FrameCompleteCallback callback) {
nSetFrameCompleteCallback(mNativeProxy, callback);
}
@@ -896,13 +902,27 @@
*
* @hide
*/
+ public interface FrameCommitCallback {
+ /**
+ * Invoked after a new frame was drawn
+ *
+ * @param didProduceBuffer The draw successfully produced a new buffer.
+ */
+ void onFrameCommit(boolean didProduceBuffer);
+ }
+
+ /**
+ * Interface used to be notified when RenderThread has finished an attempt to draw. This doesn't
+ * mean a new frame has drawn, specifically if there's nothing new to draw, but only that
+ * RenderThread had a chance to draw a frame.
+ *
+ * @hide
+ */
public interface FrameCompleteCallback {
/**
- * Invoked after a frame draw
- *
- * @param frameNr The id of the frame that was drawn.
+ * Invoked after a frame draw was attempted.
*/
- void onFrameComplete(long frameNr);
+ void onFrameComplete();
}
/**
@@ -1391,6 +1411,9 @@
private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
+ private static native void nSetFrameCommitCallback(long nativeProxy,
+ FrameCommitCallback callback);
+
private static native void nSetFrameCompleteCallback(long nativeProxy,
FrameCompleteCallback callback);
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 1ca4ce9..e536950 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -73,6 +73,10 @@
} gFrameDrawingCallback;
struct {
+ jmethodID onFrameCommit;
+} gFrameCommitCallback;
+
+struct {
jmethodID onFrameComplete;
} gFrameCompleteCallback;
@@ -101,22 +105,21 @@
JavaVM* mVm;
};
-class FrameCompleteWrapper : public LightRefBase<FrameCompleteWrapper> {
+class FrameCommitWrapper : public LightRefBase<FrameCommitWrapper> {
public:
- explicit FrameCompleteWrapper(JNIEnv* env, jobject jobject) {
+ explicit FrameCommitWrapper(JNIEnv* env, jobject jobject) {
env->GetJavaVM(&mVm);
mObject = env->NewGlobalRef(jobject);
LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref");
}
- ~FrameCompleteWrapper() {
- releaseObject();
- }
+ ~FrameCommitWrapper() { releaseObject(); }
- void onFrameComplete(int64_t frameNr) {
+ void onFrameCommit(bool didProduceBuffer) {
if (mObject) {
- ATRACE_FORMAT("frameComplete %" PRId64, frameNr);
- getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, frameNr);
+ ATRACE_FORMAT("frameCommit success=%d", didProduceBuffer);
+ getenv(mVm)->CallVoidMethod(mObject, gFrameCommitCallback.onFrameCommit,
+ didProduceBuffer);
releaseObject();
}
}
@@ -607,15 +610,33 @@
}
}
+static void android_view_ThreadedRenderer_setFrameCommitCallback(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jobject callback) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ if (!callback) {
+ proxy->setFrameCommitCallback(nullptr);
+ } else {
+ sp<FrameCommitWrapper> wrapper = new FrameCommitWrapper{env, callback};
+ proxy->setFrameCommitCallback(
+ [wrapper](bool didProduceBuffer) { wrapper->onFrameCommit(didProduceBuffer); });
+ }
+}
+
static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env,
jobject clazz, jlong proxyPtr, jobject callback) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
if (!callback) {
proxy->setFrameCompleteCallback(nullptr);
} else {
- sp<FrameCompleteWrapper> wrapper = new FrameCompleteWrapper{env, callback};
- proxy->setFrameCompleteCallback([wrapper](int64_t frameNr) {
- wrapper->onFrameComplete(frameNr);
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ JavaVM* vm = nullptr;
+ LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
+ auto globalCallbackRef =
+ std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback));
+ proxy->setFrameCompleteCallback([globalCallbackRef]() {
+ JNIEnv* env = getenv(globalCallbackRef->vm());
+ env->CallVoidMethod(globalCallbackRef->object(),
+ gFrameCompleteCallback.onFrameComplete);
});
}
}
@@ -907,6 +928,8 @@
(void*)android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCallback},
{"nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCallback},
+ {"nSetFrameCommitCallback", "(JLandroid/graphics/HardwareRenderer$FrameCommitCallback;)V",
+ (void*)android_view_ThreadedRenderer_setFrameCommitCallback},
{"nSetFrameCompleteCallback",
"(JLandroid/graphics/HardwareRenderer$FrameCompleteCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCompleteCallback},
@@ -974,10 +997,15 @@
gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
"onFrameDraw", "(J)V");
+ jclass frameCommitClass =
+ FindClassOrDie(env, "android/graphics/HardwareRenderer$FrameCommitCallback");
+ gFrameCommitCallback.onFrameCommit =
+ GetMethodIDOrDie(env, frameCommitClass, "onFrameCommit", "(Z)V");
+
jclass frameCompleteClass = FindClassOrDie(env,
"android/graphics/HardwareRenderer$FrameCompleteCallback");
- gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass,
- "onFrameComplete", "(J)V");
+ gFrameCompleteCallback.onFrameComplete =
+ GetMethodIDOrDie(env, frameCompleteClass, "onFrameComplete", "()V");
void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
fromSurface = (ANW_fromSurface)dlsym(handle_, "ANativeWindow_fromSurface");
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index bb0b135..0cd6ffb 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -492,10 +492,10 @@
// Notify the callbacks, even if there's nothing to draw so they aren't waiting
// indefinitely
waitOnFences();
- for (auto& func : mFrameCompleteCallbacks) {
- std::invoke(func, mFrameNumber);
+ for (auto& func : mFrameCommitCallbacks) {
+ std::invoke(func, false /* didProduceBuffer */);
}
- mFrameCompleteCallbacks.clear();
+ mFrameCommitCallbacks.clear();
return 0;
}
@@ -604,10 +604,10 @@
#endif
if (didSwap) {
- for (auto& func : mFrameCompleteCallbacks) {
- std::invoke(func, frameCompleteNr);
+ for (auto& func : mFrameCommitCallbacks) {
+ std::invoke(func, true /* didProduceBuffer */);
}
- mFrameCompleteCallbacks.clear();
+ mFrameCommitCallbacks.clear();
}
if (requireSwap) {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 2fed468..ed4a620 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -195,8 +195,8 @@
IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }
- void addFrameCompleteListener(std::function<void(int64_t)>&& func) {
- mFrameCompleteCallbacks.push_back(std::move(func));
+ void addFrameCommitListener(std::function<void(bool)>&& func) {
+ mFrameCommitCallbacks.push_back(std::move(func));
}
void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback) {
@@ -328,7 +328,7 @@
std::vector<std::future<void>> mFrameFences;
std::unique_ptr<IRenderPipeline> mRenderPipeline;
- std::vector<std::function<void(int64_t)>> mFrameCompleteCallbacks;
+ std::vector<std::function<void(bool)>> mFrameCommitCallbacks;
// If set to true, we expect that callbacks into onSurfaceStatsAvailable
bool mExpectSurfaceStats = false;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index e7081df..94aedd0 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -150,16 +150,18 @@
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 @@
}
// 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 @@
context->waitOnFences();
}
+ if (CC_UNLIKELY(frameCompleteCallback)) {
+ std::invoke(frameCompleteCallback);
+ }
+
if (!canUnblockUiThread) {
unblockUiThread();
}
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 6a61a2b..e3ea802 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -81,7 +81,11 @@
mFrameCallback = std::move(callback);
}
- void setFrameCompleteCallback(std::function<void(int64_t)>&& callback) {
+ void setFrameCommitCallback(std::function<void(bool)>&& callback) {
+ mFrameCommitCallback = std::move(callback);
+ }
+
+ void setFrameCompleteCallback(std::function<void()>&& callback) {
mFrameCompleteCallback = std::move(callback);
}
@@ -123,7 +127,8 @@
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
std::function<void(int64_t)> mFrameCallback;
- std::function<void(int64_t)> mFrameCompleteCallback;
+ std::function<void(bool)> mFrameCommitCallback;
+ std::function<void()> mFrameCompleteCallback;
nsecs_t mLastDequeueBufferDuration = 0;
nsecs_t mLastTargetWorkDuration = 0;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index c485ce2..72d4ac5 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -326,7 +326,11 @@
mDrawFrameTask.setFrameCallback(std::move(callback));
}
-void RenderProxy::setFrameCompleteCallback(std::function<void(int64_t)>&& callback) {
+void RenderProxy::setFrameCommitCallback(std::function<void(bool)>&& callback) {
+ mDrawFrameTask.setFrameCommitCallback(std::move(callback));
+}
+
+void RenderProxy::setFrameCompleteCallback(std::function<void()>&& callback) {
mDrawFrameTask.setFrameCompleteCallback(std::move(callback));
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 2b5405c..6417b38 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -124,7 +124,8 @@
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 setFrameCompleteCallback(std::function<void(int64_t)>&& callback);
+ void setFrameCommitCallback(std::function<void(bool)>&& callback);
+ void setFrameCompleteCallback(std::function<void()>&& callback);
void addFrameMetricsObserver(FrameMetricsObserver* observer);
void removeFrameMetricsObserver(FrameMetricsObserver* observer);