Decides which tiles a viewer draws and when: visible tiles first (each visible page's low-resolution placeholder, then its sharp tiles), then the tiles near the viewport, then the tiles ahead in the scroll direction; cancels work the viewport has left; keeps the tiles on the surface, the tiles being drawn and the document's render caches within one memory budget.
public sealed class TileScheduler : IDisposable
Spec #33 viewer capabilities 1 (tiles from cached display lists), 3 (render-ahead with cancellation) and 13 (one memory budget). ISO 32000-2 §10.7.1 (rendering through display lists).
The shell calls Update(in Viewport) whenever the viewport changes and RunFrame(TimeSpan) once per frame (for example from
requestAnimationFrame) while it returns true. With a cooperative session (the browser, one thread) the
frame does the work itself, in slices of the session's SliceBudget, until the frame's budget is spent:
at most one display-list build runs per frame, and only while no slow build has run in it yet, because a build cannot be
interrupted, so a frame overruns its budget by at most one build. With a background session the frame only plans: it queues up to
MaxConcurrency tile jobs on the thread pool and returns at once, and each job loads its page,
builds or takes its display list, renders and presents on workers, so Present(Tile, Bitmap) and
Evict(Tile) are then called on worker threads too (#357): the UI thread only draws what the surface holds.
A tile of a lower priority starts only once every wanted tile of a higher one is on the surface (or failed), so an off-screen tile never renders before a visible one. A render the viewport has left is cancelled and never reaches the surface. The tiles on the surface are kept (scrolling back shows them without rendering) until the budget needs their bytes: tiles no longer wanted go first, least recently wanted first, then the document's caches are trimmed (TrimCaches(Int64)), then wanted tiles of a lower priority than the one being started. The surface drops evicted tiles in Evict(Tile).
Use from one thread (the UI thread); the background renders it starts take its lock to report back. Disposing it cancels its renders; it does not close the session or clear the surface.
kind:method, kind:property, kind:ctor. Press Esc to clear.TileScheduler(DocumentSession, PageLayout, IRenderSurface, TileSchedulerOptions?)Initializes a new instance of the TileScheduler class.IsIdleGets a value indicating whether every wanted tile is on the surface (or failed), so frames have nothing to do.LayersGets the layers the tiles show (All by default). With SeparateOverlays, the content layer and the annotation and form-field layers are separate tiles, the overlays transparent and drawn over the content tile of the same region.LayoutGets the layout the tiles are cut from.StatisticsGets what the scheduler holds and has done.Dispose()Cancels every render; tiles already on the surface stay there.GetFrame(in Viewport, Span<FramePart>)Lists what a shell draws for viewport from what is on the surface now, before any render for it completes: each visible page's paper, then every tile on the surface that shows in the viewport, stretched or shrunk from its own scale to the viewport's zoom, the sharpest last. A zoom step shows at once this way (scaled tiles, never a blank page) while sharp tiles render at the settled scale.Invalidate(Int32, PdfRectangle, DisplayLayers)Redraws the tiles of a page that show area in layers, after an edit changed what they show (an annotation added, moved or removed, a field's value). A tile on the surface that is still wanted stays there, and in GetFrame(in Viewport, Span<FramePart>), until its redraw replaces it (Invalidated), so the edit never shows a blank frame; one no longer wanted leaves the surface; renders in progress restart.Invalidate(Int32, DisplayLayers)Redraws every tile of a page that shows any of layers.RunFrame(TimeSpan)Does one frame's work: with a cooperative session, draws wanted tiles in priority order until budget is spent; with a background session, starts renders up to the concurrency limit.SetLayers(DisplayLayers)Shows or hides layers: tiles of layers no longer shown leave the surface at once, and the next frames draw only the tiles the new layers add. With SeparateOverlays, toggling the annotation or form-field layer redraws only the overlay tiles; the content tiles stay.SetLayout(PageLayout)Replaces the layout (after a mode, rotation or page-size change): tiles already on the surface stay valid when their page's size is unchanged. The next Update(in Viewport) or RunFrame(TimeSpan) works out the wanted tiles again.Update(in Viewport)Sets the viewport: works out the wanted tiles in priority order and cancels the renders of tiles no longer wanted. The scroll direction (for look-ahead) is the direction of the last change along the layout's strip.