--- nono/vm/renderer.cpp 2026/04/29 17:05:41 1.1.1.13 +++ nono/vm/renderer.cpp 2026/04/29 17:05:49 1.1.1.14 @@ -21,6 +21,7 @@ #define PERFREND #include "stopwatch.h" static Stopwatch sw_notify; +static uint64 last_report_rtime; static uint64 notify_time; static uint notify_count; static uint64 render_time; @@ -51,8 +52,8 @@ Renderer::~Renderer() bool Renderer::Init() { - scheduler = GetScheduler(); syncer = GetSyncer(); + uimessage = gMainApp.GetUIMessage(); // GUI ならレンダラ有効。 if (gMainApp.IsGUI()) { @@ -82,6 +83,9 @@ Renderer::ResetHard(bool poweron) stat_output_count = 0; last_output_time = now; ma_output_span.Clear(); +#if defined(PERFREND) + last_report_rtime = syncer->GetRealTime(); +#endif } // 電源オフ @@ -93,7 +97,7 @@ Renderer::PowerOff() sw_notify.Restart(); #endif // レンダリングスレッドに指示 - std::unique_lock lock(mtx); + std::lock_guard lock(mtx); request |= REQ_SCREENOFF; cv.notify_one(); } @@ -121,7 +125,7 @@ Renderer::NotifyRender() // レンダラスレッドに描画指示を出すだけ。 { - std::unique_lock lock(mtx); + std::lock_guard lock(mtx); request |= REQ_RENDER; cv.notify_one(); } @@ -162,6 +166,9 @@ Renderer::ThreadRun() // req に基づいて処理。 int64 t = DoRender(req); +#if defined(PERFREND) + PrintPerf(); +#endif if (t == 0 || (req & REQ_POST)) { // UI に即通知。 @@ -171,7 +178,7 @@ Renderer::ThreadRun() ma_output_span.EnqueueForce(now - last_output_time); last_output_time = now; - UIMessage::Post(UIMessage::RENDER); + uimessage->Post(UIMessage::RENDER); delay = 0; } else if (t > 0) { // 指定時間後に UI に通知。 @@ -279,16 +286,7 @@ Renderer::DoRender(uint32 req) #if defined(PERFREND) sw.Stop(); convert_time += sw.Elapsed(); -#endif - -#if defined(PERFREND) - if (++convert_count % 100 == 0) { - printf("Notify %u, Render %u, Stretch %u, Convert %u [usec]\n", - (uint)(notify_time / notify_count / 1000U), - (uint)(render_time / stat_render_count / 1000U), - (uint)(stretch_time / convert_count / 1000U), - (uint)(convert_time / convert_count / 1000U)); - } + convert_count++; #endif if ((req & (REQ_SCREENOFF | REQ_RESIZE))) { @@ -305,11 +303,49 @@ Renderer::DoRender(uint32 req) return 0; } +#if defined(PERFREND) +void +Renderer::PrintPerf() +{ + uint64 now = syncer->GetRealTime(); + if (now - last_report_rtime < 5_sec) { + return; + } + + double rate = 0; + uint nt = 0; + uint rt = 0; + uint st = 0; + uint ct = 0; + if (notify_count != 0) { + rate = (double)notify_count * 1_sec / (now - last_report_rtime); + nt = notify_time / notify_count / 1000U; + rt = render_time / notify_count / 1000U; + } + if (convert_count != 0) { + st = stretch_time / convert_count / 1000U; + ct = convert_time / convert_count / 1000U; + } + + printf( + "%5.1f calls/s: Notify %u us, Render %u us, Stretch %u us, Convert %u us\n", + rate, nt, rt, st, ct); + + notify_time = 0; + render_time = 0; + stretch_time = 0; + convert_time = 0; + notify_count = 0; + convert_count = 0; + last_report_rtime = now; +} +#endif // PERFREND + // スレッドの終了を指示 void Renderer::Terminate() { - std::unique_lock lock(mtx); + std::lock_guard lock(mtx); request |= REQ_TERMINATE; cv.notify_one(); } @@ -323,7 +359,7 @@ Renderer::ResizeView(uint width_, uint h new_viewwidth = width_; new_viewheight = height_; - std::unique_lock lock(mtx); + std::lock_guard lock(mtx); request |= REQ_RESIZE; cv.notify_one(); } @@ -341,6 +377,7 @@ Renderer::MonitorUpdate(Monitor *, TextS { int x; int y; + uint64 ma; screen.Clear(); @@ -351,15 +388,8 @@ Renderer::MonitorUpdate(Monitor *, TextS screen.Puts(0, y, "Input Count"); screen.Print(x, y++, "%26s", format_number(stat_input_count).c_str()); - uint count = ma_input_span.Length(); - uint64 ma = 0; - for (uint i = 0; i < count; i++) { - ma += ma_input_span.Peek(i); - } - if (count != 0) { - ma /= count; - } screen.Puts(0, y, "Input Frequency(VT)"); + ma = ma_input_span.GetMovingAverage(); screen.Print(x + 18, y, "%5.1f Hz", ma == 0 ? 0.0 : (double)1000'000'000 / ma); y++; @@ -375,15 +405,8 @@ Renderer::MonitorUpdate(Monitor *, TextS y++; screen.Puts(0, y, "Output Count"); screen.Print(x, y++, "%26s", format_number(stat_output_count).c_str()); - count = ma_output_span.Length(); - ma = 0; - for (uint i = 0; i < count; i++) { - ma += ma_output_span.Peek(i); - } - if (count != 0) { - ma /= count; - } screen.Puts(0, y, "Output Frequency(RT)"); + ma = ma_output_span.GetMovingAverage(); screen.Print(x + 18, y, "%5.1f Hz", ma == 0 ? 0.0 : (double)1000'000'000 / ma); y++;