Annotation of nono/vm/renderer.h, revision 1.1.1.8

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.