--- nono/vm/renderer.cpp 2026/04/29 17:04:32 1.1.1.2 +++ nono/vm/renderer.cpp 2026/04/29 17:04:50 1.1.1.4 @@ -1,12 +1,13 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "object.h" +#include "renderer.h" #include "bitmap.h" #include "bt454.h" -#include "renderer.h" +#include "mythread.h" #include "tvram.h" std::unique_ptr gRenderer; @@ -18,6 +19,9 @@ Renderer::Renderer() { logname = "renderer"; devname = "Render"; + + // 初回は必ず描画する? (電源オン直後かな?) + invalidate = true; } // デストラクタ @@ -88,11 +92,21 @@ Renderer::Render() cv.notify_one(); } +// 全画面無効化の指示 (パレット変更で呼ばれる)。 +// ここでは無効化だけ受け付けておいて、実際の処理はレンダリングの際に行う。 +void +Renderer::Invalidate() +{ + std::unique_lock lock(mtx); + request |= REQ_INVALIDATE; + cv.notify_one(); +} + // レンダリングスレッドのエントリポイント void * renderer_run(void *dummy) { - pthread_setname_np("Renderer"); + PTHREAD_SETNAME("Renderer"); gRenderer->ThreadRun(); return NULL; @@ -116,8 +130,8 @@ Renderer::ThreadRun() if ((req & REQ_TERMINATE)) { // 終了するので、他のフラグは無視 break; - - } else if ((req & REQ_REND_POWEROFF)) { + } + if ((req & REQ_REND_POWEROFF)) { // 電源オフ時の描画 (通常描画フラグは無視) // 電源オフされると画面を灰色にする。 @@ -125,8 +139,16 @@ Renderer::ThreadRun() memset(imagebuf, 0x70, width * height * BPP); // ウィンドウに通知 refresh_callback(); - - } else if ((req & REQ_REND_NORMAL)) { + continue; + } + if ((req & REQ_INVALIDATE)) { + // 全画面無効化の指示。ここではフラグを立てるだけ。 + // パレットは普段はまず変更されないが、変更する時には連続して + // 全パレットが変更されがちなので、ここでフラグを蓄積する。 + // このフラグは同じスレッドの RenderMain() 内で回収する。 + invalidate = true; + } + if ((req & REQ_REND_NORMAL)) { // 通常描画 // レンダラを駆動して @@ -192,11 +214,23 @@ LunaRenderer::~LunaRenderer() { } +bool +LunaRenderer::Init() +{ + if (inherited::Init() == false) { + return false; + } + + // ホストパレット配列を取得。 + pal = gBT454->GetHostPalette(); + return true; +} + + // 画面合成 bool LunaRenderer::RenderMain() { - const uint8 *pal; const uint32 *plane0; std::atomic *dirty; int hscroll; @@ -207,9 +241,6 @@ LunaRenderer::RenderMain() assert(imagebuf); dst0 = imagebuf; - // パレット取得 - pal = gBT454->GetHostPalette(); - // ビットマップ gBitmap->GetRFCNT(&hscroll, &vscroll); const uint8 *mem = gBitmap->GetBuf(); @@ -222,11 +253,20 @@ LunaRenderer::RenderMain() // レンダリング終了時に dirty が 2 なら 0 に戻す。 // これによりレンダリング中に VRAM への書き込みがあれば次回描画される。 + // 全域を無効化して画面全体を描画し直す。 + // XXX この処理中に VRAM 書き込み等があっても整合するんだっけこれ + if (invalidate) { + for (int y = 0; y < height; y++) { + dirty[y] = 1; + } + invalidate = false; + } + // sy はメモリ上の Y 座標 // dy はレンダラ画面の Y 座標 (RFCNT のラスタカウンタを考慮) // XXX とりあえず1プレーン - plane0 = (uint32 *)mem; + plane0 = (const uint32 *)mem; int sy = vscroll; for (int dy = 0; dy < height; dst0 += width * BPP, dy++, sy++) { sy &= 0x3ff;