initialize static method
- bool enablePerformanceMonitor = true,
- bool warmUpImpellerPipeline = true,
- GlassQualityPersistence? qualityPersistence,
Initializes platform-level resources for the Liquid Glass library.
Responsibility: async platform / engine setup only. Call once in
main() before runApp. All behavioral configuration belongs in wrap.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await LiquidGlassWidgets.initialize();
runApp(LiquidGlassWidgets.wrap(const MyApp()));
}
Parameters
enablePerformanceMonitor (default true)
In debug and profile builds, the library registers a
SchedulerBinding.addTimingsCallback that watches raster durations while
GlassQuality.premium surfaces are mounted. When frames consistently
exceed the GPU budget, a single FlutterError is emitted with actionable
guidance. The monitor is automatically disabled in release builds —
zero overhead in shipped apps. Set to false to suppress it during
profiling sessions where the warning would be a false positive.
Tasks performed
- Pre-warms / precaches the lightweight fragment shader.
- Pre-warms the interactive indicator shader (custom refraction).
- Pre-warms the Impeller rendering pipeline (iOS / Android / macOS).
- Optionally registers the debug performance monitor.
Shaders pre-warmed
| Shader | Role |
|---|---|
lightweight_glass.frag |
Minimal glass layer |
interactive_indicator.frag |
Custom refraction effect |
liquid_glass_geometry_blended.frag |
Geometry / SDF pass |
liquid_glass_final_render.frag |
Final composite pass |
progressive_blur.frag |
Graduated backdrop blur (ProgressiveBlur) |
qualityPersistence
Optional. Pass the same GlassQualityPersistence instance given to
wrap's qualityPersistence parameter to guarantee its persisted
GlassQuality read completes before runApp — eliminating the
GlassAdaptiveScope warm-up benchmark's ~3-second jank window on every
cold start, not just most of them. See GlassQualityPersistence for
details and the best-effort fallback when this isn't provided.
Implementation
static Future<void> initialize({
bool enablePerformanceMonitor = true,
bool warmUpImpellerPipeline = true,
GlassQualityPersistence? qualityPersistence,
}) async {
debugPrint('[LiquidGlass] Initializing library...');
// 1. Pre-warm shader programs in parallel — prevents first-frame jank /
// "white flash" when glass widgets first appear.
//
// Shader asset disk-loads are always performed (fast, I/O only, safe on
// all platforms). The GPU warm-up step is conditionally skipped via
// [warmUpImpellerPipeline].
await Future.wait([
LightweightLiquidGlass.preWarm(),
GlassEffect.preWarm(),
MultiShaderBuilder.precacheShaders([
ShaderKeys.blendedGeometry,
ShaderKeys.liquidGlassRender,
]),
// ProgressiveBlur's graduated-blur shader — warmed here too so consumers
// never need a separate preload call (it degrades to a uniform blur if the
// shader can't load, so this never throws).
ProgressiveBlur.preload(),
// Persisted GlassQuality read (if any) — awaited here so it's
// guaranteed ready by the time wrap() builds GlassAdaptiveScope.
if (qualityPersistence != null) qualityPersistence.ready.then((_) {}),
]);
// 2. GPU pipeline warm-up — Android only, sequential after step 1.
//
// Must run after precacheShaders so the cached FragmentProgram objects
// are available for the toImage() draw call.
//
// On Android GLES, glCompileShader + glLinkProgram is synchronous on the
// raster thread (100–800 ms on mid-range SoCs). Running this before
// runApp ensures compilation completes behind the native splash screen,
// eliminating the nativeSurfaceChanged race condition that causes ANRs
// (see GitHub issue #187).
//
// iOS / macOS use precompiled Metal shaders (zero runtime compilation
// cost) and skip this step entirely.
if (warmUpImpellerPipeline) {
await _warmUpImpellerPipeline();
}
// 3. Register the debug performance monitor (no-op in release builds).
if (enablePerformanceMonitor && !kReleaseMode) {
GlassPerformanceMonitor.start();
}
debugPrint('[LiquidGlass] Initialization complete.');
}