The general approach for NImpeller is to treat impeller.h as the only source of truth and manually write only some convenience code or code dealing with native->managed callbacks (there is only a few of those). The generator is supposed to generate the entire P/Invoke layer and at least 90% of .NET classes exposed as the public API.
Generated bindings file is NOT checked out into the repo, because right now the bindings considered to be versionless, i. e. being compatible with any version of impeller.h. You can find an example of generated code here if you don't want to clone/build the repo and want a sneak peek.
- Generate the Impeller bindings. If you have never generated the bindings, they will be generated on first build of NImpeller via an MSBuild task. You should see this as
DownloadSdkAndGenerateBindings. You can also use the InteropGen program directly with theimpeller.hheader, or use the Nuke task
./build.sh GenerateBindingsto automatically download and build the bindings.
- Run the Sandbox sample. The runtime file used is based on the
Impeller.targetsfile. You can either manually set up the library you want to test with, or use the Nuke tasks below for automatically setting it up per commit, or with the latest commit.
It will only work for platforms where SDL2 can create a GLES context. I've only tested it with Linux with an Intel iGPU, so good luck.
Flutter builds toolkit binaries on a nightly feed, that you can download from.
Typical link is https://storage.googleapis.com/flutter_infra_release/flutter/$FLUTTER_SHA/$PLATFORM_ARCH/impeller_sdk.zip
Where:
$FLUTTER_SHAis a commit hash$PLATFORM_ARCHis one oflinux-arm64,linux-x64,windows-arm64,windows-x64,darwin-arm64,darwin-x64orandroid-arm64
From this zip you will need include/impeller.h and lib/impeller.so (or impeller.dll/impeller.dylib).
See Impeller Toolkit: Prebuilt Artifacts
The files can be automatically downloaded via Nuke using the Powershell, Bash, or global Nuke command. Using either:
./build.sh DownloadLatestImpeller --Allto download the newest Impeller build by the newest commit to Flutter, or
./build.sh DownloadImpeller --impeller-sha (Commit Sha) --AllFor a specific commit.
Native impeller handles are represented by two separate types:
- FooHandle - a SafeHandle passed to P/Invoke layer
- Foo - a managed wrapper around FooHandle that exposes actual methods and factories in idiomatic .NET style
There is no object tracking, for each call to a native function that returns you an existing Foo instance you will get a new Foo object with reference counter of the native one being increased by one.
The bindings are generated by InteropGen, a simple C# console app that uses CppAst library to parse impeller.h and conver it into NativeModel that has some .NET-specific stuff already mapped.
The model is then used to generate the bindings code. Generator is aware of impeller.h naming conventions, so it will place functions to appropriate classes, properly wrap factories for New-suffixed methods, call *Retain function when obtaining and existing object counter, etc.
# Update ninja files without attempting to rebuild THE ENTIRE FLUTTER
./engine/src/flutter/tools/gn --runtime-mode debug --no-stripped --no-lto --no-rbe --no-goma
# Compile just interop library and not THE ENTIRE FLUTTER
ninja -C engine/src/out/host_debug library
# Generate compile_commands.json for IDE integration for just the interop library and deps and not THE ENTIRE FLUTTER
mkdir -p ide
/path/to/1.13.1/ninja -C engine/src/out/host_debug -t compdb-targets library > ide/compile_commands.json
#jq 'map(select(.command | startswith("vpython") or startswith("rm") or startswith("ln") | not))'