You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(core) Add animationsInProgress + layersRendered to onFrameComplete
Extends the onFrameComplete callback payload with animation state so
consumers (notably headless capture pipelines) can tell when a frame is
visually settled vs. when timer-driven animations would change the next
frame.
`animationsInProgress` aggregates three sources:
- layer uniform transitions (existing `Layer#hasUniformTransition`)
- GPU attribute interpolations (new `AttributeManager#hasActiveTransitions`,
delegating to a new `AttributeTransitionManager#isInProgress`)
- viewport transitions (new `Controller#hasActiveTransition`, surfaced
through new `ViewManager#hasActiveTransitions`)
A new `Layer#hasActiveTransitions` aggregates uniform + attribute state
per layer; `LayerManager#hasActiveTransitions` aggregates across layers.
Time-based layer props such as `TripsLayer.currentTime` are intentionally
not tracked — they are driven explicitly by the application each frame.
`layersRendered` exposes the count of layers submitted to the renderer
for the just-finished pass, useful for instrumentation.
Animation state is re-read at fire time so that values reported via the
async GPU-timing poll path reflect the freshest state.
Tests:
- updated existing onFrameComplete tests to assert the new fields
- added a viewport-transition test that confirms animationsInProgress
flips true → false across the lifetime of a flyTo-style transition
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Called after each on-screen frame completes rendering, with CPU and (when supported) GPU timing information. Picking and other off-screen passes do not invoke this callback.
579
+
Called after each on-screen frame completes rendering, with CPU and (when supported) GPU timing information plus animation state. Picking and other off-screen passes do not invoke this callback.
580
580
581
-
This is useful for performance instrumentation, frame-pacing logic, and headless capture pipelines that need to know when the GPU has finished a frame before reading pixels.
581
+
This is useful for performance instrumentation, frame-pacing logic, and headless capture pipelines that need to know when the GPU has finished a frame before reading pixels and whether any animations would change the next frame.
582
582
583
583
Receives a single object argument with:
584
584
585
585
* `cpuTime` (number) - CPU time spent in the deck.gl draw pipeline for this frame, in milliseconds.
586
586
* `gpuTime` (number | null) - GPU time for this frame in milliseconds, when available. `null` if GPU timing is not supported on the current device or the timing query did not resolve in time.
587
587
* `gpuTimingSupported` (boolean) - whether the underlying device exposes the `timestamp-query` feature (WebGL2: `EXT_disjoint_timer_query_webgl2`, WebGPU: `timestamp-query`).
588
588
* `timestamp` (number) - high-resolution `performance.now()` timestamp of when the callback fired.
589
+
* `layersRendered` (number) - the number of layers submitted to the renderer for this frame (includes sub-layers expanded from composite layers).
590
+
* `animationsInProgress` (boolean) - `true` while any timer-driven animation is still running:
- viewport transitions (e.g. `flyTo`/`linearTransition` triggered by setting `transitionDuration`).
594
+
595
+
Time-based layer props such as `TripsLayer.currentTime` are *not* included since they are driven explicitly by the application each frame. For headless video export, treating each frame as independent (no transitions) is preferred — disable layer/viewport transitions in your scene rather than relying on `animationsInProgress` to settle.
589
596
590
597
GPU timing is read asynchronously: the callback may be deferred a few frames while the GPU pipeline flushes. If the timing query does not resolve after a small number of `requestAnimationFrame` polls, `gpuTime` is reported as `null`.
591
598
592
599
Errors thrown from `onFrameComplete` are caught and logged via `log.warn` and do not interrupt the render loop.
593
600
594
-
Example:
601
+
Example — performance instrumentation:
595
602
596
603
```js
597
604
newDeck({
@@ -606,6 +613,19 @@ new Deck({
606
613
});
607
614
```
608
615
616
+
Example — headless capture: wait until animations settle before capturing.
0 commit comments