Compositor surfaces are only used for nested navigables now. The
display list command already carries the CompositorSurfaceId, but
playback still resolved that id through DisplayListResourceStorage and
WebContent exposed IPC for direct surface updates and clears.
Keep published child surfaces as PaintingSurface entries on the
compositor ContextState and pass that map into Skia display list
playback. Publishing and detaching nested contexts now update the parent
cache entirely inside the compositor, so WebContent no longer needs
update_compositor_surface or clear_compositor_surface messages.
DisplayListPlayerSkia kept a separate DecodedImageFrameSkiaImageCache
that was pruned during flushes. That made Skia image lifetime
independent of display list resource lifetime, even though resource
storage is what knows when image frames and compositor surfaces are no
longer needed.
Make DisplayListResourceStorage own an opaque stored image-frame
resource that holds the decoded frame and its lazily-created SkImage.
Removing image frames or compositor surfaces now drops the decoded frame
and Skia image together, while transactions still carry only Skia-free
decoded frames.
PaintNestedDisplayList carried both a display list resource id and an
inline copy of that resource's command buffer. Repeated SVG image paints
therefore duplicated the nested command stream in every parent display
list even though resource storage already owns and deduplicates it.
Drop the inline command byte span and replay nested display lists from
the resource table. Resource collection now follows the referenced
resource's command bytes as well, so cached paint data and compositor
transactions keep the same nested resource retention behavior.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/9929
Cached display list command sequences used to carry their own
DisplayListResourceStorage. That kept resource ID sets and referenced
fonts, images, video frames, and nested display lists alive on every
cached phase, even though the command bytes already contain enough
information to discover those references when they are needed.
This makes cached command sequences store only command bytes. Resource
references are collected transiently from those bytes when a cache entry
is installed or invalidated. The navigable's central display list
resource storage now keeps cache reference counts, so compositor pruning
retains resources used by live cached commands without duplicating
storage in each sequence.
Display lists owned the accumulated visual context tree through a
ref-counted pointer. That tied visual-context state to display-list
lifetime and made compositor updates treat the two as one unit, even
though AVC trees need to become independently updateable compositor
state.
Make accumulated visual context trees plain versioned values, have each
display list store the compatible tree version, and pass the matching
tree alongside display-list updates and replay calls. Replay verifies
that the provided tree matches the display list before executing it.
This prepares the compositor for receiving AVC tree updates separately
from display-list updates: it now accepts the tree as a separate update
parameter, stores it next to the display list, and uses that stored tree
for replay and async-scroll hit testing. Nested display-list resources
carry their own tree snapshots for the same version check.
DisplayListRecorder::display_list(), DisplayListResourceStorage's
set_video_frame() and set_display_list(), and
DisplayListRecordingContext's css_viewport_rect() plus the
scale_to_css_{pixels,point,size,rect}() family have no callers.
The compositor IPC path needs to send display-list resources across a
process boundary without losing the resource IDs referenced by
display-list commands. The previous transaction shape carried font and
image-frame objects whose IDs are process-local and would be regenerated
after decoding.
Store explicit IDs with font and image-frame transaction entries and add
IPC serializers that rebuild the resource objects while preserving those
IDs. Fonts now serialize through Gfx::Typeface IPC, image frames use
shareable bitmaps, and video frames keep their existing ID-bearing
transaction entry. This lets the receiver apply the regular transaction
directly.
This is preparatory work required to add IPC between the main and
compositor threads.
Future compositor-process work needs to push video frame updates without
going through VideoFrameSource. That object cannot be shared through
IPC, so video display-list resources now use stable VideoFrameResourceId
values and the current frame is sent through explicit resource/update
commands.
Display lists kept canvas and nested navigable content alive through
ExternalContentSource objects. That made the resource graph depend on
process-local object identity instead of a stable surface handle, which
blocks compositor process isolation and made teardown-sensitive embedded
content harder to reason about.
Allocate CompositorSurfaceId values for canvases and child navigables,
publish their backing stores to the owning compositor, and paint them
with DrawCompositorSurface. Child navigables now publish to parent
compositors by CompositorContextId instead of raw object pointers, so
the in-process path uses the same stable addressing model required by a
remote compositor.
Clear and skip stale child surfaces during teardown, preserve Skia
canvas state while drawing compositor surfaces, and add display-list
coverage for canvas and iframe compositor surfaces. The nested navigable
async-scrolling baseline now expects DrawCompositorSurface.
Display lists used to own the resource storage needed to replay their
command bytes. That kept the compositor tied to in-process object
ownership: sending a display list update also meant sharing the same
resource container with the recording side.
Move resource storage out of DisplayList and make display list updates
carry a transaction of resources to add and remove. Navigable now tracks
the resources referenced by the current display list, sends only the
delta to the compositor, and trims its recording-side storage to the
active set. The compositor applies those transactions to its own storage
before replacing the cached display list.
This still carries in-process resource objects, but it puts the
ownership boundary in the right place. Command bytes and resource
lifetime are now synchronized explicitly, which is the shape needed
before the compositor can receive serializable resource updates across a
process boundary.
Prep work for serializing display lists across the IPC boundary. Replace
Gfx::Filter's Skia-specific backing with a portable Variant-based
representation, add serialize_filter/deserialize_filter, and store
filter data inline in ApplyEffects/ApplyBackdropFilter command payloads
instead of in DisplayListResourceStorage. FilterResourceId is removed
along with the per-storage filter map.
Paint styles were stored as display list resources, which kept path
painting tied to in-process C++ objects. Move the gradient and pattern
payload into FillPath and StrokePath instead, with gradient stops
serialized as parallel color and position spans.
This is prep work for making display lists serializable across the IPC
boundary without needing to marshal SVG paint style objects separately.
Replace Vector<Variant<...>> display-list storage with a contiguous byte
buffer of command headers, trivially-destructible payloads, and inline
data spans. Variable-size data such as glyphs, paths, dash arrays,
gradient stops, and nested command bytes is appended next to the command
that references it.
The flat representation is prep work for sending display lists over IPC
to a dedicated rasterization process, which the previous Variant-based
structure could not support directly. It also avoids walking command
destructors when a display list is discarded and reduces per-command
allocation and indirection, improving memory use and data locality.
Commands used to keep rendering resources directly in the variant:
image frames, external content and video sources, filters, SVG paint
styles, and nested display lists. That makes the command stream own its
dependencies and prevents it from becoming a POD-like byte buffer.
Add DisplayListResourceStorage and replace those command fields with
stable resource IDs. The storage deduplicates resources by their
existing IDs and can copy only the resources referenced by a captured
command sequence, giving the future IPC boundary a clear list of
resources that must be communicated to the rasterization process.