Begin with the layer state actually exported
The inspected compiler accepts a 320 × 480 logical scene and a constrained set of layers and effects. It requires a preorder tree with parents preceding children and checks sibling depth ordering. This is a model-layer compiler, not a complete replacement for Apple’s compositor. [image]
Apple distinguishes model values, in-flight presentation values, and private rendering state. Exporting an app’s target layer properties does not automatically reproduce an animation’s current visual state. That distinction matters before calling a bridge “Core Animation support.” [ca]
Placement, bounds origin, and clipping
For the axis-aligned geometry shown, the compiler computes a layer’s top-left from its inherited origin, position, anchor, and size. It then subtracts the layer’s bounds origin when deriving the state inherited by children. Changing bounds origin therefore moves descendants without moving the parent’s outer rectangle. [image]
topLeft = inheritedOrigin + position − anchor × size childOrigin = topLeft − bounds.origin visibleBox = intersection(layerBox, inheritedClip)
Clipping is inherited only when the parent’s clip flag requires it; visibility also propagates from hidden ancestors. The diagram lets you change the bounds origin and clip flag independently. If the orange child moves but the clip stays attached to the parent, the relationship is working as intended.
Opacity is another distinct operation. The inspected path emits BeginGroup and EndGroup commands for supported group opacity, and Android draws the group through saveLayerAlpha. Applying opacity separately to overlapping children can produce a different result. Neither the rectangular diagram nor a generic “draw layers” label demonstrates that behavior. [image], [view]
Backing resources have their own lifetime
Text-mask and color-image resources arrive in framed chunks. The decoder bounds metadata before allocation, requires exact chunk offsets, inflates a complete zlib stream, and checks the uncompressed resource CRC before exposing it. The layer compiler then checks the resource’s sequence, layer identity, dimensions, and supported format. [image]
| Inspected limit | Scope | Why it matters |
|---|---|---|
| 2 MiB | Individual image decoder bounds | Compressed and decoded allocations are bounded |
| 64 resources / 8 MiB | Frame resource set | A small per-image limit alone would not bound a whole frame |
| 32,768 characters | Layer-tree payload | Structure parsing has a separate bound |
| Depth 16 | JSON nesting check | Shape validation precedes scene compilation |
These are validation limits, not a measured process memory budget. Compressed input, decoded bytes, converted pixel arrays, Android bitmaps, and temporary composition surfaces can overlap in lifetime. “Eight megabytes of resources” must not be reported as “eight megabytes of RAM.” [image], [view]
There is also a mode distinction: the socket client constructs its unframed stream with an optional color flag, while GuestFrameDelivery constructs a default stream. In this snapshot the reliable envelope therefore does not simply inherit color support from the socket flag. The supported wire path must accompany a graphics claim. [frame], [view]
A frame crosses several acceptance boundaries
The envelope receiver checks sequence, announced size, contiguous data, final byte count, CRC, and strict inner decoding. It remembers the last accepted payload digest. An identical retry can produce an acknowledgement without a second frame callback; conflicting bytes under that identity are rejected. CRC detects corruption; it is not authentication. [frame]
The socket client schedules the frame callback before queuing the acknowledgement. In the activity, that callback writes a single pending-frame slot and reposts a UI task. A newer frame can replace the pending one before the task executes. Thus “accepted,” “queued to UI,” “drawn,” and “presented” are not synonyms. [view]
Android performs the final drawing and composition
GuestFrameActivity translates to the view center, rotates if requested, scales, translates by the guest center, and clips the guest canvas. Draw commands become Canvas operations for rectangles, text masks, images, and supported opacity groups. The details of that sequence also determine input mapping. [view]
At the Android system level, graphics buffers pass between producers and consumers; SurfaceFlinger composes surfaces with hardware-composer participation. The app’s Canvas call is upstream of physical presentation. A transport ACK does not cover those later boundaries. [android]
Compare a named path against a named reference
The dated checkpoint reports controlled text matches, but also 10 discrepant pixels around a scroll indicator and 721 around a slider in specific settled frames. It records tree construction improving from roughly 109 ms to 10 ms and a roughly 65 ms median capture in one run. These are different measurements; 65 ms capture is not a guaranteed 15 FPS application pipeline. [checkpoint]
The useful experiment names the guest build, fixture, scale, export path, host backend, comparison region, and reference. Keep differences visible. CPU readback is not automatically the reference for every composition effect, and a correct still frame says little about pacing or frame loss during interaction.
References and evidence
Implementation references describe a working-tree snapshot. They are not all present in a public repository. The source inventory records file hashes; historical notes are not new device tests.
- [image] Daybreak, GuestImageResources.kt / GuestLayerCompiler.kt. Inspected working tree, 2026-09-10; same Android directory. Allocation bounds, formats, geometry and supported effects. Private workspace source; collaborator access required.
- [ca] Apple, Core Animation Basics. Archived conceptual guide, especially “Layer Trees Reflect Different Aspects of the Animation State.”
- [view] Daybreak, GuestFrameActivity.kt / GuestSocketClient.kt. Inspected working tree, 2026-09-10; same Android directory. UI scheduling, Canvas operations, reliable/unframed selection, paced input. Private workspace source; collaborator access required.
- [frame] Daybreak, GuestFrameDelivery.kt / GuestLayerStream.kt. Inspected working tree, 2026-09-10; android/app/src/main/java/com/daybreak/host/skia/. Envelope integrity, duplicate handling, frame-local resources. Private workspace source; collaborator access required.
- [android] Android Open Source Project, Graphics architecture. Updated 2025-10-21; buffer transport, SurfaceFlinger and Hardware Composer.
- [checkpoint] Daybreak, iOS Runtime Checkpoint and Next Gate. docs/research/ios-runtime-next.md, updated September 8–9, 2026. Dated evidence, remaining fixture boundary and rendering discrepancies. Private workspace source; collaborator access required.