--- nono/vm/accel_neon.cpp 2026/04/29 17:05:29 1.1 +++ nono/vm/accel_neon.cpp 2026/04/29 17:05:51 1.1.1.2 @@ -11,30 +11,30 @@ #include "videoctlr.h" #include -// コントラスト (0-254) を適用。 +// コントラスト (1-254) を適用。dst サイズでクリップする。 // (ちなみに _gen は 1265 usec) /*static*/ void VideoCtlrDevice::RenderContrast_neon(BitmapRGBX& dst, const BitmapRGBX& src, uint32 contrast) { - // この変換は一次元配列とみなしても行える。 - // また必ずテキスト画面全域なので端数の考慮は不要。 - uint pxlen = src.GetWidth() * src.GetHeight(); - const uint32 *s32 = (const uint32 *)src.GetRowPtr(0); - uint32 *d32 = (uint32 *)dst.GetRowPtr(0); - uint32 *d32end = d32 + pxlen; - uint8x8_t vcont = vdup_n_u8(contrast); - for (; d32 < d32end; ) { - // 2ピクセルずつ処理する - // 614 usec + // 今のところ幅は 2ピクセルで割り切れる。 + uint width = dst.GetWidth(); + for (uint y = 0, yend = dst.GetHeight(); y < yend; y++) { + const uint32 *s32 = (const uint32 *)src.GetRowPtr(y); + uint32 *d32 = (uint32 *)dst.GetRowPtr(y); + uint32 *d32end = d32 + width; + for (; d32 < d32end; ) { + // 2ピクセルずつ処理する。 + // 614 usec - uint8x8_t vsrc = vld1_u8((const uint8 *)s32); - uint16x8_t vmul = vmull_u8(vsrc, vcont); - uint8x8_t vres = vrshrn_n_u16(vmul, 8); - vst1_u8((uint8 *)d32, vres); - s32 += 2; - d32 += 2; + uint8x8_t vsrc = vld1_u8((const uint8 *)s32); + uint16x8_t vmul = vmull_u8(vsrc, vcont); + uint8x8_t vres = vrshrn_n_u16(vmul, 8); + vst1_u8((uint8 *)d32, vres); + s32 += 2; + d32 += 2; + } } }