10#include "imgui/imgui.h"
25 "Initialized performance integration for canvas: %s",
36 std::make_unique<gfx::ScopedTimer>(
"canvas_frame_" +
canvas_id_);
39 "Started performance monitoring for canvas: %s",
63 "Stopped performance monitoring for canvas: %s",
87 static auto last_save = std::chrono::steady_clock::now();
88 auto now = std::chrono::steady_clock::now();
89 if (std::chrono::duration_cast<std::chrono::seconds>(now - last_save)
97 const std::string& operation_name,
double time_ms,
CanvasUsage usage_mode) {
102 switch (usage_mode) {
133 size_t bitmap_memory,
134 size_t palette_memory) {
151 std::ostringstream summary;
153 summary <<
"Canvas Performance Summary (" <<
canvas_id_ <<
")\n";
154 summary <<
"=====================================\n\n";
156 summary <<
"Timing Metrics:\n";
161 summary <<
" Interaction Time: "
166 summary <<
"Operation Counts:\n";
173 summary <<
"Canvas Operations:\n";
177 summary <<
" Rectangle Select: "
184 summary <<
"Memory Usage:\n";
185 summary <<
" Texture Memory: "
188 summary <<
" Bitmap Memory: "
191 summary <<
" Palette Memory: "
195 summary <<
"Cache Performance:\n";
196 summary <<
" Hit Ratio: " << std::fixed << std::setprecision(1)
201 return summary.str();
204std::vector<std::string>
206 std::vector<std::string> recommendations;
210 recommendations.push_back(
211 "Frame time is high - consider reducing draw calls or optimizing "
217 recommendations.push_back(
218 "Draw time is high - consider using texture atlases or reducing "
226 if (total_memory > 100) {
227 recommendations.push_back(
228 "Memory usage is high - consider implementing texture streaming or "
234 recommendations.push_back(
235 "Cache hit ratio is low - consider increasing cache size or improving "
241 recommendations.push_back(
242 "High draw call count - consider batching operations or using "
243 "instanced rendering");
247 recommendations.push_back(
248 "Frequent texture updates - consider using texture arrays or atlases");
251 return recommendations;
255 std::ostringstream report;
257 report <<
"Canvas Performance Report\n";
258 report <<
"========================\n\n";
260 report <<
"Canvas ID: " <<
canvas_id_ <<
"\n";
268 report <<
"Performance History:\n";
269 report <<
"===================\n\n";
273 report <<
"Sample " << (i + 1) <<
":\n";
274 report <<
" Frame Time: " <<
FormatTime(metrics.frame_time_ms) <<
"\n";
275 report <<
" Draw Calls: " << metrics.draw_calls <<
"\n";
276 report <<
" Memory: "
278 metrics.bitmap_memory_mb +
279 metrics.palette_memory_mb) *
287 if (!recommendations.empty()) {
288 report <<
"Recommendations:\n";
289 report <<
"===============\n\n";
290 for (
const auto& rec : recommendations) {
291 report <<
"• " << rec <<
"\n";
318 if (ImGui::Button(
"Toggle Detailed Metrics")) {
322 if (ImGui::Button(
"Toggle Recommendations")) {
326 if (ImGui::Button(
"Export Report")) {
335 std::shared_ptr<CanvasUsageTracker> tracker) {
370 if (total_requests > 0) {
393 double frame_time_trend = 0.0;
394 double memory_trend = 0.0;
400 frame_time_trend += (curr.frame_time_ms - prev.frame_time_ms);
401 memory_trend += ((curr.texture_memory_mb + curr.bitmap_memory_mb +
402 curr.palette_memory_mb) -
403 (prev.texture_memory_mb + prev.bitmap_memory_mb +
404 prev.palette_memory_mb));
411 if (std::abs(frame_time_trend) > 1.0) {
413 "Canvas %s: Frame time trend: %.2f ms/sample",
canvas_id_.c_str(),
417 if (std::abs(memory_trend) > 1.0) {
418 LOG_DEBUG(
"CanvasPerformance",
"Canvas %s: Memory trend: %.2f MB/sample",
424 ImGui::Text(
"Performance Overview");
430 ImGui::TextColored(frame_color,
"Frame Time: %s",
436 ImGui::TextColored(draw_color,
"Draw Time: %s",
444 ImGui::TextColored(memory_color,
"Memory: %s",
450 ImGui::TextColored(cache_color,
"Cache Hit Ratio: %.1f%%",
455 ImGui::Text(
"Detailed Metrics");
469 if (ImGui::CollapsingHeader(
"Memory Usage")) {
471 "Texture Memory: %s",
477 "Palette Memory: %s",
483 ImGui::Text(
"Total Memory: %s",
FormatMemory(total * 1024 * 1024).c_str());
488 if (ImGui::CollapsingHeader(
"Operation Counts")) {
495 ImGui::Text(
"Canvas Operations:");
498 ImGui::Text(
" Rectangle Select: %d",
501 ImGui::Text(
" BPP Conversion: %d",
507 if (ImGui::CollapsingHeader(
"Cache Performance")) {
518 ImGui::Text(
"Performance Recommendations");
522 if (recommendations.empty()) {
523 ImGui::TextColored(ImVec4(0.2F, 1.0F, 0.2F, 1.0F),
524 "✓ Performance looks good!");
526 for (
const auto& rec : recommendations) {
527 ImGui::TextColored(ImVec4(1.0F, 0.8F, 0.2F, 1.0F),
"⚠ %s", rec.c_str());
533 if (ImGui::CollapsingHeader(
"Performance Graph")) {
535 static std::vector<float> frame_times;
536 static std::vector<float> draw_times;
543 if (frame_times.size() > 100) {
544 frame_times.erase(frame_times.begin());
545 draw_times.erase(draw_times.begin());
548 if (!frame_times.empty()) {
549 ImGui::PlotLines(
"Frame Time (ms)", frame_times.data(),
550 static_cast<int>(frame_times.size()), 0,
nullptr, 0.0F,
551 50.0F, ImVec2(0, 100));
552 ImGui::PlotLines(
"Draw Time (ms)", draw_times.data(),
553 static_cast<int>(draw_times.size()), 0,
nullptr, 0.0F,
554 30.0F, ImVec2(0, 100));
561 return std::to_string(
static_cast<int>(time_ms * 1000)) +
" μs";
562 }
else if (time_ms < 1000.0) {
563 return std::to_string(
static_cast<int>(time_ms * 10) / 10.0) +
" ms";
565 return std::to_string(
static_cast<int>(time_ms / 1000)) +
" s";
571 return std::to_string(bytes) +
" B";
572 }
else if (bytes < 1024 * 1024) {
573 return std::to_string(bytes / 1024) +
" KB";
575 return std::to_string(bytes / (1024 * 1024)) +
" MB";
580 double value,
double threshold_good,
double threshold_warning)
const {
581 if (value <= threshold_good) {
582 return ImVec4(0.2F, 1.0F, 0.2F, 1.0F);
583 }
else if (value <= threshold_warning) {
584 return ImVec4(1.0F, 1.0F, 0.2F, 1.0F);
586 return ImVec4(1.0F, 0.2F, 0.2F, 1.0F);
598 const std::string& canvas_id,
599 std::shared_ptr<CanvasPerformanceIntegration> integration) {
602 "Registered performance integration for canvas: %s",
606std::shared_ptr<CanvasPerformanceIntegration>
617 integration->UpdateMetrics();
622 std::ostringstream summary;
624 summary <<
"Global Canvas Performance Summary\n";
625 summary <<
"=================================\n\n";
627 summary <<
"Registered Canvases: " <<
integrations_.size() <<
"\n\n";
630 summary <<
"Canvas: " <<
id <<
"\n";
631 summary <<
"----------------------------------------\n";
632 summary << integration->GetPerformanceSummary() <<
"\n\n";
635 return summary.str();
639 std::ostringstream report;
641 report <<
"Global Canvas Performance Report\n";
642 report <<
"================================\n\n";
647 report <<
"Global Recommendations:\n";
648 report <<
"=======================\n\n";
651 auto recommendations = integration->GetPerformanceRecommendations();
652 if (!recommendations.empty()) {
653 report <<
"Canvas " <<
id <<
":\n";
654 for (
const auto& rec : recommendations) {
655 report <<
" • " << rec <<
"\n";
666 integration->StopMonitoring();
669 LOG_DEBUG(
"CanvasPerformance",
"Cleared all canvas performance integrations");
#define LOG_DEBUG(category, format,...)
CanvasUsage
Canvas usage patterns and tracking.