frust_shell_common/lib.rs
1//! Platform-agnostic shell plumbing shared by every Frust platform shell.
2//!
3//! The Android (`frust-shell-android`) and iOS shells both need the same
4//! non-FFI machinery: the [`AppTree`] type-erasure that lets a non-generic
5//! native handle drive any app's `State`/`app_logic`, a handful of pure
6//! helpers for crossing an FFI boundary safely ([`guard`]) and turning an
7//! untrusted density into HiDPI layout math ([`sanitize_scale`]/[`logical_size`]/
8//! [`logical_insets`]/[`logical_corner_insets`], the last two converting platform
9//! per-edge insets and window-control corners into a logical
10//! [`WindowInsets`](frust_core::insets::WindowInsets) /
11//! [`CornerInsets`](frust_core::insets::CornerInsets)),
12//! the shared window-shape publish path ([`window_metrics`] assembling a
13//! logical [`WindowMetrics`](frust_core::WindowMetrics) and
14//! [`WindowMetricsPublisher`] deciding — on all three shells — whether it
15//! actually changed and so may be re-provided to app code),
16//! the app-facing theme override slot ([`set_app_theme`]/[`clear_app_theme`]/
17//! [`ThemeOverrideWatcher`] — see [`theme_override`]'s module docs for the
18//! layering rationale), the [`perf`] module's frame-timing/startup-span
19//! instrumentation, the [`frame_gate`] module's shared skip-frame decision
20//! ([`FrameGate`]/[`FrameInputs`]/[`FrameDecision`]) the mobile shells consult
21//! to idle on unchanged frames, the [`resample`]
22//! module's pointer-event resampling ([`PointerResampler`]) plus deadline-aware
23//! pacing helpers the mobile shells drive from their touch + frame paths, and
24//! the [`render_split`] module's UI→render-thread plumbing
25//! ([`render_channel`]'s latest-wins scene handoff + [`RenderCommand`]/[`Ack`]
26//! lifecycle vocabulary, gated by [`render_thread_enabled`], plus
27//! [`scene_return_channel`]'s reverse give-back slot restoring buffer reuse
28//! across the split) the shells split the frame pipeline across. The
29//! [`platform_view`] module is the differ turning `frust-core`'s
30//! per-paint-pass platform-view frames into an idempotent
31//! [`ViewCommand`]/[`PlatformViewState`] backlog both mobile shells' FFI peek
32//! getters serve, and [`surface_mode`] is the
33//! process-global translucent-surface pair: the host **declaration** latch
34//! ([`declare_host_translucent_surface`]/[`SurfaceModeWatcher`]) — settable
35//! only by each shell's own JNI/C-ABI host-glue callback, never re-exported
36//! past this crate — each shell's
37//! surface-creation path reads pre-configure, plus the **resolved** slot
38//! ([`publish_resolved_surface_mode`]/[`resolved_surface_mode`]) each mobile
39//! shell publishes the live surface's actual verdict
40//! into, so app code can observe a `RefusedTranslucent` platform refusal
41//! instead of an invisible native sibling. Behind the non-default `gpu`
42//! cargo feature, [`gpu`] carries the process-wide GPU-device slot
43//! ([`gpu::install_gpu_handle`]/[`gpu::gpu_handle`]) a shell's render
44//! executor installs its device into once, type-erased so this crate still
45//! names no GPU type — see the module's own docs.
46//!
47//! This crate is deliberately platform-free: it depends on `frust-core`
48//! (retained tree / `RenderRoot`) plus `frust-scene`/`frust-text`/
49//! `frust-theme` for the types a shell composes around it, but never on
50//! `jni`/`ndk`/`winit`. It contains no `unsafe` and no FFI, so it compiles
51//! unchanged on the host and on `aarch64-linux-android`/iOS with no cfg
52//! gymnastics. Each platform shell keeps its own FFI boundary (JNI exports,
53//! raw-window handling) and reuses this crate rather than duplicating the
54//! plumbing.
55
56mod app_tree;
57/// The in-app devtools service's shell side — the [`DevtoolsUi`](devtools::DevtoolsUi)
58/// hop seam, the process-wide [`start`](devtools::start)/[`pump`](devtools::pump)
59/// pair, and the `DevtoolsBackend` implementation behind them. Compiled only
60/// under the `devtools` cargo feature; absent entirely otherwise (see the
61/// module's own docs).
62#[cfg(feature = "devtools")]
63pub mod devtools;
64mod ffi_support;
65pub mod font_registry;
66pub mod frame_gate;
67/// The process-wide GPU-device slot — [`gpu::install_gpu_handle`]/
68/// [`gpu::gpu_handle`] — a shell's render executor installs its device into
69/// once, and the facade's `frust::gpu::with_context` (see
70/// `crates/frust/src/lib.rs`) reads it back. Compiled only under the `gpu`
71/// cargo feature; absent entirely otherwise, and type-erased even then so
72/// this crate names no GPU type (see the module's own docs).
73#[cfg(feature = "gpu")]
74pub mod gpu;
75pub mod perf;
76pub mod platform_view;
77pub mod render_split;
78pub mod resample;
79mod surface_mode;
80mod system_ui;
81mod theme_default;
82mod theme_override;
83
84pub use app_tree::{AppTree, new_boxed_app, new_boxed_app_with};
85pub use ffi_support::{
86 WindowMetricsPublisher, guard, logical_corner_insets, logical_insets, logical_size,
87 run_guarded_thread, sanitize_scale, window_metrics,
88};
89pub use frame_gate::{
90 FrameDecision, FrameGate, FrameInputs, FramePacing, anim_pacing_kill_switch_engaged,
91};
92pub use platform_view::{PlatformViewState, ViewCommand};
93pub use render_split::{
94 Ack, AckWaiter, FrameMeta, NO_RENDER_THREAD_VAR, RenderBatch, RenderCommand, RenderEvent,
95 RenderPhase, RenderReceiver, RenderSender, SceneFrame, SceneReturnReceiver, SceneReturnSender,
96 SurfaceSize, ack_pair, next_render_phase, render_channel, render_thread_enabled,
97 scene_return_channel,
98};
99pub use resample::{PointerResampler, RawPointerSample};
100pub use surface_mode::{
101 ResolvedSurfaceMode, SurfaceMode, SurfaceModeWatcher, declare_host_translucent_surface,
102 publish_resolved_surface_mode, resolved_surface_mode,
103};
104pub use system_ui::{
105 SystemUiMode, SystemUiOverlay, SystemUiWatcher, current_system_ui_mode, encoded_state,
106 set_system_ui_mode,
107};
108pub use theme_default::{default_theme, set_default_theme};
109pub use theme_override::{
110 ThemeOverrideWatcher, clear_app_theme, effective_brightness_for_platform_change, set_app_theme,
111 theme_override_active,
112};