FastLED 3.9.12
Loading...
Searching...
No Matches
pixel_iterator.h
Go to the documentation of this file.
1
3
4#pragma once
5
6#include <stddef.h>
7#include <stdint.h>
8#include <string.h>
9
10#include "fl/namespace.h"
11#include "rgbw.h"
12
13#include "crgb.h"
14
16
17template<typename PixelControllerT>
19 static void loadAndScaleRGBW(void* pixel_controller, Rgbw rgbw, uint8_t* b0_out, uint8_t* b1_out, uint8_t* b2_out, uint8_t* b3_out) {
20 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
21 pc->loadAndScaleRGBW(rgbw, b0_out, b1_out, b2_out, b3_out);
22 }
23
24 static void loadAndScaleRGB(void* pixel_controller, uint8_t* r_out, uint8_t* g_out, uint8_t* b_out) {
25 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
26 pc->loadAndScaleRGB(r_out, g_out, b_out);
27 }
28
29 static void loadAndScale_APA102_HD(void* pixel_controller, uint8_t* b0_out, uint8_t* b1_out, uint8_t* b2_out, uint8_t* brightness_out) {
30 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
31 pc->loadAndScale_APA102_HD(b0_out, b1_out, b2_out, brightness_out);
32 }
33
34 static void loadAndScale_WS2816_HD(void* pixel_controller, uint16_t *s0_out, uint16_t* s1_out, uint16_t* s2_out) {
35 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
36 pc->loadAndScale_WS2816_HD(s0_out, s1_out, s2_out);
37 }
38
39 static void stepDithering(void* pixel_controller) {
40 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
41 pc->stepDithering();
42 }
43
44 static void advanceData(void* pixel_controller) {
45 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
46 pc->advanceData();
47 }
48
49 static int size(void* pixel_controller) {
50 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
51 return pc->size();
52 }
53 static bool has(void* pixel_controller, int n) {
54 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
55 return pc->has(n);
56 }
57
58 // function for getHdScale
59 #if FASTLED_HD_COLOR_MIXING
60 static void getHdScale(void* pixel_controller, uint8_t* c0, uint8_t* c1, uint8_t* c2, uint8_t* brightness) {
61 PixelControllerT* pc = static_cast<PixelControllerT*>(pixel_controller);
62 pc->getHdScale(c0, c1, c2, brightness);
63 }
64 #endif
65};
66
67typedef void (*loadAndScaleRGBWFunction)(void* pixel_controller, Rgbw rgbw, uint8_t* b0_out, uint8_t* b1_out, uint8_t* b2_out, uint8_t* b3_out);
68typedef void (*loadAndScaleRGBFunction)(void* pixel_controller, uint8_t* r_out, uint8_t* g_out, uint8_t* b_out);
69typedef void (*loadAndScale_APA102_HDFunction)(void* pixel_controller, uint8_t* b0_out, uint8_t* b1_out, uint8_t* b2_out, uint8_t* brightness_out);
70typedef void (*loadAndScale_WS2816_HDFunction)(void* pixel_controller, uint16_t* b0_out, uint16_t* b1_out, uint16_t* b2_out);
71typedef void (*stepDitheringFunction)(void* pixel_controller);
72typedef void (*advanceDataFunction)(void* pixel_controller);
73typedef int (*sizeFunction)(void* pixel_controller);
74typedef bool (*hasFunction)(void* pixel_controller, int n);
75typedef uint8_t (*globalBrightness)(void* pixel_controller);
76typedef void (*getHdScaleFunction)(void* pixel_controller, uint8_t* c0, uint8_t* c1, uint8_t* c2, uint8_t* brightness);
77
78
79// PixelIterator is turns a PixelController<> into a concrete object that can be used to iterate
80// over pixels and transform them into driver data. See PixelController<>::as_iterator() for how
81// to create a PixelIterator.
82// Note: This is designed for micro-controllers with a lot of memory. DO NOT use this in the core library
83// as a PixelIterator consumes a *lot* more instruction data than an instance of PixelController<RGB_ORDER>.
84// This iterator is designed for code in src/platforms/**.
86 public:
87 template<typename PixelControllerT>
88 PixelIterator(PixelControllerT* pc, Rgbw rgbw)
89 : mPixelController(pc), mRgbw(rgbw) {
90 // Manually build up a vtable.
91 // Wait... what? Stupid nerds trying to show off how smart they are...
92 // Why not just use a virtual function?!
93 //
94 // Before you think this then you should know that the alternative straight
95 // forward way is to have a virtual interface class that PixelController inherits from.
96 // ...and that was already tried. And if you try to do this yourself
97 // this then let me tell you what is going to happen...
98 //
99 // EVERY SINGLE PLATFORM THAT HAS A COMPILED BINARY SIZE CHECK WILL IMMEDIATELY
100 // FAIL AS THE BINARY BLOWS UP BY 10-30%!!! It doesn't matter if only one PixelController
101 // with a vtable is used, gcc seems not to de-virtualize the calls. And we really care
102 // about binary size since FastLED needs to run on those tiny little microcontrollers like
103 // the Attiny85 (and family) which are in the sub $1 range used for commercial products.
104 //
105 // So to satisfy these tight memory requirements we make the dynamic dispatch used in PixelIterator
106 // an optional zero-cost abstraction which doesn't affect the binary size for platforms that
107 // don't use it. So that's why we are using this manual construction of the vtable that is built
108 // up using template magic. If your platform has lots of memory then you'll gladly trade
109 // a sliver of memory for the convenience of having a concrete implementation of
110 // PixelController that you can use without having to make all your driver code a template.
111 //
112 // Btw, this pattern in C++ is called the "type-erasure pattern". It allows non virtual
113 // polymorphism by leveraging the C++ template system to ensure type safety.
115 mLoadAndScaleRGBW = &Vtable::loadAndScaleRGBW;
116 mLoadAndScaleRGB = &Vtable::loadAndScaleRGB;
117 mLoadAndScale_APA102_HD = &Vtable::loadAndScale_APA102_HD;
118 mLoadAndScale_WS2816_HD = &Vtable::loadAndScale_WS2816_HD;
119 mStepDithering = &Vtable::stepDithering;
120 mAdvanceData = &Vtable::advanceData;
121 mSize = &Vtable::size;
122 mHas = &Vtable::has;
123 #if FASTLED_HD_COLOR_MIXING
124 mGetHdScale = &Vtable::getHdScale;
125 #endif
126 }
127
128 bool has(int n) { return mHas(mPixelController, n); }
129 void loadAndScaleRGBW(uint8_t *b0_out, uint8_t *b1_out, uint8_t *b2_out, uint8_t *w_out) {
130 mLoadAndScaleRGBW(mPixelController, mRgbw, b0_out, b1_out, b2_out, w_out);
131 }
132 void loadAndScaleRGB(uint8_t *r_out, uint8_t *g_out, uint8_t *b_out) {
133 mLoadAndScaleRGB(mPixelController, r_out, g_out, b_out);
134 }
135 void loadAndScale_APA102_HD(uint8_t *b0_out, uint8_t *b1_out, uint8_t *b2_out, uint8_t *brightness_out) {
136 mLoadAndScale_APA102_HD(mPixelController, b0_out, b1_out, b2_out, brightness_out);
137 }
138 void loadAndScale_WS2816_HD(uint16_t *s0_out, uint16_t *s1_out, uint16_t *s2_out) {
139 mLoadAndScale_WS2816_HD(mPixelController, s0_out, s1_out, s2_out);
140 }
141 void stepDithering() { mStepDithering(mPixelController); }
142 void advanceData() { mAdvanceData(mPixelController); }
143 int size() { return mSize(mPixelController); }
144
145 void set_rgbw(Rgbw rgbw) { mRgbw = rgbw; }
146 Rgbw get_rgbw() const { return mRgbw; }
147
148 #if FASTLED_HD_COLOR_MIXING
149 void getHdScale(uint8_t* c0, uint8_t* c1, uint8_t* c2, uint8_t* brightness) {
150 mGetHdScale(mPixelController, c0, c1, c2, brightness);
151 }
152 #endif
153
154 private:
155 // vtable emulation
156 void* mPixelController = nullptr;
157 Rgbw mRgbw;
158 loadAndScaleRGBWFunction mLoadAndScaleRGBW = nullptr;
159 loadAndScaleRGBFunction mLoadAndScaleRGB = nullptr;
160 loadAndScale_APA102_HDFunction mLoadAndScale_APA102_HD = nullptr;
161 loadAndScale_WS2816_HDFunction mLoadAndScale_WS2816_HD = nullptr;
162 stepDitheringFunction mStepDithering = nullptr;
163 advanceDataFunction mAdvanceData = nullptr;
164 sizeFunction mSize = nullptr;
165 hasFunction mHas = nullptr;
166 #if FASTLED_HD_COLOR_MIXING
167 getHdScaleFunction mGetHdScale = nullptr;
168 #endif
169};
170
171
Defines the red, green, and blue (RGB) pixel struct.
Implements the FastLED namespace macros.
#define FASTLED_NAMESPACE_END
End of the FastLED namespace.
Definition namespace.h:16
#define FASTLED_NAMESPACE_BEGIN
Start of the FastLED namespace.
Definition namespace.h:14
Functions for red, green, blue, white (RGBW) output.
Definition rgbw.h:28