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