mirror of
https://github.com/wled/WLED.git
synced 2025-07-23 10:46:33 +00:00
more improvements to setPixelColor
- code is a bit cleaner and faster as well - chaning array access to pointer access in bus_manager makes it a few instructions faster - changed getNumberOfPins and getNumberOfChannels to return 32bit values, saving the unnecessary 8bit conversion
This commit is contained in:
parent
5c2bac4b9d
commit
0a05611e1d
@ -156,21 +156,26 @@ uint16_t IRAM_ATTR_YN Segment::XY(int x, int y)
|
|||||||
// raw setColor function without checks (checks are done in setPixelColorXY())
|
// raw setColor function without checks (checks are done in setPixelColorXY())
|
||||||
void IRAM_ATTR_YN Segment::_setPixelColorXY_raw(int& x, int& y, uint32_t& col)
|
void IRAM_ATTR_YN Segment::_setPixelColorXY_raw(int& x, int& y, uint32_t& col)
|
||||||
{
|
{
|
||||||
|
const int baseX = start + x;
|
||||||
|
const int baseY = startY + y;
|
||||||
#ifndef WLED_DISABLE_MODE_BLEND
|
#ifndef WLED_DISABLE_MODE_BLEND
|
||||||
// if blending modes, blend with underlying pixel
|
// if blending modes, blend with underlying pixel
|
||||||
if (_modeBlend) col = color_blend(strip.getPixelColorXY(start + x, startY + y), col, 0xFFFFU - progress(), true);
|
if (_modeBlend) col = color_blend(strip.getPixelColorXY(baseX, baseY), col, 0xFFFFU - progress(), true);
|
||||||
#endif
|
#endif
|
||||||
strip.setPixelColorXY(start + x, startY + y, col);
|
strip.setPixelColorXY(baseX, baseY, col);
|
||||||
if (mirror) { //set the corresponding horizontally mirrored pixel
|
|
||||||
if (transpose) strip.setPixelColorXY(start + x, startY + height() - y - 1, col);
|
// Apply mirroring
|
||||||
else strip.setPixelColorXY(start + width() - x - 1, startY + y, col);
|
if (mirror || mirror_y) {
|
||||||
}
|
auto setMirroredPixel = [&](int mx, int my) {
|
||||||
if (mirror_y) { //set the corresponding vertically mirrored pixel
|
strip.setPixelColorXY(mx, my, col);
|
||||||
if (transpose) strip.setPixelColorXY(start + width() - x - 1, startY + y, col);
|
};
|
||||||
else strip.setPixelColorXY(start + x, startY + height() - y - 1, col);
|
|
||||||
}
|
const int mirrorX = start + width() - x - 1;
|
||||||
if (mirror_y && mirror) { //set the corresponding vertically AND horizontally mirrored pixel
|
const int mirrorY = startY + height() - y - 1;
|
||||||
strip.setPixelColorXY(start + width() - x - 1, startY + height() - y - 1, col);
|
|
||||||
|
if (mirror) setMirroredPixel(transpose ? baseX : mirrorX, transpose ? mirrorY : baseY);
|
||||||
|
if (mirror_y) setMirroredPixel(transpose ? mirrorX : baseX, transpose ? baseY : mirrorY);
|
||||||
|
if (mirror && mirror_y) setMirroredPixel(mirrorX, mirrorY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,16 +201,12 @@ void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col)
|
|||||||
int H = height();
|
int H = height();
|
||||||
x *= groupLen; // expand to physical pixels
|
x *= groupLen; // expand to physical pixels
|
||||||
y *= groupLen; // expand to physical pixels
|
y *= groupLen; // expand to physical pixels
|
||||||
int yY = y;
|
const int maxY = std::min(y + grouping, H);
|
||||||
for (int j = 0; j < grouping; j++) { // groupping vertically
|
const int maxX = std::min(x + grouping, W);
|
||||||
if (yY >= H) break;
|
for (int yY = y; yY < maxY; yY++) {
|
||||||
int xX = x;
|
for (int xX = x; xX < maxX; xX++) {
|
||||||
for (int g = 0; g < grouping; g++) { // groupping horizontally
|
|
||||||
if (xX >= W) break; // we have reached X dimension's end
|
|
||||||
_setPixelColorXY_raw(xX, yY, col);
|
_setPixelColorXY_raw(xX, yY, col);
|
||||||
xX++;
|
|
||||||
}
|
}
|
||||||
yY++;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_setPixelColorXY_raw(x, y, col);
|
_setPixelColorXY_raw(x, y, col);
|
||||||
|
@ -308,20 +308,20 @@ void BusDigital::setStatusPixel(uint32_t c) {
|
|||||||
|
|
||||||
void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
|
void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
|
||||||
if (!_valid) return;
|
if (!_valid) return;
|
||||||
uint8_t cctWW = 0, cctCW = 0;
|
|
||||||
if (hasWhite()) c = autoWhiteCalc(c);
|
if (hasWhite()) c = autoWhiteCalc(c);
|
||||||
if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
|
if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
|
||||||
if (_data) {
|
if (_data) {
|
||||||
size_t offset = pix * getNumberOfChannels();
|
size_t offset = pix * getNumberOfChannels();
|
||||||
|
uint8_t* dataptr = _data + offset;
|
||||||
if (hasRGB()) {
|
if (hasRGB()) {
|
||||||
_data[offset++] = R(c);
|
*dataptr++ = R(c);
|
||||||
_data[offset++] = G(c);
|
*dataptr++ = G(c);
|
||||||
_data[offset++] = B(c);
|
*dataptr++ = B(c);
|
||||||
}
|
}
|
||||||
if (hasWhite()) _data[offset++] = W(c);
|
if (hasWhite()) *dataptr++ = W(c);
|
||||||
// unfortunately as a segment may span multiple buses or a bus may contain multiple segments and each segment may have different CCT
|
// unfortunately as a segment may span multiple buses or a bus may contain multiple segments and each segment may have different CCT
|
||||||
// we need to store CCT value for each pixel (if there is a color correction in play, convert K in CCT ratio)
|
// we need to store CCT value for each pixel (if there is a color correction in play, convert K in CCT ratio)
|
||||||
if (hasCCT()) _data[offset] = Bus::_cct >= 1900 ? (Bus::_cct - 1900) >> 5 : (Bus::_cct < 0 ? 127 : Bus::_cct); // TODO: if _cct == -1 we simply ignore it
|
if (hasCCT()) *dataptr = Bus::_cct >= 1900 ? (Bus::_cct - 1900) >> 5 : (Bus::_cct < 0 ? 127 : Bus::_cct); // TODO: if _cct == -1 we simply ignore it
|
||||||
} else {
|
} else {
|
||||||
if (_reversed) pix = _len - pix -1;
|
if (_reversed) pix = _len - pix -1;
|
||||||
pix += _skip;
|
pix += _skip;
|
||||||
@ -336,8 +336,14 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
|
|||||||
case 2: c = RGBW32(R(cOld), G(cOld), W(c) , 0); break;
|
case 2: c = RGBW32(R(cOld), G(cOld), W(c) , 0); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasCCT()) Bus::calculateCCT(c, cctWW, cctCW);
|
uint16_t wwcw = 0;
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co, (cctCW<<8) | cctWW);
|
if (hasCCT()) {
|
||||||
|
uint8_t cctWW = 0, cctCW = 0;
|
||||||
|
Bus::calculateCCT(c, cctWW, cctCW);
|
||||||
|
wwcw = (cctCW<<8) | cctWW;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co, wwcw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +351,7 @@ void IRAM_ATTR BusDigital::setPixelColor(unsigned pix, uint32_t c) {
|
|||||||
uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
|
uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
|
||||||
if (!_valid) return 0;
|
if (!_valid) return 0;
|
||||||
if (_data) {
|
if (_data) {
|
||||||
size_t offset = pix * getNumberOfChannels();
|
const size_t offset = pix * getNumberOfChannels();
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
if (!hasRGB()) {
|
if (!hasRGB()) {
|
||||||
c = RGBW32(_data[offset], _data[offset], _data[offset], _data[offset]);
|
c = RGBW32(_data[offset], _data[offset], _data[offset], _data[offset]);
|
||||||
@ -356,7 +362,7 @@ uint32_t IRAM_ATTR BusDigital::getPixelColor(unsigned pix) const {
|
|||||||
} else {
|
} else {
|
||||||
if (_reversed) pix = _len - pix -1;
|
if (_reversed) pix = _len - pix -1;
|
||||||
pix += _skip;
|
pix += _skip;
|
||||||
unsigned co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
|
const unsigned co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
|
||||||
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, (_type==TYPE_WS2812_1CH_X3) ? IC_INDEX_WS2812_1CH_3X(pix) : pix, co),_bri);
|
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, (_type==TYPE_WS2812_1CH_X3) ? IC_INDEX_WS2812_1CH_3X(pix) : pix, co),_bri);
|
||||||
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs
|
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs
|
||||||
unsigned r = R(c);
|
unsigned r = R(c);
|
||||||
|
@ -110,7 +110,7 @@ class Bus {
|
|||||||
inline void setStart(uint16_t start) { _start = start; }
|
inline void setStart(uint16_t start) { _start = start; }
|
||||||
inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; }
|
inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; }
|
||||||
inline uint8_t getAutoWhiteMode() const { return _autoWhiteMode; }
|
inline uint8_t getAutoWhiteMode() const { return _autoWhiteMode; }
|
||||||
inline uint8_t getNumberOfChannels() const { return hasWhite() + 3*hasRGB() + hasCCT(); }
|
inline uint32_t getNumberOfChannels() const { return hasWhite() + 3*hasRGB() + hasCCT(); }
|
||||||
inline uint16_t getStart() const { return _start; }
|
inline uint16_t getStart() const { return _start; }
|
||||||
inline uint8_t getType() const { return _type; }
|
inline uint8_t getType() const { return _type; }
|
||||||
inline bool isOk() const { return _valid; }
|
inline bool isOk() const { return _valid; }
|
||||||
@ -119,8 +119,8 @@ class Bus {
|
|||||||
inline bool containsPixel(uint16_t pix) const { return pix >= _start && pix < _start + _len; }
|
inline bool containsPixel(uint16_t pix) const { return pix >= _start && pix < _start + _len; }
|
||||||
|
|
||||||
static inline std::vector<LEDType> getLEDTypes() { return {{TYPE_NONE, "", PSTR("None")}}; } // not used. just for reference for derived classes
|
static inline std::vector<LEDType> getLEDTypes() { return {{TYPE_NONE, "", PSTR("None")}}; } // not used. just for reference for derived classes
|
||||||
static constexpr uint8_t getNumberOfPins(uint8_t type) { return isVirtual(type) ? 4 : isPWM(type) ? numPWMPins(type) : is2Pin(type) + 1; } // credit @PaoloTK
|
static constexpr uint32_t getNumberOfPins(uint8_t type) { return isVirtual(type) ? 4 : isPWM(type) ? numPWMPins(type) : is2Pin(type) + 1; } // credit @PaoloTK
|
||||||
static constexpr uint8_t getNumberOfChannels(uint8_t type) { return hasWhite(type) + 3*hasRGB(type) + hasCCT(type); }
|
static constexpr uint32_t getNumberOfChannels(uint8_t type) { return hasWhite(type) + 3*hasRGB(type) + hasCCT(type); }
|
||||||
static constexpr bool hasRGB(uint8_t type) {
|
static constexpr bool hasRGB(uint8_t type) {
|
||||||
return !((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_ANALOG_1CH || type == TYPE_ANALOG_2CH || type == TYPE_ONOFF);
|
return !((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_ANALOG_1CH || type == TYPE_ANALOG_2CH || type == TYPE_ONOFF);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user