Skip to main content

Module scroll_copy

Module scroll_copy 

Expand description

Scrolling by copying the pixels that stay on screen.

A scroll moves every pixel of a scroller’s content, so damage alone repaints its whole viewport on every frame of a scroll. When the content moved by a pure translation since the frame the host last presented, most of those pixels are already in the host’s retained target, one delta away.

A scroller says so from its collect_damage (offer) instead of damaging its viewport: where its content paints, how far it moved, and what it paints over its content that does not move with it (a scroll bar, an edge fade). A host that keeps the last frame’s pixels collects damage inside accepting; any other host gets the viewport damage as before, because offer answers false there.

The host then plans each offer (plan) against the widget tree it just drew: the copy is clipped by every ancestor’s child clip and kept to whole device pixels; a delta that is not a whole number of device pixels, or a scroller drawn under another transform than the window’s, is refused (the viewport is damaged instead). What may paint over or under the content without moving with it is damage: the scroller’s own overlays, every other widget whose box (with its effect reach) reaches into the viewport, and the edges of every ancestor and of every frame that holds the viewport (a border or an inset shadow drawn over children). Damage a copy reads, those overlays and whatever else changed in place this frame, is carried to where the copy lands (carry), and what the copy exposed is repainted. The renderer copies first (encode_copies, or copy_pixels on a CPU canvas), then rasterizes the damage.

A relayout’s moves are checked against the offers ([moves_besides]): content that moved by its scroller’s delta is the copy’s; content that came, went or stayed put (a long list mounting rows, a pinned title, a sticky header) is damage; anything else that moved makes the host repaint as it would without copies.

Structs§

CopyPlan
What a host does with a frame’s offers, in device pixels: the copies, in order; the damage they add where something does not move with the content (each copy’s overlays, a refused offer’s viewport), which the host carries along with the rest of its damage (carry); and what the copies exposed, repainted as it is.
CopyScratch
A target’s scratch space for copies within it, which a copy cannot do in place: WebGPU refuses a copy whose source and destination are the same texture’s same subresource. Each copy moves through it in bands of at most [BAND] rows, so it holds a band, not a viewport.
DeviceCopy
One planned copy within a host’s retained target, in device pixels: the source rectangle, and how far it moves.
HostCopies
While held, every crate::app::EmbeddedApp drawn on this thread is drawn for a host that presents each frame over the pixels it last presented and can move them, as crate::app::EmbeddedApp::set_accepts_scroll_copies says; an app that learned so keeps handing out copies, which a host that cannot make them repaints where they land.
MovedRegion
A copy as a host that composites the target elsewhere sees it: the rectangle it reads and how far it moves it, in the coordinates of the scene the target is drawn into (an embedded app’s region in a desktop section), before that scene is rasterised.
ScrollOffer
A scroller’s claim that, since the frame its host last presented, its content moved by a pure translation within an unchanged viewport.

Constants§

EFFECT_REACH
How far outside its layout box a widget may paint: anti-aliasing, a shadow, a hover lift. The native window grows every widget’s damage by as much, in logical pixels.

Functions§

accepting
Run collect (a widget tree’s collect_damage) with scroll copies accepted, and return what the scrollers in it offered instead of damaging their viewports. Only a host that presents over its last frame’s pixels and copies each planned offer (plan, encode_copies) may call it.
carried
Where copies take the pixels rects cover (device pixels): each piece of a rect a copy reads, one delta away.
carry
Add to damage (device pixels, where a frame differs from the last in place) where copies take what it covers: a pixel that changed in place and that a copy moves lands, stale, one delta away. Everything but what the copies exposed goes through here, the overlays the plan found included.
copy_pixels
Apply copies to pixels, a width-pixel-wide RGBA8 image whose rows are stride bytes apart, in order. Returns false, changing nothing, when a copy would leave the image.
drawing_into_cache
Record draw into a cache its caller then appends with transform (a container that draws its children at the identity into a retained scene): a scroller drawn inside learns where its content lands on screen (on_screen).
encode_copies
Record copies within texture, in order, each through scratch. Returns false, recording nothing, when a copy would leave the texture: the caller must then repaint the target whole.
host_copies
Whether the host drawing now copies (HostCopies).
host_device_scale
How many pixels of the target of the host drawing now one unit of its scene is (HostCopies::begin_scaled); 1 outside any.
marks_over_copies
Add to damage what marks painted over a window’s content without moving with it, and unseen by the planner (collaborators’ pointers and names), cost its copies (device pixels, as each would be repainted): the target holds the marks of the frame on screen (shown), which a copy moves with the content, stale, one delta away; and this frame’s marks (painted) must be repainted wherever a copy wrote under them. Where a mark changed in place is the frame’s other damage, carried with it (carry).
offer
From a scroller’s collect_damage: offer to have its host copy what of its content stays on screen. viewport is where the content paints, delta how far it moved on screen since the frame the host last presented, and overlays what the scroller paints over its content that does not move with it, all in logical pixels; transform is the one its content landed on screen with this frame (on_screen). The scroller must still damage whatever inside its content changed besides moving.
on_screen
Where transform, the one a widget draws with, lands on screen: through every cache being recorded around it.
plan
Plan offers against the trees under roots just drawn (the app’s, then any the window draws beside it, such as History’s toolbar), at scale device pixels per logical pixel, for a width × height target: each becomes a copy and the damage around it, or, when it cannot be copied exactly, damage over its whole viewport.
plan_scaled
plan for a window drawn at drawn_scale scene pixels per logical pixel into a host target of device_per_scene pixels per scene pixel (an app drawn into a desktop’s logical scene, shown at 200 %): the plan is in those device pixels, for a width × height target of them.