Live anti-aliasing knobs — MSAA sample count, SSAA render scale and alpha-to-coverage apply at the next frame boundary, so the effect is visible immediately while hunting for the shipped default. Live frame-phase breakdown from the always-on FrameProfiler ring (World::Simulate marks setup/draw/hud/ai+veh/sound/swap each frame).
| 1385 | // visible immediately while hunting for the shipped default. |
| 1386 | // Live frame-phase breakdown from the always-on FrameProfiler ring |
| 1387 | // (World::Simulate marks setup/draw/hud/ai+veh/sound/swap each frame). |
| 1388 | void DrawPerfTab() |
| 1389 | { |
| 1390 | Dev::FrameProfiler& perf = Dev::GFrameProfiler(); |
| 1391 | const int frames = perf.FrameCount(); |
| 1392 | if (frames == 0) |
| 1393 | { |
| 1394 | ImGui::TextDisabled("no frames recorded yet"); |
| 1395 | return; |
| 1396 | } |
| 1397 | |
| 1398 | const Dev::FrameProfiler::PhaseStats total = perf.TotalStats(); |
| 1399 | ImGui::Text("FPS %.1f", perf.AvgFps()); |
| 1400 | ImGui::SameLine(); |
| 1401 | ImGui::TextDisabled("frame %.2f ms avg / %.2f p95 / %.2f max (last %d frames)", total.avgMs, total.p95Ms, |
| 1402 | total.maxMs, frames); |
| 1403 | |
| 1404 | static float history[Dev::FrameProfiler::kRingSize]; |
| 1405 | const int n = frames; |
| 1406 | for (int i = 0; i < n; i++) |
| 1407 | history[i] = perf.Frame(n - 1 - i).totalMs; // oldest → newest |
| 1408 | ImGui::PlotLines("##frametimes", history, n, 0, "frame ms", 0.f, total.maxMs * 1.2f, ImVec2(-1, 64)); |
| 1409 | |
| 1410 | if (ImGui::BeginTable("phases", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) |
| 1411 | { |
| 1412 | ImGui::TableSetupColumn("phase"); |
| 1413 | ImGui::TableSetupColumn("avg ms"); |
| 1414 | ImGui::TableSetupColumn("p95 ms"); |
| 1415 | ImGui::TableSetupColumn("max ms"); |
| 1416 | ImGui::TableSetupColumn("% frame"); |
| 1417 | ImGui::TableHeadersRow(); |
| 1418 | for (int p = 0; p < Dev::FrameProfiler::PhaseCount; p++) |
| 1419 | { |
| 1420 | const auto s = perf.Stats(static_cast<Dev::FrameProfiler::Phase>(p)); |
| 1421 | ImGui::TableNextRow(); |
| 1422 | ImGui::TableNextColumn(); |
| 1423 | ImGui::TextUnformatted(Dev::FrameProfiler::PhaseName(p)); |
| 1424 | ImGui::TableNextColumn(); |
| 1425 | ImGui::Text("%.2f", s.avgMs); |
| 1426 | ImGui::TableNextColumn(); |
| 1427 | ImGui::Text("%.2f", s.p95Ms); |
| 1428 | ImGui::TableNextColumn(); |
| 1429 | ImGui::Text("%.2f", s.maxMs); |
| 1430 | ImGui::TableNextColumn(); |
| 1431 | ImGui::Text("%.0f%%", total.avgMs > 0.001f ? 100.f * s.avgMs / total.avgMs : 0.f); |
| 1432 | } |
| 1433 | ImGui::EndTable(); |
| 1434 | } |
| 1435 | ImGui::Text("draw calls %.0f avg", perf.AvgDrawCalls()); |
| 1436 | ImGui::SameLine(); |
| 1437 | if (ImGui::Button("Reset window")) |
| 1438 | perf.Reset(); |
| 1439 | } |
| 1440 | void DrawRenderTab() |
| 1441 | { |
no test coverage detected