|
|
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"
15: #include "monitor.h"
16: #include "spscqueue.h"
17: #include "stopwatch.h"
1.1 root 18: #include <condition_variable>
19: #include <mutex>
20:
1.1.1.9 ! root 21: class PlaneVRAMDevice;
! 22: class Syncer;
1.1.1.7 root 23:
24: // 更新情報交換用構造体
25: struct ModifyInfo
1.1 root 26: {
1.1.1.9 ! root 27: std::array<uint8, 1024> bits {};
1.1.1.7 root 28: uint32 n_dirty {};
29:
30: // パレットを変更した場合とスクロールした場合のように
31: // composite に変更によらず bitmap を更新する場合は true。
32: bool invalidate2 {};
33:
1.1.1.9 ! root 34: void Fill(uint8 v) {
1.1.1.7 root 35: std::fill(bits.begin(), bits.end(), v);
36: if (v) {
37: n_dirty = bits.size();
38: } else {
39: n_dirty = 0;
40: }
41: }
42:
43: bool IsClean() const { return n_dirty == 0; }
44: bool IsDirty() const { return n_dirty != 0; }
45: };
1.1 root 46:
1.1.1.7 root 47: class Renderer : public ThreadDevice
48: {
49: using inherited = ThreadDevice;
50: public:
1.1 root 51: static const uint REQ_TERMINATE = 0x01; // スレッド終了指示
52: static const uint REQ_REND_POWEROFF = 0x02; // 電源オフ時の描画指示
53: static const uint REQ_REND_NORMAL = 0x04; // 通常の描画指示
1.1.1.7 root 54:
1.1 root 55: public:
56: Renderer();
1.1.1.5 root 57: virtual ~Renderer() override;
1.1 root 58:
1.1.1.9 ! root 59: bool Init() override;
1.1.1.7 root 60: void ResetHard(bool poweron) override;
61: void PowerOff() override;
1.1 root 62:
1.1.1.7 root 63: // 出力ビットマップを取得
64: const BitmapRGB& GetBitmap() { return bitmap; }
1.1 root 65:
1.1.1.7 root 66: // 合成処理イネーブル
67: void Enable();
68:
69: // 画面合成処理 (CRTC/CRTC2 から呼ばれる)
1.1 root 70: void Render();
71:
1.1.1.7 root 72: // 全画面更新の指示 (パレット変更とスクロール座標変更で呼ばれる)
73: void Invalidate2();
1.1.1.6 root 74:
1.1 root 75: // 仮想画面幅(ピクセル)を取得
76: int GetWidth() const { return width; }
77:
78: // 仮想画面高さ(ピクセル)を取得
79: int GetHeight() const { return height; }
80:
1.1.1.7 root 81: // 描画更新(通知)間隔を設定 (GUI から呼ばれる)
82: void SetRefreshInterval(uint64 t);
1.1 root 83:
84: protected:
1.1.1.7 root 85: // レンダリングスレッド
86: void ThreadRun() override;
87:
1.1 root 88: // 画面合成。更新があれば true を返す。(派生クラス側で用意)
89: virtual bool RenderMain() = 0;
90:
1.1.1.7 root 91: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
92:
1.1 root 93: // ウィンドウとして表示される画面はオプションや設定などで縮尺を変える
94: // ことが出来るが (こっちを実画面とする)、ここで扱う仮想画面とはそれに
95: // 関わらず常にその機種の最大描画面積を指す。
96: // LUNA でいう 1280 x 1024 のこと。
97:
98: // 仮想画面幅(ピクセル)
1.1.1.4 root 99: int width {};
1.1 root 100:
101: // 仮想画面高さ(ピクセル)
1.1.1.4 root 102: int height {};
1.1 root 103:
1.1.1.7 root 104: // レンダリング結果のビットマップ
105: BitmapRGB bitmap {};
1.1 root 106:
1.1.1.7 root 107: // ステージ2 の全画面更新指示フラグ
108: bool invalidate2 {};
1.1.1.6 root 109:
1.1 root 110: // リクエストフラグ
1.1.1.4 root 111: uint32 request {};
1.1 root 112: std::mutex mtx {};
113: std::condition_variable cv {};
1.1.1.2 root 114:
1.1.1.7 root 115: // 合成処理有効フラグ
116: bool enable {};
117:
118: // 更新情報を VM -> Renderer スレッドに渡すための 1 要素キュー
119: SPSCQueue<ModifyInfo, 1> modq {};
120:
121: // レンダラスレッドで受け取った更新情報 (モニタ表示のため)
122: ModifyInfo modify {};
1.1.1.2 root 123:
1.1.1.7 root 124: // 画面更新を UI に通知する間隔
125: uint64 refresh_interval {};
126: // 次回更新を通知する実時刻
127: uint64 next_refresh_rtime {};
128:
129: // 出力画面に更新がある (UI に通知する必要がある) 場合は true
130: bool out_dirty {};
131:
132: // 統計情報
133: uint64 render_exec {}; // RenderMain() の実行回数
134: Stopwatch render_time {}; // RenderMain() の総実行時間
135: uint32 last_mod_blocks {}; // 直近の更新ブロック数
136: uint64 total_mod_blocks {}; // 総更新ブロック数
137: uint64 total_invalidate2 {}; // ステージ2の全画面更新回数
138:
1.1.1.9 ! root 139: PlaneVRAMDevice *planevram {};
! 140: Syncer *syncer {};
1.1.1.7 root 141:
142: Monitor monitor { this };
143:
144: private:
1.1.1.2 root 145: // スレッドの終了を指示
1.1.1.7 root 146: void Terminate() override;
1.1 root 147: };
148:
149: //
150: // X68030 レンダラ
151: //
152: class X68030Renderer : public Renderer
153: {
1.1.1.3 root 154: using inherited = Renderer;
1.1 root 155: public:
156: X68030Renderer();
1.1.1.5 root 157: virtual ~X68030Renderer() override;
1.1 root 158:
1.1.1.3 root 159: bool RenderMain() override;
1.1 root 160: };
161:
162: //
163: // LUNA レンダラ
164: //
165: class LunaRenderer : public Renderer
166: {
1.1.1.3 root 167: using inherited = Renderer;
1.1 root 168: public:
169: LunaRenderer();
1.1.1.5 root 170: virtual ~LunaRenderer() override;
1.1 root 171:
1.1.1.3 root 172: bool RenderMain() override;
1.1 root 173: };
174:
1.1.1.9 ! root 175: //
! 176: // NEWS レンダラ
! 177: //
! 178: class NewsRenderer : public Renderer
! 179: {
! 180: using inherited = Renderer;
! 181: public:
! 182: NewsRenderer();
! 183: virtual ~NewsRenderer() override;
! 184:
! 185: bool RenderMain() override;
! 186: };
! 187:
! 188: static inline Renderer *GetRenderer() {
! 189: return Object::GetObject<Renderer>(OBJ_RENDERER);
! 190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.