Flutter web: a script's `Image:view()` samples nothing in a GPU canvas

Aperta
#669 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
dart, flutter
Ambito
backend

Direzione di ricerca

Start with the reported paths: rive-runtime’s renderer/include/rive/renderer/cmd/deferred_replayer.hpp and rive_native’s native/platform/wasm/webgl_factory.cpp; compare the linked fix branch and patch against the stated two replay failures. Reproduce with the standalone project’s repro/assets/image_view.riv in Flutter web and inspect the console output. Done means both squares render the checker under dart2js and dart2wasm, with no replay messages.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

known
Submission checklist
  • I have confirmed the issue is present in the latest version of the rive Flutter package
  • I have searched the documentation and forums and could not find an answer
  • I have searched existing issues and this is not a duplicate
Description

On Flutter web, a Luau script that samples an embedded image through Image:view() in a GPU canvas draws nothing, and every render pass that binds the view drops its draws. The same file draws correctly in the Rive CLI, which runs the same deferred replay natively. The public reproduction, captures and a suggested fix are included here. Thank you for taking a look.

Following the arrangement in #665, the suggested fix is offered on a copy of rive_native 0.2.0-dev.4 verbatim from pub.dev: branch, one-commit comparison, .patch. The same patch is included locally. A separate report on two dart2wasm interop failures uses the same copy: rive_wasm_issue.

image_view.riv draws one embedded 256 px image twice: the left square with renderer:drawImage, the right square in a GPU canvas whose fragment shader samples image:view() at mip level 0. On Flutter web the right square stays empty, with both dart2js and dart2wasm, and the console shows, right after rive_native: deferred replay active (web W1 inline):

rive ore replay: skip make wrapImageView '' id=6 gen=0 (unresolved dep, churn)
rive ore replay: bind group handle 7 dropped pass draws: bindGroup '' skipped, unresolved dependency

Expected: both squares show the same orange and teal checker, as they do in the Rive CLI 1.9.1 on macOS (Metal), whose log reports deferred replay: inline. The same scenes draw natively in our app on iOS and Android with the same runtime.

Actual, with rive 0.15.0-dev.4 / rive_native 0.2.0-dev.4: the right square is empty on every frame. With the suggested fix it matches the left square under both compilers, and the console shows no replay messages.

Two things combine in the web deferred replay:

  1. The Ore image resolver in DeferredReplayer returns a resident 2D image unprepped. On the web that is a context agnostic WebGL2RenderImage, which only prep() turns into the RiveRenderImage that the wrapImageView make casts to, so the cast always fails. Foreign images are already prepped.
  2. The recorder reads an image's size from the encoded header (DeferredFactory::decodeImage), so a script sees width > 0 on its first frame and records the view then. The replay decodes its own copy through the browser, asynchronously, so the first replay finds it still decoding. The wrap and the bind groups made on it are recorded once, so the skip is permanent, where a 2D draw or a paint asks again on the next frame.

Fixing the first alone is not enough: with only that change, a debug build showed the resident image at width 0 when the wrap was made, and the scene stayed blank.

Reproduction steps / code

The standalone project, its Rive source, the signed file, scripts and captures are at https://github.com/rydmike/rive_web_image_view_issue.

If preferred, the whole sample is also in the ZIP under "Upload your reproduction files / stack trace". The .riv file is repro/assets/image_view.riv in it, so it is not uploaded again under "Source .riv / .rev file".

  1. Use Flutter 3.47.9 stable / Dart 3.13.7. From repro/, run flutter pub get.
  2. Run flutter build web --release.
  3. From the repository root, run python3 tool/serve.py repro/build/web --port 8123.
  4. Open http://127.0.0.1:8123 in Chrome. The left square shows the checker, the right square stays empty, and the console shows the two lines above.
  5. To see the fix, rebuild with --dart-define=RIVE_NATIVE_WASM_HOST=https://cdn.jsdelivr.net/gh/rydmike/[email protected]/native/wasm/, which loads a wasm built from the fix branch (build notes).

The script, rive_project/image_view.luau, makes the view once, as soon as the image reports a size, which is how a scene uses a file image in a GPU canvas:

if self.bind == nil then
    self.bind = GPUBindGroup.new({
        layout = layout,
        textures = { { slot = 0, view = image:view() } },
        samplers = { { slot = 1, sampler = sampler } },
    })
end

The shader, rive_project/image_view.wgsl, draws one textured quad with textureSampleLevel(picture, pictureSampler, i.uv, 0.0). Reading level 0 only keeps empty lower mip levels out of the picture.

Upload your reproduction files / stack trace

rive_web_image_view_issue-repro.zip

Source .riv / .rev file

No response

Screenshots / video

cli-macos-metal.png
published-js.png
fixed-js.png

Rive Flutter package version

Latest published prereleases: rive 0.15.0-dev.4 / rive_native 0.2.0-dev.4, which load @rive-app/[email protected]. Versions checked against pub.dev on 2026-11-08; the fix is based on rive_native 0.2.0-dev.4. The latest stable pair (rive 0.14.11 / rive_native 0.1.11) also leaves the right square empty but prints no replay messages; this report concerns the prerelease pair, which a file built by the Rive CLI 1.9 needs.

Flutter version

Flutter 3.47.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision c197ca5199 (10 days ago) • 2026-10-29 10:10:20 -0400
Engine • hash 9e025265bef30b838c0c1b68cad19decf97048f2 (revision 89c39edfdf) (11 days ago) • 2026-10-27 19:51:20.000Z
Tools • Dart 3.13.7 • DevTools 2.60.0

Device

Desktop web, arm64 host; real headless Google Chrome 156.0.8078.81, controlled with puppeteer-core 25.15.0, software WebGL with --enable-unsafe-swiftshader. The right square is also empty in a regular, GPU-backed Chromium window.

OS version

macOS 27.0.1, build 26A434, arm64.

Additional context

rive_native does not offer a public repository for a pull request, so the suggested fix follows the packaging used in #665: a verbatim pub.dev baseline, one commit and a downloadable patch.

The replayer half of the fix, renderer/include/rive/renderer/cmd/deferred_replayer.hpp, is in rive-runtime, where the same code is on main today; a pull request there for that half can follow if it helps. The WebGL half is in rive_native's native/platform/wasm/webgl_factory.cpp.

We also verified the fix in our production app, a large Flutter app with many scripted GPU canvas scenes, by loading the wasm built from the fix branch through RIVE_NATIVE_WASM_HOST. In both a local dart2js build and a dart2wasm build deployed to our staging site, the scenes that drew nothing before render correctly in Chrome, with no replay messages.

Lingua principale
Dart
Stelle
1.5k
Fork
244
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di rive-app/rive-flutter

Tutte le issue di rive-app/rive-flutter

Issue simili

Altre issue su Dart

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.