| 174 | // --- Stall threshold matrix ------------------------------------------------- |
| 175 | |
| 176 | void testStallThresholdMatrix() |
| 177 | { |
| 178 | struct Case { |
| 179 | const char* name; |
| 180 | double justUnder; |
| 181 | double justOver; |
| 182 | QString expectedStallKind; |
| 183 | std::function<void(double)> trigger; |
| 184 | }; |
| 185 | |
| 186 | // Thresholds duplicated from PerfTelemetry.cpp; if either side drifts, |
| 187 | // these test values must move in lockstep. |
| 188 | const std::vector<Case> cases = { |
| 189 | {"panUpdate stall (8.0 ms)", 7.5, 8.5, QStringLiteral("updateSpectrum"), |
| 190 | [](double v){ PerfTelemetry::instance().recordPanUpdate(v); }}, |
| 191 | {"waterfallUpdate stall (12.0 ms)", 11.0, 13.0, QStringLiteral("updateWaterfallRow"), |
| 192 | [](double v){ PerfTelemetry::instance().recordWaterfallUpdate(v); }}, |
| 193 | {"render stall (16.0 ms)", 15.0, 17.0, QStringLiteral("render"), |
| 194 | [](double v){ PerfTelemetry::instance().recordRender(v); }}, |
| 195 | {"frameAge stall (100.0 ms)", 99.0, 101.0, QStringLiteral("frameAge"), |
| 196 | [](double v){ PerfTelemetry::instance().recordFrameAge(PerfTelemetry::FrameKind::Panadapter, v); }}, |
| 197 | {"udpDrain stall (8.0 ms)", 7.5, 8.5, QStringLiteral("udpDrain"), |
| 198 | [](double v){ PerfTelemetry::instance().recordUdpBatch(1, 100, v); }}, |
| 199 | {"input stall (16.0 ms)", 15.0, 17.0, QStringLiteral("input"), |
| 200 | [](double v){ PerfTelemetry::instance().recordInputEvent("wheel", v); }}, |
| 201 | }; |
| 202 | |
| 203 | qint64 t = 100'000'000'000LL; |
| 204 | for (const auto& c : cases) { |
| 205 | // Below threshold: no stall of this kind. |
| 206 | prime(t); |
| 207 | c.trigger(c.justUnder); |
| 208 | bool sawBelow = false; |
| 209 | for (const auto& line : stallLines()) |
| 210 | if (fieldValue(line, QStringLiteral("kind")) == c.expectedStallKind) |
| 211 | sawBelow = true; |
| 212 | report((std::string(c.name) + " below threshold: no stall").c_str(), !sawBelow); |
| 213 | |
| 214 | // Above threshold: stall fires. |
| 215 | t += 5'000'000'000LL; |
| 216 | prime(t); |
| 217 | c.trigger(c.justOver); |
| 218 | bool sawAbove = false; |
| 219 | for (const auto& line : stallLines()) |
| 220 | if (fieldValue(line, QStringLiteral("kind")) == c.expectedStallKind) |
| 221 | sawAbove = true; |
| 222 | report((std::string(c.name) + " above threshold: stall fires").c_str(), sawAbove); |
| 223 | |
| 224 | t += 5'000'000'000LL; |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | // --- Drag-aware UI lag thresholds ------------------------------------------- |
| 229 | // |
no test coverage detected