Skip to content

Commit

Permalink
Reduced render time for bars by 60-80%, by caching IsSpatial
Browse files Browse the repository at this point in the history
In my profiling, GetSpatialColor represents 33% of the time spent inside BarsEffect::Render, just checking buffer.palette.IsSpatial(colorIdx) for every pixel. If you're not using spatial colors, this time is pure wastage.
The optimiser can't see deep enough to know that it can cache IsSpatial, so I've done it manually. Despite expecting a saving of only 33%, it's actually more like 60%, because skipping the GetSpatialColor function call also skips all of the maths done to build its parameters, such as `(float)x / (float)buffer.BufferWi`, and `(float)(n % barHt) / (float)barHt`.

5.878s -> 2.184s for my test sequence, that is one bars effect with 3 colours, across all channels.

More savings could undoubtedly be had by performing this same optimisation on other effects.
  • Loading branch information
degracode authored and dkulp committed Dec 31, 2024
1 parent 132aa2f commit 81f936e
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions xLights/effects/BarsEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,19 +214,24 @@ void BarsEffect::Render(Effect* effect, const SettingsMap& SettingsMap, RenderBu
}
color = hsv;
}

const bool isSpatialColor = buffer.palette.IsSpatial(colorIdx); // Cache the spatial color check, as it's expensive to do for every pixel

switch (direction) {
case 1:
// down
for (int x = 0; x < buffer.BufferWi; ++x) {
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
buffer.SetPixel(x, y, color);
}
break;
case 2:
// expand
if (y <= newCenter) {
for (int x = 0; x < buffer.BufferWi; ++x) {
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
buffer.SetPixel(x, y, color);
buffer.SetPixel(x, newCenter + (newCenter - y), color);
}
Expand All @@ -236,7 +241,8 @@ void BarsEffect::Render(Effect* effect, const SettingsMap& SettingsMap, RenderBu
// compress
if (y >= newCenter) {
for (int x = 0; x < buffer.BufferWi; ++x) {
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
buffer.SetPixel(x, y, color);
buffer.SetPixel(x, newCenter + (newCenter - y), color);
}
Expand All @@ -245,7 +251,8 @@ void BarsEffect::Render(Effect* effect, const SettingsMap& SettingsMap, RenderBu
default:
// up
for (int x = 0; x < buffer.BufferWi; ++x) {
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, 1.0 - (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, (float)x / (float)buffer.BufferWi, 1.0 - (float)(n % barHt) / (float)barHt, buffer, gradient, highlightColor, highlight, show3D, barHt, n, pct, color2);
buffer.SetPixel(x, buffer.BufferHt - y - 1, color);
}
break;
Expand Down Expand Up @@ -357,19 +364,24 @@ void BarsEffect::Render(Effect* effect, const SettingsMap& SettingsMap, RenderBu
hsv.value *= double(barWi - n % barWi - 1) / barWi;
color = hsv;
}

const bool isSpatialColor = buffer.palette.IsSpatial(colorIdx); // Cache the spatial color check, as it's expensive to do for every pixel

switch (direction) {
case 5:
// right
for (int y = 0; y < buffer.BufferHt; ++y) {
GetSpatialColor(color, colorIdx, 1.0 - pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, 1.0 - pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
buffer.SetPixel(buffer.BufferWi - x - 1, y, color);
}
break;
case 6:
// H-expand
if (x <= newCenter) {
for (int y = 0; y < buffer.BufferHt; ++y) {
GetSpatialColor(color, colorIdx, pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
buffer.SetPixel(x, y, color);
buffer.SetPixel(newCenter + (newCenter - x), y, color);
}
Expand All @@ -379,7 +391,8 @@ void BarsEffect::Render(Effect* effect, const SettingsMap& SettingsMap, RenderBu
// H-compress
if (x >= newCenter) {
for (int y = 0; y < buffer.BufferHt; ++y) {
GetSpatialColor(color, colorIdx, pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
buffer.SetPixel(x, y, color);
buffer.SetPixel(newCenter + (newCenter - x), y, color);
}
Expand All @@ -388,7 +401,8 @@ void BarsEffect::Render(Effect* effect, const SettingsMap& SettingsMap, RenderBu
default:
// left
for (int y = 0; y < buffer.BufferHt; ++y) {
GetSpatialColor(color, colorIdx, pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
if (isSpatialColor)
GetSpatialColor(color, colorIdx, pct, (double)y / (double)buffer.BufferHt, buffer, gradient, highlightColor, highlight, show3D, barWi, n, pct, color2);
buffer.SetPixel(x, y, color);
}
break;
Expand Down

0 comments on commit 81f936e

Please sign in to comment.