This directory contains:
* `impeller.h` - impeller's C API header symlinked for convenience (you need to pull the flutter submodule too as that's where the file actually resides)
* `generate_impeller_api_json.py` - to generate a json from `impeller.h`
* `impeller_api.json` - the json file generated by above script.
* `crates/impellers_codegen` - generates raw FFI bindings for impeller's C API using bindgen.
* `impellers` - wraps the FFI bindings with safe rust types and functions. and uses build script to download/link the prebuilt impeller library artefacts
* `.github/workflows/assets.yaml` - This uses `build_impeller.sh` and `BUILD.gn.patch` to generate zip files of static libraries for linux/windows x64.
* `download_flutter_artefacts.sh` - This downloads the flutter pre-built libs hosted by flutter. Just run it with an argument of `target_dir` where you want to download the artefacts to.
### Rust Bindings Generation
We will assume that you are in the root of the repo.
Just run:
> `cargo run -p impellers_codegen
If you first set the `env` variable `RUST_LOG=debug`, the generator will log a bunch of extra stuff to stdout which might be helpful if you are debugging it.
Generated bindings will be placed in `src/sys.rs`.
The `codegen.rs` file contains the code to generate the bindings. We do some convenient "post-processing" to make the bindings easier to re-export by default.
eg: We strip the Impeller prefix from enum names and the enum name prefixes from enum variants to match rust naming conventions.
### Safe Rust API
The `src/lib.rs` contains the safe rust API. It is mostly a thin wrapper around the raw bindings.
The documentation is rough (mostly copy-pasted from `impeller.h`).
### API.json
It covers *most* of the API, except "macros" (including version macros)
Here's a few tips:
* All identifiers start with `Impeller`
* Almost ALL functions are "methods" which take a handle (opaque struct pointer) as the first argument. These function names start with the name of the handle. For example, if the handle name is ImpellerContext, the name of the function to delete it would be ImpellerContextRelease.
* While we do have structs like rect/matrix, their functionality is not included her. So, you must implement the matrix multiplication or translating rect etc.. yourself.
* The json file doesn't specify which structs are thread-safe, you must manually read the docs for that.
* some fields may be skipped if they have default values. eg: you may assume that nonnull (boolean) default is false if not explicitly specified.
The structure is pretty simple. The root object contains 4 objects:
1. `enums`: The keys in this object are "enum" names and the values are list of "variant" names. Use this to generate enums.
2. `handles`: The keys are names of opaque structs. The values are simply the docstrings of these handles.
3. `functions`: the keys in this object are function names. The values are objects with these keys:
1. `doc`: this is the docstring of the function
2. `return_ty`: this is an object
1. `nodiscard`: whether the return type should be discarded (default is false)
2. `ty`: the return type of the fn. we more or less just copy/paste the c type like "const uint32_t*", so it is upto you to interpret it.
3. `nonnull`: If the return type is a pointer/handle, whether it should be non-null. default is false.
3. `args`: this is an array of arg objects (and also used as field object for pod structs - see below). each arg object has the following properties
1. `name`: name of argument
2. `ty`: type of argument, just like return type, we copy-paste the type from source. The first arg is almost always a handle.
3. `nonnull`: If pointer or handle type, whether it should be non-null (default false)
4. `array_size`: If argument is an array (pointer?), the size of the required array. (default 0, as arrays are very rare)
4. `pod_structs`: This is an object where keys are names of the PlainOldData C structs (non-opaque). The values are objects describing the struct.
1. `doc`: docstring of type
2. `fields`: an array of fields of this struct, and each field is exactly the same as the arg of a function. look above for the description of the arg object
5. `types`: Finally, this holds the types used in the Impeller API. eg: 'bool' or 'const uint8_t*'. It is important to note that, this list does not contain handles, enums or pod structs (or pointers to structs). They are implicitly assumed to be used somewhere.
# Static Builds
The flutter submodule is mainly intended for building static libraries. If you want to play with that, just remember these few things.
* Look at `.github/workflows/statics.yaml` and `build_impeller.sh` files
for how we build things.
* Look at wiki pages [setting up environment](https://github.com/flutter/flutter/blob/master/engine/src/flutter/docs/contributing/Setting-up-the-Engine-development-environment.md) and [compiling engine](https://github.com/flutter/flutter/blob/master/engine/src/flutter/docs/contributing/Compiling-the-engine.md) and walk through them *step* by *step* to see that you are not missing anything.
* Just add lots of print statements in gn files or src/flutter/tools/gn to debug any issues.
### Problems with Static linking
TODO: Is this still a problem?
I am just documenting this here, in case anyone familiar with gn build system can help fix this.
On linux, libcxx sources are not getting pulled into static library. We can verify this by just generating the gn files and looking at the diff between `library_static.ninja` vs `library.ninja` in the `out/{profile}/obj/flutter/impeller/toolkit/interop` directory.
This causes undefined reference errors for libcxx symbols like strings/share_ptrs when you try to link `libimpeller.a` with your app.
If we explicitly add libcxx as a dependency to `library_static` target, it works on linux, but causes issues with windows builds. So, for now, we only add libcxx as the dependency for `library_static` if the target os is not windows.
### Dependencies
We generally need these libraries
- cmake
- glfw
- x11 development headers (xrandr, xinerama, xcursor, xi, x11)
- Roboto font (for running text related examples)