77 double max_p95_ms = std::numeric_limits<double>::infinity();
89 : root_(root), recorder_(surface) {
91 throw std::logic_error(
92 "FrameCostProbe: the root has a WindowHost; its damage would not "
103 root_.set_plugin_view_host(previous_);
112 const auto t0 = std::chrono::steady_clock::now();
113 std::forward<Fn>(frame)();
114 const auto t1 = std::chrono::steady_clock::now();
116 f.
ms = std::chrono::duration<double, std::milli>(t1 - t0).count();
117 f.full_damage = recorder_.full > 0;
118 f.has_bounds = recorder_.have;
119 f.damage = recorder_.uni;
120 f.repaint_requests = recorder_.full + recorder_.bounded;
121 f.frame_requests = recorder_.frames_only;
123 frames_.push_back(
f);
124 return frames_.back();
127 const std::vector<Frame>&
frames()
const {
136 s.
frames =
static_cast<int>(frames_.size());
139 std::vector<double> ms;
140 ms.reserve(frames_.size());
143 bool have_union =
false;
144 for (
const auto&
f : frames_) {
147 ++
s.full_damage_frames;
148 if (
f.layout_passes > 0)
150 if (
f.repaint_requests > 0)
153 area +=
static_cast<double>(
f.damage.width) *
f.damage.height;
155 s.damage_union = have_union ? unite(
s.damage_union,
f.damage) :
f.damage;
159 std::sort(ms.begin(), ms.end());
160 s.p50_ms = ms[ms.size() / 2];
161 s.p95_ms = ms[std::min(ms.size() - 1, ms.size() * 95 / 100)];
162 s.max_ms = ms.back();
163 s.mean_damage_area = area_frames > 0 ? area / area_frames : 0.0;
170 std::vector<std::string> breaches;
172 breaches.push_back(
"positive control: only " + std::to_string(
s.painted_frames) +
173 " frames painted (need " +
175 "); the run measured nothing");
177 breaches.push_back(std::to_string(
s.full_damage_frames) +
"/" +
178 std::to_string(
s.frames) +
179 " frames requested a whole-surface repaint");
181 breaches.push_back(std::to_string(
s.layout_frames) +
"/" + std::to_string(
s.frames) +
182 " frames ran a layout pass");
184 breaches.push_back(
"mean bounded damage " + std::to_string(
s.mean_damage_area) +
188 breaches.push_back(std::string(
baseline ?
"p95 grew " :
"p95 ") +
189 std::to_string(grown) +
" ms (budget " +
196 const float x0 = std::min(
a.x,
b.x), y0 = std::min(
a.y,
b.y);
197 return {x0, y0, std::max(
a.x +
a.width,
b.x +
b.width) - x0,
198 std::max(
a.y +
a.height,
b.y +
b.height) - y0};
201 class Recorder final :
public PluginViewHost {
203 explicit Recorder(Size size) : size_(size) {}
204 int full = 0, bounded = 0, frames_only = 0;
221 const auto snap =
damage_.take();
222 if (snap.is_bounded()) {
224 uni = have ? unite(uni, snap.bounds()) : snap.
bounds();
230 void set_size(std::uint32_t
w, std::uint32_t
h)
override {
241 full = bounded = frames_only = 0;
252 PluginViewHost* previous_ =
nullptr;
253 std::vector<Frame> frames_;
FrameCostProbe & operator=(const FrameCostProbe &)=delete
FrameCostProbe(View &root, PluginViewHost::Size surface={})
Attach a recording host to root for the probe's lifetime.
Definition frame_cost_probe.hpp:88
Summary summary() const
Definition frame_cost_probe.hpp:134
const std::vector< Frame > & frames() const
Definition frame_cost_probe.hpp:127
FrameCostProbe(const FrameCostProbe &)=delete
static std::vector< std::string > check(const Summary &s, const Budget &budget, const Summary *baseline=nullptr)
One human-readable line per breach of budget; empty when within it.
Definition frame_cost_probe.hpp:168
~FrameCostProbe()
Definition frame_cost_probe.hpp:102
const Frame & measure(Fn &&frame)
Run one frame's work and record what it cost.
Definition frame_cost_probe.hpp:109
void clear()
Definition frame_cost_probe.hpp:130
virtual Size get_size() const =0
virtual void request_frame()
A frame without damage (see WindowHost::request_frame()).
Definition plugin_view_host.hpp:244
virtual NativeViewHandle native_handle()=0
PendingDamage damage_
Definition plugin_view_host.hpp:254
WindowHost * window_host() const
Definition view.hpp:2454
static std::uint64_t layout_pass_count() noexcept
Definition view.hpp:883
void layout_children_if_needed()
Lay out only when a geometry mutation has happened since this root's last completed pass.
Definition view.hpp:369
PluginViewHost * plugin_view_host() const
Definition view.hpp:2461
virtual void set_plugin_view_host(PluginViewHost *host)
Back-reference to the PluginViewHost that owns this editor tree.
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ s
Definition input_events.hpp:41
@ a
Definition input_events.hpp:39
@ h
Definition input_events.hpp:39
@ f
Definition input_events.hpp:39
@ b
Definition input_events.hpp:39
@ w
Definition input_events.hpp:41
@ bounds
Definition waveform_editor_primitives.hpp:192
@ baseline
Definition geometry.hpp:370
void * NativeViewHandle
Definition native_view_host.hpp:19
Definition frame_cost_probe.hpp:74
double max_mean_damage_area
Definition frame_cost_probe.hpp:80
int max_layout_frames
Definition frame_cost_probe.hpp:79
int max_full_damage_frames
Definition frame_cost_probe.hpp:78
int min_painted_frames
Positive control: a run that painted fewer frames than this measured nothing, and is reported as a br...
Definition frame_cost_probe.hpp:83
double max_p95_ms
Absolute p95 ceiling, or (with a baseline) the most the p95 may grow over the baseline's p95.
Definition frame_cost_probe.hpp:77
Definition frame_cost_probe.hpp:54
Rect damage
union of the bounded requests
Definition frame_cost_probe.hpp:58
int frame_requests
frames requested without damage
Definition frame_cost_probe.hpp:60
std::uint64_t layout_passes
layout_children() calls the frame ran
Definition frame_cost_probe.hpp:61
bool has_bounds
bounded damage was requested
Definition frame_cost_probe.hpp:57
int repaint_requests
damage-marking requests the frame caused
Definition frame_cost_probe.hpp:59
double ms
wall time of the frame's work
Definition frame_cost_probe.hpp:55
bool full_damage
some request repainted the whole surface
Definition frame_cost_probe.hpp:56
Definition frame_cost_probe.hpp:64
double p50_ms
Definition frame_cost_probe.hpp:66
double max_ms
Definition frame_cost_probe.hpp:66
Rect damage_union
union of every frame's bounded damage
Definition frame_cost_probe.hpp:71
double mean_damage_area
mean bounded area over painted frames
Definition frame_cost_probe.hpp:70
int full_damage_frames
frames with any whole-surface request
Definition frame_cost_probe.hpp:67
int layout_frames
frames that ran at least one layout pass
Definition frame_cost_probe.hpp:68
int painted_frames
frames that requested any repaint at all
Definition frame_cost_probe.hpp:69
double p95_ms
Definition frame_cost_probe.hpp:66
int frames
Definition frame_cost_probe.hpp:65
Definition plugin_view_host.hpp:66
Axis-aligned rectangle in continuous (float) coordinates.
Definition geometry.hpp:52