Skip to content

Commit d0ad3bf

Browse files
committed
chore: merge upstream main
# Conflicts: # docs/STRUCTURE.md
2 parents 81d83ba + 3d82ec2 commit d0ad3bf

31 files changed

Lines changed: 3126 additions & 139 deletions

File tree

‎.github/workflows/esp32p4.yml‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: ESP32-P4 backend
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- ".github/workflows/esp32p4.yml"
7+
- "engine/core/**"
8+
- "engine/backends/esp32p4-ppa/**"
9+
- "hosts/esp32p4/**"
10+
push:
11+
branches: [main]
12+
paths:
13+
- ".github/workflows/esp32p4.yml"
14+
- "engine/core/**"
15+
- "engine/backends/esp32p4-ppa/**"
16+
- "hosts/esp32p4/**"
17+
workflow_dispatch: {}
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
rust:
24+
name: Rust renderer
25+
runs-on: ubuntu-latest
26+
timeout-minutes: 15
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- uses: dtolnay/rust-toolchain@stable
31+
32+
- name: Test RGB565 core rasterizer
33+
run: cargo test --locked --manifest-path engine/core/Cargo.toml
34+
35+
- name: Test ESP32-P4 DrawList backend
36+
run: cargo test --locked --manifest-path engine/backends/esp32p4-ppa/Cargo.toml --features std
37+
38+
- name: Check ESP-IDF Rust adapter
39+
run: cargo check --locked --manifest-path engine/backends/esp32p4-ppa/Cargo.toml --features esp-idf
40+
41+
esp-idf:
42+
name: ESP-IDF release/v6.0
43+
runs-on: ubuntu-latest
44+
timeout-minutes: 30
45+
steps:
46+
- uses: actions/checkout@v4
47+
48+
- name: Build ESP32-P4 component smoke app
49+
uses: espressif/esp-idf-ci-action@v1
50+
with:
51+
esp_idf_version: release-v6.0
52+
target: esp32p4
53+
path: hosts/esp32p4/examples/ppa-smoke

