Commit graph

11 commits

Author SHA1 Message Date
Aliaksandr Kalenik
5c3e61efb6 Compositor: Rasterize nested contexts during replay
Nested compositor contexts used the same vsync scheduling path as
top-level contexts. That made iframe presents depend on a context's own
timer instead of the display refresh rate, and screenshots needed a
separate descendant flush to avoid stale child surfaces.

Keep top-level contexts on vsync, but make nested contexts dirty their
containing context instead of scheduling themselves. When a composited
child surface is resolved, synchronously rasterize the child if it has
a pending frame, using a separate display-list player so recursive
replay does not reuse the active player state. This lets screenshots and
normal presentation share the same child-surface update path.
2026-06-19 17:09:44 +02:00
Aliaksandr Kalenik
d96dc6535f LibWeb+Compositor+WebContent: Simplify nested context composition
Nested navigables were represented through compositor surface ids owned
by the parent context. That forced CompositorState and ContextState to
maintain bidirectional attach/detach bookkeeping, publish child
snapshots into a surface map, and keep presentation mode variants just
to distinguish UI presentation from parent composition.

Record the child compositor context id directly in the display list and
let the compositor resolve it against the painting parent at playback
time. Child contexts now keep their parent context id and latest
rendered surface, while parents no longer track child maps or compositor
surface ids. UI presentation is represented separately from parent
composition, so closing a page only stops client presentation and nested
contexts keep using set_parent_context.
2026-06-18 07:08:34 +02:00
Aliaksandr Kalenik
7ca410c66c LibWeb: Stop storing compositor surfaces as display list resources
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.
2026-06-17 20:20:24 +02:00
Aliaksandr Kalenik
af8b41e1cb LibWeb+Compositor: Add canvas display-list surfaces
Canvas contexts need a compositor-owned surface path that can be shared
by 2D canvas and WebGL. Add CanvasId and a CanvasSurfaceRegistry, pass
the registry into display-list playback, and teach Skia playback how to
resolve and draw a registered canvas surface.

This only adds the shared display-list command and registry plumbing.
Existing canvas elements still publish their old compositor surfaces, so
the behavior change is left for the later canvas-host commits.
2026-06-17 19:07:32 +02:00
Andreas Kling
5a000da13e Compositor: Keep pinch zoom transforms in sync
Preserve fractional pinch focal points when updating the
main-thread visual viewport. Only coalesce queued pinch events
that share the same focal point and modifiers so WebContent sees
a transform equivalent to the event sequence seen by the
compositor.

Also clear a speculative async visual viewport transform once
async wheel or pinch admission becomes blocked. At that point the
compositor can no longer advance that transform to match
WebContent. Use a looser translation tolerance when comparing
visual viewport transforms to account for subpixel differences in
the compositor and main-thread math.
2026-06-16 02:03:59 +02:00
Andreas Kling
a11c281dc3 Compositor: Handle pinch zoom asynchronously
Apply pinch zoom deltas to the compositor's visual viewport transform
so the currently presented display list can respond without waiting for
the WebContent main thread. Keep the normal WebContent pinch event path
so the real VisualViewport state and DOM-visible events catch up after.

Only take the compositor path when async scrolling is enabled and there
are no blocking wheel listeners, since pinch zoom dispatches a synthetic
wheel event that script may cancel. Coalesce queued pinch events in
WebContent so main-thread catch-up can adopt multiple gesture deltas
together.

Use the compositor visual viewport transform for wheel hit testing and
consume wheel deltas as visual viewport pan while zoomed. Scale the
handoff to layout viewport scrolling by the inverse visual viewport
scale, so touchpad momentum does not jump when the visual viewport hits
an edge.
2026-06-16 02:03:59 +02:00
Aliaksandr Kalenik
5572605395 Compositor+LibWeb+WebContent: Add visual context tree update IPC
Display list updates already ship their compatible accumulated visual
context tree to the compositor, but there was no way to replace only the
tree for an existing display list. That kept any visual-context-only
change tied to a full display list update.

Add an update_visual_context_tree IPC path from WebContent through the
Compositor service. ContextState validates that the incoming tree
matches the installed display list's compatible tree version and
rebuilds wheel hit-test targets when async scrolling state is present.
2026-06-03 02:12:39 +01:00
Aliaksandr Kalenik
d015e276cf Compositor: Store async scrolling policy in context state
Async scrolling is enabled or disabled when the compositor process is
created, but ContextState::install_display_list_update() still accepted
that policy on every display-list update. That made the update path look
as if the policy could change between display lists.
2026-05-30 21:52:17 +01:00
Aliaksandr Kalenik
eecc40c2ad Compositor: Construct context state with its owner
ContextState required a WebContent client and page identity before it
could service any compositor context operation, but the refactor kept a
default constructor followed by an initialize() call. That left the type
with an uninitialized state that was not actually used by the creation
path.
2026-05-30 21:52:17 +01:00
Aliaksandr Kalenik
3fe1b97ad0 Compositor: Tighten internal state invariants
Several compositor helpers still treated internally-owned state as
optional after their callers had already established the necessary
preconditions. That made invalid parent/child surface state, screenshot
traversal state, and scrollbar capture indices look like normal no-op
paths.
2026-05-30 21:52:17 +01:00
Aliaksandr Kalenik
894b9098fe Compositor: Extract per-context state handling
CompositorState mixed service-level orchestration with the mutable
state transitions for each compositor context. That made parent context
lookup, vsync scheduling, backing-store lifetime, async scrolling, and
presentation bookkeeping harder to reason about because most helpers
reached directly into ContextState fields.

Move ContextState into its own service file and give it methods for
per-context updates: display-list resource installation, async scroll
state, scrollbar interaction, backing-store resize state, screenshot
painting, and present/ack bookkeeping. CompositorState keeps the
cross-context work: lookup, parent/child surface wiring, vsync
scheduling, async present completion, and client publication.
2026-05-30 21:52:17 +01:00