diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 14:10:31 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 14:10:31 +0300 |
| commit | 7633ab2c60b40bd5aa67ef391b2a0d149685742f (patch) | |
| tree | 37d4f89722605a177715f400eb103382ff08e2c3 /src/screen.h | |
| parent | 274abc013e4b914b005191a7f74eaf2961a1e59e (diff) | |
Optimize screen scrolling, SIMD wrap padding, and reflow loops
- Batch full-screen scroll rotations, eliminating row-by-row scroll loops
- Use block memmove for sub-region scrolling, eliminating heap/stack row swaps
- Vectorize CELL_WRAP_PAD flag setting with AVX2/SSE2/NEON in screen.h
- Replace scalar tab-stop loops with 64-bit word stamping
- Optimize active row backwards scan in resize and erase mode 2
Diffstat (limited to 'src/screen.h')
| -rw-r--r-- | src/screen.h | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/screen.h b/src/screen.h index 0110049..50e18c6 100644 --- a/src/screen.h +++ b/src/screen.h @@ -42,6 +42,64 @@ static inline int phys_row(const struct term *t, int y) return p >= t->scr.rows ? p - t->scr.rows : p; } +#if defined(TERM_KERNEL_AVX2) +TERM_TARGET_AVX2 +static inline void set_cells_wrap_pad_avx2(struct cell *cells, int count) +{ + const __m256i mask = _mm256_setr_epi32(0, 0, 0, (int)CELL_WRAP_PAD, + 0, 0, 0, (int)CELL_WRAP_PAD); + int i = 0; + for (; i + 4 <= count; i += 4) { + __m256i v0 = _mm256_loadu_si256((const __m256i *)(cells + i)); + __m256i v1 = _mm256_loadu_si256((const __m256i *)(cells + i + 2)); + v0 = _mm256_or_si256(v0, mask); + v1 = _mm256_or_si256(v1, mask); + _mm256_storeu_si256((__m256i *)(cells + i), v0); + _mm256_storeu_si256((__m256i *)(cells + i + 2), v1); + } + for (; i < count; i++) + cells[i].flags |= CELL_WRAP_PAD; +} +#endif + +static inline void set_cells_wrap_pad(struct cell *cells, int count) +{ + if (count <= 0) + return; +#if defined(TERM_KERNEL_AVX2) + if (term_use_avx2() && count >= 4) { + set_cells_wrap_pad_avx2(cells, count); + return; + } +#endif +#if defined(__x86_64__) || defined(_M_X64) + const __m128i mask = _mm_setr_epi32(0, 0, 0, (int)CELL_WRAP_PAD); + int i = 0; + for (; i + 2 <= count; i += 2) { + __m128i v0 = _mm_loadu_si128((const __m128i *)(cells + i)); + __m128i v1 = _mm_loadu_si128((const __m128i *)(cells + i + 1)); + _mm_storeu_si128((__m128i *)(cells + i), _mm_or_si128(v0, mask)); + _mm_storeu_si128((__m128i *)(cells + i + 1), _mm_or_si128(v1, mask)); + } + for (; i < count; i++) + cells[i].flags |= CELL_WRAP_PAD; +#elif defined(__aarch64__) + const uint32x4_t mask = { 0, 0, 0, CELL_WRAP_PAD }; + int i = 0; + for (; i + 2 <= count; i += 2) { + uint32x4_t v0 = vld1q_u32((const uint32_t *)(cells + i)); + uint32x4_t v1 = vld1q_u32((const uint32_t *)(cells + i + 1)); + vst1q_u32((uint32_t *)(cells + i), vorrq_u32(v0, mask)); + vst1q_u32((uint32_t *)(cells + i + 1), vorrq_u32(v1, mask)); + } + for (; i < count; i++) + cells[i].flags |= CELL_WRAP_PAD; +#else + for (int i = 0; i < count; i++) + cells[i].flags |= CELL_WRAP_PAD; +#endif +} + static inline void init_ascii_text_row(struct text_row *tr, uint8_t *text, uint16_t len) { tr->text = text; |
