From d9583094beef84c5d4436ef618ed27bdc151f38a Mon Sep 17 00:00:00 2001 From: “Shadman Date: Tue, 14 Jan 2025 18:24:10 +0000 Subject: preload Buffer Allocator instance on the ViewRootImpl init - Improves time to first draw by ~5-10ms on low core devices. Earlier initialization results in less time during choreographer's first frame draw waiting for buffer allocator to be initialized. Test: Build and wear hermetic app launch test Bug: 389908734 Flag: com.android.graphics.hwui.flags.early_preinit_buffer_allocator Change-Id: I41883e735557f186f4ed5004b092f018b7b67574 --- core/java/android/view/ViewRootImpl.java | 16 ++++++++++++++++ graphics/java/android/graphics/HardwareRenderer.java | 12 ++++++++++++ libs/hwui/aconfig/hwui_flags.aconfig | 10 +++++++++- libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 16 ++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 80b4f2caabbb..de3e45b8ebde 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -537,6 +537,11 @@ public final class ViewRootImpl implements ViewParent, */ private static boolean sAlwaysAssignFocus; + /** + * whether we pre-initialized the Buffer Allocator + */ + private static boolean sPreInitializedBufferAllocator = false; + /** * This list must only be modified by the main thread. */ @@ -1342,6 +1347,11 @@ public final class ViewRootImpl implements ViewParent, com.android.server.display.feature.flags.Flags.subscribeGranularDisplayEvents(); mSendPerfHintOnTouch = adpfViewrootimplActionDownBoost(); + + if (!sPreInitializedBufferAllocator) { + preInitBufferAllocator(); + sPreInitializedBufferAllocator = true; + } } public static void addFirstDrawHandler(Runnable callback) { @@ -13562,4 +13572,10 @@ public final class ViewRootImpl implements ViewParent, sProtoLogInitialized = true; } } + + private void preInitBufferAllocator() { + if (com.android.graphics.hwui.flags.Flags.earlyPreinitBufferAllocator()) { + ThreadedRenderer.preInitBufferAllocator(); + } + } } diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index 940cd93c53f2..65854dd51a91 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -1466,6 +1466,18 @@ public class HardwareRenderer { */ public static native void preload(); + /** + * Initialize the Buffer Allocator singleton + * + * This takes 10-20ms on low-resourced devices, so doing it on-demand when an app + * tries to render its first frame causes drawFrames to be blocked for buffer + * allocation due to just initializing the allocator. + * + * Should only be called when a buffer is expected to be used. + * @hide + */ + public static native void preInitBufferAllocator(); + /** * @hide */ diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index 62fd7d358123..7e1f2e2a3490 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -174,7 +174,7 @@ flag { flag { name: "early_preload_gl_context" namespace: "core_graphics" - description: "Initialize GL context and GraphicBufferAllocater init on renderThread preload. This improves app startup time for apps using GL." + description: "Preload GL context on renderThread preload. This improves app startup time for apps using GL." bug: "383612849" } @@ -187,4 +187,12 @@ flag { metadata { purpose: PURPOSE_BUGFIX } +} + +flag { + name: "early_preinit_buffer_allocator" + namespace: "core_graphics" + description: "Initialize GraphicBufferAllocater on ViewRootImpl init, to avoid blocking on init during buffer allocation, improving app launch latency." + bug: "389908734" + is_fixed_read_only: true } \ No newline at end of file diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index df9f83036709..99e7740d66d2 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -52,6 +52,9 @@ #include #include #include +#ifdef __ANDROID__ +#include +#endif #include #include #include @@ -849,6 +852,17 @@ static void android_view_ThreadedRenderer_preload(JNIEnv*, jclass) { RenderProxy::preload(); } +static void android_view_ThreadedRenderer_preInitBufferAllocator(JNIEnv*, jclass) { +#ifdef __ANDROID__ + CommonPool::async([] { + ATRACE_NAME("preInitBufferAllocator:GraphicBufferAllocator"); + // This involves several binder calls which we do not want blocking + // critical path of the activity that is launching. + GraphicBufferAllocator::getInstance(); + }); +#endif +} + static void android_view_ThreadedRenderer_setRtAnimationsEnabled(JNIEnv* env, jobject clazz, jboolean enabled) { RenderProxy::setRtAnimationsEnabled(enabled); @@ -1040,6 +1054,8 @@ static const JNINativeMethod gMethods[] = { (void*)android_view_ThreadedRenderer_setDisplayDensityDpi}, {"nInitDisplayInfo", "(IIFIJJZZZ)V", (void*)android_view_ThreadedRenderer_initDisplayInfo}, {"preload", "()V", (void*)android_view_ThreadedRenderer_preload}, + {"preInitBufferAllocator", "()V", + (void*)android_view_ThreadedRenderer_preInitBufferAllocator}, {"isWebViewOverlaysEnabled", "()Z", (void*)android_view_ThreadedRenderer_isWebViewOverlaysEnabled}, {"nSetDrawingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDrawingEnabled}, -- cgit v1.2.3-59-g8ed1b