From 7a3123acd787ded38e0a262832d160334d6ad7dc Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Mon, 27 Jan 2025 19:15:04 +0100 Subject: [PATCH 1/3] improved speed and fixed issue - fixed issue: blending was also done when color was on a key-index-color which is now skipped - speed improvement: conversion is skipped if color is key-color --- wled00/colors.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/wled00/colors.cpp b/wled00/colors.cpp index f154a1aea0..d88cfe97e5 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -87,29 +87,31 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) uint32_t ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brightness, TBlendType blendType) { if (blendType == LINEARBLEND_NOWRAP) { - index = (index*240) >> 8; // Blend range is affected by lo4 blend of values, remap to avoid wrapping + index = (index * 0xF0) >> 8; // Blend range is affected by lo4 blend of values, remap to avoid wrapping } + uint32_t clr32; unsigned hi4 = byte(index) >> 4; - const CRGB* entry = (CRGB*)((uint8_t*)(&(pal[0])) + (hi4 * sizeof(CRGB))); - unsigned red1 = entry->r; - unsigned green1 = entry->g; - unsigned blue1 = entry->b; - if (blendType != NOBLEND) { + unsigned lo4 = (index & 0x0F); + const CRGB* entry = (CRGB*)&(pal[0]) + hi4; + if(lo4 && blendType != NOBLEND) { + unsigned red1 = entry->r; + unsigned green1 = entry->g; + unsigned blue1 = entry->b; if (hi4 == 15) entry = &(pal[0]); else ++entry; - unsigned f2 = ((index & 0x0F) << 4) + 1; // +1 so we scale by 256 as a max value, then result can just be shifted by 8 - unsigned f1 = (257 - f2); // f2 is 1 minimum, so this is 256 max - red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8; + unsigned f2 = (lo4 << 4); + unsigned f1 = 256 - f2; + red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8; // note: using color_blend() is 20% slower green1 = (green1 * f1 + (unsigned)entry->g * f2) >> 8; blue1 = (blue1 * f1 + (unsigned)entry->b * f2) >> 8; + clr32 = RGBW32(red1, green1, blue1, 0); } + else + clr32 = RGBW32(entry->r, entry->g, entry->b, 0); if (brightness < 255) { // note: zero checking could be done to return black but that is hardly ever used so it is omitted - uint32_t scale = brightness + 1; // adjust for rounding (bitshift) - red1 = (red1 * scale) >> 8; - green1 = (green1 * scale) >> 8; - blue1 = (blue1 * scale) >> 8; + clr32 = color_fade(clr32, brightness); } - return RGBW32(red1,green1,blue1,0); + return clr32; } void setRandomColor(byte* rgb) From 01977a4cd8d1e3c16acd808a7e75f162260ec7bb Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Tue, 28 Jan 2025 11:26:44 +0100 Subject: [PATCH 2/3] revert using color_fade() as it is slower - ran a few more tests, it is 30% faster like it was originally so reverting. The conversion to 32bit color appears to be wasteful in resources. --- wled00/colors.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/wled00/colors.cpp b/wled00/colors.cpp index d88cfe97e5..ae60caca8c 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -86,6 +86,7 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) // 1:1 replacement of fastled function optimized for ESP, slightly faster, more accurate and uses less flash (~ -200bytes) uint32_t ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brightness, TBlendType blendType) { + if (blendType == LINEARBLEND_NOWRAP) { index = (index * 0xF0) >> 8; // Blend range is affected by lo4 blend of values, remap to avoid wrapping } @@ -93,25 +94,25 @@ uint32_t ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t unsigned hi4 = byte(index) >> 4; unsigned lo4 = (index & 0x0F); const CRGB* entry = (CRGB*)&(pal[0]) + hi4; + unsigned red1 = entry->r; + unsigned green1 = entry->g; + unsigned blue1 = entry->b; if(lo4 && blendType != NOBLEND) { - unsigned red1 = entry->r; - unsigned green1 = entry->g; - unsigned blue1 = entry->b; if (hi4 == 15) entry = &(pal[0]); else ++entry; unsigned f2 = (lo4 << 4); unsigned f1 = 256 - f2; - red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8; // note: using color_blend() is 20% slower + red1 = (red1 * f1 + (unsigned)entry->r * f2) >> 8; // note: using color_blend() is 20% slower green1 = (green1 * f1 + (unsigned)entry->g * f2) >> 8; blue1 = (blue1 * f1 + (unsigned)entry->b * f2) >> 8; - clr32 = RGBW32(red1, green1, blue1, 0); } - else - clr32 = RGBW32(entry->r, entry->g, entry->b, 0); if (brightness < 255) { // note: zero checking could be done to return black but that is hardly ever used so it is omitted - clr32 = color_fade(clr32, brightness); + uint32_t scale = brightness + 1; // adjust for rounding (bitshift) + red1 = (red1 * scale) >> 8; // note: using color_fade() is 30% slower + green1 = (green1 * scale) >> 8; + blue1 = (blue1 * scale) >> 8; } - return clr32; + return RGBW32(red1,green1,blue1,0); } void setRandomColor(byte* rgb) From b0b66ae79b264e2bc5ec85ede39c5a22a85be3e6 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Tue, 28 Jan 2025 11:30:07 +0100 Subject: [PATCH 3/3] removed unnecessary changes --- wled00/colors.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/wled00/colors.cpp b/wled00/colors.cpp index ae60caca8c..500687b2ea 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -86,11 +86,9 @@ uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) // 1:1 replacement of fastled function optimized for ESP, slightly faster, more accurate and uses less flash (~ -200bytes) uint32_t ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t brightness, TBlendType blendType) { - if (blendType == LINEARBLEND_NOWRAP) { index = (index * 0xF0) >> 8; // Blend range is affected by lo4 blend of values, remap to avoid wrapping } - uint32_t clr32; unsigned hi4 = byte(index) >> 4; unsigned lo4 = (index & 0x0F); const CRGB* entry = (CRGB*)&(pal[0]) + hi4;