‎contracts/spec/spec.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,11 @@ export const ENUMS = {
496496
// ---------------------------------------------------------------------------
497497
// Values MUST equal rust-psp's TexturePixelFormat (sceGuTexMode arg), as used
498498
// by the dreamcart runtime — verified against rust-psp/psp/src/sys/gu.rs
499-
// (Psm4444 = 2, Psm8888 = 3) and runtime/src/gfx3d.rs psm_for(). v1 supports
500-
// only these two (4444 for baked corner/shadow alpha sprites, 8888 for images).
499+
// (Psm5650 = 0, Psm4444 = 2, Psm8888 = 3) and runtime/src/gfx3d.rs
500+
// psm_for().
501501

502502
export const PSM = {
503+
PSM_5650: 0, // RGB 565, 16-bit (B5:G6:R5 bit order)
503504
PSM_4444: 2, // RGBA 4444, 16-bit
504505
PSM_8888: 3, // RGBA 8888, 32-bit
505506
PSM_T8: 5, // CLUT8: one palette index/px + a 256 x u32 ABGR palette

‎docs/DESIGN.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ artifacts: `$JOB_TMP/map-*.json`).
6060
PSP bin wraps it with QuickJS + sceGu; `wasm32-unknown-unknown` build wraps
6161
it with a deterministic software rasterizer used by BOTH the browser dev
6262
host and headless Bun goldens. One layout engine everywhere.
63+
- **ESP32-P4 stays 16-bit**: `engine/backends/esp32p4-ppa/` consumes the same
64+
DrawList into an opaque RGB565 target. It maps flat fills, A8 coverage
65+
blending, and compatible PSM 5650 texture transforms to the PPA, then
66+
preserves ordering with the core RGB565 rasterizer for unsupported ops.
67+
It never allocates a full-frame RGB888/ARGB8888 intermediate.
6368
- **Native animation**: tweens/springs tick in Rust per vblank with **fixed
6469
dt = 1/60 s** (frame content is a pure function of frame index — this is
6570
what makes byte-exact goldens possible **[R]**). JS only declares motion.

‎docs/STRUCTURE.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ directory; nothing else gets a top-level name.
99
pocketjs/
1010
├─ engine/ Cores: the Rust simulation cores
1111
│ ├─ core/ pocketjs-core — retained UI tree, taffy layout, raster (standalone crate)
12+
│ ├─ backends/ platform render backends (ESP32-P4 PPA is a standalone no_std crate)
1213
│ ├─ wasm/ core compiled to wasm32 for web/sim hosts (standalone crate)
1314
│ ├─ pocket3d/ the 3D core family (bsp, cook, gu, vita) + desktop examples
1415
│ ├─ crates/ non-3D engine crates: pocket-mod, pocket-ui-wgpu, pocket-vrm, pocket-widget
@@ -19,6 +20,7 @@ pocketjs/
1920
│ ├─ psp/ QuickJS + rust-psp EBOOT host
2021
│ ├─ vita/ Vita host
2122
│ ├─ switch/ QuickJS + libnx/Rust NRO host
23+
│ ├─ esp32p4/ reusable ESP-IDF PPA adapter + component smoke build
2224
│ ├─ web/ browser dev host (wasm core)
2325
│ └─ sim/ deterministic headless simulation host (docs/DETERMINISM.md)
2426
├─ framework/ Guest: @pocketjs/framework
@@ -64,7 +66,7 @@ New things go where the axis says — never invent a top-level directory:
6466
- **npm surface is frozen**: `@pocketjs/framework/*` export *keys* never
6567
change; the `exports`/`files` maps in package.json absorb internal moves.
6668
- **Cargo stays non-workspace where toolchains demand it**: `engine/core`,
67-
`engine/wasm`, `hosts/psp`, `hosts/vita`, `hosts/switch`, and the gu/vita 3D
68-
crates each stand alone with their own lockfiles. `engine/Cargo.toml` is the
69-
one desktop workspace.
69+
`engine/wasm`, `engine/backends/esp32p4-ppa`, `hosts/psp`, `hosts/vita`,
70+
`hosts/switch`, and the gu/vita 3D crates each stand alone with their own
71+
lockfiles. `engine/Cargo.toml` is the one desktop workspace.
7072
- **Moves are `git mv`** — history stays traceable.

‎engine/Cargo.toml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
# (docs/RUNTIMES.md: these are the Cores plus their desktop surfaces).
33
#
44
# Deliberately EXCLUDED and standalone (each with its own Cargo.lock):
5-
# core/, wasm/ — cargo-psp needs hosts/psp to consume core as a
6-
# lone standalone crate (see core/Cargo.toml)
5+
# core/, wasm/, backends/esp32p4-ppa/
6+
# — cargo-psp and ESP-IDF need to consume these as
7+
# lone standalone crates (see their Cargo.toml)
78
# pocket3d/crates/pocket3d-gu, gu-demo — PSP-only (cargo-psp toolchain)
89
# pocket3d/crates/pocket3d-vita — Vita-only (vitasdk toolchain)
910
[workspace]
@@ -21,6 +22,7 @@ members = [
2122
"pocket3d/examples/uihost",
2223
]
2324
exclude = [
25+
"backends/esp32p4-ppa",
2426
"core",
2527
"wasm",
2628
"pocket3d/crates/pocket3d-gu",

‎engine/backends/esp32p4-ppa/Cargo.lock‎

Lines changed: 121 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "pocketjs-esp32p4-ppa"
3+
version = "0.1.0"
4+
edition = "2021"
5+
license = "MIT"
6+
publish = false
7+
8+
[dependencies]
9+
pocketjs-core = { path = "../../core" }
10+
11+
[dev-dependencies]
12+
pocketjs-core = { path = "../../core", features = ["std"] }
13+
14+
[features]
15+
default = []
16+
esp-idf = []
17+
std = ["pocketjs-core/std"]
18+
19+
[workspace]
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# PocketJS ESP32-P4 PPA backend
2+
3+
This `no_std` crate interprets PocketJS DrawLists directly into an RGB565
4+
surface. It accelerates operations that map exactly to the ESP32-P4 Pixel
5+
Processing Accelerator and preserves DrawList order with an RGB565 software
6+
fallback for everything else.
7+
8+
The default crate deliberately does not depend on ESP-IDF or a board support
9+
package. Hosts can implement `PpaOps` for another driver or test double.
10+
Enabling the `esp-idf` feature exposes the concrete `EspIdfPpaOps`
11+
implementation, backed by the reusable ESP-IDF component under
12+
[`hosts/esp32p4`](../../../hosts/esp32p4/README.md). Board-specific display
13+
presentation remains in the BSP.
14+
15+
Accelerated paths:
16+
17+
- opaque and translucent flat rectangles (`FILL` or A8 `BLEND`);
18+
- antialiased font runs (`A8` coverage composed once, then `BLEND`);
19+
- single-color alpha textures such as PocketJS rounded-corner masks (`A8`
20+
`BLEND`);
21+
- opaque PSM 5650 texture quads (`SRM`) when scaling semantics are compatible.
22+
23+
Gradients, arbitrary triangles, textured triangles, and unsupported texture
24+
formats fall back to `pocketjs_core::raster::render_scaled_rgb565_over`.
25+
No full-frame RGB888 or ARGB8888 surface is allocated.
26+
27+
## Test
28+
29+
Run the portable renderer and pixel-parity tests on the host:
30+
31+
```sh
32+
cargo test --locked --manifest-path engine/backends/esp32p4-ppa/Cargo.toml \
33+
--features std
34+
```
35+
36+
Compile-check the Rust side of the ESP-IDF adapter without linking an IDF
37+
application:
38+
39+
```sh
40+
cargo check --locked --manifest-path engine/backends/esp32p4-ppa/Cargo.toml \
41+
--features esp-idf
42+
```

0 commit comments

Comments
 (0)