GlassContentDeclaration enum Cost and policy

Whether the host may hold a proxy that nothing it watches has changed.

Nothing about content is declared here: ProxyLayerWatch reads the host's composited subtree, and this enum is a permission to use that answer.

Why it exists. The retake oracle's staleness ceiling is zero on every measured finish at the default budget, so without a hold the proxy would be re-recorded on every frame, a completely still screen included. That zero is not a defect in the staleness table — the table is about a moving scene, and the branch it gates has just established that nothing the oracle can see changed, where staleness of unchanged content costs nothing.

Why declared is the default. Re-recording a still screen costs most of what the glass adds to a frame: 79.4% and 66.3% on Adreno 830, 97.8% on an M2 iPad Pro. Holding risks only changes the watch cannot see, and the watch reads the composited output, where a repaint cannot hide; the remaining exposure is its table of layer types, which a test checks against the SDK's layer.dart. The watch itself costs under 3 µs a frame.

Passed to GlassHost.content. The default needs nothing written; the opt-out is for a host that composites through something the watch cannot read, or for measuring the capture:

GlassHost(
  content: GlassContentDeclaration.undeclared, // re-record every frame
  child: const MyScreen(),
)

See also:

Inheritance
Available extensions

Values

undeclared → const GlassContentDeclaration

Assume anything may have changed since the last frame, and re-record.

"Distrust the watch": the proxy is re-recorded on every frame regardless of what the composited subtree says. It is the most expensive thing this package can be asked to do — the capture is 77% of what the glass adds to a frame on a dpr-2 screen (M2 iPad Pro) — and it is worth asking for in exactly two situations: a host that composites through a layer type it has reason to think this package misreads, and a benchmark that wants the capture measured on every frame.

declared → const GlassContentDeclaration

Hold a clean proxy, and let the watch decide what "clean" means.

The default. Under it a clean proxy is held indefinitely: the ceiling is not consulted at all, because a picture that did not change costs nothing to be a frame old, and consulting a table measured on a moving scene would return zero and undo the whole thing.

This is a permission and not a promise. The application does not vouch for its content: a realistic screen crosses 8 to 15 nested repaint boundaries, and no application could verify all of them. What decides is ProxyLayerWatch, which reads the host's composited subtree rather than its render tree — a repaint cannot hide from the layer that owns it, and the one change that repaints nothing is a property of a retained layer.

What is left for the application to say is nothing about its content. The one input that is still a declaration is what a GlassProxy marker says, and that is not about pixels: a marker changing role changes what the capture would draw while the screen stays exactly as it was. GlassProxyHandle.noteChange remains as the imperative override for anything an application knows and the composited output does not.

What the host still cannot see, it refuses to hold through rather than believing anybody: a Texture, a platform view and any layer type the watch's table has never met read as changing on every frame. That refusal is what makes this a safe default rather than an optimistic one, and it is why the table it stands on is checked against the SDK's own layer.dart.

The watch says where, so the hold does not need the screen to be still — only the glass to be missed. ProxyLayerWatch returns a region, and the host compares it against what the atlas actually holds; a change that reaches no slot is held through. On a screen with one spinner turning 500 logical pixels from a glass bar, that is one capture in a 30-second window against one per frame, and the frame is 6.5-10.2% cheaper for it; the same spinner inside the bar captures on every frame, and the saving disappears (Xclipse 920, provenance/digest/s22u-aside-{a,b}.json). With the spinner away from the glass, the frame costs the same as the screen with no glass in it, within the device's noise.

The bound is never tighter than the nearest enclosing repaint boundary — PictureLayer.canvasBounds is the boundary's bounds and not the picture's — so this pays where the change sits in a nested boundary that misses the glass, and not otherwise. How common that is, is a property of the application's tree.

Properties

hashCode → int
The hash code for this object.
no setterinherited
index → int
A numeric identifier for the enumerated value.
no setterinherited
name → String

Available on Enum, provided by the EnumName extension

The name of the enum value.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Constants

byDefault → const GlassContentDeclaration
What a host uses when the application says nothing.
values → const List<GlassContentDeclaration>
A constant List of the values in this enum, in order of their declaration.