11#include "imgui/imgui.h"
26 "Initialized performance integration for canvas: %s",
37 std::make_unique<gfx::ScopedTimer>(
"canvas_frame_" +
canvas_id_);
40 "Started performance monitoring for canvas: %s",
64 "Stopped performance monitoring for canvas: %s",
88 static auto last_save = std::chrono::steady_clock::now();
89 auto now = std::chrono::steady_clock::now();
90 if (std::chrono::duration_cast<std::chrono::seconds>(now - last_save)
98 const std::string& operation_name,
double time_ms,
CanvasUsage usage_mode) {
103 switch (usage_mode) {
134 size_t bitmap_memory,
135 size_t palette_memory) {
152 std::ostringstream summary;
154 summary <<
"Canvas Performance Summary (" <<
canvas_id_ <<
")\n";
155 summary <<
"=====================================\n\n";
157 summary <<
"Timing Metrics:\n";
162 summary <<
" Interaction Time: "
167 summary <<
"Operation Counts:\n";
174 summary <<
"Canvas Operations:\n";
178 summary <<
" Rectangle Select: "
185 summary <<
"Memory Usage:\n";
186 summary <<
" Texture Memory: "
189 summary <<
" Bitmap Memory: "
192 summary <<
" Palette Memory: "
196 summary <<
"Cache Performance:\n";
197 summary <<
" Hit Ratio: " << std::fixed << std::setprecision(1)
202 return summary.str();
205std::vector<std::string>
207 std::vector<std::string> recommendations;
211 recommendations.push_back(
212 "Frame time is high - consider reducing draw calls or optimizing "
218 recommendations.push_back(
219 "Draw time is high - consider using texture atlases or reducing "
227 if (total_memory > 100) {
228 recommendations.push_back(
229 "Memory usage is high - consider implementing texture streaming or "
235 recommendations.push_back(
236 "Cache hit ratio is low - consider increasing cache size or improving "
242 recommendations.push_back(
243 "High draw call count - consider batching operations or using "
244 "instanced rendering");
248 recommendations.push_back(
249 "Frequent texture updates - consider using texture arrays or atlases");
252 return recommendations;
256 std::ostringstream report;
258 report <<
"Canvas Performance Report\n";
259 report <<
"========================\n\n";
261 report <<
"Canvas ID: " <<
canvas_id_ <<
"\n";
269 report <<
"Performance History:\n";
270 report <<
"===================\n\n";
274 report <<
"Sample " << (i + 1) <<
":\n";
275 report <<
" Frame Time: " <<
FormatTime(metrics.frame_time_ms) <<
"\n";
276 report <<
" Draw Calls: " << metrics.draw_calls <<
"\n";
277 report <<
" Memory: "
279 metrics.bitmap_memory_mb +
280 metrics.palette_memory_mb) *
288 if (!recommendations.empty()) {
289 report <<
"Recommendations:\n";
290 report <<
"===============\n\n";
291 for (
const auto& rec : recommendations) {
292 report <<
"• " << rec <<
"\n";
319 if (ImGui::Button(tr(
"Toggle Detailed Metrics"))) {
323 if (ImGui::Button(tr(
"Toggle Recommendations"))) {
327 if (ImGui::Button(tr(
"Export Report"))) {
336 std::shared_ptr<CanvasUsageTracker> tracker) {
371 if (total_requests > 0) {
394 double frame_time_trend = 0.0;
395 double memory_trend = 0.0;
401 frame_time_trend += (curr.frame_time_ms - prev.frame_time_ms);
402 memory_trend += ((curr.texture_memory_mb + curr.bitmap_memory_mb +
403 curr.palette_memory_mb) -
404 (prev.texture_memory_mb + prev.bitmap_memory_mb +
405 prev.palette_memory_mb));
412 if (std::abs(frame_time_trend) > 1.0) {
414 "Canvas %s: Frame time trend: %.2f ms/sample",
canvas_id_.c_str(),
418 if (std::abs(memory_trend) > 1.0) {
419 LOG_DEBUG(
"CanvasPerformance",
"Canvas %s: Memory trend: %.2f MB/sample",
425 ImGui::Text(tr(
"Performance Overview"));
431 ImGui::TextColored(frame_color, tr(
"Frame Time: %s"),
437 ImGui::TextColored(draw_color, tr(
"Draw Time: %s"),
445 ImGui::TextColored(memory_color, tr(
"Memory: %s"),
451 ImGui::TextColored(cache_color, tr(
"Cache Hit Ratio: %.1f%%"),
456 ImGui::Text(tr(
"Detailed Metrics"));
470 if (ImGui::CollapsingHeader(tr(
"Memory Usage"))) {
472 tr(
"Texture Memory: %s"),
475 tr(
"Bitmap Memory: %s"),
478 tr(
"Palette Memory: %s"),
484 ImGui::Text(tr(
"Total Memory: %s"),
490 if (ImGui::CollapsingHeader(tr(
"Operation Counts"))) {
494 ImGui::Text(tr(
"Bitmap Operations: %d"),
498 ImGui::Text(tr(
"Canvas Operations:"));
500 ImGui::Text(tr(
" Tile Select: %d"),
502 ImGui::Text(tr(
" Rectangle Select: %d"),
504 ImGui::Text(tr(
" Color Paint: %d"),
506 ImGui::Text(tr(
" BPP Conversion: %d"),
512 if (ImGui::CollapsingHeader(tr(
"Cache Performance"))) {
515 ImGui::Text(tr(
"Hit Ratio: %.1f%%"),
524 ImGui::Text(tr(
"Performance Recommendations"));
528 if (recommendations.empty()) {
529 ImGui::TextColored(ImVec4(0.2F, 1.0F, 0.2F, 1.0F),
530 tr(
"✓ Performance looks good!"));
532 for (
const auto& rec : recommendations) {
533 ImGui::TextColored(ImVec4(1.0F, 0.8F, 0.2F, 1.0F),
"⚠ %s", rec.c_str());
539 if (ImGui::CollapsingHeader(tr(
"Performance Graph"))) {
541 static std::vector<float> frame_times;
542 static std::vector<float> draw_times;
549 if (frame_times.size() > 100) {
550 frame_times.erase(frame_times.begin());
551 draw_times.erase(draw_times.begin());
554 if (!frame_times.empty()) {
555 ImGui::PlotLines(
"Frame Time (ms)", frame_times.data(),
556 static_cast<int>(frame_times.size()), 0,
nullptr, 0.0F,
557 50.0F, ImVec2(0, 100));
558 ImGui::PlotLines(
"Draw Time (ms)", draw_times.data(),
559 static_cast<int>(draw_times.size()), 0,
nullptr, 0.0F,
560 30.0F, ImVec2(0, 100));
567 return std::to_string(
static_cast<int>(time_ms * 1000)) +
" μs";
568 }
else if (time_ms < 1000.0) {
569 return std::to_string(
static_cast<int>(time_ms * 10) / 10.0) +
" ms";
571 return std::to_string(
static_cast<int>(time_ms / 1000)) +
" s";
577 return std::to_string(bytes) +
" B";
578 }
else if (bytes < 1024 * 1024) {
579 return std::to_string(bytes / 1024) +
" KB";
581 return std::to_string(bytes / (1024 * 1024)) +
" MB";
586 double value,
double threshold_good,
double threshold_warning)
const {
587 if (value <= threshold_good) {
588 return ImVec4(0.2F, 1.0F, 0.2F, 1.0F);
589 }
else if (value <= threshold_warning) {
590 return ImVec4(1.0F, 1.0F, 0.2F, 1.0F);
592 return ImVec4(1.0F, 0.2F, 0.2F, 1.0F);
604 const std::string& canvas_id,
605 std::shared_ptr<CanvasPerformanceIntegration> integration) {
608 "Registered performance integration for canvas: %s",
612std::shared_ptr<CanvasPerformanceIntegration>
623 integration->UpdateMetrics();
628 std::ostringstream summary;
630 summary <<
"Global Canvas Performance Summary\n";
631 summary <<
"=================================\n\n";
633 summary <<
"Registered Canvases: " <<
integrations_.size() <<
"\n\n";
636 summary <<
"Canvas: " <<
id <<
"\n";
637 summary <<
"----------------------------------------\n";
638 summary << integration->GetPerformanceSummary() <<
"\n\n";
641 return summary.str();
645 std::ostringstream report;
647 report <<
"Global Canvas Performance Report\n";
648 report <<
"================================\n\n";
653 report <<
"Global Recommendations:\n";
654 report <<
"=======================\n\n";
657 auto recommendations = integration->GetPerformanceRecommendations();
658 if (!recommendations.empty()) {
659 report <<
"Canvas " <<
id <<
":\n";
660 for (
const auto& rec : recommendations) {
661 report <<
" • " << rec <<
"\n";
672 integration->StopMonitoring();
675 LOG_DEBUG(
"CanvasPerformance",
"Cleared all canvas performance integrations");
#define LOG_DEBUG(category, format,...)
CanvasUsage
Canvas usage patterns and tracking.