11#include "imgui/imgui.h"
25 "Initialized performance integration for canvas: %s",
36 LOG_DEBUG(
"CanvasPerformance",
"Started performance monitoring for canvas: %s",
59 LOG_DEBUG(
"CanvasPerformance",
"Stopped performance monitoring for canvas: %s",
82 static auto last_save = std::chrono::steady_clock::now();
83 auto now = std::chrono::steady_clock::now();
84 if (std::chrono::duration_cast<std::chrono::seconds>(now - last_save).count() >= 5) {
126 size_t bitmap_memory,
127 size_t palette_memory) {
142 std::ostringstream summary;
144 summary <<
"Canvas Performance Summary (" <<
canvas_id_ <<
")\n";
145 summary <<
"=====================================\n\n";
147 summary <<
"Timing Metrics:\n";
153 summary <<
"Operation Counts:\n";
159 summary <<
"Canvas Operations:\n";
166 summary <<
"Memory Usage:\n";
171 summary <<
"Cache Performance:\n";
172 summary <<
" Hit Ratio: " << std::fixed << std::setprecision(1)
177 return summary.str();
181 std::vector<std::string> recommendations;
185 recommendations.push_back(
"Frame time is high - consider reducing draw calls or optimizing rendering");
190 recommendations.push_back(
"Draw time is high - consider using texture atlases or reducing texture switches");
197 if (total_memory > 100) {
198 recommendations.push_back(
"Memory usage is high - consider implementing texture streaming or compression");
203 recommendations.push_back(
"Cache hit ratio is low - consider increasing cache size or improving cache strategy");
208 recommendations.push_back(
"High draw call count - consider batching operations or using instanced rendering");
212 recommendations.push_back(
"Frequent texture updates - consider using texture arrays or atlases");
215 return recommendations;
219 std::ostringstream report;
221 report <<
"Canvas Performance Report\n";
222 report <<
"========================\n\n";
224 report <<
"Canvas ID: " <<
canvas_id_ <<
"\n";
231 report <<
"Performance History:\n";
232 report <<
"===================\n\n";
236 report <<
"Sample " << (i + 1) <<
":\n";
237 report <<
" Frame Time: " <<
FormatTime(metrics.frame_time_ms) <<
"\n";
238 report <<
" Draw Calls: " << metrics.draw_calls <<
"\n";
239 report <<
" Memory: " <<
FormatMemory((metrics.texture_memory_mb +
240 metrics.bitmap_memory_mb +
241 metrics.palette_memory_mb) * 1024 * 1024) <<
"\n\n";
247 if (!recommendations.empty()) {
248 report <<
"Recommendations:\n";
249 report <<
"===============\n\n";
250 for (
const auto& rec : recommendations) {
251 report <<
"• " << rec <<
"\n";
277 if (ImGui::Button(
"Toggle Detailed Metrics")) {
281 if (ImGui::Button(
"Toggle Recommendations")) {
285 if (ImGui::Button(
"Export Report")) {
327 if (total_requests > 0) {
348 double frame_time_trend = 0.0;
349 double memory_trend = 0.0;
355 frame_time_trend += (curr.frame_time_ms - prev.frame_time_ms);
356 memory_trend += ((curr.texture_memory_mb + curr.bitmap_memory_mb + curr.palette_memory_mb) -
357 (prev.texture_memory_mb + prev.bitmap_memory_mb + prev.palette_memory_mb));
364 if (std::abs(frame_time_trend) > 1.0) {
365 LOG_DEBUG(
"CanvasPerformance",
"Canvas %s: Frame time trend: %.2f ms/sample",
369 if (std::abs(memory_trend) > 1.0) {
370 LOG_DEBUG(
"CanvasPerformance",
"Canvas %s: Memory trend: %.2f MB/sample",
376 ImGui::Text(
"Performance Overview");
392 ImGui::TextColored(memory_color,
"Memory: %s",
FormatMemory(total_memory * 1024 * 1024).c_str());
400 ImGui::Text(
"Detailed Metrics");
414 if (ImGui::CollapsingHeader(
"Memory Usage")) {
422 ImGui::Text(
"Total Memory: %s",
FormatMemory(total * 1024 * 1024).c_str());
427 if (ImGui::CollapsingHeader(
"Operation Counts")) {
434 ImGui::Text(
"Canvas Operations:");
444 if (ImGui::CollapsingHeader(
"Cache Performance")) {
455 ImGui::Text(
"Performance Recommendations");
459 if (recommendations.empty()) {
460 ImGui::TextColored(ImVec4(0.2F, 1.0F, 0.2F, 1.0F),
"✓ Performance looks good!");
462 for (
const auto& rec : recommendations) {
463 ImGui::TextColored(ImVec4(1.0F, 0.8F, 0.2F, 1.0F),
"⚠ %s", rec.c_str());
469 if (ImGui::CollapsingHeader(
"Performance Graph")) {
471 static std::vector<float> frame_times;
472 static std::vector<float> draw_times;
479 if (frame_times.size() > 100) {
480 frame_times.erase(frame_times.begin());
481 draw_times.erase(draw_times.begin());
484 if (!frame_times.empty()) {
485 ImGui::PlotLines(
"Frame Time (ms)", frame_times.data(),
486 static_cast<int>(frame_times.size()), 0,
nullptr, 0.0F, 50.0F,
488 ImGui::PlotLines(
"Draw Time (ms)", draw_times.data(),
489 static_cast<int>(draw_times.size()), 0,
nullptr, 0.0F, 30.0F,
497 return std::to_string(
static_cast<int>(time_ms * 1000)) +
" μs";
498 }
else if (time_ms < 1000.0) {
499 return std::to_string(
static_cast<int>(time_ms * 10) / 10.0) +
" ms";
501 return std::to_string(
static_cast<int>(time_ms / 1000)) +
" s";
507 return std::to_string(bytes) +
" B";
508 }
else if (bytes < 1024 * 1024) {
509 return std::to_string(bytes / 1024) +
" KB";
511 return std::to_string(bytes / (1024 * 1024)) +
" MB";
516 double threshold_good,
517 double threshold_warning)
const {
518 if (value <= threshold_good) {
519 return ImVec4(0.2F, 1.0F, 0.2F, 1.0F);
520 }
else if (value <= threshold_warning) {
521 return ImVec4(1.0F, 1.0F, 0.2F, 1.0F);
523 return ImVec4(1.0F, 0.2F, 0.2F, 1.0F);
535 const std::string& canvas_id,
536 std::shared_ptr<CanvasPerformanceIntegration> integration) {
539 "Registered performance integration for canvas: %s",
543std::shared_ptr<CanvasPerformanceIntegration>
554 integration->UpdateMetrics();
559 std::ostringstream summary;
561 summary <<
"Global Canvas Performance Summary\n";
562 summary <<
"=================================\n\n";
564 summary <<
"Registered Canvases: " <<
integrations_.size() <<
"\n\n";
567 summary <<
"Canvas: " <<
id <<
"\n";
568 summary <<
"----------------------------------------\n";
569 summary << integration->GetPerformanceSummary() <<
"\n\n";
572 return summary.str();
576 std::ostringstream report;
578 report <<
"Global Canvas Performance Report\n";
579 report <<
"================================\n\n";
584 report <<
"Global Recommendations:\n";
585 report <<
"=======================\n\n";
588 auto recommendations = integration->GetPerformanceRecommendations();
589 if (!recommendations.empty()) {
590 report <<
"Canvas " <<
id <<
":\n";
591 for (
const auto& rec : recommendations) {
592 report <<
" • " << rec <<
"\n";
603 integration->StopMonitoring();
606 LOG_DEBUG(
"CanvasPerformance",
"Cleared all canvas performance integrations");
#define LOG_DEBUG(category, format,...)
CanvasUsage
Canvas usage patterns and tracking.
Main namespace for the application.