FastLED 3.10.8
Loading...
Searching...
No Matches

◆ vpass_rowmajor_impl()

template<int R, typename RGB_T, typename acc_t, bool ApplyAlpha, typename AlphaT>
static FL_OPTIMIZE_FUNCTION void fl::gfx::blur_detail::vpass_rowmajor_impl ( RGB_T * pixels,
int w,
int h,
RGB_T * scratch,
AlphaT alpha )
static

Definition at line 968 of file blur.cpp.hpp.

971 {
972 constexpr int shift = 2 * R;
973 using P = pixel_ops<RGB_T>;
974
975 // Ring buffer: bufs[0..R-1] = saved previous rows, bufs[R] = save slot.
976 // Extra zero_row for bottom-boundary padding.
977 RGB_T *bufs[5] = {nullptr, nullptr, nullptr, nullptr, nullptr};
978 for (int i = 0; i <= R; ++i)
979 bufs[i] = scratch + i * w;
980 RGB_T *zero_row = scratch + (R + 1) * w;
981
982 // Zero all: first R buffers (top-boundary padding) + zero_row.
983 FL_BUILTIN_MEMSET(scratch, 0, (R + 2) * w * sizeof(RGB_T));
984
985 for (int y = 0; y < h; ++y) {
986 RGB_T *out_row = pixels + y * w;
987
988 // Save current row before we overwrite it.
989 FL_BUILTIN_MEMCPY(bufs[R], out_row, w * sizeof(RGB_T));
990
991 // Forward row pointers (rows y+1 .. y+R, or zero_row if OOB).
992 const RGB_T *fwd[4] = {zero_row, zero_row, zero_row, zero_row};
993 for (int k = 0; k < R; ++k)
994 fwd[k] = (y + 1 + k < h) ? (pixels + (y + 1 + k) * w) : zero_row;
995
996 // Prefetch the furthest-ahead row needed by the NEXT iteration.
997 // At row y, next iteration needs fwd[R-1] = row y+1+R.
998 // Prefetching 2 rows ahead gives the memory subsystem time to fetch.
999 {
1000 const int prefetch_y = y + R + 2;
1001 if (prefetch_y < h) {
1002 const char *pf = (const char *)(pixels + prefetch_y * w);
1003 const int row_bytes = w * (int)sizeof(RGB_T);
1004 for (int off = 0; off < row_bytes; off += 64)
1005 __builtin_prefetch(pf + off, 0, 3);
1006 }
1007 }
1008
1009 // Process all pixels in this output row.
1010 // For u8-channel types (CRGB), process as raw byte stream — all
1011 // channels use the same kernel weights, so we treat the row as a
1012 // flat u8 array of w*sizeof(RGB_T) bytes. This produces a simpler
1013 // loop that the compiler can optimize better at low -O levels.
1014 if (sizeof(typename RGB_T::fp) == 1 && !ApplyAlpha) {
1015 // Raw byte fast path (CRGB without alpha).
1016 const int nbytes = w * (int)sizeof(RGB_T);
1017 u8 *ob = (u8 *)out_row;
1018
1019 simd_vconv_dispatch<R>::apply(bufs, fwd, ob, nbytes);
1020 } else {
1021 // Generic path: per-pixel struct access (CRGB16 or alpha case).
1022 for (int x = 0; x < w; ++x) {
1023 acc_t r, g, b;
1024
1026
1027 if (ApplyAlpha) {
1028 out_row[x] = P::make(static_cast<acc_t>(r >> shift),
1029 static_cast<acc_t>(g >> shift),
1030 static_cast<acc_t>(b >> shift), alpha);
1031 } else {
1032 out_row[x] = P::make(static_cast<acc_t>(r >> shift),
1033 static_cast<acc_t>(g >> shift),
1034 static_cast<acc_t>(b >> shift));
1035 }
1036 }
1037 }
1038
1039 // Rotate ring buffer: discard oldest, current becomes newest saved.
1040 RGB_T *recycled = bufs[0];
1041 for (int i = 0; i < R; ++i) bufs[i] = bufs[i + 1];
1042 bufs[R] = recycled;
1043 }
1044}
#define FL_BUILTIN_MEMCPY(dest, src, n)
#define FL_BUILTIN_MEMSET(dest, val, n)
unsigned char u8
Definition stdint.h:131
FASTLED_FORCE_INLINE fl::u8 P(fl::u8 x) FL_NO_EXCEPT
InputGamut g
Definition rgbw.h:125

References FL_BUILTIN_MEMCPY, FL_BUILTIN_MEMSET, fl::FL_NO_EXCEPT, fl::g, fl::P(), fl::x, and fl::y.

Referenced by vpass_full().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: