[Magnifier-26] Wire up frame callback for realsies

Test: none yet
Bug: 73810478
Bug: 72041926
Change-Id: I7154ed4b3d2cd820dc8c8ff55eed130be87d1606
This commit is contained in:
Mihai Popa
2018-02-23 16:10:11 +00:00
committed by John Reck
parent 99ef04f717
commit 9568800d90
7 changed files with 90 additions and 18 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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));
}

View File

@@ -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 {

View File

@@ -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 */

View File

@@ -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(); });
}

View File

@@ -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);