From 259b25a310bf3beb5d41233717aaf3dc02a46c36 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 1 Dec 2017 16:18:53 -0800 Subject: [PATCH] Switch RenderThread to a Java daemon thread Bug: 69962494 Test: device boots, hwui unit tests pass Change-Id: I9d5f2fccebf845328914c82aa97285cf605a4354 --- core/jni/android_view_ThreadedRenderer.cpp | 15 +++++++++++++++ libs/hwui/renderthread/RenderThread.cpp | 10 ++++++++++ libs/hwui/renderthread/RenderThread.h | 3 +++ libs/hwui/thread/ThreadBase.h | 5 ++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 870a0c2073d8f..519a8858aa039 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -1043,7 +1043,22 @@ static const JNINativeMethod gMethods[] = { { "nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText }, }; +static JavaVM* mJvm = nullptr; + +static void attachRenderThreadToJvm() { + LOG_ALWAYS_FATAL_IF(!mJvm, "No jvm but we set the hook??"); + + JavaVMAttachArgs args; + args.version = JNI_VERSION_1_4; + args.name = (char*) "RenderThread"; + args.group = NULL; + JNIEnv* env; + mJvm->AttachCurrentThreadAsDaemon(&env, (void*) &args); +} + int register_android_view_ThreadedRenderer(JNIEnv* env) { + env->GetJavaVM(&mJvm); + RenderThread::setOnStartHook(&attachRenderThreadToJvm); jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver"); gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie( env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;"); diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 05a9b75b45042..20443ec38c907 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -51,10 +51,17 @@ static const nsecs_t DISPATCH_FRAME_CALLBACKS_DELAY = milliseconds_to_nanosecond static bool gHasRenderThreadInstance = false; +static void (*gOnStartHook)() = nullptr; + bool RenderThread::hasInstance() { return gHasRenderThreadInstance; } +void RenderThread::setOnStartHook(void (*onStartHook)()) { + LOG_ALWAYS_FATAL_IF(hasInstance(), "can't set an onStartHook after we've started..."); + gOnStartHook = onStartHook; +} + RenderThread& RenderThread::getInstance() { // This is a pointer because otherwise __cxa_finalize // will try to delete it like a Good Citizen but that causes us to crash @@ -256,6 +263,9 @@ void RenderThread::requestVsync() { bool RenderThread::threadLoop() { setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY); + if (gOnStartHook) { + gOnStartHook(); + } initThreadLocals(); while (true) { diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index d17a509f63574..970537b69fad1 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -67,6 +67,9 @@ class RenderThread : private ThreadBase { PREVENT_COPY_AND_ASSIGN(RenderThread); public: + // Sets a callback that fires before any RenderThread setup has occured. + ANDROID_API static void setOnStartHook(void (*onStartHook)()); + WorkQueue& queue() { return ThreadBase::queue(); } // Mimics android.view.Choreographer diff --git a/libs/hwui/thread/ThreadBase.h b/libs/hwui/thread/ThreadBase.h index b3fec1fb36c35..8068121f64cf9 100644 --- a/libs/hwui/thread/ThreadBase.h +++ b/libs/hwui/thread/ThreadBase.h @@ -31,7 +31,10 @@ class ThreadBase : protected Thread { PREVENT_COPY_AND_ASSIGN(ThreadBase); public: - ThreadBase() : mLooper(new Looper(false)), mQueue([this]() { mLooper->wake(); }, mLock) {} + ThreadBase() + : Thread(false) + , mLooper(new Looper(false)) + , mQueue([this]() { mLooper->wake(); }, mLock) {} WorkQueue& queue() { return mQueue; }