[Magnifier-26] Wire up frame callback for realsies
Test: none yet Bug: 73810478 Bug: 72041926 Change-Id: I7154ed4b3d2cd820dc8c8ff55eed130be87d1606
This commit is contained in:
@@ -1008,10 +1008,8 @@ public final class ThreadedRenderer {
|
||||
final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L;
|
||||
mFrameInfo.setVsync(vsync, vsync);
|
||||
mFrameInfo.addFlags(1 << 2 /* VSYNC */);
|
||||
// TODO: remove this fence
|
||||
nFence(mNativeProxy);
|
||||
if (callback != null) {
|
||||
callback.onFrameDraw(mSurface.getNextFrameNumber());
|
||||
nSetFrameCallback(mNativeProxy, callback);
|
||||
}
|
||||
nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length);
|
||||
}
|
||||
@@ -1184,6 +1182,7 @@ public final class ThreadedRenderer {
|
||||
private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
|
||||
private static native void nSetContentDrawBounds(long nativeProxy, int left,
|
||||
int top, int right, int bottom);
|
||||
private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
|
||||
|
||||
private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
|
||||
private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
|
||||
|
||||
@@ -471,12 +471,12 @@ public final class Magnifier {
|
||||
* Destroys this instance.
|
||||
*/
|
||||
public void destroy() {
|
||||
mRenderer.destroy();
|
||||
mSurface.destroy();
|
||||
mSurfaceControl.destroy();
|
||||
mSurfaceSession.kill();
|
||||
mBitmapRenderNode.destroy();
|
||||
synchronized (mLock) {
|
||||
mRenderer.destroy();
|
||||
mSurface.destroy();
|
||||
mSurfaceControl.destroy();
|
||||
mSurfaceSession.kill();
|
||||
mBitmapRenderNode.destroy();
|
||||
mHandler.removeCallbacks(mMagnifierUpdater);
|
||||
if (mBitmap != null) {
|
||||
mBitmap.recycle();
|
||||
@@ -518,17 +518,22 @@ public final class Magnifier {
|
||||
final int pendingY = mWindowPositionY;
|
||||
|
||||
callback = frame -> {
|
||||
mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
|
||||
// Show or move the window at the content draw frame.
|
||||
SurfaceControl.openTransaction();
|
||||
mSurfaceControl.deferTransactionUntil(mSurface, frame);
|
||||
if (updateWindowPosition) {
|
||||
mSurfaceControl.setPosition(pendingX, pendingY);
|
||||
synchronized (mLock) {
|
||||
if (!mSurface.isValid()) {
|
||||
return;
|
||||
}
|
||||
mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
|
||||
// Show or move the window at the content draw frame.
|
||||
SurfaceControl.openTransaction();
|
||||
mSurfaceControl.deferTransactionUntil(mSurface, frame);
|
||||
if (updateWindowPosition) {
|
||||
mSurfaceControl.setPosition(pendingX, pendingY);
|
||||
}
|
||||
if (firstDraw) {
|
||||
mSurfaceControl.show();
|
||||
}
|
||||
SurfaceControl.closeTransaction();
|
||||
}
|
||||
if (firstDraw) {
|
||||
mSurfaceControl.show();
|
||||
}
|
||||
SurfaceControl.closeTransaction();
|
||||
};
|
||||
} else {
|
||||
callback = null;
|
||||
|
||||
@@ -68,6 +68,10 @@ struct {
|
||||
jmethodID callback;
|
||||
} gFrameMetricsObserverClassInfo;
|
||||
|
||||
struct {
|
||||
jmethodID onFrameDraw;
|
||||
} gFrameDrawingCallback;
|
||||
|
||||
static JNIEnv* getenv(JavaVM* vm) {
|
||||
JNIEnv* env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
@@ -849,6 +853,44 @@ static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env,
|
||||
proxy->setContentDrawBounds(left, top, right, bottom);
|
||||
}
|
||||
|
||||
class JGlobalRefHolder {
|
||||
public:
|
||||
JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
|
||||
|
||||
virtual ~JGlobalRefHolder() {
|
||||
getenv(mVm)->DeleteGlobalRef(mObject);
|
||||
mObject = nullptr;
|
||||
}
|
||||
|
||||
jobject object() { return mObject; }
|
||||
JavaVM* vm() { return mVm; }
|
||||
|
||||
private:
|
||||
JGlobalRefHolder(const JGlobalRefHolder&) = delete;
|
||||
void operator=(const JGlobalRefHolder&) = delete;
|
||||
|
||||
JavaVM* mVm;
|
||||
jobject mObject;
|
||||
};
|
||||
|
||||
static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
|
||||
jobject clazz, jlong proxyPtr, jobject frameCallback) {
|
||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||
if (!frameCallback) {
|
||||
proxy->setFrameCallback(nullptr);
|
||||
} else {
|
||||
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(frameCallback));
|
||||
proxy->setFrameCallback([globalCallbackRef](int64_t frameNr) {
|
||||
JNIEnv* env = getenv(globalCallbackRef->vm());
|
||||
env->CallVoidMethod(globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw,
|
||||
static_cast<jlong>(frameNr));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
|
||||
jobject clazz, jobject jsurface, jint left, jint top,
|
||||
jint right, jint bottom, jobject jbitmap) {
|
||||
@@ -1034,6 +1076,8 @@ static const JNINativeMethod gMethods[] = {
|
||||
{ "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
|
||||
{ "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
|
||||
{ "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
|
||||
{ "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V",
|
||||
(void*)android_view_ThreadedRenderer_setFrameCallback},
|
||||
{ "nAddFrameMetricsObserver",
|
||||
"(JLandroid/view/FrameMetricsObserver;)J",
|
||||
(void*)android_view_ThreadedRenderer_addFrameMetricsObserver },
|
||||
@@ -1078,6 +1122,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) {
|
||||
gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
|
||||
env, metricsClass, "mTimingData", "[J");
|
||||
|
||||
jclass frameCallbackClass = FindClassOrDie(env,
|
||||
"android/view/ThreadedRenderer$FrameDrawingCallback");
|
||||
gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
|
||||
"onFrameDraw", "(J)V");
|
||||
|
||||
return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
|
||||
@@ -94,12 +94,20 @@ void DrawFrameTask::run() {
|
||||
|
||||
// Grab a copy of everything we need
|
||||
CanvasContext* context = mContext;
|
||||
std::function<void(int64_t)> callback = std::move(mFrameCallback);
|
||||
|
||||
// From this point on anything in "this" is *UNSAFE TO ACCESS*
|
||||
if (canUnblockUiThread) {
|
||||
unblockUiThread();
|
||||
}
|
||||
|
||||
// Even if we aren't drawing this vsync pulse the next frame number will still be accurate
|
||||
if (CC_UNLIKELY(callback)) {
|
||||
context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
|
||||
callback(frameNr);
|
||||
});
|
||||
}
|
||||
|
||||
if (CC_LIKELY(canDrawThisFrame)) {
|
||||
context->draw();
|
||||
} else {
|
||||
|
||||
@@ -74,6 +74,10 @@ public:
|
||||
|
||||
void run();
|
||||
|
||||
void setFrameCallback(std::function<void(int64_t)>&& callback) {
|
||||
mFrameCallback = std::move(callback);
|
||||
}
|
||||
|
||||
private:
|
||||
void postAndWait();
|
||||
bool syncFrameState(TreeInfo& info);
|
||||
@@ -96,6 +100,8 @@ private:
|
||||
int64_t mSyncQueued;
|
||||
|
||||
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
|
||||
|
||||
std::function<void(int64_t)> mFrameCallback;
|
||||
};
|
||||
|
||||
} /* namespace renderthread */
|
||||
|
||||
@@ -270,6 +270,10 @@ void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom)
|
||||
mDrawFrameTask.setContentDrawBounds(left, top, right, bottom);
|
||||
}
|
||||
|
||||
void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
|
||||
mDrawFrameTask.setFrameCallback(std::move(callback));
|
||||
}
|
||||
|
||||
void RenderProxy::serializeDisplayListTree() {
|
||||
mRenderThread.queue().post([=]() { mContext->serializeDisplayListTree(); });
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
ANDROID_API void removeRenderNode(RenderNode* node);
|
||||
ANDROID_API void drawRenderNode(RenderNode* node);
|
||||
ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom);
|
||||
ANDROID_API void setFrameCallback(std::function<void(int64_t)>&& callback);
|
||||
|
||||
ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer);
|
||||
ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
|
||||
|
||||
Reference in New Issue
Block a user