10#include "imgui/imgui.h"
28 auto now = std::chrono::high_resolution_clock::now();
29 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
45 ImGui::Begin(
"Graphics Performance Dashboard", &
visible_);
87 }
else if (score >= 70) {
89 }
else if (score >= 50) {
97 summary.
recommendations.push_back(
"Enable palette lookup optimization");
119 std::ostringstream report;
121 report <<
"=== YAZE Graphics Performance Report ===\n";
122 report <<
"Generated: "
123 << std::chrono::system_clock::now().time_since_epoch().count()
127 report <<
"Current Performance Metrics:\n";
128 report <<
" Frame Time: " << std::fixed << std::setprecision(2)
130 report <<
" Palette Lookup: "
132 report <<
" Texture Updates: "
134 report <<
" Batch Operations: "
136 report <<
" Memory Usage: " << std::fixed << std::setprecision(2)
138 report <<
" Cache Hit Ratio: " << std::fixed << std::setprecision(1)
142 report <<
" Texture Updates/Frame: "
146 report <<
"Optimization Status:\n";
147 report <<
" Palette Lookup: "
149 report <<
" Dirty Region Tracking: "
152 report <<
" Resource Pooling: "
154 report <<
" Batch Operations: "
156 report <<
" Atlas Rendering: "
158 report <<
" Memory Pool: "
163 report <<
"Performance Summary:\n";
164 report <<
" Optimization Score: " << summary.optimization_score <<
"/100\n";
165 report <<
" Status: " << summary.status_message <<
"\n";
167 if (!summary.recommendations.empty()) {
168 report <<
"\nRecommendations:\n";
169 for (
const auto& rec : summary.recommendations) {
170 report <<
" - " << rec <<
"\n";
178 ImGui::Text(
"Performance Metrics");
180 ImGui::Columns(2,
"MetricsColumns");
183 ImGui::Text(
"Palette Lookup: %s",
185 ImGui::Text(
"Texture Updates: %s",
187 ImGui::Text(
"Batch Operations: %s",
193 ImGui::Text(
"Cache Hit Ratio: %.1f%%",
196 ImGui::Text(
"Texture Updates/Frame: %d",
203 ImGui::Text(
"Optimization Status");
205 ImGui::Columns(2,
"OptimizationColumns");
207 ImGui::Text(
"Palette Lookup: %s",
210 :
"✗ Not Optimized");
211 ImGui::Text(
"Dirty Regions: %s",
216 "Resource Pooling: %s",
221 ImGui::Text(
"Batch Operations: %s",
224 ImGui::Text(
"Atlas Rendering: %s",
235 ImGui::Text(
"Optimization Score: %d/100", summary.optimization_score);
238 float progress = summary.optimization_score / 100.0F;
239 ImGui::ProgressBar(progress, ImVec2(-1, 0), summary.status_message.c_str());
243 ImGui::Text(
"Memory Usage");
248 std::vector<float> float_history;
251 float_history.push_back(
static_cast<float>(value));
254 ImGui::PlotLines(
"Memory (MB)", float_history.data(),
255 static_cast<int>(float_history.size()));
259 ImGui::Text(
"Memory Pool: %s / %s",
FormatMemory(used_bytes).c_str(),
263 total_bytes > 0 ?
static_cast<float>(used_bytes) / total_bytes : 0.0F;
264 ImGui::ProgressBar(pool_usage, ImVec2(-1, 0),
"Memory Pool Usage");
268 ImGui::Text(
"Atlas Renderer: %d atlases, %d/%d entries used",
269 atlas_stats.total_atlases, atlas_stats.used_entries, atlas_stats.total_entries);
270 ImGui::Text(
"Atlas Memory: %s",
FormatMemory(atlas_stats.total_memory).c_str());
272 if (atlas_stats.total_entries > 0) {
273 float atlas_usage =
static_cast<float>(atlas_stats.used_entries) / atlas_stats.total_entries;
274 ImGui::ProgressBar(atlas_usage, ImVec2(-1, 0),
"Atlas Utilization");
279 ImGui::Text(
"Frame Rate Analysis");
283 std::vector<float> fps_history;
287 if (frame_time > 0.0) {
288 fps_history.push_back(1000.0F /
static_cast<float>(frame_time));
292 if (!fps_history.empty()) {
293 ImGui::PlotLines(
"FPS", fps_history.data(),
294 static_cast<int>(fps_history.size()));
304 ImGui::Text(
"Average Frame Time: %.2f ms", avg_frame_time);
305 ImGui::Text(
"95th Percentile: %.2f ms", p95_frame_time);
306 ImGui::Text(
"99th Percentile: %.2f ms", p99_frame_time);
311 ImGui::Text(
"Performance Recommendations");
315 if (summary.recommendations.empty()) {
316 ImGui::TextColored(ImVec4(0, 1, 0, 1),
"✓ All optimizations are active!");
318 ImGui::TextColored(ImVec4(1, 1, 0, 1),
319 "⚠ Performance improvements available:");
320 for (
const auto& rec : summary.recommendations) {
321 ImGui::BulletText(
"%s", rec.c_str());
327 if (ImGui::Checkbox(
"Enable Performance Monitoring", &monitoring_enabled)) {
332 if (ImGui::Button(
"Clear All Data")) {
337 if (ImGui::Button(
"Generate Report")) {
342 if (ImGui::Button(
"Export Performance Report")) {
345 ImGui::SetClipboardText(report.c_str());
346 ImGui::Text(
"Report copied to clipboard");
360 auto palette_stats = profiler.GetStats(
"palette_lookup_optimized");
363 auto texture_stats = profiler.GetStats(
"texture_update_optimized");
366 auto batch_stats = profiler.GetStats(
"texture_batch_queue");
374 double total_cache_operations = 0.0;
375 double total_cache_time = 0.0;
378 for (
const auto& op_name : profiler.GetOperationNames()) {
379 if (op_name.find(
"cache") != std::string::npos ||
380 op_name.find(
"tile_cache") != std::string::npos) {
381 auto stats = profiler.GetStats(op_name);
382 total_cache_operations += stats.sample_count;
383 total_cache_time += stats.total_time_ms;
388 if (total_cache_operations > 0) {
389 double avg_cache_time = total_cache_time / total_cache_operations;
392 1.0 - (avg_cache_time - 10.0) / 40.0));
399 int texture_updates = 0;
401 for (
const auto& op_name : profiler.GetOperationNames()) {
402 if (op_name.find(
"draw") != std::string::npos ||
403 op_name.find(
"render") != std::string::npos) {
404 draw_calls += profiler.GetOperationCount(op_name);
406 if (op_name.find(
"texture_update") != std::string::npos ||
407 op_name.find(
"texture") != std::string::npos) {
408 texture_updates += profiler.GetOperationCount(op_name);
440 auto palette_stats = profiler.GetStats(
"palette_lookup_optimized");
441 if (palette_stats.avg_time_us > 0 && palette_stats.avg_time_us < 5.0) {
446 auto texture_stats = profiler.GetStats(
"texture_update_optimized");
447 if (texture_stats.avg_time_us > 0 && texture_stats.avg_time_us < 200.0) {
452 auto batch_stats = profiler.GetStats(
"texture_batch_queue");
453 if (batch_stats.sample_count > 0) {
461 double frame_time_change =
463 if (frame_time_change > 2.0) {
472 const std::vector<double>& values) {
477 for (
double value : values) {
480 return sum / values.size();
484 const std::vector<double>& values,
double percentile) {
488 std::vector<double> sorted_values = values;
489 std::sort(sorted_values.begin(), sorted_values.end());
492 static_cast<size_t>((percentile / 100.0) * sorted_values.size());
493 if (index >= sorted_values.size()) {
494 index = sorted_values.size() - 1;
497 return sorted_values[index];
502 return std::to_string(
static_cast<int>(time_us * 1000.0)) +
" ns";
504 if (time_us < 1000.0) {
505 return std::to_string(
static_cast<int>(time_us)) +
" μs";
507 return std::to_string(
static_cast<int>(time_us / 1000.0)) +
" ms";
512 return std::to_string(bytes) +
" B";
514 if (bytes < 1024 * 1024) {
515 return std::to_string(bytes / 1024) +
" KB";
517 return std::to_string(bytes / (1024 * 1024)) +
" MB";
523 if (summary.optimization_score >= 90) {
524 return "Performance is excellent. All optimizations are active.";
526 if (summary.optimization_score >= 70) {
527 return "Performance is good. Consider enabling remaining optimizations.";
529 if (summary.optimization_score >= 50) {
530 return "Performance is fair. Several optimizations are available.";
532 return "Performance needs improvement. Enable graphics optimizations.";
AtlasStats GetStats() const
Get atlas statistics.
static AtlasRenderer & Get()
std::pair< size_t, size_t > GetMemoryStats() const
Get memory usage statistics.
static MemoryPool & Get()
Main namespace for the application.