FastLED 3.9.15
Loading...
Searching...
No Matches

◆ resolveDynamicDriver()

FL_NO_INLINE fl::shared_ptr< IChannelDriver > fl::Channel::resolveDynamicDriver ( )
private

Cold slow-path helper for showPixels() when the driver was NOT pre-bound via setDriver().

Cold fallback for the non-pre-bound driver path.

Handles dynamic ChannelManager::selectDriverForChannel() lookup AND the bus-key-miss diagnostics (#2455 / #2459).

Marked FL_NO_INLINE so the legacy addLeds<> hot path stays compact — see #2773 item 2.1. Returns nullptr on a hard miss (caller should silently bail).

Handles dynamic ChannelManager::selectDriverForChannel lookup AND the bus-key-miss diagnostic chain. Hoisted out of showPixels so the hot legacy addLeds<> path stays compact — see #2773 item 2.1.

Marked noinline (via FL_NOINLINE) so the compiler doesn't fold the cold body back into showPixels. The whole helper is reachable only when mDriverPreBound == false, which on stock Blink is never true — LTO can use that across the call site to keep the cold body off the hot icache line.

Definition at line 391 of file channel.cpp.hpp.

391 {
392#if defined(FASTLED_DISABLE_DYNAMIC_DRIVER) && FASTLED_DISABLE_DYNAMIC_DRIVER
393 // Body excluded via FASTLED_DISABLE_DYNAMIC_DRIVER (#2926). The
394 // showPixels call site is also gated so this is unreachable; the
395 // empty body lets the linker dead-strip ChannelManager::findDriverByName
396 // and selectDriverForChannel along with this symbol.
397 return {};
398#else
399 // Build busKey only when we actually need it (mBus != AUTO).
400 fl::string busKey;
401 if (mBus != Bus::AUTO) {
403 }
404
405 fl::shared_ptr<IChannelDriver> driver =
407 mDriver = driver;
408
409 // #2455 / #2459: one-shot diagnostic when a typed-Bus miss happens.
410 // Probe via `findDriverByName` (silent) to distinguish "driver wasn't
411 // instantiated" from "driver exists but canHandle() rejected this
412 // chipset" — resolution paths differ. The mBusWarned guard suppresses
413 // duplicate logs on subsequent shows of the same channel.
414#if FASTLED_LOG_RUNTIME_ENABLED
415 if (mBus != Bus::AUTO && !mBusWarned &&
416 (!driver || driver->getName() != busKey)) {
417 auto busDriver = ChannelManager::instance().findDriverByName(busKey);
418 if (!busDriver) {
419 // Typed Bus miss — emit the actionable hint with the three
420 // currently-shipping remediations (option 3 added in #2460).
421 FL_ERROR("Channel '" << mName << "': Driver '" << busKey
422 << "' wasn't instantiated. Resolve with: "
423 << "(1) fl::enableDrivers<fl::Bus::" << busKey << ">() "
424 << "(links only this driver), "
425 << "(2) FastLED.enableAllDrivers() (links every driver), or "
426 << "(3) FastLED.addLeds<..., fl::Bus::" << busKey << ">(...) "
427 << "(legacy API; pins Bus + triggers linker keep-alive). "
428 << "Defaulting to AUTO/priority dispatch.");
429 } else {
430 // Registered, but canHandle() said no — bus/chipset mismatch.
431 FL_ERROR("Channel '" << mName << "': Driver '" << busKey
432 << "' is registered but cannot handle this channel's chipset "
433 << "(bus/chipset mismatch). Defaulting to AUTO/priority dispatch.");
434 }
435 mBusWarned = true;
436 }
437 if (!driver) {
438 FL_ERROR("Channel '" << mName << "': No compatible driver found - cannot transmit");
439 }
440#endif // FASTLED_LOG_RUNTIME_ENABLED — release skips the per-frame
441 // driver->getName() != busKey compare + the silent
442 // findDriverByName probe (used only to differentiate the
443 // FL_ERROR message). The functional return value below is
444 // preserved in both builds. See #2952.
445 return driver;
446#endif // !FASTLED_DISABLE_DYNAMIC_DRIVER
447}
bool mBusWarned
Definition channel.h:265
ChannelDataPtr mChannelData
Definition channel.h:279
fl::weak_ptr< IChannelDriver > mDriver
Definition channel.h:256
fl::string mName
Definition channel.h:277
fl::shared_ptr< IChannelDriver > selectDriverForChannel(const ChannelDataPtr &data, const fl::string &affinity) FL_NOEXCEPT
Select best driver for channel data (used by Channel::showPixels)
fl::shared_ptr< IChannelDriver > findDriverByName(const fl::string &name) const FL_NOEXCEPT
Silent counterpart to getDriverByName().
static ChannelManager & instance() FL_NOEXCEPT
Get the global singleton instance.
static string from_literal(const char *literal) FL_NOEXCEPT
#define FL_ERROR(X)
Definition log.h:219
const char * busName(Bus b) FL_NOEXCEPT
Canonical driver-name string for a Bus value.
Definition bus.h:167
@ AUTO
Sentinel: defer to DefaultBus<Chipset>::value.
Definition bus.h:61

References fl::AUTO, fl::busName(), fl::ChannelManager::findDriverByName(), FL_ERROR, fl::string::from_literal(), fl::ChannelManager::instance(), mBus, mBusWarned, mChannelData, mDriver, mName, and fl::ChannelManager::selectDriverForChannel().

Referenced by showPixels().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: