fix color jump if changing mid transition#5601
Conversation
WalkthroughstartTransition() now preserves visual continuity for in-flight transitions by restoring or blending the old segment from the transition-start state, capturing current blended colors when no old segment is created, and conditionally resetting palette-blend tracking and timers. ChangesMid-Transition State Management
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
|
@blazoncek I looked at your commit blazoncek@40d9812 |
|
A credit would be due. Don't you think? |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@wled00/FX_fcn.cpp`:
- Around line 301-324: When promoting an in-flight fade into a segmentCopy
transition (the branch where segmentCopy && !_t->_oldSegment), refresh the
transition's stored "from" visual state so it reflects the current blended
frame: for each color set _t->_colors[i] to the current blend (use color_blend16
with _t->_colors[i], colors[i], and _t->_progress), and set _t->_bri =
currentBri() and _t->_cct = currentCCT() before restarting _t->_start/_t->_dur
and creating _t->_oldSegment; this ensures beginDraw(), currentBri(), and
currentCCT() animate from the actual mid-fade values rather than the original
start values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d26c0df1-c4fb-45ce-a2c4-775a180bdc4e
📒 Files selected for processing (1)
wled00/FX_fcn.cpp
| if (segmentCopy && !_t->_oldSegment) { | ||
| // already in transition but segment copy requested and not yet created | ||
| _t->_oldSegment = new(std::nothrow) Segment(*this); // store/copy current segment settings | ||
| _t->_start = millis(); // restart countdown | ||
| _t->_start = millis(); // restart transition timer | ||
| _t->_dur = dur; | ||
| _t->_prevPaletteBlends = 0; | ||
| _t->_prevPaletteBlends = 0; // reset palette blends | ||
| if (_t->_oldSegment) { | ||
| _t->_oldSegment->palette = _t->_palette; // restore original palette and colors (from start of transition) | ||
| for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i]; | ||
| // if already partway through a FADE transition, set old segment's colors to current blend to avoid jumping back to original colors | ||
| if (_t->_progress > 0) | ||
| for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = color_blend16(_t->_colors[i], colors[i], _t->_progress); | ||
| else | ||
| for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i]; | ||
| DEBUGFX_PRINTF_P(PSTR("-- Updated transition with segment copy: S=%p T(%p) O[%p] OP[%p]\n"), this, _t, _t->_oldSegment, _t->_oldSegment->pixels); | ||
| if (!_t->_oldSegment->isActive()) stopTransition(); | ||
| } | ||
| } else if (_t->_progress > 0) { | ||
| // already in a transition: capture the current visual blend as the new "from" state so the incoming change does not cause a visible jump. | ||
| // _palT already holds the intermediate blended palette and will continue blending toward the new target (see beginDraw()), so no palette action needed. | ||
| // initial version by @blazoncek (https://github.com/blazoncek/WLED/commit/40d9812) | ||
| for (unsigned i = 0; i < NUM_COLORS; i++) _t->_colors[i] = color_blend16(_t->_colors[i], colors[i], _t->_progress); | ||
| _t->_palette = palette; // update "original" palette (reduces jump in SAVE_RAM builds) | ||
| _t->_bri = currentBri(); // update "original" brightness note: _t->_progress is updated in updateTransitionProgress() so still valid here | ||
| _t->_cct = currentCCT(); // update "original" CCT (reduces jump) |
There was a problem hiding this comment.
Refresh _t’s blended state before restarting a late segmentCopy transition.
When this branch upgrades an in-flight fade into a segmentCopy transition, it restarts _t->_start / _t->_dur but leaves _t->_colors, _t->_bri, and _t->_cct at the original transition start. beginDraw(), currentBri(), and currentCCT() then animate from stale values, so a mid-fade mode change can still snap brightness/CCT — and sometimes colors — backwards on the first frame.
💡 Suggested fix
if (isInTransition()) {
if (segmentCopy && !_t->_oldSegment) {
// already in transition but segment copy requested and not yet created
+ uint32_t blendedColors[NUM_COLORS];
+ for (unsigned i = 0; i < NUM_COLORS; i++) {
+ blendedColors[i] = (_t->_progress > 0)
+ ? color_blend16(_t->_colors[i], colors[i], _t->_progress)
+ : _t->_colors[i];
+ }
+ _t->_palette = palette;
+ _t->_bri = currentBri();
+ _t->_cct = currentCCT();
+ for (unsigned i = 0; i < NUM_COLORS; i++) _t->_colors[i] = blendedColors[i];
+
_t->_oldSegment = new(std::nothrow) Segment(*this); // store/copy current segment settings
_t->_start = millis(); // restart transition timer
_t->_dur = dur;
_t->_prevPaletteBlends = 0; // reset palette blends
if (_t->_oldSegment) {
_t->_oldSegment->palette = _t->_palette; // restore original palette and colors (from start of transition)
- // if already partway through a FADE transition, set old segment's colors to current blend to avoid jumping back to original colors
- if (_t->_progress > 0)
- for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = color_blend16(_t->_colors[i], colors[i], _t->_progress);
- else
- for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i];
+ for (unsigned i = 0; i < NUM_COLORS; i++) _t->_oldSegment->colors[i] = _t->_colors[i];🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@wled00/FX_fcn.cpp` around lines 301 - 324, When promoting an in-flight fade
into a segmentCopy transition (the branch where segmentCopy &&
!_t->_oldSegment), refresh the transition's stored "from" visual state so it
reflects the current blended frame: for each color set _t->_colors[i] to the
current blend (use color_blend16 with _t->_colors[i], colors[i], and
_t->_progress), and set _t->_bri = currentBri() and _t->_cct = currentCCT()
before restarting _t->_start/_t->_dur and creating _t->_oldSegment; this ensures
beginDraw(), currentBri(), and currentCCT() animate from the actual mid-fade
values rather than the original start values.
|
BTW both our fixes are still flawed to some extent. Question is if it is worth investing much time in edge cases. |
This improves the color changes while a FADE transition is going on.
Summary by CodeRabbit