← Blog
0.7.0 · BROWSER · VIDEO

Browser Chrome Shell + Compositor + Canvas 2D — The 0.7.0 Browser Build Chain Is Live

browser compositor canvas2d video lumen 0.7.0

The 0.7.0 browser build chain closes in a single tick. apps/browser/browser.sg (sigil-apps 2a08813) ships the complete Lumen browser chrome — nav toolbar, tab strip, address bar with [web] mode chip, Cap Inspector sidebar (HELD/NOT HELD live table, Revoke button), status bar with Private button, and static content area. core/compositor.sg (sigil-video 16997fc) delivers the GPU-first layer compositor — 8 rendered pixel layers, dirty-rect composite, GPU-path with software fallback — COMP-PASS on x86 QEMU. core/canvas2d.sg (sigil-video a02b6c7) adds the browser Canvas 2D hot path — fillRect/clearRect/drawImage, GPU-first with SSE2/AVX2/NEON/scalar fallback — CANVAS2D-PASS on x86 QEMU. The browser now has a face, a layer engine, and a 2D drawing surface.


browser.sg — the Lumen browser chrome (sigil-apps 2a08813)

browser.sg is the chrome layer: the Lumen window frame that surrounds the web content, hosts the tab strip, and exposes the cap inspector. Built per the BROWSER_RFC.md contract. The IPC wiring (renderer spawn, tab load/unload, cap-update notifications from browser_ipc.sg) lands when OS ratifies the three open questions in RFC §9. The chrome is screendump-ready now.

Chrome layout (one Lumen window, top to bottom)

