Establishes the v0.1 foundations on both platforms: - dr-types: SourceRef (never a filesystem path — Android SAF has none), Format, Availability, Validator with ETag quote normalisation - dr-gpu: wgpu device, compute pass writing a storage texture, resize - dr-ui: Slint shell with FR-UI-1 adaptive layout, computed in Rust to avoid a binding loop - docker/android: pinned toolchain, verified producing API 28 ARM binaries Measured the cost of the temporary CPU readback path (dr-gpu bench): compute is 0.06-0.28ms across sizes while readback is 0.63-7.43ms, so readback is 90-96% of frame time and scales with area. Recorded in ARCH §6.1 — this is why spike S1 is the priority. Mitigations pending S1: reuse the staging buffer, apply at most one resize per frame, and cap render resolution at 2048 on the long edge. 10 tests passing; core crates cross-compile for aarch64-linux-android.
74 lines
2.5 KiB
Markdown
74 lines
2.5 KiB
Markdown
# Android build environment
|
|
|
|
Reproducible container for cross-compiling DarkRoom to Android. CI and local builds use the same
|
|
image, so a break appears in one place rather than two.
|
|
|
|
## Use
|
|
|
|
```bash
|
|
# Cross-compile for a device ABI
|
|
./docker/android/build.sh cargo ndk -t arm64-v8a build --release
|
|
|
|
# All four ABIs
|
|
./docker/android/build.sh cargo ndk -t arm64-v8a -t armeabi-v7a -t x86_64 -t x86 build --release
|
|
|
|
# Type-check without linking
|
|
./docker/android/build.sh cargo check --target aarch64-linux-android
|
|
|
|
# Interactive shell
|
|
./docker/android/build.sh
|
|
|
|
# After editing the Dockerfile
|
|
./docker/android/build.sh --rebuild
|
|
```
|
|
|
|
Prefers `podman`, falls back to `docker`. First run builds the image, which takes several minutes;
|
|
after that it is cached.
|
|
|
|
## Pinned versions
|
|
|
|
| Component | Version | Why this one |
|
|
|---|---|---|
|
|
| JDK | 17 | AGP's stable target. The host's JDK 25 breaks Gradle. |
|
|
| Compile SDK | API 36 | Required for Play distribution |
|
|
| **Min API** | **28** (Android 9) | Floor where Vulkan support is dependable (NFR-COMPAT-1) |
|
|
| Build tools | 36.0.0 | Matches compile SDK |
|
|
| NDK | 27.2.12479018 (r27c) | Current LTS |
|
|
| Rust | 1.92.0 | Slint 1.17 requires it; cargo-ndk 4.1.x needs ≥ 1.86 |
|
|
| cargo-ndk | 4.1.2 | |
|
|
|
|
Bumping any of these is a reviewable change, not silent drift.
|
|
|
|
### Compile SDK versus min API
|
|
|
|
These are different and both matter. `ANDROID_API` (36) is what the SDK compiles against — the
|
|
newest APIs available. `MIN_API` (28) is what native code *links* against, and determines the
|
|
oldest device that can run the result.
|
|
|
|
cargo-ndk defaults to **API 21** if not told otherwise, which is far below what this app needs.
|
|
`CARGO_NDK_PLATFORM` and the per-target linker paths both pin it to `MIN_API`. Verify with:
|
|
|
|
```bash
|
|
file target/aarch64-linux-android/release/*.so
|
|
# → "... for Android 28, built by NDK r27c"
|
|
```
|
|
|
|
## Caching
|
|
|
|
The cargo registry and target directory persist in `~/.cache/darkroom-android`, so rebuilds do not
|
|
re-download the crate index. Clear with:
|
|
|
|
```bash
|
|
rm -rf ~/.cache/darkroom-android
|
|
```
|
|
|
|
The Android target dir is kept separate from the host's `target/` — sharing one directory between
|
|
host and container builds causes constant rebuilds as they invalidate each other's fingerprints.
|
|
|
|
## What is not here
|
|
|
|
No emulator, no `adb` device access. This image cross-compiles; it does not run or deploy. Device
|
|
testing (spikes S2 and S10, which need two GPU vendors) happens on real hardware — the emulator's
|
|
GPU behaviour is not representative of Adreno or Mali, which is precisely what those spikes exist
|
|
to test.
|