FastLED 3.9.15
Loading...
Searching...
No Matches
pixel_controller.h
Go to the documentation of this file.
1#pragma once
2
5
6// Note that new code should use the PixelIterator concrete object to write out
7// led data.
8// Using this class deep in driver code is deprecated because it's templates will
9// infact everything it touches. PixelIterator is concrete and doesn't have these
10// problems. See PixelController::as_iterator() for how to create a PixelIterator.
11
12
13#include "lib8tion/intmap.h"
14
15#include "rgbw.h"
17#include "fl/force_inline.h"
18#include "lib8tion/scale8.h"
19#include "fl/namespace.h"
20#include "eorder.h"
21#include "dither_mode.h"
22#include "pixel_iterator.h"
23#include "crgb.h"
24#include "fl/compiler_control.h"
25
26
27#include "FastLED.h" // Problematic.
28
29
34
35
37
38
45#define RO(X) RGB_BYTE(RGB_ORDER, X)
46
53#define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3)
54
57#define RGB_BYTE0(RO) ((RO>>6) & 0x3)
60#define RGB_BYTE1(RO) ((RO>>3) & 0x3)
63#define RGB_BYTE2(RO) ((RO) & 0x3)
64
65// operator byte *(struct CRGB[] arr) { return (byte*)arr; }
66
69 #if FASTLED_HD_COLOR_MIXING
70 CRGB color;
71 uint8_t brightness;
72 #endif
73};
74
75
82template<EOrder RGB_ORDER, int LANES=1, uint32_t MASK=0xFFFFFFFF>
84 const uint8_t *mData;
85 int mLen;
87 uint8_t d[3];
88 uint8_t e[3];
89 int8_t mAdvance;
90 int mOffsets[LANES];
92
93 enum {
94 kLanes = LANES,
95 kMask = MASK
96 };
97
101
103 #if FASTLED_HD_COLOR_MIXING
104 mColorAdjustment.premixed = CRGB(mColorAdjustment.brightness, mColorAdjustment.brightness, mColorAdjustment.brightness);
105 mColorAdjustment.color = CRGB(0xff, 0xff, 0xff);
106 #endif
107 }
108
112 copy(other);
113 }
114
115 template<EOrder RGB_ORDER_OTHER>
119
120 template<typename PixelControllerT>
121 void copy(const PixelControllerT& other) {
122 static_assert(int(kLanes) == int(PixelControllerT::kLanes), "PixelController lanes must match or mOffsets will be wrong");
123 static_assert(int(kMask) == int(PixelControllerT::kMask), "PixelController mask must match or else one or the other controls different lanes");
124 d[0] = other.d[0];
125 d[1] = other.d[1];
126 d[2] = other.d[2];
127 e[0] = other.e[0];
128 e[1] = other.e[1];
129 e[2] = other.e[2];
130 mData = other.mData;
131 mColorAdjustment = other.mColorAdjustment;
132 mAdvance = other.mAdvance;
133 mLenRemaining = mLen = other.mLen;
134 for(int i = 0; i < LANES; ++i) { mOffsets[i] = other.mOffsets[i]; }
135 }
136
139 void initOffsets(int len) {
140 int nOffset = 0;
141 for(int i = 0; i < LANES; ++i) {
142 mOffsets[i] = nOffset;
143 if((1<<i) & MASK) { nOffset += (len * mAdvance); }
144 }
145 }
146
155 const uint8_t *d, int len, ColorAdjustment color_adjustment,
156 EDitherMode dither, bool advance, uint8_t skip)
157 : mData(d), mLen(len), mLenRemaining(len), mColorAdjustment(color_adjustment) {
159 mData += skip;
160 mAdvance = (advance) ? 3+skip : 0;
161 initOffsets(len);
162 }
163
170 const CRGB *d, int len, ColorAdjustment color_adjustment,
172 : mData((const uint8_t*)d), mLen(len), mLenRemaining(len), mColorAdjustment(color_adjustment) {
174 mAdvance = 3;
175 initOffsets(len);
176 }
177
184 const CRGB &d, int len, ColorAdjustment color_adjustment, EDitherMode dither)
185 : mData((const uint8_t*)&d), mLen(len), mLenRemaining(len), mColorAdjustment(color_adjustment) {
187 mAdvance = 0;
188 initOffsets(len);
189 }
190
191 #if FASTLED_HD_COLOR_MIXING
192 uint8_t global_brightness() const {
193 return mColorAdjustment.brightness;
194 }
195 #endif
196
197
198#if !defined(NO_DITHERING) || (NO_DITHERING != 1)
199
201#define MAX_LIKELY_UPDATE_RATE_HZ 400
202
204#define MIN_ACCEPTABLE_DITHER_RATE_HZ 50
205
207#define UPDATES_PER_FULL_DITHER_CYCLE (MAX_LIKELY_UPDATE_RATE_HZ / MIN_ACCEPTABLE_DITHER_RATE_HZ)
208
222#define RECOMMENDED_VIRTUAL_BITS ((UPDATES_PER_FULL_DITHER_CYCLE>1) + \
223 (UPDATES_PER_FULL_DITHER_CYCLE>2) + \
224 (UPDATES_PER_FULL_DITHER_CYCLE>4) + \
225 (UPDATES_PER_FULL_DITHER_CYCLE>8) + \
226 (UPDATES_PER_FULL_DITHER_CYCLE>16) + \
227 (UPDATES_PER_FULL_DITHER_CYCLE>32) + \
228 (UPDATES_PER_FULL_DITHER_CYCLE>64) + \
229 (UPDATES_PER_FULL_DITHER_CYCLE>128) )
230
232#define VIRTUAL_BITS RECOMMENDED_VIRTUAL_BITS
233
234#endif
235
236
239#if !defined(NO_DITHERING) || (NO_DITHERING != 1)
240 // R is the digther signal 'counter'.
241 static uint8_t R = 0;
242 ++R;
243
244 // R is wrapped around at 2^ditherBits,
245 // so if ditherBits is 2, R will cycle through (0,1,2,3)
246 uint8_t ditherBits = VIRTUAL_BITS;
247 R &= (0x01 << ditherBits) - 1;
248
249 // Q is the "unscaled dither signal" itself.
250 // It's initialized to the reversed bits of R.
251 // If 'ditherBits' is 2, Q here will cycle through (0,128,64,192)
252 uint8_t Q = 0;
253
254 // Reverse bits in a byte
255 {
256 if(R & 0x01) { Q |= 0x80; }
257 if(R & 0x02) { Q |= 0x40; }
258 if(R & 0x04) { Q |= 0x20; }
259 if(R & 0x08) { Q |= 0x10; }
260 if(R & 0x10) { Q |= 0x08; }
261 if(R & 0x20) { Q |= 0x04; }
262 if(R & 0x40) { Q |= 0x02; }
263 if(R & 0x80) { Q |= 0x01; }
264 }
265
266 // Now we adjust Q to fall in the center of each range,
267 // instead of at the start of the range.
268 // If ditherBits is 2, Q will be (0, 128, 64, 192) at first,
269 // and this adjustment makes it (31, 159, 95, 223).
270 if( ditherBits < 8) {
271 Q += 0x01 << (7 - ditherBits);
272 }
273
274 // D and E form the "scaled dither signal"
275 // which is added to pixel values to affect the
276 // actual dithering.
277
278 // Setup the initial D and E values
279 for(int i = 0; i < 3; ++i) {
280 uint8_t s = mColorAdjustment.premixed.raw[i];
281 e[i] = s ? (256/s) + 1 : 0;
282 d[i] = scale8(Q, e[i]);
283#if (FASTLED_SCALE8_FIXED == 1)
284 if(d[i]) (--d[i]);
285#endif
286 if(e[i]) --e[i];
287 }
288#endif
289 }
290
295 return mLenRemaining >= n;
296 }
297
304 switch(dither) {
306 default: d[0]=d[1]=d[2]=e[0]=e[1]=e[2]=0; break;
307 }
308 }
309
313
316 FASTLED_FORCE_INLINE int lanes() { return LANES; }
317
321
324
328 // IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN
329 // clockless_trinket.h!
330 d[0] = e[0] - d[0];
331 d[1] = e[1] - d[1];
332 d[2] = e[2] - d[2];
333 }
334
337 d[RO(0)] = e[RO(0)] - d[RO(0)];
338 }
339
343
347 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t loadByte(PixelController & pc) { return pc.mData[RO(SLOT)]; }
348
353 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t loadByte(PixelController & pc, int lane) { return pc.mData[pc.mOffsets[lane] + RO(SLOT)]; }
354
360 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t dither(PixelController & pc, uint8_t b) { return b ? qadd8(b, pc.d[RO(SLOT)]) : 0; }
361
366 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t dither(PixelController & , uint8_t b, uint8_t d) { return b ? qadd8(b,d) : 0; }
367
373 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t scale(PixelController & pc, uint8_t b) { return scale8(b, pc.mColorAdjustment.premixed.raw[RO(SLOT)]); }
374
379 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t scale(PixelController & , uint8_t b, uint8_t scale) { return scale8(b, scale); }
380
386
387
391 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t loadAndScale(PixelController & pc) { return scale<SLOT>(pc, pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc))); }
392
397 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t loadAndScale(PixelController & pc, int lane) { return scale<SLOT>(pc, pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc, lane))); }
398
405 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t loadAndScale(PixelController & pc, int lane, uint8_t d, uint8_t scale) { return scale8(pc.dither<SLOT>(pc, pc.loadByte<SLOT>(pc, lane), d), scale); }
406
412 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t loadAndScale(PixelController & pc, int lane, uint8_t scale) { return scale8(pc.loadByte<SLOT>(pc, lane), scale); }
413
414
417 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t advanceAndLoadAndScale(PixelController & pc) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc); }
418
422 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t advanceAndLoadAndScale(PixelController & pc, int lane) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc, lane); }
423
428 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t advanceAndLoadAndScale(PixelController & pc, int lane, uint8_t scale) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc, lane, scale); }
429
431
432
437
443 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t getd(PixelController & pc) { return pc.d[RO(SLOT)]; }
444
450 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t getscale(PixelController & pc) { return pc.mColorAdjustment.premixed.raw[RO(SLOT)]; }
451
453
454
456
457 // Helper functions to get around gcc stupidities
458 FASTLED_FORCE_INLINE uint8_t loadAndScale0(int lane, uint8_t scale) { return loadAndScale<0>(*this, lane, scale); }
459 FASTLED_FORCE_INLINE uint8_t loadAndScale1(int lane, uint8_t scale) { return loadAndScale<1>(*this, lane, scale); }
460 FASTLED_FORCE_INLINE uint8_t loadAndScale2(int lane, uint8_t scale) { return loadAndScale<2>(*this, lane, scale); }
461 FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale0(int lane, uint8_t scale) { return advanceAndLoadAndScale<0>(*this, lane, scale); }
463
464 FASTLED_FORCE_INLINE uint8_t loadAndScale0(int lane) { return loadAndScale<0>(*this, lane); }
465 FASTLED_FORCE_INLINE uint8_t loadAndScale1(int lane) { return loadAndScale<1>(*this, lane); }
466 FASTLED_FORCE_INLINE uint8_t loadAndScale2(int lane) { return loadAndScale<2>(*this, lane); }
469
470 // LoadAndScale0 loads the pixel data in the order specified by RGB_ORDER and then scales it by the color correction values
471 // For example in color order GRB, loadAndScale0() will return the green channel scaled by the color correction value for green.
477
478 FASTLED_FORCE_INLINE uint8_t getScale0() { return getscale<0>(*this); }
479 FASTLED_FORCE_INLINE uint8_t getScale1() { return getscale<1>(*this); }
480 FASTLED_FORCE_INLINE uint8_t getScale2() { return getscale<2>(*this); }
481
482 #if FASTLED_HD_COLOR_MIXING
483 template<int SLOT> FASTLED_FORCE_INLINE static uint8_t getScaleFullBrightness(PixelController & pc) { return pc.mColorAdjustment.color.raw[RO(SLOT)]; }
484 // Gets the color corection and also the brightness as seperate values.
485 // This is needed for the higher precision chipsets like the APA102.
486 FASTLED_FORCE_INLINE void getHdScale(uint8_t* c0, uint8_t* c1, uint8_t* c2, uint8_t* brightness) {
487 *c0 = getScaleFullBrightness<0>(*this);
488 *c1 = getScaleFullBrightness<1>(*this);
489 *c2 = getScaleFullBrightness<2>(*this);
490 *brightness = mColorAdjustment.brightness;
491 }
492 #endif
493
494
495 FASTLED_FORCE_INLINE void loadAndScale_APA102_HD(uint8_t *b0_out, uint8_t *b1_out,
496 uint8_t *b2_out,
497 uint8_t *brightness_out) {
498 CRGB rgb = CRGB(mData[0], mData[1], mData[2]);
499 uint8_t brightness = 0;
500 if (rgb) {
501 #if FASTLED_HD_COLOR_MIXING
502 brightness = mColorAdjustment.brightness;
504 #else
505 brightness = 255;
506 CRGB scale = mColorAdjustment.premixed;
507 #endif
509 rgb,
510 scale,
512 &rgb,
513 &brightness);
514 }
515 const uint8_t b0_index = RGB_BYTE0(RGB_ORDER);
516 const uint8_t b1_index = RGB_BYTE1(RGB_ORDER);
517 const uint8_t b2_index = RGB_BYTE2(RGB_ORDER);
518 *b0_out = rgb.raw[b0_index];
519 *b1_out = rgb.raw[b1_index];
520 *b2_out = rgb.raw[b2_index];
521 *brightness_out = brightness;
522 }
523
524 FASTLED_FORCE_INLINE void loadAndScaleRGB(uint8_t *b0_out, uint8_t *b1_out,
525 uint8_t *b2_out) {
526 *b0_out = loadAndScale0();
527 *b1_out = loadAndScale1();
528 *b2_out = loadAndScale2();
529 }
530
531 // WS2816B has native 16 bit/channel color and internal 4 bit gamma correction.
532 // So we don't do gamma here, and we don't bother with dithering.
533 FASTLED_FORCE_INLINE void loadAndScale_WS2816_HD(uint16_t *s0_out, uint16_t *s1_out, uint16_t *s2_out) {
534 // Note that the WS2816 has a 4 bit gamma correction built in. To improve things this algorithm may
535 // change in the future with a partial gamma correction that is completed by the chipset gamma
536 // correction.
537 uint16_t r16 = map8_to_16(mData[0]);
538 uint16_t g16 = map8_to_16(mData[1]);
539 uint16_t b16 = map8_to_16(mData[2]);
540 if (r16 || g16 || b16) {
541 #if FASTLED_HD_COLOR_MIXING
542 uint8_t brightness = mColorAdjustment.brightness;
544 #else
545 uint8_t brightness = 255;
546 CRGB scale = mColorAdjustment.premixed;
547 #endif
548 if (scale[0] != 255) {
549 r16 = scale16by8(r16, scale[0]);
550 }
551 if (scale[1] != 255) {
552 g16 = scale16by8(g16, scale[1]);
553 }
554 if (scale[2] != 255) {
555 b16 = scale16by8(b16, scale[2]);
556 }
557 if (brightness != 255) {
558 r16 = scale16by8(r16, brightness);
559 g16 = scale16by8(g16, brightness);
560 b16 = scale16by8(b16, brightness);
561 }
562 }
563 uint16_t rgb16[3] = {r16, g16, b16};
564 const uint8_t s0_index = RGB_BYTE0(RGB_ORDER);
565 const uint8_t s1_index = RGB_BYTE1(RGB_ORDER);
566 const uint8_t s2_index = RGB_BYTE2(RGB_ORDER);
567 *s0_out = rgb16[s0_index];
568 *s1_out = rgb16[s1_index];
569 *s2_out = rgb16[s2_index];
570 }
571
572 FASTLED_FORCE_INLINE void loadAndScaleRGBW(Rgbw rgbw, uint8_t *b0_out, uint8_t *b1_out,
573 uint8_t *b2_out, uint8_t *b3_out) {
574#ifdef __AVR__
575 // Don't do RGBW conversion for AVR, just set the W pixel to black.
576 uint8_t out[4] = {
577 // Get the pixels in native order.
581 0,
582 };
583 EOrderW w_placement = rgbw.w_placement;
584 // Apply w-component insertion.
586 w_placement, out[0], out[1], out[2],
587 0, // Pre-ordered RGB data with a 0 white component.
588 b0_out, b1_out, b2_out, b3_out);
589#else
590 const uint8_t b0_index = RGB_BYTE0(RGB_ORDER); // Needed to re-order RGB back into led native order.
591 const uint8_t b1_index = RGB_BYTE1(RGB_ORDER);
592 const uint8_t b2_index = RGB_BYTE2(RGB_ORDER);
593 // Get the naive RGB data order in r,g,b order.
594 CRGB rgb(mData[0], mData[1], mData[2]);
595 uint8_t w = 0;
596 fl::rgb_2_rgbw(rgbw.rgbw_mode,
597 rgbw.white_color_temp,
598 rgb.r, rgb.g, rgb.b, // Input colors
599 mColorAdjustment.premixed.r, mColorAdjustment.premixed.g, mColorAdjustment.premixed.b, // How these colors are scaled for color balance.
600 &rgb.r, &rgb.g, &rgb.b, &w);
601 // Now finish the ordering so that the output is in the native led order for all of RGBW.
603 rgbw.w_placement,
604 rgb.raw[b0_index], // in-place re-ordering for the RGB data.
605 rgb.raw[b1_index],
606 rgb.raw[b2_index],
607 w, // The white component is not ordered in this call.
608 b0_out, b1_out, b2_out, b3_out); // RGBW data now in total native led order.
609#endif
610 }
611};
612
613
615
616
central include file for FastLED, defines the CFastLED class/object
uint16_t scale
Definition Noise.ino:74
Rgbw rgbw
UISlider brightness("Brightness", 128, 0, 255, 1)
#define FL_DISABLE_WARNING_IMPLICIT_INT_CONVERSION
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_SIGN_CONVERSION
#define FL_DISABLE_WARNING_POP
#define FL_DISABLE_WARNING_FLOAT_CONVERSION
Defines the red, green, and blue (RGB) pixel struct.
FASTLED_NAMESPACE_BEGIN typedef fl::u8 EDitherMode
The dither setting, either DISABLE_DITHER or BINARY_DITHER.
Definition dither_mode.h:17
#define BINARY_DITHER
Enable dithering using binary dithering (only option)
Definition dither_mode.h:14
Declares dithering options and types.
fl::EOrderW EOrderW
Definition eorder.h:10
Defines color channel ordering enumerations.
Declares functions for five-bit gamma correction.
#define FASTLED_FORCE_INLINE
Definition force_inline.h:6
LIB8STATIC_ALWAYS_INLINE uint8_t qadd8(uint8_t i, uint8_t j)
Add one byte to another, saturating at 0xFF.
Definition math8.h:40
LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8(uint16_t i, fract8 scale)
Scale a 16-bit unsigned value by an 8-bit value, which is treated as the numerator of a fraction whos...
Definition scale8.h:478
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:44
LIB8STATIC_ALWAYS_INLINE uint16_t map8_to_16(uint8_t x)
Definition intmap.h:25
Defines integer mapping functions.
#define FASTLED_NAMESPACE_END
Definition namespace.h:23
#define FASTLED_NAMESPACE_BEGIN
Definition namespace.h:22
Implements the FastLED namespace macros.
void five_bit_hd_gamma_bitshift(CRGB colors, CRGB colors_scale, fl::u8 global_brightness, CRGB *out_colors, fl::u8 *out_power_5bit)
FASTLED_FORCE_INLINE void rgb_2_rgbw(RGBW_MODE mode, uint16_t w_color_temperature, uint8_t r, uint8_t g, uint8_t b, uint8_t r_scale, uint8_t g_scale, uint8_t b_scale, uint8_t *out_r, uint8_t *out_g, uint8_t *out_b, uint8_t *out_w)
Converts RGB to RGBW using one of the functions.
Definition rgbw.h:149
void rgbw_partial_reorder(EOrderW w_placement, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t w, uint8_t *out_b0, uint8_t *out_b1, uint8_t *out_b2, uint8_t *out_b3)
Definition rgbw.cpp:134
#define VIRTUAL_BITS
Alias for RECOMMENDED_VIRTUAL_BITS.
#define RGB_BYTE2(RO)
Gets the color channel for byte 2.
#define RGB_BYTE1(RO)
Gets the color channel for byte 1.
#define RGB_BYTE0(RO)
Gets the color channel for byte 0.
#define RO(X)
Gets the assigned color channel for a byte's position in the output, using the color order (EOrder) t...
Non-templated low level pixel data writing class.
Functions for red, green, blue, white (RGBW) output.
Fast, efficient 8-bit scaling functions specifically designed for high-performance LED programming.
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:86
FASTLED_FORCE_INLINE uint8_t loadAndScale0(int lane)
non-template alias of loadAndScale<0>()
FASTLED_FORCE_INLINE void loadAndScale_WS2816_HD(uint16_t *s0_out, uint16_t *s1_out, uint16_t *s2_out)
static FASTLED_FORCE_INLINE uint8_t scale(PixelController &pc, uint8_t b)
Scale a value using the per-channel scale data.
FASTLED_FORCE_INLINE void loadAndScale_APA102_HD(uint8_t *b0_out, uint8_t *b1_out, uint8_t *b2_out, uint8_t *brightness_out)
FASTLED_FORCE_INLINE uint8_t stepAdvanceAndLoadAndScale0()
stepDithering() and advanceAndLoadAndScale0()
int8_t mAdvance
how many bytes to advance the pointer by each time. For CRGB this is 3.
FASTLED_FORCE_INLINE uint8_t loadAndScale1(int lane, uint8_t scale)
non-template alias of loadAndScale<1>()
FASTLED_FORCE_INLINE uint8_t stepAdvanceAndLoadAndScale0(int lane)
stepDithering() and advanceAndLoadAndScale0()
static FASTLED_FORCE_INLINE uint8_t loadAndScale(PixelController &pc, int lane, uint8_t scale)
Loads and scales a single byte for a given output slot and lane.
void init_binary_dithering()
Set up the values for binary dithering.
FASTLED_FORCE_INLINE uint8_t loadAndScale1(int lane)
non-template alias of loadAndScale<1>()
FASTLED_FORCE_INLINE uint8_t getScale0()
non-template alias of getscale<0>()
int mLenRemaining
counter for the number of LEDs left to process
FASTLED_FORCE_INLINE uint8_t loadAndScale2(int lane, uint8_t scale)
non-template alias of loadAndScale<2>()
void initOffsets(int len)
Initialize the PixelController::mOffsets array based on the length of the strip.
FASTLED_FORCE_INLINE void loadAndScaleRGB(uint8_t *b0_out, uint8_t *b1_out, uint8_t *b2_out)
FASTLED_FORCE_INLINE void preStepFirstByteDithering()
Some chipsets pre-cycle the first byte, which means we want to cycle byte 0's dithering separately.
FASTLED_FORCE_INLINE uint8_t loadAndScale2(int lane)
non-template alias of loadAndScale<2>()
FASTLED_FORCE_INLINE uint8_t loadAndScale0(int lane, uint8_t scale)
non-template alias of loadAndScale<0>()
FASTLED_FORCE_INLINE uint8_t loadAndScale0()
non-template alias of loadAndScale<0>()
FASTLED_FORCE_INLINE int advanceBy()
Get the amount to advance the pointer by.
const uint8_t * mData
pointer to the underlying LED data
static FASTLED_FORCE_INLINE uint8_t loadAndScale(PixelController &pc)
Loads, dithers, and scales a single byte for a given output slot, using class dither and scale values...
uint8_t d[3]
values for the scaled dither signal
FASTLED_FORCE_INLINE int lanes()
Get the number of lanes of the Controller.
int mOffsets[LANES]
the number of bytes to offset each lane from the starting pointer
FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale0(int lane, uint8_t scale)
non-template alias of advanceAndLoadAndScale<0>()
PixelController(const PixelController< RGB_ORDER_OTHER, LANES, MASK > &other)
PixelController(const CRGB &d, int len, ColorAdjustment color_adjustment, EDitherMode dither)
Constructor.
ColorAdjustment mColorAdjustment
FASTLED_FORCE_INLINE uint8_t getScale2()
non-template alias of getscale<2>()
static FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale(PixelController &pc)
A version of loadAndScale() that advances the output data pointer.
int mLen
number of LEDs in the data for one lane
static FASTLED_FORCE_INLINE uint8_t loadAndScale(PixelController &pc, int lane)
Loads, dithers, and scales a single byte for a given output slot and lane, using class dither and sca...
static FASTLED_FORCE_INLINE uint8_t loadByte(PixelController &pc)
Read a byte of LED data.
static FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale(PixelController &pc, int lane, uint8_t scale)
A version of loadAndScale() that advances the output data pointer without dithering.
static FASTLED_FORCE_INLINE uint8_t loadAndScale(PixelController &pc, int lane, uint8_t d, uint8_t scale)
Loads, dithers, and scales a single byte for a given output slot and lane.
FASTLED_FORCE_INLINE int size()
Get the length of the LED strip.
static FASTLED_FORCE_INLINE uint8_t getd(PixelController &pc)
Gets the dithering data for the provided output slot.
FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale0(int lane)
non-template alias of advanceAndLoadAndScale<0>()
uint8_t e[3]
values for the unscaled dither signal
static FASTLED_FORCE_INLINE uint8_t getscale(PixelController &pc)
Gets the scale data for the provided output slot.
static FASTLED_FORCE_INLINE uint8_t dither(PixelController &, uint8_t b, uint8_t d)
Calculate a dither value.
static FASTLED_FORCE_INLINE uint8_t dither(PixelController &pc, uint8_t b)
Calculate a dither value using the per-channel dither data.
FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale0()
non-template alias of advanceAndLoadAndScale<0>()
FASTLED_FORCE_INLINE void loadAndScaleRGBW(Rgbw rgbw, uint8_t *b0_out, uint8_t *b1_out, uint8_t *b2_out, uint8_t *b3_out)
void enable_dithering(EDitherMode dither)
Toggle dithering enable If dithering is set to enabled, this will re-init the dithering values (init_...
static FASTLED_FORCE_INLINE uint8_t scale(PixelController &, uint8_t b, uint8_t scale)
Scale a value.
FASTLED_FORCE_INLINE void advanceData()
Advance the data pointer forward, adjust position counter.
FASTLED_FORCE_INLINE bool has(int n)
Do we have n pixels left to process?
PixelController(const CRGB *d, int len, ColorAdjustment color_adjustment, EDitherMode dither)
Constructor.
FASTLED_FORCE_INLINE void stepDithering()
Step the dithering forward.
FASTLED_FORCE_INLINE uint8_t stepAdvanceAndLoadAndScale0(int lane, uint8_t scale)
stepDithering() and advanceAndLoadAndScale0()
FASTLED_FORCE_INLINE fl::PixelIterator as_iterator(const Rgbw &rgbw)
PixelController(const uint8_t *d, int len, ColorAdjustment color_adjustment, EDitherMode dither, bool advance, uint8_t skip)
Constructor.
PixelController(const PixelController &other)
Copy constructor.
FASTLED_FORCE_INLINE uint8_t loadAndScale1()
non-template alias of loadAndScale<1>()
static FASTLED_FORCE_INLINE uint8_t advanceAndLoadAndScale(PixelController &pc, int lane)
A version of loadAndScale() that advances the output data pointer.
FASTLED_FORCE_INLINE uint8_t getScale1()
non-template alias of getscale<1>()
static FASTLED_FORCE_INLINE uint8_t loadByte(PixelController &pc, int lane)
Read a byte of LED data for parallel output.
void copy(const PixelControllerT &other)
FASTLED_FORCE_INLINE uint8_t loadAndScale2()
non-template alias of loadAndScale<2>()
Pixel controller class.