|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
1.1 root 7: //
8: // レンダラ
9: //
10:
11: #pragma once
12:
1.1.1.7 root 13: #include "thread.h"
14: #include "bitmap.h"
1.1.1.11! root 15: #include "fixedqueue.h"
1.1.1.7 root 16: #include "monitor.h"
17: #include "spscqueue.h"
1.1 root 18: #include <condition_variable>
19: #include <mutex>
20:
1.1.1.9 root 21: class PlaneVRAMDevice;
1.1.1.11! root 22: class Scheduler;
1.1.1.9 root 23: class Syncer;
1.1.1.10 root 24: class VideoCtlrDevice;
1.1.1.7 root 25:
26: // 更新情報交換用構造体
27: struct ModifyInfo
1.1 root 28: {
1.1.1.11! root 29: // 1ライン単位の更新フラグ。
1.1.1.9 root 30: std::array<uint8, 1024> bits {};
1.1.1.7 root 31:
1.1.1.11! root 32: // 更新フラグの立っているライン数を返す。
! 33: uint GetDirtyCount() const {
! 34: uint count = 0;
! 35: for (auto v : bits) {
! 36: if (v) {
! 37: count++;
! 38: }
1.1.1.7 root 39: }
1.1.1.11! root 40: return count;
1.1.1.7 root 41: }
42:
1.1.1.11! root 43: // bits がいずれかでも立っていれば true。
! 44: bool dirty {};
! 45: bool IsClean() const { return !dirty; }
! 46: bool IsDirty() const { return dirty; }
! 47:
! 48: // パレットを変更した場合とスクロールした場合のように
! 49: // composite の変更によらず bitmap を更新する場合は true。
! 50: bool invalidate2 {};
1.1.1.7 root 51: };
1.1 root 52:
1.1.1.7 root 53: class Renderer : public ThreadDevice
54: {
55: using inherited = ThreadDevice;
56: public:
1.1 root 57: static const uint REQ_TERMINATE = 0x01; // スレッド終了指示
1.1.1.11! root 58: static const uint REQ_SCREENOFF = 0x02; // 電源オフ時の描画指示
! 59: static const uint REQ_RENDER = 0x04; // 通常の描画指示
! 60: static const uint REQ_RESIZE = 0x08; // リサイズ指示
! 61: static const uint REQ_POST = 0x10; // UI への通知指示
1.1.1.7 root 62:
1.1 root 63: public:
64: Renderer();
1.1.1.10 root 65: ~Renderer() override;
1.1 root 66:
1.1.1.9 root 67: bool Init() override;
1.1.1.7 root 68: void ResetHard(bool poweron) override;
69: void PowerOff() override;
1.1 root 70:
1.1.1.11! root 71: // 出力ビットマップが有効なら取得。
! 72: // (wxImage に渡すため const なし)
! 73: BitmapRGB *GetBitmap() {
! 74: if (__predict_true(bitmap24_valid)) {
! 75: return bitmap24.get();
! 76: } else {
! 77: return NULL;
! 78: }
! 79: }
1.1.1.7 root 80:
1.1.1.11! root 81: // 画面合成処理の指示 (CRTC/CRTC2 から呼ばれる)
! 82: void NotifyRender();
1.1 root 83:
1.1.1.7 root 84: // 全画面更新の指示 (パレット変更とスクロール座標変更で呼ばれる)
85: void Invalidate2();
1.1.1.6 root 86:
1.1.1.11! root 87: // 表示画面サイズを設定 (GUI から呼ばれる)
! 88: void ResizeView(uint width_, uint height_);
! 89:
1.1 root 90: // 仮想画面幅(ピクセル)を取得
1.1.1.11! root 91: uint GetWidth() const { return width; }
1.1 root 92:
93: // 仮想画面高さ(ピクセル)を取得
1.1.1.11! root 94: uint GetHeight() const { return height; }
1.1 root 95:
1.1.1.7 root 96: // 描画更新(通知)間隔を設定 (GUI から呼ばれる)
97: void SetRefreshInterval(uint64 t);
1.1 root 98:
99: protected:
1.1.1.11! root 100: // モニタを初期化する
! 101: void InitMonitor();
! 102:
1.1.1.7 root 103: // レンダリングスレッド
104: void ThreadRun() override;
105:
1.1.1.11! root 106: // 描画する。
! 107: int64 DoRender(uint32 req);
! 108:
! 109: // 更新チェック。(派生クラス側で用意)
! 110: virtual bool GetModifyMD(ModifyInfo *dst) const = 0;
! 111:
! 112: // 更新情報をクリア。(派生クラス側で用意)
! 113: virtual void ClearDirtyMD() = 0;
1.1 root 114:
1.1.1.11! root 115: // 画面合成。更新があれば true を返す。(派生クラス側で用意)
! 116: virtual bool RenderMD() = 0;
1.1.1.10 root 117:
1.1.1.7 root 118: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
119:
1.1 root 120: // ウィンドウとして表示される画面はオプションや設定などで縮尺を変える
121: // ことが出来るが (こっちを実画面とする)、ここで扱う仮想画面とはそれに
122: // 関わらず常にその機種の最大描画面積を指す。
123: // LUNA でいう 1280 x 1024 のこと。
124:
125: // 仮想画面幅(ピクセル)
1.1.1.11! root 126: uint width {};
1.1 root 127:
128: // 仮想画面高さ(ピクセル)
1.1.1.11! root 129: uint height {};
1.1 root 130:
1.1.1.7 root 131: // レンダリング結果のビットマップ
1.1.1.11! root 132: BitmapRGBX bitmap {};
1.1 root 133:
1.1.1.11! root 134: // wxWidgets 用表示ビットマップ
! 135: std::unique_ptr<BitmapRGB> bitmap24 /*{}*/;
! 136:
! 137: // 表示ビットマップの大きさ
! 138: Rect viewrect {};
1.1.1.6 root 139:
1.1 root 140: // リクエストフラグ
1.1.1.4 root 141: uint32 request {};
1.1 root 142: std::mutex mtx {};
143: std::condition_variable cv {};
1.1.1.2 root 144:
1.1.1.11! root 145: // リサイズ時の要求サイズ
! 146: uint new_viewwidth {};
! 147: uint new_viewheight {};
! 148:
! 149: // レンダラ有効フラグ (GUI なら true)
1.1.1.7 root 150: bool enable {};
151:
1.1.1.11! root 152: // ステージ2 の全画面更新指示フラグ
! 153: bool invalidate2 {};
! 154:
! 155: // 初期化やリサイズ後に一度でも bitmap24 を更新すれば true。
! 156: bool bitmap24_valid {};
! 157:
1.1.1.7 root 158: // 更新情報を VM -> Renderer スレッドに渡すための 1 要素キュー
159: SPSCQueue<ModifyInfo, 1> modq {};
160:
161: // レンダラスレッドで受け取った更新情報 (モニタ表示のため)
162: ModifyInfo modify {};
1.1.1.2 root 163:
1.1.1.7 root 164: // 画面更新を UI に通知する間隔
165: uint64 refresh_interval {};
166: // 次回更新を通知する実時刻
167: uint64 next_refresh_rtime {};
168:
169: // 統計情報
1.1.1.11! root 170: uint32 last_mod_lines {}; // 直近の更新ライン数
1.1.1.7 root 171: uint64 total_invalidate2 {}; // ステージ2の全画面更新回数
172:
1.1.1.11! root 173: uint64 stat_input_count {}; // 入力通知回数
! 174: uint64 last_input_time {}; // 前回の入力通知 VM 時刻
! 175: FixedQueue<uint64, 4> ma_input_span {}; // 入力通知間隔
! 176: uint64 stat_enqueue_count {}; // リクエストキューに入れた回数
! 177: uint64 stat_enqueue_full {}; // キューに入れられなかった回数
! 178: uint64 stat_render_count {}; // RenderMD() の実行回数
! 179: uint64 stat_noupdate_count {}; // bitmap24 への更新が不要だった回数
! 180: uint64 stat_nobitmap_count {}; // bitmap24 が用意できてなかった回数
! 181: uint64 stat_output_count {}; // UI への出力通知回数
! 182: uint64 last_output_time {}; // 前回の出力通知 RT 時刻
! 183: FixedQueue<uint64, 4> ma_output_span {}; // 出力通知間隔
! 184:
! 185: Scheduler *scheduler {};
1.1.1.9 root 186: Syncer *syncer {};
1.1.1.7 root 187:
188: Monitor monitor { this };
189:
190: private:
1.1.1.2 root 191: // スレッドの終了を指示
1.1.1.7 root 192: void Terminate() override;
1.1 root 193: };
194:
195: //
196: // X68030 レンダラ
197: //
198: class X68030Renderer : public Renderer
199: {
1.1.1.3 root 200: using inherited = Renderer;
1.1 root 201: public:
202: X68030Renderer();
1.1.1.10 root 203: ~X68030Renderer() override;
1.1 root 204:
1.1.1.10 root 205: bool Init() override;
1.1.1.11! root 206: bool GetModifyMD(ModifyInfo *) const override;
! 207: void ClearDirtyMD() override;
! 208: bool RenderMD() override;
1.1.1.10 root 209:
210: private:
1.1.1.11! root 211: PlaneVRAMDevice *planevram {};
1.1.1.10 root 212: VideoCtlrDevice *videoctlr {};
1.1 root 213: };
214:
215: //
216: // LUNA レンダラ
217: //
218: class LunaRenderer : public Renderer
219: {
1.1.1.3 root 220: using inherited = Renderer;
1.1 root 221: public:
222: LunaRenderer();
1.1.1.10 root 223: ~LunaRenderer() override;
1.1 root 224:
1.1.1.10 root 225: bool Init() override;
1.1.1.11! root 226: bool GetModifyMD(ModifyInfo *) const override;
! 227: void ClearDirtyMD() override;
! 228: bool RenderMD() override;
1.1.1.10 root 229:
230: private:
1.1.1.11! root 231: PlaneVRAMDevice *planevram {};
1.1 root 232: };
233:
1.1.1.9 root 234: //
1.1.1.10 root 235: // 何もしないレンダラ
1.1.1.9 root 236: //
1.1.1.10 root 237: class NopRenderer : public Renderer
1.1.1.9 root 238: {
239: using inherited = Renderer;
240: public:
1.1.1.10 root 241: NopRenderer();
242: ~NopRenderer() override;
1.1.1.9 root 243:
1.1.1.11! root 244: bool GetModifyMD(ModifyInfo *) const override;
! 245: void ClearDirtyMD() override;
! 246: bool RenderMD() override;
1.1.1.9 root 247: };
248:
249: static inline Renderer *GetRenderer() {
250: return Object::GetObject<Renderer>(OBJ_RENDERER);
251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.