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

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: }

unix.superglobalmegacorp.com

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