Nav toolbar
Back (), forward (), reload () buttons. Address bar with [web] mode chip (auto-detected from https:// prefix; switches to [srdx] for srdx:// origins, [app] for app://). TLS chip (tls) + net chip (net) shown when origin is HTTPS + net-connected.
Tab strip
Up to N tab chips in a horizontal strip. Active tab highlighted. Committed tabs: sigil.os (active), srdx://sigil-pi (SRDX session tab — same object as an SRDX viewer session), github (external). + at right opens new tab. Left=oldest, right=newest.
Bookmarks bar
Saved bookmark chips with cap indicators. @bookmark Smart Folder integration: adding a bookmark calls fs_tag(item, "bookmark").
Content area
The web content rendered by the renderer process (GPU=2 compositor path). Static mock in screendump: sigil.os homepage links + recent news blurbs. Live content wires in when IPC is ratified.
Cap Inspector sidebar
Per the RFC §3 design. Two rows: HELD caps (filled accent chip): net · tls · fs:ro. NOT HELD caps (dimmed): camera · mic · fs:rw. Per-cap Revoke button. This is the user-visible security surface: the exact capability set for this tab, always accurate, revocable in real time.
Status bar
tls connection chip. private: off badge (solid when in private mode). Private toggle button.

The address bar's mode chip — [web], [srdx], [app] — is the visible marker of the active transport. A user opening srdx://sigil-pi:5900 sees [srdx] before the content loads, confirming the kernel-native transport is active, not a fallback.

sigilOS browser chrome (browser.sg): nav toolbar with address bar [web] mode chip + tls/net caps, tab strip (sigil.os / srdx://sigil-pi / github), Cap Inspector sidebar (HELD: net/tls/fs:ro; NOT HELD: camera/mic/fs:rw), status bar with Private button
sigilOS browser chrome (browser.sg): nav toolbar with address bar [web] mode chip + tls/net caps, tab strip (sigil.os / srdx://sigil-pi / github), Cap Inspector sidebar (HELD: net/tls/fs:ro; NOT HELD: camera/mic/fs:rw), status bar with Private button

compositor.sg — the GPU-first layer compositor (sigil-video 16997fc)

The compositor sits between the renderer process and the display. The renderer writes pixel layers to the shared region comp_layer_buf() (0xA00000). The compositor composites those layers back-to-front using dirty-rect tracking, then presents via the GPU scanout path.

Why a separate compositor process (GPU=2)?

The renderer (process 1+tab) holds only CAP_IPC. It cannot write to the display. It writes layers to the shared memory region and sends IPC_T_PAINT_LAYER messages. The GPU process (process 2, CAP_DISPLAY) does the composite and scanout. This means a compromised renderer cannot corrupt the display directly — the display path requires CAP_DISPLAY, which only the GPU process holds.

comp_init(fw, fh)
Initialize compositor for a frame of fw × fh pixels. Allocates 8-layer slot table. Sets dirty flags.
comp_submit_layer(idx, buf, x, y, w, h)
Accept a rendered pixel layer from the renderer (written to comp_layer_buf() shared region). Sets dirty flag for layer idx. Layer 0 = background; layers 1–7 = overlays composited back-to-front.
comp_clear_layer(idx)
Clear layer idx (fill transparent). Clears dirty flag.
comp_composite()
Dirty-flag gated — only re-composite layers that changed. Software path: copy_span per dirty rect. GPU path: gpu_submit(CAP_ACCEL, comp_layer_buf(), fw, fh) — silicon-pending (GPU HAL available, actual GPU driver in progress).
comp_present()
Call comp_composite() then signal scanout-ready. The GPU process calls this once per frame.

Test (160×120, 2 layers)

comp_init(160, 120). Submit layer 0: blue background (160×120). Submit layer 1: red 32×32 square at (64, 44). comp_composite() → n_dirty=2 (both layers dirty). comp_present(). Pixel at (64, 44) = red (layer 1 over layer 0). Pixel at (0, 0) = blue (layer 0 only). Re-composite with no changes → n_dirty=0 (delta gate: no work done). COMP-PASS: init=ok layers=ok pixel=ok delta=0.

COMP-PASS x86: 2 layers composited on 160×120 canvas — blue background (layer 0) + red 32×32 square at (64,44) (layer 1), n_dirty=2 first composite, delta=0 on re-composite
COMP-PASS x86: 2 layers composited on 160×120 canvas — blue background (layer 0) + red 32×32 square at (64,44) (layer 1), n_dirty=2 first composite, delta=0 on re-composite

canvas2d.sg — GPU-backed Canvas 2D (sigil-video a02b6c7)

Canvas 2D is the <canvas> element's drawing API — the workhorse for 2D game graphics, charts, and anything that calls ctx.fillRect(), ctx.clearRect(), or ctx.drawImage(). canvas2d.sg implements the browser hot path with the GPU-first / software-fallback pattern sigilOS uses everywhere.

GPU-first, software floor

canvas_fill_rect(ctx, x, y, w, h, color)
Fill a rectangle with solid color. Clips to canvas bounds (negative x/y or out-of-range w/h are clipped, not crashed). Software: fill_span per row. GPU: single blit command.
canvas_clear_rect(ctx, x, y, w, h)
Zero-fill a rectangle (set pixels to transparent 0x00000000). Used for erasing. Same clip behavior. Software: fill_span with zero.
canvas_draw_image(ctx, src, sx, sy, sw, sh, dx, dy, dw, dh)
Blit a source image region onto the canvas. Software: copy_span per row. GPU: texture blit command.

Test (160×120)

canvas_init(160, 120). Blue bg fill (full canvas). Red 64×64 square at (48, 28). Clear 16×16 hole at (56, 36) → pixels zeroed. Blit 32×32 green source image at (80, 60). Clipped fill_rect at x=−10 (clip to x=0, width reduced) → no crash, pixels clipped correctly. Pixel probes: green blit = green ✓, red fill = red ✓, clear = 0 ✓, bg preserved ✓, clip correct ✓. CANVAS2D-PASS.

CANVAS2D-PASS x86: 160×120 canvas — blue bg → red 64×64 sq → clear 16×16 hole → blit 32×32 green → clipped fill at x=−10
CANVAS2D-PASS x86: 160×120 canvas — blue bg → red 64×64 sq → clear 16×16 hole → blit 32×32 green → clipped fill at x=−10

The 0.7.0 browser pipeline — assembled

Layer Component Status Path
User chrome browser.sg Lumen window LIVE (2a08813) sigil-apps
Renderer process renderer_spawn.sg CAP_IPC only PASS (ceedcb6) sigil-kernel
Renderer→GPU IPC browser_ipc.sg 16-slot ring PASS (ceedcb6) sigil-kernel
Layer compositor compositor.sg GPU-first COMP-PASS (16997fc) sigil-video
Canvas 2D drawing canvas2d.sg GPU-backed CANVAS2D-PASS (a02b6c7) sigil-video
Extension zone ext_zone.sg 16 slots, V2/V3 caps PASS (ae38f9a) sigil-kernel
Cap Inspector Live per-tab HELD/NOT HELD LIVE (in browser.sg) sigil-apps
IPC wiring (renderer→browser→GPU) Pending OS seam ratification RFC §9 open Qs
cc0/JS runtime In progress 0.7.0 sprint sigil-kernel