Headless per-frame cost accounting for an animated view tree. More...
#include <pulp/view/plugin_view_host.hpp>#include <pulp/view/view.hpp>#include <algorithm>#include <chrono>#include <cstdint>#include <limits>#include <stdexcept>#include <string>#include <utility>#include <vector>Go to the source code of this file.
Classes | |
| class | pulp::view::FrameCostProbe |
| struct | pulp::view::FrameCostProbe::Frame |
| struct | pulp::view::FrameCostProbe::Summary |
| struct | pulp::view::FrameCostProbe::Budget |
Namespaces | |
| namespace | pulp |
| namespace | pulp::view |
| Hover-cursor tracking for platform window hosts. | |
Headless per-frame cost accounting for an animated view tree.
"Is this animation cheap?" has three answers a wall clock cannot give on its own, and each one is a separate way an animated control goes wrong:
FrameCostProbe attaches a recording PluginViewHost to the root for its lifetime and measures each frame the caller drives (measure(fn)): the damage the frame requested (bounded rect union, or whole surface), the layout passes it ran (View::layout_pass_count) and its wall time. check() holds a Summary to a Budget – optionally relative to a baseline Summary of the same tree without the animation – and returns one line per breach, so a test asserts the list is empty and prints it when it is not.
Damage is classified per REQUEST, not per frame: the recorder takes the pending damage on every repaint() call, and View routes a bounded request through mark_dirty_region() (rect already in the damage) and a rect-less one through mark_dirty_full(). So a frame mixing both is reported full, which is what a partial-repaint host would have to paint.
Headless only: the root must not have a WindowHost (its damage would go there instead). Not thread-safe; drive it from the thread that owns the tree. Pair every passing budget with a negative control that must fail it (a plant that forces full invalidation) – a probe that cannot see damage passes every budget.