iris: fold render state into Ui

This commit is contained in:
iris committed 2026-09-10 23:58:43 -04:00
1 parent 44a5da378b
commit 9b4c690916
25 files changed
+421 -390

No files matched your search

+46 -27
View File
@@ -123,7 +123,7 @@ pub trait HasAndroidUiState: Sized + 'static {
pub trait AndroidAppState: HasAndroidUiState {
fn new(ui_state: AndroidUiState, rsc: &mut AndroidRsc<Self>) -> Self;
#[allow(unused_variables)]
fn back_pressed(&mut self, rsc: &mut AndroidRsc<Self>, render: &mut UiRenderState) -> bool {
fn back_pressed(&mut self, rsc: &mut AndroidRsc<Self>) -> bool {
false
}
#[allow(unused_variables)]
@@ -167,7 +167,7 @@ impl WindowInsets {
}
pub struct AndroidRsc<State: 'static> {
pub ui: UiData,
pub ui: Ui,
pub events: EventManager<Self>,
pub tasks: Tasks<Self>,
pub state: WidgetState,
@@ -181,10 +181,10 @@ impl<State> AndroidRsc<State> {
}
impl<State> UiRsc for AndroidRsc<State> {
fn ui(&self) -> &UiData {
fn ui(&self) -> &Ui {
&self.ui
}
fn ui_mut(&mut self) -> &mut UiData {
fn ui_mut(&mut self) -> &mut Ui {
&mut self.ui
}
fn on_draw(&mut self, active: &ActiveData) {
@@ -232,7 +232,6 @@ impl<State: 'static> HasWidgetState for AndroidRsc<State> {
/// Java the same way android-view's own demo does.
pub struct IrisViewPeer<State: AndroidAppState> {
pub(super) rsc: AndroidRsc<State>,
pub(super) render: UiRenderState,
pub(super) state: State,
task_recv: TaskMsgReceiver<AndroidRsc<State>>,
/// The one ruler this view dates everything on: touch samples in
@@ -277,7 +276,9 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
let ui_state = self.state.android_state_mut();
let cursor = ui_state.cursor.clone();
let old_focus = ui_state.focus;
self.render
let render_state = self.rsc.ui.render_state();
render_state
.get()
.run_sensors(&mut self.rsc, &mut self.state, cursor, window_size);
let ui_state = self.state.android_state_mut();
@@ -306,7 +307,11 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
let ui_state = self.state.android_state_mut();
ui_state.cursor.end_frame();
if self.render.needs_redraw(&ui_state.root, self.rsc.widgets()) {
let render_state = self.rsc.ui.render_state();
if render_state
.get()
.needs_redraw(&ui_state.root, self.rsc.widgets())
{
ctx.view.post_frame_callback(&mut ctx.env);
}
}
@@ -360,11 +365,17 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
"render(): root={:?} widgets={} active={} root_px={:?} out_size={:?}",
ui_state.root.is_some(),
self.rsc.widgets().len(),
self.render.active_widgets(),
self.rsc.ui.render_state().get().active_widgets(),
ui_state
.root
.as_ref()
.and_then(|r| self.render.window_region(r, &self.rsc)),
.and_then(|r| {
self.rsc
.ui
.render_state()
.get()
.window_region(r, &self.rsc)
}),
self.window_size(),
);
}
@@ -374,12 +385,12 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
ctx.view.post_frame_callback(&mut ctx.env);
}
let ui_state = self.state.android_state_mut();
self.render.update(&ui_state.root, &mut self.rsc);
self.rsc.draw(&ui_state.root);
let ui_state = self.state.android_state_mut();
let Some(renderer) = &mut ui_state.renderer else {
return;
};
let frame_diagnostics = renderer.update(&mut self.rsc.ui, &mut self.render);
let frame_diagnostics = renderer.update(&mut self.rsc.ui);
if renderer.frame_count() <= DIAGNOSTIC_FRAMES {
log::info!(
"iris frame diagnostics: frame={} masks_resized={} moves_resized={} \
@@ -400,26 +411,33 @@ impl<State: AndroidAppState> IrisViewPeer<State> {
.android_state_mut()
.frame_report
.record(now, parts, animating);
crate::diagnostics::log_frame(&self.render, now, parts, animating);
let render_state = self.rsc.ui.render_state();
crate::diagnostics::log_frame(&render_state.get(), now, parts, animating);
if crate::diagnostics::trace_enabled() {
let ui_state = self.state.android_state();
log::debug!(
target: "iris::frame",
"render(): after update active={} root_px={:?}",
self.render.active_widgets(),
self.rsc.ui.render_state().get().active_widgets(),
ui_state
.root
.as_ref()
.and_then(|r| self.render.window_region(r, &self.rsc)),
.and_then(|r| {
self.rsc
.ui
.render_state()
.get()
.window_region(r, &self.rsc)
}),
);
}
let ui_state = self.state.android_state_mut();
if let Some(tree_update) =
ui_state
.access
.update(self.rsc.widgets(), &self.render, &self.rsc)
{
if let Some(tree_update) = ui_state.access.update(
self.rsc.widgets(),
&self.rsc.ui.render_state().get(),
&self.rsc,
) {
let ui_state = self.state.android_state_mut();
if let Some(events) = ui_state.access_adapter.update_if_active(|| tree_update) {
ctx.push_dynamic_deferred_callback(move |env, view| {
@@ -467,7 +485,7 @@ impl<State: AndroidAppState> ViewPeer for IrisViewPeer<State> {
self.after_input(ctx);
return true;
}
let handled = self.state.back_pressed(&mut self.rsc, &mut self.render);
let handled = self.state.back_pressed(&mut self.rsc);
if handled {
self.after_input(ctx);
}
@@ -646,7 +664,7 @@ impl<State: AndroidAppState> ViewPeer for IrisViewPeer<State> {
// dividing the whole window into a separate logical space, which
// is what used to make every `abs`-unit size (a fixed `.height(56)`
// in particular) mean something different from a `rest`-based one.
self.render.resize((width as f32, height as f32));
self.rsc.ui.resize((width as f32, height as f32));
// `AndroidRenderer::resize` only reconfigures the wgpu surface and
// rewrites the window uniform -- device, atlas, buffers and bind
@@ -779,9 +797,11 @@ impl<State: AndroidAppState> AccessibilityNodeProvider for IrisViewPeer<State> {
ctx: &mut CallbackCtx<'local>,
virtual_view_id: jint,
) -> AccessibilityNodeInfo<'local> {
let render_handle = self.rsc.ui.render_state();
let render_state = render_handle.get();
let mut source = AndroidAccessSource {
widgets: self.rsc.widgets(),
render: &self.render,
render: &render_state,
rsc: &self.rsc,
};
let ui_state = self.state.android_state_mut();
@@ -798,9 +818,11 @@ impl<State: AndroidAppState> AccessibilityNodeProvider for IrisViewPeer<State> {
ctx: &mut CallbackCtx<'local>,
focus_type: jint,
) -> AccessibilityNodeInfo<'local> {
let render_handle = self.rsc.ui.render_state();
let render_state = render_handle.get();
let mut source = AndroidAccessSource {
widgets: self.rsc.widgets(),
render: &self.render,
render: &render_state,
rsc: &self.rsc,
};
let ui_state = self.state.android_state_mut();
@@ -869,18 +891,15 @@ pub fn new_peer<'local, State: AndroidAppState>(
state: Default::default(),
_state: PhantomData,
};
rsc.ui.text.density = content_scale;
rsc.ui.set_density(content_scale);
let shared = Rc::new(RefCell::new(Shared::default()));
let ui_state = AndroidUiState::new(shared.clone(), content_scale);
let mut state = State::new(ui_state, &mut rsc);
let platform_vm = env.get_java_vm().unwrap();
let platform_view = env.new_global_ref(&view.0).unwrap();
state.platform_ready(&mut rsc, platform_vm, platform_view);
let mut render = UiRenderState::new();
render.set_density(content_scale);
let peer = IrisViewPeer {
rsc,
render,
state,
task_recv,
device_clock: None,