# vflutter_ffi example A Mandelbrot explorer whose pixels are computed in V. Scroll to zoom smoothly, tap to zoom in, right-click to zoom out — all anchored at the cursor. Sliders control the iteration cap and how many isolates the frame is split across; "Reset view" restores the framing without disturbing either. It exists to exercise the parts of the bridge the string demo cannot: * **Bulk data across the boundary.** Each frame is a full RGBA buffer, not a string. Dart allocates it and `vf_mandelbrot` fills it in place, so no V memory crosses the boundary and there is nothing to `vf_free`. * **Band parallelism.** The image splits into horizontal strips rendered on separate isolates. Bands are independent by construction, and `-gc none` means no stop-the-world phase to serialise them. * **An honest benchmark.** The same algorithm is written twice — in V (`src/vflutter.v`) and in Dart (`lib/mandelbrot_dart.dart`) — and the Benchmark button times both. The tests assert the two agree pixel-for-pixel, which is what makes the comparison meaningful. ## What the numbers actually say Measured here (800x600, maxIter 500, release build, 8-core Linux): | | time | |---|---| | V, one isolate | ~152 ms | | V, 4 isolates | ~65 ms | | Dart AOT, one isolate | ~165 ms | **V is not meaningfully faster than Dart at this.** For a scalar floating-point loop, V-through-C and Dart AOT land within ~10% of each other. The 2.5x comes from the parallel split, which Dart could do on its own without any FFI. Treat this app as a demonstration of the *bridge* — bulk buffers, caller-owned memory, safe multi-isolate calls — not as a speed claim for V. Reach for V here because you want to write the logic in V, or already have it in V, not because C-via-V is expected to outrun Dart AOT on arithmetic. ## Run it ```bash just mandelbrot ``` or, driving Flutter yourself: ```bash cd example flutter run -d linux ``` Only the Linux runner is generated. For the other platforms, generate their runner directories once first: ```bash flutter create --platforms=android,ios,macos,windows . ``` `flutter create` leaves `lib/`, `test/` and `pubspec.yaml` alone. The native library is built by the plugin itself: CMake invokes `v` on Linux, Windows and Android; iOS and macOS compile the pre-generated C in `ios/Classes/`. ## Tests `flutter test` runs on the host VM rather than in the app bundle, so it needs the native library on the loader path: ```bash ./tool/build.sh cd example && LD_LIBRARY_PATH=../build flutter test ``` The suite covers the zoom maths as a property (the point under the cursor stays put), the buffer contract, the band split matching a single-shot render, and the V and Dart kernels agreeing exactly. ## Headless scripts No Flutter SDK needed — only `dart` and the host library. Run from the repository root, which resolves without Flutter: ```bash ./tool/build.sh LD_LIBRARY_PATH=build dart example/lib/fractal_bench.dart # V vs Dart timings LD_LIBRARY_PATH=build dart example/lib/main_test.dart # string round-trips LD_LIBRARY_PATH=build dart example/lib/memory_check.dart # RSS regression guard ``` For a like-for-like comparison with a release app, compile the benchmark AOT first — `dart run` uses the JIT: ```bash dart compile exe example/lib/fractal_bench.dart -o /tmp/bench LD_LIBRARY_PATH=build /tmp/bench ```