Shelley Chen has submitted this change. ( https://review.coreboot.org/c/coreboot/+/45235 )
Change subject: libpayload: cbgfx: Fix 'equals' counter for Lanczos resampling ......................................................................
libpayload: cbgfx: Fix 'equals' counter for Lanczos resampling
The current initialization of the 'equals' counter is incorrect, so that when 'equals >= SSZ * SSZ', the pixels in the sample array might not be all the same, leading to a wrong pixel value being set in the framebuffer.
The 'equals' counter stores the number of latest pixels that were exactly equal. Within the for loop of 'ox', the sample array is updated in a column-based order, and the 'equals' counter is updated accordingly. However, the 'equals' counter is initialized in a row-based order, which causes it to be set too large than it should be. Consider the example where sample[sx][sy] are initially:
[X X X A A A] // sy = 0 [X X X B B B] [X X X B B B] [X X X B B B] [X X X B B B] [X X X B B B] // sy = SSZ
Then, the correct implementation will initialize 'equals' to be 15, with last_equal being B. Suppose all of the remaining pixels are B. Then, at the end of the 'while (fpfloor(ixfp) > ix)' loop when ix = 4, or equivalently after 4 more columns of sample are updated, 'equals' will be 15 + 6 * 4 = 39, which is greater than SSZ * SSZ = 36, but we can see there are still 2 A's in the sample:
[B B B B A A] [B B B B B B] [B B B B B B] [B B B B B B] [B B B B B B] [B B B B B B]
Therefore, we must also initialize the 'equals' counter in a column-based order.
BUG=b:167739127 TEST=emerge-puff libpayload TEST=Character 'k' is rendered correctly on puff BRANCH=zork
Change-Id: Ibc91ad1af85adcf093eff40797cd54f32f57111d Signed-off-by: Yu-Ping Wu yupingso@chromium.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/45235 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Julius Werner jwerner@chromium.org --- M payloads/libpayload/drivers/video/graphics.c 1 file changed, 13 insertions(+), 14 deletions(-)
Approvals: build bot (Jenkins): Verified Julius Werner: Looks good to me, approved
diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c index 2bf5e19..563f296 100644 --- a/payloads/libpayload/drivers/video/graphics.c +++ b/payloads/libpayload/drivers/video/graphics.c @@ -858,24 +858,25 @@ }
/* - * Initialize the sample array for this line. For pixels to the - * left of S0 there are no corresponding input pixels so just - * copy the S0 values over. - * - * Also initialize the equals counter, which counts how many of - * the latest pixels were exactly equal. We know the columns - * left of S0 must be equal to S0, so start with that number. + * Initialize the sample array for this line, and also + * the equals counter, which counts how many of the latest + * pixels were exactly equal. */ - int equals = S0 * SSZ; + int equals = 0; uint8_t last_equal = ypix[0][0]; - for (sy = 0; sy < SSZ; sy++) { - for (sx = S0; sx < SSZ; sx++) { - if (sx >= dim_org->width) { + for (sx = 0; sx < SSZ; sx++) { + for (sy = 0; sy < SSZ; sy++) { + if (sx - S0 >= dim_org->width) { sample[sx][sy] = sample[sx - 1][sy]; equals++; continue; } - uint8_t i = ypix[sy][sx - S0]; + /* + * For pixels to the left of S0 there are no + * corresponding input pixels so just use + * ypix[sy][0]. + */ + uint8_t i = ypix[sy][MAX(0, sx - S0)]; if (pal_to_rgb(i, pal, header->colors_used, &sample[sx][sy])) goto bitmap_error; @@ -886,8 +887,6 @@ equals = 1; } } - for (sx = S0 - 1; sx >= 0; sx--) - sample[sx][sy] = sample[S0][sy]; }
ix = 0;