Missing clipping fix

- small speed optimisations
This commit is contained in:
Blaž Kristan 2024-08-01 10:24:40 +02:00
parent c03422ee37
commit 365c1987ed
3 changed files with 35 additions and 28 deletions

View File

@ -351,7 +351,7 @@ typedef enum mapping1D2D {
M12_sPinwheel = 4
} mapping1D2D_t;
// segment, 80 bytes
// segment, 68 bytes
typedef struct Segment {
public:
uint16_t start; // start index / start X coordinate 2D (left)
@ -639,7 +639,7 @@ typedef struct Segment {
uint16_t virtualHeight(void) const; // segment height in virtual pixels (accounts for groupping and spacing)
uint16_t nrOfVStrips(void) const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
#ifndef WLED_DISABLE_2D
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment
uint16_t XY(int x, int y); // support function to get relative index within segment
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); }
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); }
@ -678,7 +678,7 @@ typedef struct Segment {
inline void blur2d(fract8 blur_amount) { blur(blur_amount); }
inline void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); }
#else
inline uint16_t XY(uint16_t x, uint16_t y) { return x; }
inline uint16_t XY(int x, int y) { return x; }
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); }
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); }
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); }

View File

@ -161,8 +161,7 @@ void WS2812FX::setUpMatrix() {
#ifndef WLED_DISABLE_2D
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
uint16_t IRAM_ATTR Segment::XY(uint16_t x, uint16_t y)
{
uint16_t IRAM_ATTR Segment::XY(int x, int y) {
unsigned width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
unsigned height = virtualHeight(); // segment height in logical pixels (is always >= 1)
return isActive() ? (x%width) + (y%height) * width : 0;
@ -207,7 +206,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
int vH = virtualHeight();
#ifndef WLED_DISABLE_MODE_BLEND
if (!_modeBlend &&
if (isInTransition() && !_modeBlend &&
(blendingStyle == BLEND_STYLE_PUSH_RIGHT ||
blendingStyle == BLEND_STYLE_PUSH_LEFT ||
blendingStyle == BLEND_STYLE_PUSH_UP ||
@ -239,13 +238,16 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
x *= groupLength(); // expand to physical pixels
y *= groupLength(); // expand to physical pixels
if (x >= width() || y >= height()) return; // if pixel would fall out of segment just exit
int W = width();
int H = height();
if (x >= W || y >= H) return; // if pixel would fall out of segment just exit
uint32_t tmpCol = col;
for (int j = 0; j < grouping; j++) { // groupping vertically
for (int g = 0; g < grouping; g++) { // groupping horizontally
unsigned xX = (x+g), yY = (y+j);
if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end
if (xX >= W || yY >= H) continue; // we have reached one dimension's end
#ifndef WLED_DISABLE_MODE_BLEND
// if blending modes, blend with underlying pixel
@ -255,15 +257,15 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
strip.setPixelColorXY(start + xX, startY + yY, tmpCol);
if (mirror) { //set the corresponding horizontally mirrored pixel
if (transpose) strip.setPixelColorXY(start + xX, startY + height() - yY - 1, tmpCol);
else strip.setPixelColorXY(start + width() - xX - 1, startY + yY, tmpCol);
if (transpose) strip.setPixelColorXY(start + xX, startY + H - yY - 1, tmpCol);
else strip.setPixelColorXY(start + W - xX - 1, startY + yY, tmpCol);
}
if (mirror_y) { //set the corresponding vertically mirrored pixel
if (transpose) strip.setPixelColorXY(start + width() - xX - 1, startY + yY, tmpCol);
else strip.setPixelColorXY(start + xX, startY + height() - yY - 1, tmpCol);
if (transpose) strip.setPixelColorXY(start + W - xX - 1, startY + yY, tmpCol);
else strip.setPixelColorXY(start + xX, startY + H - yY - 1, tmpCol);
}
if (mirror_y && mirror) { //set the corresponding vertically AND horizontally mirrored pixel
strip.setPixelColorXY(width() - xX - 1, height() - yY - 1, tmpCol);
strip.setPixelColorXY(W - xX - 1, H - yY - 1, tmpCol);
}
}
}

View File

@ -754,7 +754,7 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
bool IRAM_ATTR Segment::isPixelClipped(int i) {
#ifndef WLED_DISABLE_MODE_BLEND
if (_clipStart != _clipStop && blendingStyle > BLEND_STYLE_FADE) {
bool invert = _clipStart > _clipStop; // ineverted start & stop
bool invert = _clipStart > _clipStop; // ineverted start & stop
int start = invert ? _clipStop : _clipStart;
int stop = invert ? _clipStart : _clipStop;
if (blendingStyle == BLEND_STYLE_FAIRY_DUST) {
@ -892,7 +892,8 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
#endif
#ifndef WLED_DISABLE_MODE_BLEND
if (!_modeBlend && (blendingStyle == BLEND_STYLE_PUSH_RIGHT || blendingStyle == BLEND_STYLE_PUSH_LEFT)) {
// if we blend using "push" style we need to "shift" new mode to left or right
if (isInTransition() && !_modeBlend && (blendingStyle == BLEND_STYLE_PUSH_RIGHT || blendingStyle == BLEND_STYLE_PUSH_LEFT)) {
unsigned prog = 0xFFFF - progress();
unsigned dI = prog * vL / 0xFFFF;
if (blendingStyle == BLEND_STYLE_PUSH_RIGHT) i -= dI;
@ -1043,7 +1044,7 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
#endif
#ifndef WLED_DISABLE_MODE_BLEND
if (!_modeBlend && (blendingStyle == BLEND_STYLE_PUSH_RIGHT || blendingStyle == BLEND_STYLE_PUSH_LEFT)) {
if (isInTransition() && !_modeBlend && (blendingStyle == BLEND_STYLE_PUSH_RIGHT || blendingStyle == BLEND_STYLE_PUSH_LEFT)) {
unsigned prog = 0xFFFF - progress();
unsigned dI = prog * vL / 0xFFFF;
if (blendingStyle == BLEND_STYLE_PUSH_RIGHT) i -= dI;
@ -1425,43 +1426,47 @@ void WS2812FX::service() {
unsigned dw = p * w / 0xFFFFU + 1;
unsigned dh = p * h / 0xFFFFU + 1;
switch (blendingStyle) {
case BLEND_STYLE_FAIRY_DUST: // fairy dust (must set entire segment, see isPixelXYClipped())
case BLEND_STYLE_FAIRY_DUST: // fairy dust (must set entire segment, see isPixelXYClipped())
Segment::setClippingRect(0, w, 0, h);
break;
case BLEND_STYLE_SWIPE_RIGHT: // left-to-right
case BLEND_STYLE_PUSH_RIGHT: // left-to-right
Segment::setClippingRect(0, dw, 0, h);
break;
case BLEND_STYLE_SWIPE_LEFT: // right-to-left
case BLEND_STYLE_SWIPE_LEFT: // right-to-left
case BLEND_STYLE_PUSH_LEFT: // right-to-left
Segment::setClippingRect(w - dw, w, 0, h);
break;
case BLEND_STYLE_PINCH_OUT: // corners
case BLEND_STYLE_PINCH_OUT: // corners
Segment::setClippingRect((w + dw)/2, (w - dw)/2, (h + dh)/2, (h - dh)/2); // inverted!!
break;
case BLEND_STYLE_INSIDE_OUT: // outward
case BLEND_STYLE_INSIDE_OUT: // outward
Segment::setClippingRect((w - dw)/2, (w + dw)/2, (h - dh)/2, (h + dh)/2);
break;
case BLEND_STYLE_SWIPE_DOWN: // top-to-bottom (2D)
case BLEND_STYLE_SWIPE_DOWN: // top-to-bottom (2D)
case BLEND_STYLE_PUSH_DOWN: // top-to-bottom (2D)
Segment::setClippingRect(0, w, 0, dh);
break;
case BLEND_STYLE_SWIPE_UP: // bottom-to-top (2D)
case BLEND_STYLE_SWIPE_UP: // bottom-to-top (2D)
case BLEND_STYLE_PUSH_UP: // bottom-to-top (2D)
Segment::setClippingRect(0, w, h - dh, h);
break;
case BLEND_STYLE_OPEN_H: // horizontal-outward (2D) same look as INSIDE_OUT on 1D
case BLEND_STYLE_OPEN_H: // horizontal-outward (2D) same look as INSIDE_OUT on 1D
Segment::setClippingRect((w - dw)/2, (w + dw)/2, 0, h);
break;
case BLEND_STYLE_OPEN_V: // vertical-outward (2D)
case BLEND_STYLE_OPEN_V: // vertical-outward (2D)
Segment::setClippingRect(0, w, (h - dh)/2, (h + dh)/2);
break;
case BLEND_STYLE_PUSH_TL: // TL-to-BR (2D)
case BLEND_STYLE_PUSH_TL: // TL-to-BR (2D)
Segment::setClippingRect(0, dw, 0, dh);
break;
case BLEND_STYLE_PUSH_TR: // TR-to-BL (2D)
case BLEND_STYLE_PUSH_TR: // TR-to-BL (2D)
Segment::setClippingRect(w - dw, w, 0, dh);
break;
case BLEND_STYLE_PUSH_BR: // BR-to-TL (2D)
case BLEND_STYLE_PUSH_BR: // BR-to-TL (2D)
Segment::setClippingRect(w - dw, w, h - dh, h);
break;
case BLEND_STYLE_PUSH_BL: // BL-to-TR (2D)
case BLEND_STYLE_PUSH_BL: // BL-to-TR (2D)
Segment::setClippingRect(0, dw, h - dh, h);
break;
}