initialize VirtualMachineEnv on the right thread (#9624)

PerformanceHint manager needs a java thread during initialization,
so we need to attach a jvm to the thread that's going to be used.
That thread is the filament backend thread, not necessarily the thread 
the platform is created on.

So we make sure to do that from the backend thread.


FIXES=[427945768]
This commit is contained in:
Mathias Agopian
2026-01-22 10:24:39 -08:00
committed by GitHub
parent 9ab2326f15
commit cff958587d
4 changed files with 22 additions and 20 deletions

View File

@@ -180,10 +180,6 @@ private:
int32_t setProducerThrottlingEnabled(EGLNativeWindowType nativeWindow, bool enabled) const;
struct InitializeJvmForPerformanceManagerIfNeeded {
InitializeJvmForPerformanceManagerIfNeeded();
};
struct ExternalTextureAndroid : public ExternalTexture {
EGLImageKHR eglImage = EGL_NO_IMAGE;
};
@@ -191,7 +187,6 @@ private:
int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager;
AndroidDetails& mAndroidDetails;
InitializeJvmForPerformanceManagerIfNeeded const mInitializeJvmForPerformanceManagerIfNeeded;
utils::PerformanceHintManager mPerformanceHintManager;
utils::PerformanceHintManager::Session mPerformanceHintSession;
using clock = std::chrono::high_resolution_clock;

View File

@@ -119,18 +119,6 @@ struct PlatformEGLAndroid::AndroidDetails {
// ---------------------------------------------------------------------------------------------
PlatformEGLAndroid::InitializeJvmForPerformanceManagerIfNeeded::InitializeJvmForPerformanceManagerIfNeeded() {
// PerformanceHintManager() needs the calling thread to be a Java thread; so we need
// to attach this thread to the JVM before we initialize PerformanceHintManager.
// This should be done in PerformanceHintManager(), but libutils doesn't have access to
// VirtualMachineEnv.
if (PerformanceHintManager::isSupported()) {
(void)VirtualMachineEnv::get().getEnvironment();
}
}
// ---------------------------------------------------------------------------------------------
PlatformEGLAndroid::PlatformEGLAndroid() noexcept
: mExternalStreamManager(ExternalStreamManagerAndroid::create()),
mAndroidDetails(*(new(std::nothrow) AndroidDetails{})) {
@@ -145,6 +133,7 @@ PlatformEGLAndroid::~PlatformEGLAndroid() noexcept {
}
void PlatformEGLAndroid::terminate() noexcept {
mPerformanceHintManager.terminate();
mAndroidDetails.androidFrameCallback.terminate();
ExternalStreamManagerAndroid::destroy(&mExternalStreamManager);
PlatformEGL::terminate();
@@ -223,6 +212,14 @@ void PlatformEGLAndroid::preCommit() noexcept {
Driver* PlatformEGLAndroid::createDriver(void* sharedContext,
const DriverConfig& driverConfig) {
// PerformanceHintManager() needs the calling thread to be a Java thread; so we need
// to attach this thread to the JVM before we initialize PerformanceHintManager.
if (PerformanceHintManager::isSupported()) {
(void)VirtualMachineEnv::get().getEnvironment();
}
mPerformanceHintManager.init();
// the refresh rate default value doesn't matter, we change it later
int32_t const tid = gettid();
mPerformanceHintSession = PerformanceHintManager::Session{

View File

@@ -55,10 +55,15 @@ public:
int reportActualWorkDuration(int64_t actualDurationNanos) noexcept;
};
// caveat: This must be called on a Java thread
PerformanceHintManager() noexcept;
~PerformanceHintManager() noexcept;
// caveat: This must be called on a Java thread
void init();
// caveat: This must be called on the same thread as init
void terminate();
// Whether PerformanceHintManager APIs are supported (which doesn't mean PerformanceHintManager
// itself is, use isValid()).
static bool isSupported() noexcept;

View File

@@ -39,13 +39,18 @@ struct PerformanceHintManager::SessionDetails {
APerformanceHintSession* mSession = nullptr;
};
PerformanceHintManager::PerformanceHintManager() noexcept {
PerformanceHintManager::PerformanceHintManager() noexcept = default;
PerformanceHintManager::~PerformanceHintManager() noexcept = default;
void PerformanceHintManager::init() {
if (__builtin_available(android __ANDROID_API_T__, *)) {
mImpl->mManager = APerformanceHint_getManager();
}
}
PerformanceHintManager::~PerformanceHintManager() noexcept = default;
void PerformanceHintManager::terminate() {
}
bool PerformanceHintManager::isSupported() noexcept {
if (__builtin_available(android __ANDROID_API_T__, *)) {