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

Commit 898123b6 authored by Stan Iliev's avatar Stan Iliev
Browse files

Start RenderThread earlier to preload Vulkan/EGL drivers

This CL should fix application startup regression for Vulkan
detected by "Hermetic Startup: EmptyActivity" test.
EGL drivers are loaded in a temp thread to leave more time
in RenderThread for other work. Loading EGL drivers
on the RenderThread may cause a perf regression.

Test: Ran cold-dropcache-test test.
Bug: 122659224
Bug: 123361175
Change-Id: I8ca818e98fac196a41d079be15594caca5cb1bab
parent c7e26f7f
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -3229,8 +3229,9 @@ public final class ActivityThread extends ClientTransactionHandler {
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        if (!ThreadedRenderer.sRendererDisabled) {
            GraphicsEnvironment.earlyInitEGL();
        if (!ThreadedRenderer.sRendererDisabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        WindowManagerGlobal.initialize();

+0 −20
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.opengl.EGL14;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
@@ -677,25 +676,6 @@ public class GraphicsEnvironment {
        return true;
    }

    /**
     * Start a background thread to initialize EGL.
     *
     * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
     * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
     * its first frame adds directly to user-visible app launch latency. By starting it earlier
     * on a separate thread, it can usually be finished well before the UI is ready to be drawn.
     *
     * Should only be called after chooseDriver().
     */
    public static void earlyInitEGL() {
        final Thread eglInitThread = new Thread(
                () -> {
                    EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
                },
                "EGL Init");
        eglInitThread.start();
    }

    private static String chooseAbi(ApplicationInfo ai) {
        final String isa = VMRuntime.getCurrentInstructionSet();
        if (ai.primaryCpuAbi != null &&
+5 −0
Original line number Diff line number Diff line
@@ -1029,6 +1029,10 @@ static void android_view_ThreadedRenderer_setForceDark(JNIEnv* env, jobject claz
    proxy->setForceDark(enable);
}

static void android_view_ThreadedRenderer_preload(JNIEnv*, jclass) {
    RenderProxy::preload();
}

// ----------------------------------------------------------------------------
// FrameMetricsObserver
// ----------------------------------------------------------------------------
@@ -1144,6 +1148,7 @@ static const JNINativeMethod gMethods[] = {
    { "nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority },
    { "nAllocateBuffers", "(J)V", (void*)android_view_ThreadedRenderer_allocateBuffers },
    { "nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark },
    { "preload", "()V", (void*)android_view_ThreadedRenderer_preload },
};

static JavaVM* mJvm = nullptr;
+12 −0
Original line number Diff line number Diff line
@@ -1027,6 +1027,18 @@ public class HardwareRenderer {
     */
    public static native void disableVsync();

    /**
     * Start render thread and initialize EGL or Vulkan.
     *
     * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
     * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
     * its first frame adds directly to user-visible app launch latency.
     *
     * Should only be called after GraphicsEnvironment.chooseDriver().
     * @hide
     */
    public static native void preload();

    /** @hide */
    protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);

+8 −0
Original line number Diff line number Diff line
@@ -381,6 +381,14 @@ void RenderProxy::releaseVDAtlasEntries() {
    });
}

void RenderProxy::preload() {
    // Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
    auto& thread = RenderThread::getInstance();
    thread.queue().post([&thread]() {
        thread.preload();
    });
}

} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
Loading