Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bf3d9ed authored by Yiwei Zhang's avatar Yiwei Zhang
Browse files

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
parent 07806b3d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -518,7 +518,7 @@ public final class Zygote {
        ZygoteArguments args = null;

        // Load resources
        ZygoteInit.nativePreloadOpenGL();
        ZygoteInit.nativePreloadGraphicsDriver();

        while (true) {
            try {
+10 −9
Original line number Diff line number Diff line
@@ -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();
        }
    }

+14 −4
Original line number Diff line number Diff line
@@ -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 @@ 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;
    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
+9 −11
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Original line number Diff line number Diff line
@@ -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;