On 3/15/22 12:07, Geert Uytterhoeven wrote: > The conversion functions drm_fb_xrgb8888_to_mono() and > drm_fb_gray8_to_mono_line() do not behave correctly when the > horizontal boundaries of the clip rectangle are not multiples of 8: > a. When x1 % 8 != 0, the calculated pitch is not correct, > b. When x2 % 8 != 0, the pixel data for the last byte is wrong. > Thanks a lot for tracking down and fixing these issues. > Simplify the code and fix (a) by: > 1. Removing start_offset, and always storing the first pixel in the > first bit of the monochrome destination buffer. > Drivers that require the first pixel in a byte to be located at an > x-coordinate that is a multiple of 8 can always align the clip > rectangle before calling drm_fb_xrgb8888_to_mono(). > Note that: > - The ssd130x driver does not need the alignment, as the > monochrome buffer is a temporary format, > - The repaper driver always updates the full screen, so the clip > rectangle is always aligned. > 2. Passing the number of pixels to drm_fb_gray8_to_mono_line(), > instead of the number of bytes, and the number of pixels in the > last byte. > > Fix (b) by explicitly setting the target bit, instead of always setting > bit 7 and shifting the value in each loop iteration. > > Remove the bogus pitch check, which operates on bytes instead of pixels, > and triggers when e.g. flashing the cursor on a text console with a font > that is 8 pixels wide. > > Drop the confusing comment about scanlines, as a pitch in bytes always > contains a multiple of 8 pixels. > > While at it, use the drm_rect_height() helper instead of open-coding the > same operation. > > Update the comments accordingly. > > Fixes: bcf8b616deb87941 ("drm/format-helper: Add drm_fb_xrgb8888_to_mono_reversed()") > Signed-off-by: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> > --- Acked-by: Javier Martinez Canillas <javierm@xxxxxxxxxx> I just have a small comment below. [snip] > +static void drm_fb_gray8_to_mono_line(u8 *dst, const u8 *src, unsigned int pixels) > +{ > + while (pixels) { > + unsigned int i, bits = min(pixels, 8U); > + u8 byte = 0; > > - byte >>= 1; > - if (src[x] >> 7) > - byte |= BIT(7); > + for (i = 0; i < bits; i++, pixels--) { I think is worth to add a comment here explaining that the pixel is set to 1 for brightness > 127 and to 0 for brightness < 128. Or as kernel-doc for this helper function. > + if (*src++ & BIT(7)) Pekka also mentioned that if (*src++ > 127) would make this easier to read. > + byte |= BIT(i); > } > *dst++ = byte; > } -- Best regards, Javier Martinez Canillas Linux Engineering Red Hat