From 4bf3d9eda41325b3e859377ce5ca6005e4a7d885 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Mon, 15 Apr 2019 16:24:32 -0700 Subject: [PATCH] Zygote: add a way to preload Vulkan driver Since HWUI render pipeline has both GL and Vulkan backends now, we'd like to preload either GL or Vulkan driver based upon HWUI's choice on the render backend. 1) Keep using ro.zygote.disable_gl_preload property to disable Vulkan driver preloading if HWUI's render pipeline uses Vulkan backend. Properly rename the corresponding APIs for driver preloading. 2) Add a path to preload Vulkan driver based on HWUI's render backend. Bug: 131249898 Test: build, flash and boot. Test: verified with set USE_VULKAN=true Test: verified with setprop debug.hwui.renderer skiagl/skiavk Change-Id: Ie0bf5d18edcf907c75a25ac3249e2620ec21b63c --- core/java/com/android/internal/os/Zygote.java | 2 +- .../com/android/internal/os/ZygoteInit.java | 19 +++++++++--------- .../com_android_internal_os_ZygoteInit.cpp | 18 +++++++++++++---- libs/hwui/Properties.cpp | 20 +++++++++---------- libs/hwui/Properties.h | 1 + 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 46d9aac24d4f5..99175b8becfe8 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -518,7 +518,7 @@ public final class Zygote { ZygoteArguments args = null; // Load resources - ZygoteInit.nativePreloadOpenGL(); + ZygoteInit.nativePreloadGraphicsDriver(); while (true) { try { diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index e19eb998849b5..f9e868fafe505 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -85,7 +85,8 @@ public class ZygoteInit { // TODO (chriswailes): Change this so it is set with Zygote or ZygoteSecondary as appropriate private static final String TAG = "Zygote"; - private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload"; + private static final String PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING = + "ro.zygote.disable_gl_preload"; private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020; @@ -149,8 +150,8 @@ public class ZygoteInit { Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); nativePreloadAppProcessHALs(); Trace.traceEnd(Trace.TRACE_TAG_DALVIK); - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL"); - maybePreloadOpenGL(); + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver"); + maybePreloadGraphicsDriver(); Trace.traceEnd(Trace.TRACE_TAG_DALVIK); preloadSharedLibraries(); preloadTextResources(); @@ -193,19 +194,19 @@ public class ZygoteInit { native private static void nativePreloadAppProcessHALs(); /** - * This call loads the graphics driver by attempting to make an OpenGL call. If the driver is + * This call loads the graphics driver by making an OpenGL or Vulkan call. If the driver is * not currently in memory it will load and initialize it. The OpenGL call itself is relatively * cheap and pure. This means that it is a low overhead on the initial call, and is safe and * cheap to call later. Calls after the initial invocation will effectively be no-ops for the * system. */ - static native void nativePreloadOpenGL(); + static native void nativePreloadGraphicsDriver(); - private static void maybePreloadOpenGL() { + private static void maybePreloadGraphicsDriver() { String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); - if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) && - (driverPackageName == null || driverPackageName.isEmpty())) { - nativePreloadOpenGL(); + if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false) + && (driverPackageName == null || driverPackageName.isEmpty())) { + nativePreloadGraphicsDriver(); } } diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp index ac0e60030fc50..5cca0fdc735bc 100644 --- a/core/jni/com_android_internal_os_ZygoteInit.cpp +++ b/core/jni/com_android_internal_os_ZygoteInit.cpp @@ -17,12 +17,17 @@ #define LOG_TAG "Zygote" #include +#include #include +#include #include "core_jni_helpers.h" namespace { +using android::uirenderer::Properties; +using android::uirenderer::RenderPipelineType; + // Shadow call stack (SCS) is a security mitigation that uses a separate stack // (the SCS) for return addresses. In versions of Android newer than P, the // compiler cooperates with the system to ensure that the SCS address is always @@ -58,16 +63,21 @@ void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jcl // (b) loaded by most app processes. } -void android_internal_os_ZygoteInit_nativePreloadOpenGL(JNIEnv* env, jclass) { +void android_internal_os_ZygoteInit_nativePreloadGraphicsDriver(JNIEnv* env, jclass) { ScopedSCSExit x; - eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) { + eglGetDisplay(EGL_DEFAULT_DISPLAY); + } else { + uint32_t count = 0; + vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr); + } } const JNINativeMethod gMethods[] = { { "nativePreloadAppProcessHALs", "()V", (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs }, - { "nativePreloadOpenGL", "()V", - (void*)android_internal_os_ZygoteInit_nativePreloadOpenGL }, + { "nativePreloadGraphicsDriver", "()V", + (void*)android_internal_os_ZygoteInit_nativePreloadGraphicsDriver }, }; } // anonymous namespace diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 19f509ce8fd78..4b75353db22c1 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -175,24 +175,22 @@ ProfileType Properties::getProfileType() { return sProfileType; } -RenderPipelineType Properties::getRenderPipelineType() { +RenderPipelineType Properties::peekRenderPipelineType() { + // If sRenderPipelineType has been locked, just return the locked type immediately. if (sRenderPipelineType != RenderPipelineType::NotInitialized) { return sRenderPipelineType; } bool useVulkan = use_vulkan().value_or(false); char prop[PROPERTY_VALUE_MAX]; - if (useVulkan) { - property_get(PROPERTY_RENDERER, prop, "skiavk"); - } else { - property_get(PROPERTY_RENDERER, prop, "skiagl"); - } + property_get(PROPERTY_RENDERER, prop, useVulkan ? "skiavk" : "skiagl"); if (!strcmp(prop, "skiavk")) { - ALOGD("Skia Vulkan Pipeline"); - sRenderPipelineType = RenderPipelineType::SkiaVulkan; - } else { //"skiagl" - ALOGD("Skia GL Pipeline"); - sRenderPipelineType = RenderPipelineType::SkiaGL; + return RenderPipelineType::SkiaVulkan; } + return RenderPipelineType::SkiaGL; +} + +RenderPipelineType Properties::getRenderPipelineType() { + sRenderPipelineType = peekRenderPipelineType(); return sRenderPipelineType; } diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 3e91c63fcbde8..ee5d39989d496 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -218,6 +218,7 @@ public: static int overrideSpotShadowStrength; static ProfileType getProfileType(); + ANDROID_API static RenderPipelineType peekRenderPipelineType(); ANDROID_API static RenderPipelineType getRenderPipelineType(); ANDROID_API static bool enableHighContrastText;