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
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 46d9aac..99175b8 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -518,7 +518,7 @@
         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 e19eb99..f9e868f 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -85,7 +85,8 @@
     // 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 @@
         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 @@
     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 ac0e600..5cca0fd 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 <EGL/egl.h>
+#include <Properties.h>
 #include <ui/GraphicBufferMapper.h>
+#include <vulkan/vulkan.h>
 
 #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 @@
     // (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 19f509c..4b75353 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -175,24 +175,22 @@
     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 3e91c63..ee5d399 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -218,6 +218,7 @@
     static int overrideSpotShadowStrength;
 
     static ProfileType getProfileType();
+    ANDROID_API static RenderPipelineType peekRenderPipelineType();
     ANDROID_API static RenderPipelineType getRenderPipelineType();
 
     ANDROID_API static bool enableHighContrastText;