impellers 0.4.2

Bindings to Flutter's 2D vector graphics renderer
Documentation

## Overview
There's a few things happening in this repo and reading this file is useful to understand what's going on.
- Impeller lives in flutter repo, which is attached as `flutter` submodule. 
    - This contains the C sources. We only care about the impeller header though and for convenience, it is sym-linked as `impeller.h` directly.
    - `ENGINE_SHA` file keeps track of which upstream commit the submodule is tracking. Our github CI checks that `ENGINE_SHA` and the submodule are in sync.
- We generate structured info about `impeller.h` for convenience.
    - `generate_impeller_api_json.py` uses regex to parse all types/symbols/docs from `impeller.h`
    - `impeller_api.json` - the json file generated by above script.
    - This can be used to automate tasks like generate type definition files for other projects (eg: luau bindings or typescript bindings).
- Impeller team builds and hosts [both shared/static] library artefacts for *each* commit. 
    - `download_flutter_artefacts.sh` - This downloads the flutter pre-built libs hosted by flutter. It require the first argument to be `target_dir_path` where you want to download the artefacts to.
    - `.github/workflows/assets.yaml` - downloads the upstream artefacts (using above script) and uploads them to github releases. 
    - `build.rs` will download + link these libraries from github releases, if `prebuilt_libs`/`cache_libs` features are used. This allows us to skip the long compilation times of impeller (and the complexity of managing those build systems).
- `bindgen_helper.rs` module (for `build.rs`) handles the bindings generation from `impeller.h` using bindgen.
    - For most 64-bit non-windows platforms, ABI seems compatible, so, we pre-generate bindings in `src/sys/{win,nowin}.rs` for windows and non-windows platforms. This is controlled by `internal_pre_bindgen` feature. Go to next section.
    - If `bindgen_live` feature is not enabled, we just copy these pre-generated bindings to `OUT_DIR/bindings.rs` and skip dependencies like bindgen saving build time.
    - If `bindgen_live` feature is enabled, we pull in bindgen and generate them live. This is to allow niche platforms (eg: 32bit) to still work at the cost of longer cold build times. 
- `src/sys.rs` - exposes the bindings from `OUT_DIR/bindings.rs` created by `build.rs`. `sys` feature controls whether it is public or private. 
- `impellers` crate obviously exposes the safe bindings that wrap `src/sys.rs`. The rest of the files like CREDITS or README should be self-evident. 


### Rust Bindings Pre Generation
We will assume that you are in the root of the repo.
Just run:
> `cargo build --features=internal_pre_bindgen`

Generated bindings will be placed in `src/sys/{win,nowin}.rs`. The only difference between windows/non-windows is the default repr(u32/i32) for enums. 

### 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`).


### impeller_api.json
It covers *most* of the API, except "macros" (eg: `IMPELLER_VERSION_MAJOR`)
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 here. 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.

### Dependencies
We generally need these libraries
- cmake (for glfw)
- glfw
    - x11 development headers (xrandr, xinerama, xcursor, xi, x11)
- Roboto font (for running text related examples)


## Flutter Upgrade CheckList
When bumping submodule to a new commit
- update `ENGINE_SHA` using `git submodule status | cut -d ' ' -f2`
- Create a new tag with `a_` prefix like `a_0.15.2` to trigger `.github/workflows/assets.yaml` workflow.
- If above succeeds, cut a new release on github. 
- Update the assets version in `build.rs` (eg: `STATIC_*` constants)
- Pre-generate bindings using `internal_pre_bindgen` feature to update to new impeller header.
- Run `generate_impeller_api_json.py` to update `impeller_api.json`.
- Run `cargo clean` -> some tests and examples to verify that the new artefacts are working properly.
- Check for any new items via diffs in pre-generated bindings or json file. If there's new items, add safe bindings and examples to make sure that the new items are working correctly.
- Bump Cargo.toml version and publish.