Merge "Rework blast sync callback model" into sc-v2-dev
This commit is contained in:
@@ -767,6 +767,12 @@ public final class ViewRootImpl implements ViewParent,
|
||||
*/
|
||||
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
|
||||
@@ -4051,40 +4057,19 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
final Consumer<SurfaceControl.Transaction> blastSyncConsumer = mBLASTDrawConsumer;
|
||||
mBLASTDrawConsumer = null;
|
||||
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 (blastSyncConsumer != null) {
|
||||
blastSyncConsumer.accept(mSurfaceChangedTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4094,30 +4079,90 @@ public final class ViewRootImpl implements ViewParent,
|
||||
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 (mBLASTDrawConsumer != null) {
|
||||
mBLASTDrawConsumer.accept(mSurfaceChangedTransaction);
|
||||
}
|
||||
mBLASTDrawConsumer = null;
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -4147,6 +4192,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
+ " Creating transactionCompleteCallback=" + nextDrawUseBlastSync);
|
||||
}
|
||||
|
||||
mRtLastAttemptedDrawFrameNum = frame;
|
||||
|
||||
if (needsCallbackForBlur) {
|
||||
mBlurRegionAggregator
|
||||
.dispatchBlurTransactionIfNeeded(frame, blurRegionsForFrame, hasBlurUpdates);
|
||||
@@ -4169,18 +4216,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -4201,8 +4237,9 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mIsDrawing = true;
|
||||
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
|
||||
|
||||
boolean usingAsyncReport = addFrameCompleteCallbackIfNeeded();
|
||||
addFrameCallbackIfNeeded();
|
||||
addFrameCommitCallbackIfNeeded();
|
||||
boolean usingAsyncReport = addFrameCompleteCallbackIfNeeded(mReportNextDraw);
|
||||
|
||||
try {
|
||||
boolean canUseAsync = draw(fullRedrawNeeded);
|
||||
|
||||
@@ -134,6 +134,11 @@ static void nativeSetTransactionCompleteCallback(JNIEnv* env, jclass clazz, jlon
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -145,7 +150,8 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction},
|
||||
{"nativeSetTransactionCompleteCallback",
|
||||
"(JJLandroid/graphics/BLASTBufferQueue$TransactionCompleteCallback;)V",
|
||||
(void*)nativeSetTransactionCompleteCallback}
|
||||
(void*)nativeSetTransactionCompleteCallback},
|
||||
{"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public final class BLASTBufferQueue {
|
||||
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)}
|
||||
@@ -140,4 +141,7 @@ public final class BLASTBufferQueue {
|
||||
nativeMergeWithNextTransaction(mNativeObject, nativeTransaction, frameNumber);
|
||||
}
|
||||
|
||||
public long getLastAcquiredFrameNum() {
|
||||
return nativeGetLastAcquiredFrameNum(mNativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +388,8 @@ public class HardwareRenderer {
|
||||
*/
|
||||
public @NonNull FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
|
||||
@NonNull Runnable frameCommitCallback) {
|
||||
setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback));
|
||||
nSetFrameCommitCallback(mNativeProxy,
|
||||
didProduceBuffer -> executor.execute(frameCommitCallback));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -608,6 +609,11 @@ public class HardwareRenderer {
|
||||
return mOpaque;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setFrameCommitCallback(FrameCommitCallback callback) {
|
||||
nSetFrameCommitCallback(mNativeProxy, callback);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setFrameCompleteCallback(FrameCompleteCallback callback) {
|
||||
nSetFrameCompleteCallback(mNativeProxy, callback);
|
||||
@@ -904,13 +910,27 @@ public class HardwareRenderer {
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1362,6 +1382,9 @@ public class HardwareRenderer {
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -72,6 +72,10 @@ struct {
|
||||
jmethodID onFrameDraw;
|
||||
} gFrameDrawingCallback;
|
||||
|
||||
struct {
|
||||
jmethodID onFrameCommit;
|
||||
} gFrameCommitCallback;
|
||||
|
||||
struct {
|
||||
jmethodID onFrameComplete;
|
||||
} gFrameCompleteCallback;
|
||||
@@ -101,22 +105,21 @@ private:
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -637,15 +640,33 @@ static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -929,6 +950,8 @@ static const JNINativeMethod gMethods[] = {
|
||||
(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},
|
||||
@@ -994,10 +1017,15 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) {
|
||||
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");
|
||||
|
||||
@@ -491,10 +491,10 @@ nsecs_t CanvasContext::draw() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -603,10 +603,10 @@ nsecs_t CanvasContext::draw() {
|
||||
#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) {
|
||||
|
||||
@@ -187,8 +187,8 @@ public:
|
||||
|
||||
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) {
|
||||
@@ -320,7 +320,7 @@ private:
|
||||
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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -81,7 +81,11 @@ public:
|
||||
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 @@ private:
|
||||
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;
|
||||
|
||||
@@ -326,7 +326,11 @@ void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,8 @@ public:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user