-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Stencil blendingmode and some speed optimisations #4889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- better performance at the cost of about 700 bytes of flash
- Stencil overlay adds an FX on top but leaves the backgroundcolor transparent, this is useful for classic text overlays
WalkthroughUnifies per-pixel blending into a new segblend routine, adds stencil (bm=32) support, introduces push/mirror/reverse/transpose coordinate handling, updates the UI to send explicit blend values, and simplifies JSON deserialization for segment blendMode; header docs updated to mention "stencil". Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
wled00/FX.h (1)
459-459
: Document exact bm codes, incl. Stencil (32) and Average (5).Make the mapping explicit to avoid confusion and to reflect the UI: 0=top, 1=bottom, 2=add, 3=subtract, 4=difference, 5=average, 6=multiply, 7=divide, 8=lighten, 9=darken, 10=screen, 11=overlay, 12=hardlight, 13=softlight, 14=dodge, 15=burn, 32=stencil (uses colors[1] as background mask).
- uint8_t blendMode; // segment blending modes: top, bottom, add, subtract, difference, multiply, divide, lighten, darken, screen, overlay, hardlight, softlight, dodge, burn, stencil + uint8_t blendMode; // segment blending modes (bm): 0=top,1=bottom,2=add,3=subtract,4=difference,5=average,6=multiply,7=divide,8=lighten,9=darken,10=screen,11=overlay,12=hardlight,13=softlight,14=dodge,15=burn,32=stencil (bg=colors[1])wled00/data/index.js (1)
2362-2365
: Send bm as a number, not a string.Parse to int before sending to avoid accidental string types and keep consistency with other setters.
- var value = gId(`seg${s}bm`).value; - var obj = {"seg": {"id": s, "bm": value}}; + const value = parseInt(gId(`seg${s}bm`).value, 10); + const obj = {"seg": {"id": s, "bm": value}};wled00/json.cpp (1)
305-305
: Validate bm to allowed set (0–15, 32).Removing the clamp enables arbitrary values. segblend defaults to “Top”, but guarding here prevents unexpected UI/API inputs from drifting.
- getVal(elem["bm"], seg.blendMode); + if (getVal(elem["bm"], seg.blendMode)) { + if (seg.blendMode != 32 && seg.blendMode > 15) seg.blendMode = 0; // fallback to Top + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
wled00/FX.h
(1 hunks)wled00/FX_fcn.cpp
(6 hunks)wled00/data/index.js
(2 hunks)wled00/json.cpp
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
wled00/data/**/*.{htm,html,css,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data
Files:
wled00/data/index.js
wled00/{*.cpp,!(html_*)*.h}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use spaces (2 per level) for C++ source and header files
Files:
wled00/FX.h
wled00/json.cpp
wled00/FX_fcn.cpp
🧠 Learnings (2)
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
PR: wled/WLED#4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Applied to files:
wled00/FX_fcn.cpp
📚 Learning: 2025-06-07T15:58:42.579Z
Learnt from: willmmiles
PR: wled/WLED#4712
File: wled00/FX_fcn.cpp:992-993
Timestamp: 2025-06-07T15:58:42.579Z
Learning: In WLED segments, the backing pixel buffer is always allocated to the full physical segment size, but effect rendering only uses a subset when mirror or grouping are enabled. For 2D segments, this subset is vWidth() * vHeight(), and for 1D segments it's vLength(). Color processing operations like fade_out should iterate over this rendering subset, not the full allocated buffer.
Applied to files:
wled00/FX_fcn.cpp
🧬 Code graph analysis (2)
wled00/json.cpp (1)
wled00/util.cpp (2)
getVal
(66-83)getVal
(66-66)
wled00/FX_fcn.cpp (1)
wled00/colors.cpp (4)
color_add
(28-61)color_add
(28-28)color_blend
(11-21)color_blend
(11-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: wled_build / Build Environments (usermods)
- GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
- GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
- GitHub Check: wled_build / Build Environments (esp32c3dev)
- GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
- GitHub Check: wled_build / Build Environments (esp01_1m_full_compat)
- GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
- GitHub Check: wled_build / Build Environments (nodemcuv2_160)
- GitHub Check: wled_build / Build Environments (esp32dev)
- GitHub Check: wled_build / Build Environments (esp32_eth)
- GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
- GitHub Check: wled_build / Build Environments (esp32_wrover)
- GitHub Check: wled_build / Build Environments (esp01_1m_full)
- GitHub Check: wled_build / Build Environments (esp8266_2m_160)
- GitHub Check: wled_build / Build Environments (lolin_s2_mini)
- GitHub Check: wled_build / Build Environments (esp8266_2m_compat)
- GitHub Check: wled_build / Build Environments (nodemcuv2)
- GitHub Check: wled_build / Build Environments (esp8266_2m)
🔇 Additional comments (2)
wled00/data/index.js (1)
828-829
: UI option for Stencil (32) looks good.Matches FX_fcn implementation and JSON handling.
wled00/FX_fcn.cpp (1)
1345-1572
: Consolidation into segblend + push/mirror logic: solid.The restructure reduces branching and enables Stencil; coordinate transforms are gated and reused cleanly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
wled00/FX_fcn.cpp (1)
1324-1324
: Subtract mode green-channel bug fixedThe green channel now subtracts bottom from top like the others. Thanks for addressing the prior issue.
🧹 Nitpick comments (3)
wled00/FX_fcn.cpp (3)
1317-1343
: segblend() consolidation: clear and fast pathSingle switch-based routine reduces indirections and keeps hot code tight. Consider forcing placement/inlining for hot path:
- Add IRAM attribute and inline hint to avoid flash stalls in tight per-pixel loops.
-static uint32_t segblend(CRGBW tcol, CRGBW bcol, CRGBW bgcol, uint8_t blendMode) { +IRAM_ATTR static inline uint32_t segblend(CRGBW tcol, CRGBW bcol, CRGBW bgcol, uint8_t blendMode) {
1339-1340
: Stencil semantics: exact color match vs. toleranceEquality on 32-bit color is correct for a pure stencil, but can be brittle if upstream effects introduce minor channel drift. If you see unexpected “holes,” consider (optional) channel-tolerance compare.
- case 32: return tcol.color32 == bgcol.color32 ? bcol.color32 : tcol.color32; // Stencil + case 32: { + // Optional tolerance (e.g. 0..2) to avoid miss due to rounding/dithering + constexpr uint8_t tol = 0; + bool isBG = + (abs(int(tC.r)-int(bgcol.r)) <= tol) && + (abs(int(tC.g)-int(bgcol.g)) <= tol) && + (abs(int(tC.b)-int(bgcol.b)) <= tol) && + (abs(int(tC.w)-int(bgcol.w)) <= tol); + return isBG ? bcol.color32 : tcol.color32; + }
1452-1463
: Push offsets computed once; clean modulo handlingEfficient offset math and sign handling. Minor nit: make offset vars int to avoid implicit unsigned wrap on negatives before the modulo.
- unsigned offsetX = (blendingStyle == BLEND_STYLE_PUSH_UP || blendingStyle == BLEND_STYLE_PUSH_DOWN) ? 0 : progInv * nCols / 0xFFFFU; - unsigned offsetY = (blendingStyle == BLEND_STYLE_PUSH_LEFT || blendingStyle == BLEND_STYLE_PUSH_RIGHT) ? 0 : progInv * nRows / 0xFFFFU; + int offsetX = (blendingStyle == BLEND_STYLE_PUSH_UP || blendingStyle == BLEND_STYLE_PUSH_DOWN) ? 0 : int(progInv * nCols / 0xFFFFU); + int offsetY = (blendingStyle == BLEND_STYLE_PUSH_LEFT || blendingStyle == BLEND_STYLE_PUSH_RIGHT) ? 0 : int(progInv * nRows / 0xFFFFU);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
wled00/FX_fcn.cpp
(8 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
wled00/{*.cpp,!(html_*)*.h}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use spaces (2 per level) for C++ source and header files
Files:
wled00/FX_fcn.cpp
🧠 Learnings (2)
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
PR: wled/WLED#4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Applied to files:
wled00/FX_fcn.cpp
📚 Learning: 2025-06-07T15:58:42.579Z
Learnt from: willmmiles
PR: wled/WLED#4712
File: wled00/FX_fcn.cpp:992-993
Timestamp: 2025-06-07T15:58:42.579Z
Learning: In WLED segments, the backing pixel buffer is always allocated to the full physical segment size, but effect rendering only uses a subset when mirror or grouping are enabled. For 2D segments, this subset is vWidth() * vHeight(), and for 1D segments it's vLength(). Color processing operations like fade_out should iterate over this rendering subset, not the full allocated buffer.
Applied to files:
wled00/FX_fcn.cpp
🧬 Code graph analysis (1)
wled00/FX_fcn.cpp (1)
wled00/colors.cpp (4)
color_add
(28-61)color_add
(28-28)color_blend
(11-21)color_blend
(11-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
- GitHub Check: wled_build / Build Environments (usermods)
- GitHub Check: wled_build / Build Environments (esp32dev)
- GitHub Check: wled_build / Build Environments (lolin_s2_mini)
- GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
🔇 Additional comments (8)
wled00/FX_fcn.cpp (8)
371-374
: Palette blend clamp looks goodThe explicit 255 cap avoids pathological loops; safe and clear.
1345-1351
: Propagating bgColor for stencil-enabled blendingPlumbing secondary color as background for modes that need it is correct; keeps segblend signature minimal.
1425-1447
: 2D mirroring writes: order and bounds look correct
- Single write + mirrored writes use segblend then opacity mix; consistent with 1D path.
- CCT mirror updates are guarded and aligned with pixel writes. LGTM.
1455-1456
: applyReverse/applyMirror flags gate transformsGood micro-optimization to avoid unnecessary per-pixel conditionals when no reverse/transpose/mirror is active.
1474-1475
: Push mapping before sampling old/new segmentsCorrect to apply push before sampling seg/segO so clipped/fade logic sees the shifted canvas consistently.
1492-1495
: Reverse/transpose only when neededDeferred transform after sampling avoids double-mapping. Clean and readable.
1518-1531
: 1D path parity with 2D: segblend + opacityMirroring, wrapping with offset, and segblend usage match 2D semantics. Consistency reduces edge-case drift. LGTM.
1613-1615
: Gamma application guard aligns with realtime overrideSkipping gamma when ARLS requests it is correct. Note: per prior learnings, effect-level gamma shaping elsewhere is intentional—no changes needed here.
A few more comments: The use of CRGBW instead of uint32_t reduces flash size and increases speed, although how exactly eludes me: the two aliases tC / bC don't do anything but make code more compact to read and came from a version where I passed uint32_t and then cast that: if instead of aliases the arguments are used directly, codesize increases by 250bytes, no idea why having aliases makes the compiler happy. one more peculiarity: when I did initial tests in a different branch (heap_handling), using "O2" optimization flag on |
IIRC, often big changes in code size are caused by loop unrolling. |
wled00/FX_fcn.cpp
Outdated
case 0: return tcol.color32; // Top | ||
case 1: return bcol.color32; // Bottom | ||
case 2: return color_add(tcol, bcol, false); // Add | ||
case 3: c.r = _subtract(tC.r, bC.r); c.g = _subtract(tC.g, bC.g); c.b = _subtract(tC.b, bC.b); c.w = _subtract(tC.w, bC.w); break; // Subtract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit of a nitpick, but I'd recommend using an inline metafunction or a macro to do the expansion for each channel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would clean up the code significantly, I will check how to do that here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (9)
wled00/FX_fcn.cpp (9)
1295-1305
: Minor naming/usage mismatch: “unused” helpers are compiled in.
_top
,_bottom
,_add
are marked “function currently unused” and aren’t referenced. Consider removing or markingstatic inline constexpr
behind a feature flag to save a few bytes.- static uint8_t _top (uint8_t a, uint8_t b) { return a; } // function currently unused - static uint8_t _bottom (uint8_t a, uint8_t b) { return b; } // function currently unused - static uint8_t _add (uint8_t a, uint8_t b) { unsigned t = a + b; return t > 255 ? 255 : t; } // function currently unused +// #define WLED_DEBUG_BLEND_FUNCS 1 +#ifdef WLED_DEBUG_BLEND_FUNCS +static inline constexpr uint8_t _top (uint8_t a, uint8_t) { return a; } +static inline constexpr uint8_t _bottom (uint8_t, uint8_t b) { return b; } +static inline constexpr uint8_t _add (uint8_t a, uint8_t b) { unsigned t = a + b; return t > 255 ? 255 : t; } +#endif
1320-1321
: Prefer an inline function over a macro for type-safety.
APPLY_BLEND
relies on outer names (tC
,bC
,c
) and hides types. Aninline
helper is safer and can still inline well.-#define APPLY_BLEND(op) c.r = op(tC.r, bC.r); c.g = op(tC.g, bC.g); c.b = op(tC.b, bC.b); c.w = op(tC.w, bC.w) +template<typename Op> +static inline void applyBlendOp(CRGBW& out, const CRGBW& a, const CRGBW& b, Op op) { + out.r = op(a.r, b.r); out.g = op(a.g, b.g); out.b = op(a.b, b.b); out.w = op(a.w, b.w); +}Then:
- case 3: APPLY_BLEND(_subtract); break; + case 3: applyBlendOp(c, tC, bC, _subtract); break;
1322-1348
: segblend(): semantics and perf look solid; add force-inline and guard CRGBW conversions.
- Good consolidation of blend modes; stencil (32) behaves as described.
- To keep this hot path in IRAM and reduce call overhead, consider
IRAM_ATTR
andalways_inline
.- If
color_add()
only acceptsuint32_t
, relying on implicit CRGBW→u32 conversions is brittle across toolchains.-static uint32_t segblend(CRGBW tcol, CRGBW bcol, CRGBW bgcol, uint8_t blendMode) { +static inline __attribute__((always_inline)) IRAM_ATTR uint32_t segblend(CRGBW tcol, CRGBW bcol, CRGBW bgcol, uint8_t blendMode) { CRGBW tC(tcol); CRGBW bC(bcol); CRGBW c; switch (blendMode) { - case 2: return color_add(tcol, bcol, false); // Add + case 2: return color_add(tcol.color32, bcol.color32, false); // Add (explicit)Verification ask: confirm
CRGBW
has implicit conversion where used, or make all calls explicit (.color32
) to avoid accidental overload picks.
1342-1346
: Stencil equality: consider optional tolerance to handle palette/gamma drift.Exact 32-bit equality can fail if the top color is dithered or preprocessed. If needed later, add an optional “within N per-channel” compare guarded by a flag.
Would you like a tiny helper that compares channels within a tolerance (e.g., <=1) and is compiled out by default?
1430-1453
: 2D mirroring path: index math and CCT writes look correct; avoid repeated segblend bottom fetch.You recompute
segblend(c, _pixels[idx*], ...)
per mirror target (necessary because bottoms differ), but_pixels[idx*]
is read twice per pixel (once for blend input, once again implicitly in color_blend). Micro-opt: read once per idx and reuse.- _pixels[indx] = color_blend(_pixels[indx], segblend(c, _pixels[indx], bgColor, blendMode), o); + uint32_t base = _pixels[indx]; + uint32_t mixed = segblend(c, base, bgColor, blendMode); + _pixels[indx] = color_blend(base, mixed, o);Same pattern for
idxMX/idxMY/idxMM
.
1457-1468
: Push offsets: clean and branchless; mask-based wrap is fine.Minor readability nit: unify comment (“shift canvas”) once at the switch header.
1554-1563
: On/Off transition workaround still relies on global bri/briT; add a brief comment.Future readers may forget why FADE is special-cased vs others. One-line rationale would help.
1299-1319
: Divide/Dodge/Burn edge cases are safe.No divide-by-zero due to guards; semantics are consistent with your chosen definitions. Consider
constexpr
to help constant-fold.
1322-1348
: Unit test coverage for bm=32 (stencil) and regressions on bm=3 suggested.Given prior subtract-mode bug, add minimal tests (or a debug scene) to assert:
- Subtract uses bottom-minus-top across all channels.
- Stencil returns bottom when
top==bg
, otherwise top.I can provide a small harness that feeds CRGBW tuples through
segblend()
and checks results; want me to drop that intest/
?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
wled00/FX_fcn.cpp
(9 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
wled00/{*.cpp,!(html_*)*.h}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use spaces (2 per level) for C++ source and header files
Files:
wled00/FX_fcn.cpp
🧠 Learnings (3)
📓 Common learnings
Learnt from: DedeHai
PR: wled/WLED#4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
PR: wled/WLED#4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Applied to files:
wled00/FX_fcn.cpp
📚 Learning: 2025-06-07T15:58:42.579Z
Learnt from: willmmiles
PR: wled/WLED#4712
File: wled00/FX_fcn.cpp:992-993
Timestamp: 2025-06-07T15:58:42.579Z
Learning: In WLED segments, the backing pixel buffer is always allocated to the full physical segment size, but effect rendering only uses a subset when mirror or grouping are enabled. For 2D segments, this subset is vWidth() * vHeight(), and for 1D segments it's vLength(). Color processing operations like fade_out should iterate over this rendering subset, not the full allocated buffer.
Applied to files:
wled00/FX_fcn.cpp
🧬 Code graph analysis (1)
wled00/FX_fcn.cpp (1)
wled00/colors.cpp (4)
color_add
(28-61)color_add
(28-28)color_blend
(11-21)color_blend
(11-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
- GitHub Check: wled_build / Build Environments (esp32c3dev)
- GitHub Check: wled_build / Build Environments (esp32s3dev_8MB_opi)
- GitHub Check: wled_build / Build Environments (esp32_eth)
- GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
- GitHub Check: wled_build / Build Environments (usermods)
- GitHub Check: wled_build / Build Environments (lolin_s2_mini)
- GitHub Check: wled_build / Build Environments (esp32_wrover)
- GitHub Check: wled_build / Build Environments (esp32s3_4M_qspi)
- GitHub Check: wled_build / Build Environments (esp8266_2m_160)
- GitHub Check: wled_build / Build Environments (esp01_1m_full_compat)
- GitHub Check: wled_build / Build Environments (esp32dev)
- GitHub Check: wled_build / Build Environments (esp8266_2m_compat)
- GitHub Check: wled_build / Build Environments (esp32s3dev_16MB_opi)
- GitHub Check: wled_build / Build Environments (nodemcuv2_160)
- GitHub Check: wled_build / Build Environments (esp01_1m_full)
- GitHub Check: wled_build / Build Environments (nodemcuv2)
- GitHub Check: wled_build / Build Environments (esp8266_2m)
🔇 Additional comments (6)
wled00/FX_fcn.cpp (6)
372-375
: Good safety clamp on palette blends.Covers overflow in transition palette blending; no behavior concerns.
1350-1391
: blendSegment(): clipping window math is correct; single-pixel segments fallback to FADE is a nice edge-case fix.No issues; good use of dw/dh and inverted ranges for OUTSIDE_IN.
1460-1516
: Reverse/transpose gating only when needed: good for perf; group expansion bounds are correct.Use of
groupLength()
and min(...) avoids overruns. Looks good.
1531-1536
: 1D mirroring path mirrors before primary write; offset wrap is correct.No functional concerns; mirrors respect
offset
and segment bounds.
1575-1577
: Restore global blendingStyle: good defensive reset.Prevents leakage into overlay passes.
1618-1620
: Gamma guard avoids work on black; confirm realtime/gamma combo.Condition
c > 0 && !(realtimeMode && arlsDisableGammaCorrection)
is correct. Verify that “pure white with CCT-only segments” still passes as >0 (it does).If you want, I can craft a quick bench to compare FPS with/without the
c > 0
guard on typical scenes.
changed to draft, this PR needs to wait until WIP on transparency is done. |
as mentioned in #4550 there is no easy way to overlay text with the new blending modes. this addition fixes that.
I also made some slight optimisations to
blendSegment()
and found that the compiler is very unpredictable. I assume that is mostly due to pipelining and core register use. In general, replacing bit-field accessed variables with an alias or a pre-computed value is faster, but here it is not always the case. I tried different variations and this was the best performing one. Replacing any other repeated calculations inblendSegment()
does not improve performance.while flash size increases by a few hundred bytes, FPS improve by 3-5% depending on FX and layering used.
Summary by CodeRabbit
New Features
Bug Fixes
Notes