disable SPC optimizations when outputs overlap With overlapping outputs, MM specific optimizations in busses.setPixelColor() need to be disabled - a single sPC must be forwarded to all busses. gPC can stay in optimized mode, because each possible bus pixel will have the same value.
This commit is contained in:
@@ -1272,7 +1272,7 @@ int BusManager::add(BusConfig &bc) {
|
||||
lastlen = 0;
|
||||
laststart = 0;
|
||||
lastBus = nullptr;
|
||||
slowMode = false;
|
||||
bool lastSlowMode = slowMode;
|
||||
|
||||
DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
|
||||
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
|
||||
@@ -1293,6 +1293,36 @@ int BusManager::add(BusConfig &bc) {
|
||||
} else {
|
||||
busses[numBusses] = new BusPwm(bc);
|
||||
}
|
||||
|
||||
Bus *newBus = busses[numBusses];
|
||||
if (newBus == nullptr) return numBusses; // WLEDMM early exit if bus creation failed
|
||||
// WLEDMM check if added bus overlaps with any existing bus
|
||||
bool foundOverlap = false;
|
||||
unsigned busCount = getNumBusses();
|
||||
if (newBus->isOk()) {
|
||||
unsigned newStart = newBus->getStart();
|
||||
unsigned newLen = newBus->getLength();
|
||||
unsigned newEnd = (newLen > 0) ? newStart + newLen - 1 : newStart; // handle zero-length edge case (only happens when bus could not initialize)
|
||||
for (unsigned i=0; i<busCount; i++) {
|
||||
if (i == numBusses) continue; // skip self - should not happen
|
||||
Bus *theBus = getBus(i);
|
||||
if (theBus == nullptr) continue;
|
||||
if (!theBus->isOk()) continue;
|
||||
// check for overlap
|
||||
unsigned theStart = theBus->getStart();
|
||||
unsigned theLen = theBus->getLength();
|
||||
unsigned theEnd = (theLen > 0) ? theStart + theLen - 1 : theStart;
|
||||
// see https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
|
||||
if ((newStart <= theEnd) && (theStart <= newEnd)) { // catches all overlap scenarios - including "new is including (around) another range"
|
||||
foundOverlap = true;
|
||||
DEBUG_PRINTF("bus %u[%u %u] overlaps with\t%u [%u %u]\n", numBusses, newStart, newEnd, i, theStart, theEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if some busses overlap, we disable the bus caching optimization to allow multiple outputs for the same pixel
|
||||
if (foundOverlap) { overlappingBusses = true; slowMode = true; }
|
||||
if (numBusses < 1) { overlappingBusses = false; slowMode = false; }
|
||||
USER_PRINT(slowMode && (lastSlowMode != slowMode) ? F("Warning: Outputs set to SlowMode, due to overlapping bus start indices!\n") : F("")); // only print message once when we switch over to slow mode
|
||||
return numBusses++;
|
||||
}
|
||||
|
||||
@@ -1312,6 +1342,7 @@ void BusManager::removeAll() {
|
||||
laststart = 0;
|
||||
lastlen = 0;
|
||||
slowMode = false;
|
||||
overlappingBusses = false;
|
||||
}
|
||||
|
||||
void __attribute__((hot)) BusManager::show() {
|
||||
@@ -1431,7 +1462,7 @@ uint32_t IRAM_ATTR __attribute__((hot)) BusManager::getPixelColorRestored(uint_
|
||||
|
||||
bool BusManager::canAllShow() const {
|
||||
for (uint8_t i = 0; i < numBusses; i++) {
|
||||
if (!busses[i]->canShow()) return false;
|
||||
if ((busses[i]->isOk()) && !busses[i]->canShow()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ class BusNetwork : public Bus {
|
||||
return _artnet_leds_per_output;
|
||||
}
|
||||
|
||||
void setColorOrder(uint8_t colorOrder);
|
||||
void setColorOrder(uint8_t colorOrder); // ??? not implemented???
|
||||
|
||||
uint8_t getColorOrder() const override {
|
||||
return _colorOrder;
|
||||
@@ -464,7 +464,7 @@ class BusManager {
|
||||
lastBus = nullptr;
|
||||
laststart = 0;
|
||||
lastlen= 0;
|
||||
slowMode = isRTMode;
|
||||
if (isRTMode || !overlappingBusses) slowMode = isRTMode; // don't reset slowMode if we have overlaping busses
|
||||
}
|
||||
|
||||
void setStatusPixel(uint32_t c);
|
||||
@@ -507,6 +507,7 @@ class BusManager {
|
||||
unsigned laststart = 0;
|
||||
unsigned lastlen = 0;
|
||||
bool slowMode = false; // WLEDMM not sure why we need this. But its necessary.
|
||||
bool overlappingBusses = false; // WLEDMM needed to enforce "slowMode" when busses overlap (=custom bus start indices)
|
||||
|
||||
inline uint8_t getNumVirtualBusses() const {
|
||||
int j = 0;
|
||||
|
||||
Reference in New Issue
Block a user