(experimental) 2D drawPixel optimizations
* add a dedicated callback for 2D downscaling only (no nested for loop) -> up to 10% faster * minor optimizations for 2D up/downscale drawpixel - move repeated calculations out of the inner loop -> small speedup
This commit is contained in:
@@ -99,13 +99,28 @@ void drawPixelCallback2D(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8
|
||||
// Pack coordinates uniquely: outY into upper 16 bits, outX into lower 16 bits
|
||||
if (((outY << 16) | outX) == lastCoordinate) return; // skip setting same coordinate again
|
||||
lastCoordinate = (outY << 16) | outX; // since input is a "scanline" this is sufficient to identify a "unique" coordinate
|
||||
// pre-calculate final pixel color - avoids repetition inside the loop
|
||||
red = gamma8(red); green=gamma8(green); blue=gamma8(blue);
|
||||
uint32_t pColor = RGBW32(red, green, blue, 0);
|
||||
// set multiple pixels if upscaling // softhack007: changed loop x/y order -> minor speedup from better cache locality
|
||||
for (int j = 0; j < perPixelY; j++) {
|
||||
int pixelY = outY + j;
|
||||
for (int i = 0; i < perPixelX; i++) {
|
||||
activeSeg->setPixelColorXY(outX + i, outY + j, gamma8(red), gamma8(green), gamma8(blue));
|
||||
int pixelX = outX + i;
|
||||
activeSeg->setPixelColorXY(pixelX, pixelY, pColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
// WLEDMM 2D without upscaling loop - up to 10% faster
|
||||
void drawPixelCallbackDownScale2D(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
// simple nearest-neighbor downscaling
|
||||
int outX = (int)x * segCols / gifWidth;
|
||||
int outY = (int)y * segRows / gifHeight;
|
||||
int32_t newCoordinate = ((outY << 16) | outX);
|
||||
if (newCoordinate == lastCoordinate) return; // skip setting same coordinate again
|
||||
lastCoordinate = newCoordinate;
|
||||
activeSeg->setPixelColorXY(outX, outY, gamma8(red), gamma8(green), gamma8(blue));
|
||||
}
|
||||
|
||||
// calculate image scaling; updates scaling factors and sets the best pixel drawing callback
|
||||
static void calculateScaling() {
|
||||
@@ -115,7 +130,10 @@ static void calculateScaling() {
|
||||
perPixelX = (segCols + gifWidth -1) / gifWidth;
|
||||
perPixelY = (segRows + gifHeight-1) / gifHeight;
|
||||
if (segCols != gifWidth || segRows != gifHeight) {
|
||||
decoder.setDrawPixelCallback(drawPixelCallback2D); // use 2D callback with scaling
|
||||
if ((perPixelX <2) && (perPixelY <2))
|
||||
decoder.setDrawPixelCallback(drawPixelCallbackDownScale2D);// use 2D callback with downscaling only
|
||||
else
|
||||
decoder.setDrawPixelCallback(drawPixelCallback2D); // use 2D callback with full scaling
|
||||
} else {
|
||||
decoder.setDrawPixelCallback(drawPixelCallbackNoScale2D); // use 2D callback without scaling
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user