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;
|
lastlen = 0;
|
||||||
laststart = 0;
|
laststart = 0;
|
||||||
lastBus = nullptr;
|
lastBus = nullptr;
|
||||||
slowMode = false;
|
bool lastSlowMode = slowMode;
|
||||||
|
|
||||||
DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
|
DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
|
||||||
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
|
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
|
||||||
@@ -1293,6 +1293,36 @@ int BusManager::add(BusConfig &bc) {
|
|||||||
} else {
|
} else {
|
||||||
busses[numBusses] = new BusPwm(bc);
|
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++;
|
return numBusses++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1312,6 +1342,7 @@ void BusManager::removeAll() {
|
|||||||
laststart = 0;
|
laststart = 0;
|
||||||
lastlen = 0;
|
lastlen = 0;
|
||||||
slowMode = false;
|
slowMode = false;
|
||||||
|
overlappingBusses = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((hot)) BusManager::show() {
|
void __attribute__((hot)) BusManager::show() {
|
||||||
@@ -1431,7 +1462,7 @@ uint32_t IRAM_ATTR __attribute__((hot)) BusManager::getPixelColorRestored(uint_
|
|||||||
|
|
||||||
bool BusManager::canAllShow() const {
|
bool BusManager::canAllShow() const {
|
||||||
for (uint8_t i = 0; i < numBusses; i++) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ class BusNetwork : public Bus {
|
|||||||
return _artnet_leds_per_output;
|
return _artnet_leds_per_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setColorOrder(uint8_t colorOrder);
|
void setColorOrder(uint8_t colorOrder); // ??? not implemented???
|
||||||
|
|
||||||
uint8_t getColorOrder() const override {
|
uint8_t getColorOrder() const override {
|
||||||
return _colorOrder;
|
return _colorOrder;
|
||||||
@@ -464,7 +464,7 @@ class BusManager {
|
|||||||
lastBus = nullptr;
|
lastBus = nullptr;
|
||||||
laststart = 0;
|
laststart = 0;
|
||||||
lastlen= 0;
|
lastlen= 0;
|
||||||
slowMode = isRTMode;
|
if (isRTMode || !overlappingBusses) slowMode = isRTMode; // don't reset slowMode if we have overlaping busses
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStatusPixel(uint32_t c);
|
void setStatusPixel(uint32_t c);
|
||||||
@@ -507,6 +507,7 @@ class BusManager {
|
|||||||
unsigned laststart = 0;
|
unsigned laststart = 0;
|
||||||
unsigned lastlen = 0;
|
unsigned lastlen = 0;
|
||||||
bool slowMode = false; // WLEDMM not sure why we need this. But its necessary.
|
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 {
|
inline uint8_t getNumVirtualBusses() const {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user