Skip to content

Mobile Safari Skwasm canvas CSS size collapses to ~0.328px while backing store is valid #188723

Description

@MarlonJD

Summary

On MobileSafari with Skwasm, the canvas backing store can be valid (1206 x 2142) while the visible CSS/display size collapses to about 0.328125px. User-visible result: the page is blank or nearly blank even though Skwasm artifacts loaded and benchmark telemetry can complete.

Expected visible size on the tested iPhone is about 402 x 714px.

Fix candidate: #188797.

Current status: local verification of the stock #188797 bundle did not reproduce the collapsed CSS-size signature. The bundle was built without the multi-surface flag and without forced CSS/JavaScript sizing. Physical iPhone MobileSafari loaded skwasm_heavy, main.dart.mjs, and main.dart.wasm; bench_card_infinite_scroll and bench_simple_lazy_text_scroll completed with errors: []; canvas geometry was 1206 x 2142 backing / 402 x 714 CSS.

This issue is only about the MobileSafari canvas CSS-size collapse. Safari/WebKit default enablement is separate.

User Impact

Flutter web pages using Skwasm can appear blank or nearly blank on iPhone MobileSafari even when the app has loaded and the canvas backing store contains content.

Screenshots

Failing state
Blank / near-blank page while canvas CSS size is about 0.328125px.
Failing MobileSafari Skwasm blank page
Recovered / fixed state
Visible benchmark content with canvas CSS size about 402 x 714px.
Recovered MobileSafari Skwasm visible benchmark content

Additional visible benchmark states from local MobileSafari follow-up:

Card scroll
Visible card scroll benchmark
Lazy text scroll
Visible lazy text scroll benchmark
Wrapbox scroll
Visible wrapbox scroll benchmark

Related PRs

Verification for #188797

  • Renderer: Skwasm.
  • wasmAllowList.webkit=true.
  • variants=none.
  • No multi-surface flag.
  • No forced CSS/JS sizing; variant=none is telemetry-only and does not write canvas CSS.
  • Generated bundle/build logs were checked for FLUTTER_WEB_SKWASM_FORCE_MULTI_SURFACE_RASTERIZER; the string was absent.
  • Targeted render_canvas_test.dart browser test passed in the [web] Repair RenderCanvas CSS size drift #188797 checkout with --gcs-prod (chrome-dart2js-canvaskit-engine, 3/3, All tests passed!).

Local #188797 runs:

  • Simulator MobileSafari, bench_card_infinite_scroll: loaded skwasm_heavy, main.dart.mjs, and main.dart.wasm; errors: []; canvas 1206 x 2142 backing / 402 x 714 CSS.
  • Physical iPhone MobileSafari, bench_card_infinite_scroll: loaded the same Skwasm artifacts; errors: []; canvas 1206 x 2142 backing / 402 x 714 CSS.
  • Physical iPhone MobileSafari, bench_simple_lazy_text_scroll: loaded the same Skwasm artifacts; errors: []; canvas 1206 x 2142 backing / 402 x 714 CSS.

Physical iPhone caveat: page telemetry reported crossOriginIsolated=false even though the harness served isolation headers. Skwasm still loaded through the WebKit allowlist, so the physical result is local canvas-geometry and benchmark-completion evidence, not a cross-origin-isolation pass.

Investigation details

Original Observed Behavior

Default Skwasm run on physical iPhone MobileSafari:

  • Skwasm runtime initializes.
  • skwasm_heavy, main.dart.mjs, and main.dart.wasm are fetched.
  • Benchmark profiles complete.
  • No app/runtime errors are captured by the local probe.
  • A Flutter canvas exists under shadow DOM.
  • Canvas backing store: 1206 x 2142.
  • Canvas CSS/display rect: approximately 0.328125 x 0.328125px.
  • Canvas computed style width/height: 0.328125px / 0.328125px.
  • Pixel sample from the canvas is non-empty.
  • User-visible result: white/blank page because the rendered canvas is effectively microscopic.

Expected behavior:

  • With backing store 1206 x 2142 and DPR 3, the canvas CSS/display rect should be approximately 402 x 714px.

Local Recovery Probe

A local-only JavaScript probe, without changing engine source or Skwasm artifacts, searched shadow DOM for Flutter canvases and applied:

canvas.style.width = `${canvas.width / window.devicePixelRatio}px`;
canvas.style.height = `${canvas.height / window.devicePixelRatio}px`;

Result on physical iPhone MobileSafari:

  • Before forced CSS size: 0.328125 x 0.328125px.
  • After forced CSS size: 402 x 714px.
  • The page became visible while the forced size was held active.

Supporting Simulator evidence reproduced the same geometry failure and recovery.

Scope Notes

  • CanvasKit control rendered visibly on the same physical device.
  • Standalone 2D/WebGL/ImageBitmap probes were visible on iPhone, so this is not currently classified as a generic ImageBitmap or bitmaprenderer failure.
  • Wonderous, built as a real Flutter web Skwasm app, rendered visibly on the same physical iPhone MobileSafari with default Skwasm and a normal 402 x 714px canvas rect. This means the sizing collapse is not universal across all Flutter web Skwasm apps.
  • The stock [web] Repair RenderCanvas CSS size drift #188797 verification above is separate from the earlier multi-surface/transferred-canvas candidate bundle.

Investigation History

  • A Simulator MobileSafari default/no-injection rerun reproduced the collapsed canvas geometry with backing 1206 x 2142 and CSS/display rect around 0.328125 x 0.328125px. A forced CSS-size hold recovered the canvas to 402 x 714 with visible benchmark cards.
  • Diagnostic RenderCanvas logs from aligned local bundles showed _ensureSize setting 1206 x 2142 canvas attributes, then logical sizing writing 402px / 714px.
  • A copied collapsed-bundle style-observer run showed the canvas itself receiving inline CSS 0.333333px / 0.333333px; the backing store later reached 1206 x 2142, but the canvas CSS size was not corrected to 402 x 714.
  • The stock RenderCanvas same-size stale-inline-CSS repair is tracked in [web] Repair RenderCanvas CSS size drift #188797 and has the no-forced/no-multi-surface MobileSafari verification summarized above.

Metadata

Metadata

Labels

assigned for triageissue is assigned to a domain expert for further triageengineflutter/engine related. See also e: labels.platform-webWeb applications specificallyteam-webOwned by Web platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions