iris/android: fix layout/shader unit mismatch left by the density-scale commit

surface_changed's self.render.resize(...) -- UiRenderState::output_size,
what every widget's absolute PixelRegion (a fixed .height(56), notably)
is computed against -- was still being handed raw physical width/height
after the previous commit switched AndroidRenderer's own size()/resize()/
new() to logical (physical / content_scale) for the shader's window
uniform. That split layout and the shader into two different units:
layout placed a "56"-unit row inside a ~2219-physical-unit-tall canvas
(an absolute box, still exactly 56 units), the shader then divided that
same 56 by a ~845-unit *logical* window dimension -- found on the
emulator by measuring a fresh install's top button row at ~40 physical
px against the ~147px `56 * content_scale` predicts. Proportional
(rest(n)) sizes hid the mismatch by adapting to whichever total they were
given; only fixed sizes exposed it. Now divides by content_scale here
too, matching every other call site.

Verified on this checkout's emulator (EMU_GPU default, force-gles):
run-bench.sh completes end to end (frames=691, 24/24 swipes streamed
400/400 events) and a fresh-install screenshot shows visibly larger
text than before this and the previous commit, with the top row's own
sizing still worth a closer look on a real device -- see RUST.md's P0
box for what remains unverified there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Fable 5.1 committed 2026-09-05 23:57:24 -04:00
1 parent c7682297fa
commit fd7e17523d
1 file changed
+21 -1
+21 -1
View File
@@ -573,7 +573,26 @@ impl<State: AndroidAppState> ViewPeer for IrisViewPeer<State> {
// nothing but the clear colour: the widget tree laid out against // nothing but the clear colour: the widget tree laid out against
// whatever size `UiRenderState::new` starts at instead of the // whatever size `UiRenderState::new` starts at instead of the
// surface's real one. // surface's real one.
self.render.resize((width as u32, height as u32)); //
// **Logical, not physical** -- `content_scale`'s field comment on
// `AndroidUiState`. This call sets `UiRenderState::output_size`,
// which is what every widget's absolute `PixelRegion` (a fixed
// `.height(56)`, in particular) is computed against; `AndroidRenderer`'s
// own `size()`/`resize()`/`new()` already report logical dimensions
// to the *shader*'s window uniform, so leaving this call on raw
// physical `width`/`height` split the two into different units --
// layout placed a "56"-unit-tall row in an ~2219-tall physical
// canvas (an absolute, correctly-56-unit box), the shader then
// divided that same 56 by a ~845-unit *logical* window dimension,
// and the row rendered far too short rather than too tall or
// right, because a fixed-size item's absolute unit value never
// adapts to the mismatch the way a `rest(n)`-proportional one
// does. Found by measuring a fresh install's top button row at
// ~40 physical px instead of the ~147px `56 * content_scale`
// predicts, immediately after the density fix below was added.
let content_scale = self.state.android_state().content_scale;
self.render
.resize((width as f32 / content_scale, height as f32 / content_scale));
// Drop the old renderer (and the surface it owns) before building // Drop the old renderer (and the surface it owns) before building
// one from the new window -- see `AndroidRenderer`'s doc comment. // one from the new window -- see `AndroidRenderer`'s doc comment.
let ui_state = self.state.android_state_mut(); let ui_state = self.state.android_state_mut();
@@ -740,6 +759,7 @@ pub fn new_peer<'local, State: AndroidAppState>(
.resources(&mut env) .resources(&mut env)
.display_metrics(&mut env) .display_metrics(&mut env)
.density(&mut env); .density(&mut env);
log::info!("iris: new_peer content_scale={content_scale}");
let vm = env.get_java_vm().unwrap(); let vm = env.get_java_vm().unwrap();
let global_view = env.new_global_ref(&view.0).unwrap(); let global_view = env.new_global_ref(&view.0).unwrap();
let redraw: Arc<dyn RequestRedraw> = Arc::new(AndroidRedrawHandle::new(vm, global_view)); let redraw: Arc<dyn RequestRedraw> = Arc::new(AndroidRedrawHandle::new(vm, global_view));