--- nono/vm/renderer.h 2026/04/29 17:04:28 1.1.1.1 +++ nono/vm/renderer.h 2026/04/29 17:05:42 1.1.1.13 @@ -1,53 +1,81 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + // // レンダラ // #pragma once -#include "device.h" +#include "thread.h" +#include "bitmap.h" +#include "fixedqueue.h" #include #include -class Renderer : public Device +class ConsoleDevice; +class PlaneVRAMDevice; +class Scheduler; +class Syncer; +class VideoCtlrDevice; + +class Renderer : public ThreadDevice { - typedef Device inherited; + using inherited = ThreadDevice; public: - // wxWidgets のビットマップは R8_G8_B8 の3バイト。 - static const int BPP = 3; - static const uint REQ_TERMINATE = 0x01; // スレッド終了指示 - static const uint REQ_REND_POWEROFF = 0x02; // 電源オフ時の描画指示 - static const uint REQ_REND_NORMAL = 0x04; // 通常の描画指示 + 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(); + ~Renderer() override; - virtual bool Init(); - virtual bool PowerOff(); + bool Init() override; + void ResetHard(bool poweron) override; + void PowerOff() override; + + // 出力ビットマップが有効なら取得。 + // (wxImage に渡すため const なし) + BitmapRGB *GetBitmap() { + if (__predict_true(bitmap24_valid)) { + return bitmap24.get(); + } else { + return NULL; + } + } - // バッファとコールバック関数を指定 - // XXX 名前... - void SetBuf(uint8 *, void (*)(void)); + // 画面合成処理の指示 (CRTC/CRTC2 から呼ばれる) + void NotifyRender(); - // 画面合成処理 (CRTC とかから呼ばれる) - void Render(); + // 表示画面サイズを設定 (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; } - // レンダリングスレッド (エントリポイントから呼ばれる) - void ThreadRun(); + // 描画更新(通知)間隔を設定 (GUI から呼ばれる) + void SetRefreshInterval(uint64 t); protected: + // レンダリングスレッド + void ThreadRun() override; + + // 描画する。 + int64 DoRender(uint32 req); + // 画面合成。更新があれば true を返す。(派生クラス側で用意) - virtual bool RenderMain() = 0; + virtual bool RenderMD() = 0; + + DECLARE_MONITOR_CALLBACK(MonitorUpdate); // ウィンドウとして表示される画面はオプションや設定などで縮尺を変える // ことが出来るが (こっちを実画面とする)、ここで扱う仮想画面とはそれに @@ -55,22 +83,58 @@ class Renderer : public Device // LUNA でいう 1280 x 1024 のこと。 // 仮想画面幅(ピクセル) - int width = 0; + uint width {}; // 仮想画面高さ(ピクセル) - int height = 0; + uint height {}; + + // レンダリング結果のビットマップ + BitmapRGBX bitmap {}; - // バッファ (実体は wx 側で用意) - uint8 *imagebuf = NULL; + // wxWidgets 用表示ビットマップ + std::unique_ptr bitmap24 /*{}*/; - // リフレッシュを指示するためのコールバック (wx 側で用意) - // ここから直接 wxWindow::Refresh() を呼べないため。 - void (*refresh_callback)(void) = NULL; + // 表示ビットマップの大きさ + Rect viewrect {}; // リクエストフラグ - uint32 request = 0; + uint32 request {}; std::mutex mtx {}; std::condition_variable cv {}; + + // リサイズ時の要求サイズ + uint new_viewwidth {}; + uint new_viewheight {}; + + // レンダラ有効フラグ (GUI なら true) + bool enable {}; + + // 初期化やリサイズ後に一度でも bitmap24 を更新すれば true。 + bool bitmap24_valid {}; + + // 画面更新を UI に通知する間隔 + uint64 refresh_interval {}; + // 次回更新を通知する実時刻 + uint64 next_refresh_rtime {}; + + // 統計情報 + 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 {}; // 出力通知間隔 + + Syncer *syncer {}; + + Monitor *monitor {}; + + private: + // スレッドの終了を指示 + void Terminate() override; }; // @@ -78,12 +142,16 @@ class Renderer : public Device // class X68030Renderer : public Renderer { - typedef Renderer inherited; + using inherited = Renderer; public: X68030Renderer(); - virtual ~X68030Renderer(); + ~X68030Renderer() override; - virtual bool RenderMain(); + bool Init() override; + bool RenderMD() override; + + private: + VideoCtlrDevice *videoctlr {}; }; // @@ -91,12 +159,40 @@ class X68030Renderer : public Renderer // class LunaRenderer : public Renderer { - typedef Renderer inherited; + using inherited = Renderer; public: LunaRenderer(); - virtual ~LunaRenderer(); + ~LunaRenderer() override; + + bool Init() override; + bool RenderMD() 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; - virtual bool RenderMain(); + private: + ConsoleDevice *console {}; }; -extern Renderer *gRenderer; +static inline Renderer *GetRenderer() { + return Object::GetObject(OBJ_RENDERER); +}