Skip to content

Commit b15d69f

Browse files
committed
Highlight double buffering in docs, main.cpp and lights control
1 parent 7928125 commit b15d69f

File tree

3 files changed

+33
-22
lines changed

3 files changed

+33
-22
lines changed

docs/develop/architecture.md

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,22 @@ Synchronization Flow
161161

162162
void effectTask(void* param) {
163163
while (true) {
164-
if (useDoubleBuffer) {
165-
// Step 1: Copy front → back (NO LOCK)
166-
memcpy(channelsBack, channels, nrOfChannels);
167-
168-
// Step 2: Compute effects on back buffer (NO LOCK, 5-15ms)
169-
uint8_t* temp = channels;
170-
channels = channelsBack;
171-
computeEffects(); // Reads and writes channelsBack
172-
173-
// Step 3: BRIEF LOCK - Swap pointers (10µs)
164+
if (layerP.lights.useDoubleBuffer) {
165+
layerP.lights.channels = layerP.lights.channelsBack;
166+
layerP.loop(); // getRGB and setRGB both use channelsBack
167+
168+
// Atomic swap channels
169+
xSemaphoreTake(swapMutex, portMAX_DELAY);
170+
uint8_t* temp = layerP.lights.channelsBack;
171+
layerP.lights.channelsBack = layerP.lights.channels;
172+
layerP.lights.channels = temp;
173+
newFrameReady = true;
174+
xSemaphoreGive(swapMutex);
175+
176+
} else {
174177
xSemaphoreTake(swapMutex, portMAX_DELAY);
175-
channelsBack = channels;
176-
channels = temp;
178+
layerP.loop();
179+
177180
xSemaphoreGive(swapMutex);
178181
}
179182
vTaskDelay(1);
@@ -182,14 +185,20 @@ void effectTask(void* param) {
182185

183186
void driverTask(void* param) {
184187
while (true) {
185-
if (useDoubleBuffer) {
186-
// Step 4: BRIEF LOCK - Capture pointer (10µs)
187-
xSemaphoreTake(swapMutex, portMAX_DELAY);
188-
uint8_t* currentFrame = channels;
188+
xSemaphoreTake(swapMutex, portMAX_DELAY);
189+
esp32sveltekit.lps++;
190+
191+
if (layerP.lights.useDoubleBuffer) {
192+
if (newFrameReady) {
193+
newFrameReady = false;
194+
xSemaphoreGive(swapMutex);
195+
layerP.loopDrivers(); // ✅ No lock needed
196+
} else {
197+
xSemaphoreGive(swapMutex);
198+
}
199+
} else {
200+
layerP.loopDrivers(); // ✅ Protected by lock
189201
xSemaphoreGive(swapMutex);
190-
191-
// Step 5: Send to LEDs (NO LOCK, 1-5ms)
192-
sendViaDMA(currentFrame);
193202
}
194203
vTaskDelay(1);
195204
}
@@ -387,7 +396,7 @@ xTaskCreateUniversal(effectTask,
387396
"AppEffectTask",
388397
psramFound() ? 4 * 1024 : 3 * 1024,
389398
NULL,
390-
3, // Priority
399+
10, // Priority
391400
&effectTaskHandle,
392401
0 // Core 0 (PRO_CPU)
393402
);

src/MoonLight/Modules/ModuleLightsControl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ class ModuleLightsControl : public Module {
367367

368368
read([&](ModuleState& _state) {
369369
if (_socket->getConnectedClients() && _state.data["monitorOn"]) {
370+
371+
//protect emit by swapMutex, see main.cpp
370372
extern SemaphoreHandle_t swapMutex;
371373

372374
xSemaphoreTake(swapMutex, portMAX_DELAY);

src/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void effectTask(void* pvParameters) {
126126
layerP.setup(); // setup virtual layers (no node setup here as done in addNode)
127127
static unsigned long last20ms = 0;
128128

129-
for (;;) {
129+
while (true) {
130130
if (layerP.lights.useDoubleBuffer) {
131131
// effectTask always writes to channelsBack, reads previous channelsBack
132132
layerP.lights.channels = layerP.lights.channelsBack;
@@ -167,7 +167,7 @@ void driverTask(void* pvParameters) {
167167

168168
// layerP.setup() done in effectTask
169169

170-
for (;;) {
170+
while (true) {
171171
xSemaphoreTake(swapMutex, portMAX_DELAY);
172172
esp32sveltekit.lps++;
173173

0 commit comments

Comments
 (0)