--- nono/vm/planevram.cpp 2026/04/29 17:05:25 1.1.1.3 +++ nono/vm/planevram.cpp 2026/04/29 17:05:29 1.1.1.4 @@ -25,10 +25,6 @@ PlaneVRAMDevice::PlaneVRAMDevice(int wid // レンダリング時に使うテーブルを事前に計算。 InitDeptable(); - -#if defined(HAVE_AVX2) - enable_avx2 = gMainApp.enable_avx2; -#endif } // デストラクタ @@ -57,7 +53,7 @@ PlaneVRAMDevice::InitDeptable() // %0000000a'0000000b'0000000c'0000000d'0000000e'0000000f'0000000g'0000000h // の64ビットに伸張する。 // (8ビットを各バイトの最下位ビットに対応させる) - for (int i = 0; i < 256; i++) { + for (uint i = 0; i < 256; i++) { uint64 res = 0; for (int bit = 0; bit < 8; bit++) { int n = bit * 8; @@ -85,21 +81,22 @@ PlaneVRAMDevice::ClearDirty() std::fill(dirty.begin(), dirty.end(), 0); } -// 更新情報を取得。 +// 更新情報を取得。更新がなければ false を返す。 // VM スレッドから呼ばれる。 -ModifyInfo -PlaneVRAMDevice::GetModify() const +bool +PlaneVRAMDevice::GetModify(ModifyInfo *mod) const { - ModifyInfo mod; - memcpy(&mod.bits[0], &dirty[0], mod.bits.size()); - // TODO: 互換性のために n_dirty 計算。廃止するかも。 + memcpy(&mod->bits[0], &dirty[0], mod->bits.size()); + + // 一つでも更新があれば dirty。 + mod->dirty = false; for (int i = 0; i < dirty.size(); i++) { if (dirty[i]) { - mod.n_dirty++; + mod->dirty = true; + break; } } - - return mod; + return mod->dirty; } // 画面合成。 @@ -130,15 +127,15 @@ PlaneVRAMDevice::Render(BitmapRGBX& dst, void PlaneVRAMDevice::RenderVRAMToComposite(const ModifyInfo& modify) { - const int width = composite.GetWidth(); - const int height = composite.GetHeight(); - const int planesz = (width / 8) * height; + const uint width = composite.GetWidth(); + const uint height = composite.GetHeight(); + const uint planesz = (width / 8) * height; // 1bpp はパレット的にはほぼ 4bpp と同じ扱いになる。 const int nplane4 = (nplane == 1) ? 4 : nplane; // テキスト合成画面を描く - for (int y = 0; y < height; y++) { + for (uint y = 0; y < height; y++) { uint8 mod = modify.bits[y]; if (mod == 0) { continue; @@ -148,7 +145,7 @@ PlaneVRAMDevice::RenderVRAMToComposite(c src += y * width / 32; uint64 *dst = (uint64 *)composite.GetRowPtr(y); - for (int x = 0; x < width / 32; x++) { + for (uint x = 0; x < width / 32; x++) { std::array data; // VRAM はホストエンディアンに関係なく 32bit で読み込んだ @@ -174,7 +171,7 @@ PlaneVRAMDevice::RenderVRAMToComposite(c data[2] = 0xffffffff; data[3] = 0xffffffff; } else { - int offset = planesz / sizeof(uint32); + uint offset = planesz / sizeof(uint32); for (int plane = 0; plane < nplane; plane++) { data[plane] = bswap32(src[plane * offset]); } @@ -217,8 +214,8 @@ void PlaneVRAMDevice::RenderCompositeToRGBX(BitmapRGBX& dst, const ModifyInfo& modify) { - const int width = dst.GetWidth(); - const int height = dst.GetHeight(); + const uint width = dst.GetWidth(); + const uint height = dst.GetHeight(); // view_mod は表示領域 view における更新ラスタ BitmapI8 view(width, height); @@ -277,53 +274,5 @@ PlaneVRAMDevice::RenderCompositeToRGBX(B } // view (I8) を Bitmap (RGBX) に展開する -#if defined(HAVE_AVX2) - if (__predict_true(enable_avx2)) { - RenderI8toRGBX_avx2(dst, view, view_mod); - } else -#endif - { - RenderI8toRGBX_gen(dst, view, view_mod); - } -} - -// I8 から RGBX への変換。(C++ 版) -void -PlaneVRAMDevice::RenderI8toRGBX_gen(BitmapRGBX& dst, const BitmapI8& view, - const std::vector& view_mod) -{ - for (int y = 0; y < view_mod.size(); y++) { - if (view_mod[y] == 0) { - continue; - } - - const uint8 *s8 = view.GetRowPtr(y); - uint32 *d = (uint32 *)dst.GetRowPtr(y); - - const uint32 *s = (const uint32 *)s8; - const uint32 *send = (const uint32 *)(s8 + view.GetWidth()); - for (; s < send;) { - // 4ピクセルずつ処理する - - // s は BitmapI8 なのでビッグエンディアン並びに相当。 - uint32 cc4 = *s++; - // 左側ピクセルが下位バイトになるよう並び替える - cc4 = htole32(cc4); - - // 4ピクセルをそれぞれ xBGR32 に変換 - uint32 c0 = palette[ cc4 & 0xff].xbgr; - uint32 c1 = palette[(cc4 >> 8) & 0xff].xbgr; - uint32 c2 = palette[(cc4 >> 16) & 0xff].xbgr; - uint32 c3 = palette[ cc4 >> 24 ].xbgr; - - // c0 = $x0B0G0R0 - // c1 = $x1B1G1R1 - // c2 = $x2B2G2R2 - // c3 = $x3B3G3R3 - *d++ = le32toh(c0); - *d++ = le32toh(c1); - *d++ = le32toh(c2); - *d++ = le32toh(c3); - } - } + dst.DrawBitmapI8Raster(view, palette, &view_mod[0]); }