Loading core/java/android/view/ThreadedRenderer.java +2 −3 Original line number Original line Diff line number Diff line Loading @@ -1008,10 +1008,8 @@ public final class ThreadedRenderer { final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L; final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L; mFrameInfo.setVsync(vsync, vsync); mFrameInfo.setVsync(vsync, vsync); mFrameInfo.addFlags(1 << 2 /* VSYNC */); mFrameInfo.addFlags(1 << 2 /* VSYNC */); // TODO: remove this fence nFence(mNativeProxy); if (callback != null) { if (callback != null) { callback.onFrameDraw(mSurface.getNextFrameNumber()); nSetFrameCallback(mNativeProxy, callback); } } nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length); nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length); } } Loading Loading @@ -1184,6 +1182,7 @@ public final class ThreadedRenderer { private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode); private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode); private static native void nSetContentDrawBounds(long nativeProxy, int left, private static native void nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom); 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 long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer); private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); Loading core/java/android/widget/Magnifier.java +20 −15 Original line number Original line Diff line number Diff line Loading @@ -483,12 +483,12 @@ public final class Magnifier { * Destroys this instance. * Destroys this instance. */ */ public void destroy() { public void destroy() { synchronized (mLock) { mRenderer.destroy(); mRenderer.destroy(); mSurface.destroy(); mSurface.destroy(); mSurfaceControl.destroy(); mSurfaceControl.destroy(); mSurfaceSession.kill(); mSurfaceSession.kill(); mBitmapRenderNode.destroy(); mBitmapRenderNode.destroy(); synchronized (mLock) { mHandler.removeCallbacks(mMagnifierUpdater); mHandler.removeCallbacks(mMagnifierUpdater); if (mBitmap != null) { if (mBitmap != null) { mBitmap.recycle(); mBitmap.recycle(); Loading Loading @@ -530,6 +530,10 @@ public final class Magnifier { final int pendingY = mWindowPositionY; final int pendingY = mWindowPositionY; callback = frame -> { callback = frame -> { synchronized (mLock) { if (!mSurface.isValid()) { return; } mRenderer.setLightCenter(mDisplay, pendingX, pendingY); mRenderer.setLightCenter(mDisplay, pendingX, pendingY); // Show or move the window at the content draw frame. // Show or move the window at the content draw frame. SurfaceControl.openTransaction(); SurfaceControl.openTransaction(); Loading @@ -541,6 +545,7 @@ public final class Magnifier { mSurfaceControl.show(); mSurfaceControl.show(); } } SurfaceControl.closeTransaction(); SurfaceControl.closeTransaction(); } }; }; } else { } else { callback = null; callback = null; Loading core/jni/android_view_ThreadedRenderer.cpp +49 −0 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,10 @@ struct { jmethodID callback; jmethodID callback; } gFrameMetricsObserverClassInfo; } gFrameMetricsObserverClassInfo; struct { jmethodID onFrameDraw; } gFrameDrawingCallback; static JNIEnv* getenv(JavaVM* vm) { static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { Loading Loading @@ -849,6 +853,44 @@ static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env, proxy->setContentDrawBounds(left, top, right, bottom); 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, static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, jobject clazz, jobject jsurface, jint left, jint top, jobject clazz, jobject jsurface, jint left, jint top, jint right, jint bottom, jobject jbitmap) { jint right, jint bottom, jobject jbitmap) { Loading Loading @@ -1034,6 +1076,8 @@ static const JNINativeMethod gMethods[] = { { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode}, { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode}, { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode}, { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode}, { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V", (void*)android_view_ThreadedRenderer_setFrameCallback}, { "nAddFrameMetricsObserver", { "nAddFrameMetricsObserver", "(JLandroid/view/FrameMetricsObserver;)J", "(JLandroid/view/FrameMetricsObserver;)J", (void*)android_view_ThreadedRenderer_addFrameMetricsObserver }, (void*)android_view_ThreadedRenderer_addFrameMetricsObserver }, Loading Loading @@ -1078,6 +1122,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) { gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie( gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie( env, metricsClass, "mTimingData", "[J"); 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)); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } } Loading libs/hwui/renderthread/DrawFrameTask.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -94,12 +94,20 @@ void DrawFrameTask::run() { // Grab a copy of everything we need // Grab a copy of everything we need CanvasContext* context = mContext; CanvasContext* context = mContext; std::function<void(int64_t)> callback = std::move(mFrameCallback); // From this point on anything in "this" is *UNSAFE TO ACCESS* // From this point on anything in "this" is *UNSAFE TO ACCESS* if (canUnblockUiThread) { if (canUnblockUiThread) { unblockUiThread(); 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)) { if (CC_LIKELY(canDrawThisFrame)) { context->draw(); context->draw(); } else { } else { Loading libs/hwui/renderthread/DrawFrameTask.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,10 @@ public: void run(); void run(); void setFrameCallback(std::function<void(int64_t)>&& callback) { mFrameCallback = std::move(callback); } private: private: void postAndWait(); void postAndWait(); bool syncFrameState(TreeInfo& info); bool syncFrameState(TreeInfo& info); Loading @@ -96,6 +100,8 @@ private: int64_t mSyncQueued; int64_t mSyncQueued; int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; std::function<void(int64_t)> mFrameCallback; }; }; } /* namespace renderthread */ } /* namespace renderthread */ Loading Loading
core/java/android/view/ThreadedRenderer.java +2 −3 Original line number Original line Diff line number Diff line Loading @@ -1008,10 +1008,8 @@ public final class ThreadedRenderer { final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L; final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L; mFrameInfo.setVsync(vsync, vsync); mFrameInfo.setVsync(vsync, vsync); mFrameInfo.addFlags(1 << 2 /* VSYNC */); mFrameInfo.addFlags(1 << 2 /* VSYNC */); // TODO: remove this fence nFence(mNativeProxy); if (callback != null) { if (callback != null) { callback.onFrameDraw(mSurface.getNextFrameNumber()); nSetFrameCallback(mNativeProxy, callback); } } nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length); nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length); } } Loading Loading @@ -1184,6 +1182,7 @@ public final class ThreadedRenderer { private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode); private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode); private static native void nSetContentDrawBounds(long nativeProxy, int left, private static native void nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom); 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 long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer); private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); Loading
core/java/android/widget/Magnifier.java +20 −15 Original line number Original line Diff line number Diff line Loading @@ -483,12 +483,12 @@ public final class Magnifier { * Destroys this instance. * Destroys this instance. */ */ public void destroy() { public void destroy() { synchronized (mLock) { mRenderer.destroy(); mRenderer.destroy(); mSurface.destroy(); mSurface.destroy(); mSurfaceControl.destroy(); mSurfaceControl.destroy(); mSurfaceSession.kill(); mSurfaceSession.kill(); mBitmapRenderNode.destroy(); mBitmapRenderNode.destroy(); synchronized (mLock) { mHandler.removeCallbacks(mMagnifierUpdater); mHandler.removeCallbacks(mMagnifierUpdater); if (mBitmap != null) { if (mBitmap != null) { mBitmap.recycle(); mBitmap.recycle(); Loading Loading @@ -530,6 +530,10 @@ public final class Magnifier { final int pendingY = mWindowPositionY; final int pendingY = mWindowPositionY; callback = frame -> { callback = frame -> { synchronized (mLock) { if (!mSurface.isValid()) { return; } mRenderer.setLightCenter(mDisplay, pendingX, pendingY); mRenderer.setLightCenter(mDisplay, pendingX, pendingY); // Show or move the window at the content draw frame. // Show or move the window at the content draw frame. SurfaceControl.openTransaction(); SurfaceControl.openTransaction(); Loading @@ -541,6 +545,7 @@ public final class Magnifier { mSurfaceControl.show(); mSurfaceControl.show(); } } SurfaceControl.closeTransaction(); SurfaceControl.closeTransaction(); } }; }; } else { } else { callback = null; callback = null; Loading
core/jni/android_view_ThreadedRenderer.cpp +49 −0 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,10 @@ struct { jmethodID callback; jmethodID callback; } gFrameMetricsObserverClassInfo; } gFrameMetricsObserverClassInfo; struct { jmethodID onFrameDraw; } gFrameDrawingCallback; static JNIEnv* getenv(JavaVM* vm) { static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { Loading Loading @@ -849,6 +853,44 @@ static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env, proxy->setContentDrawBounds(left, top, right, bottom); 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, static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, jobject clazz, jobject jsurface, jint left, jint top, jobject clazz, jobject jsurface, jint left, jint top, jint right, jint bottom, jobject jbitmap) { jint right, jint bottom, jobject jbitmap) { Loading Loading @@ -1034,6 +1076,8 @@ static const JNINativeMethod gMethods[] = { { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode}, { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode}, { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode}, { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode}, { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V", (void*)android_view_ThreadedRenderer_setFrameCallback}, { "nAddFrameMetricsObserver", { "nAddFrameMetricsObserver", "(JLandroid/view/FrameMetricsObserver;)J", "(JLandroid/view/FrameMetricsObserver;)J", (void*)android_view_ThreadedRenderer_addFrameMetricsObserver }, (void*)android_view_ThreadedRenderer_addFrameMetricsObserver }, Loading Loading @@ -1078,6 +1122,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) { gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie( gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie( env, metricsClass, "mTimingData", "[J"); 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)); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } } Loading
libs/hwui/renderthread/DrawFrameTask.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -94,12 +94,20 @@ void DrawFrameTask::run() { // Grab a copy of everything we need // Grab a copy of everything we need CanvasContext* context = mContext; CanvasContext* context = mContext; std::function<void(int64_t)> callback = std::move(mFrameCallback); // From this point on anything in "this" is *UNSAFE TO ACCESS* // From this point on anything in "this" is *UNSAFE TO ACCESS* if (canUnblockUiThread) { if (canUnblockUiThread) { unblockUiThread(); 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)) { if (CC_LIKELY(canDrawThisFrame)) { context->draw(); context->draw(); } else { } else { Loading
libs/hwui/renderthread/DrawFrameTask.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -74,6 +74,10 @@ public: void run(); void run(); void setFrameCallback(std::function<void(int64_t)>&& callback) { mFrameCallback = std::move(callback); } private: private: void postAndWait(); void postAndWait(); bool syncFrameState(TreeInfo& info); bool syncFrameState(TreeInfo& info); Loading @@ -96,6 +100,8 @@ private: int64_t mSyncQueued; int64_t mSyncQueued; int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; std::function<void(int64_t)> mFrameCallback; }; }; } /* namespace renderthread */ } /* namespace renderthread */ Loading