--- nono/vm/renderer.h 2026/04/29 17:05:14 1.1.1.8 +++ nono/vm/renderer.h 2026/04/29 17:05:33 1.1.1.12 @@ -10,83 +10,57 @@ #pragma once -// ブロックのヒット効率(?)を測定 -#define PERF_HIT - #include "thread.h" #include "bitmap.h" -#include "monitor.h" -#include "spscqueue.h" -#include "stopwatch.h" +#include "fixedqueue.h" #include #include -#if defined(PERF_HIT) -#include "fixedqueue.h" -#endif - -// 更新情報交換用構造体 -struct ModifyInfo -{ - std::array bits {}; - uint32 n_dirty {}; -#if defined(PERF_HIT) - // 65536 = (2048px / 32bit) * 1024px - std::array dirty_word {}; -#endif - - // パレットを変更した場合とスクロールした場合のように - // composite に変更によらず bitmap を更新する場合は true。 - bool invalidate2 {}; - - void Fill(uint16 v) { - std::fill(bits.begin(), bits.end(), v); - if (v) { - n_dirty = bits.size(); - } else { - n_dirty = 0; - } - } - - bool IsClean() const { return n_dirty == 0; } - bool IsDirty() const { return n_dirty != 0; } -}; +class ConsoleDevice; +class PlaneVRAMDevice; +class Scheduler; +class Syncer; +class VideoCtlrDevice; class Renderer : public ThreadDevice { using inherited = ThreadDevice; public: static const uint REQ_TERMINATE = 0x01; // スレッド終了指示 - static const uint REQ_REND_POWEROFF = 0x02; // 電源オフ時の描画指示 - static const uint REQ_REND_NORMAL = 0x04; // 通常の描画指示 - - static const int BLKX = 128; // 1ブロックの幅 [pixel] - static const int BLKY = 16; // 1ブロックの高さ [pixel] + static const uint REQ_SCREENOFF = 0x02; // 電源オフ時の描画指示 + static const uint REQ_RENDER = 0x04; // 通常の描画指示 + static const uint REQ_RESIZE = 0x08; // リサイズ指示 + static const uint REQ_POST = 0x10; // UI への通知指示 public: Renderer(); - virtual ~Renderer() override; + ~Renderer() override; + bool Init() override; void ResetHard(bool poweron) override; void PowerOff() override; - // 出力ビットマップを取得 - const BitmapRGB& GetBitmap() { return bitmap; } - - // 合成処理イネーブル - void Enable(); + // 出力ビットマップが有効なら取得。 + // (wxImage に渡すため const なし) + BitmapRGB *GetBitmap() { + if (__predict_true(bitmap24_valid)) { + return bitmap24.get(); + } else { + return NULL; + } + } - // 画面合成処理 (CRTC/CRTC2 から呼ばれる) - void Render(); + // 画面合成処理の指示 (CRTC/CRTC2 から呼ばれる) + void NotifyRender(); - // 全画面更新の指示 (パレット変更とスクロール座標変更で呼ばれる) - void Invalidate2(); + // 表示画面サイズを設定 (GUI から呼ばれる) + void ResizeView(uint width_, uint height_); // 仮想画面幅(ピクセル)を取得 - int GetWidth() const { return width; } + uint GetWidth() const { return width; } // 仮想画面高さ(ピクセル)を取得 - int GetHeight() const { return height; } + uint GetHeight() const { return height; } // 描画更新(通知)間隔を設定 (GUI から呼ばれる) void SetRefreshInterval(uint64 t); @@ -95,8 +69,11 @@ class Renderer : public ThreadDevice // レンダリングスレッド void ThreadRun() override; + // 描画する。 + int64 DoRender(uint32 req); + // 画面合成。更新があれば true を返す。(派生クラス側で用意) - virtual bool RenderMain() = 0; + virtual bool RenderMD() = 0; DECLARE_MONITOR_CALLBACK(MonitorUpdate); @@ -106,53 +83,55 @@ class Renderer : public ThreadDevice // LUNA でいう 1280 x 1024 のこと。 // 仮想画面幅(ピクセル) - int width {}; + uint width {}; // 仮想画面高さ(ピクセル) - int height {}; + uint height {}; // レンダリング結果のビットマップ - BitmapRGB bitmap {}; + BitmapRGBX bitmap {}; + + // wxWidgets 用表示ビットマップ + std::unique_ptr bitmap24 /*{}*/; - // ステージ2 の全画面更新指示フラグ - bool invalidate2 {}; + // 表示ビットマップの大きさ + Rect viewrect {}; // リクエストフラグ uint32 request {}; std::mutex mtx {}; std::condition_variable cv {}; - // 合成処理有効フラグ - bool enable {}; + // リサイズ時の要求サイズ + uint new_viewwidth {}; + uint new_viewheight {}; - // 更新情報を VM -> Renderer スレッドに渡すための 1 要素キュー - SPSCQueue modq {}; + // レンダラ有効フラグ (GUI なら true) + bool enable {}; - // レンダラスレッドで受け取った更新情報 (モニタ表示のため) - ModifyInfo modify {}; + // 初期化やリサイズ後に一度でも bitmap24 を更新すれば true。 + bool bitmap24_valid {}; // 画面更新を UI に通知する間隔 uint64 refresh_interval {}; // 次回更新を通知する実時刻 uint64 next_refresh_rtime {}; - // 出力画面に更新がある (UI に通知する必要がある) 場合は true - bool out_dirty {}; - // 統計情報 - uint64 render_exec {}; // RenderMain() の実行回数 - Stopwatch render_time {}; // RenderMain() の総実行時間 - uint32 last_mod_blocks {}; // 直近の更新ブロック数 - uint64 total_mod_blocks {}; // 総更新ブロック数 - uint64 total_invalidate2 {}; // ステージ2の全画面更新回数 - -#if defined(PERF_HIT) - FixedQueue hitrate_ma {}; - uint64 hitrate_total_word {}; - uint64 hitrate_total_block {}; -#endif + uint64 stat_input_count {}; // 入力通知回数 + uint64 last_input_time {}; // 前回の入力通知 VM 時刻 + FixedQueue ma_input_span {}; // 入力通知間隔 + uint64 stat_render_count {}; // RenderMD() の実行回数 + uint64 stat_noupdate_count {}; // bitmap24 への更新が不要だった回数 + uint64 stat_nobitmap_count {}; // bitmap24 が用意できてなかった回数 + uint64 stat_output_count {}; // UI への出力通知回数 + uint64 last_output_time {}; // 前回の出力通知 RT 時刻 + FixedQueue ma_output_span {}; // 出力通知間隔 + + Scheduler *scheduler {}; + Syncer *syncer {}; - Monitor monitor { this }; + Monitor *monitor {}; private: // スレッドの終了を指示 @@ -167,9 +146,13 @@ class X68030Renderer : public Renderer using inherited = Renderer; public: X68030Renderer(); - virtual ~X68030Renderer() override; + ~X68030Renderer() override; + + bool Init() override; + bool RenderMD() override; - bool RenderMain() override; + private: + VideoCtlrDevice *videoctlr {}; }; // @@ -180,9 +163,37 @@ class LunaRenderer : public Renderer using inherited = Renderer; public: LunaRenderer(); - virtual ~LunaRenderer() override; + ~LunaRenderer() override; + + bool Init() override; + bool RenderMD() override; - bool RenderMain() override; + private: + PlaneVRAMDevice *planevram {}; +}; + +// +// コンソールレンダラ +// +class ConsoleRenderer : public Renderer +{ + using inherited = Renderer; + + public: + // フチ [pixel] + static const uint Padding = 3; + + public: + ConsoleRenderer(); + ~ConsoleRenderer() override; + + bool Init() override; + bool RenderMD() override; + + private: + ConsoleDevice *console {}; }; -extern Renderer *gRenderer; +static inline Renderer *GetRenderer() { + return Object::GetObject(OBJ_RENDERER); +}