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

Abierto
#669 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
dart, flutter
Área
backend

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.

Lenguaje dominante
Dart
Estrellas
1.5k
Forks
244
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de rive-app/rive-flutter

Todos los issues de rive-app/rive-flutter

Issues similares

Más issues de Dart

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.