Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panic: Add integer scaling to blit()

Add a parameter to the blit function, to upscale the image.
This is necessary to draw a QR code, otherwise, the pixels are
usually too small to be readable by most QR code reader.
It can also be used later for drawing fonts on high DPI display.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20240822073852.562286-2-jfalempe@redhat.com

+19 -14
+19 -14
drivers/gpu/drm/drm_panic.c
··· 257 257 static void drm_panic_blit16(struct iosys_map *dmap, unsigned int dpitch, 258 258 const u8 *sbuf8, unsigned int spitch, 259 259 unsigned int height, unsigned int width, 260 - u16 fg16) 260 + unsigned int scale, u16 fg16) 261 261 { 262 262 unsigned int y, x; 263 263 264 264 for (y = 0; y < height; y++) 265 265 for (x = 0; x < width; x++) 266 - if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y)) 266 + if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) 267 267 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16); 268 268 } 269 269 270 270 static void drm_panic_blit24(struct iosys_map *dmap, unsigned int dpitch, 271 271 const u8 *sbuf8, unsigned int spitch, 272 272 unsigned int height, unsigned int width, 273 - u32 fg32) 273 + unsigned int scale, u32 fg32) 274 274 { 275 275 unsigned int y, x; 276 276 ··· 278 278 for (x = 0; x < width; x++) { 279 279 u32 off = y * dpitch + x * 3; 280 280 281 - if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y)) { 281 + if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) { 282 282 /* write blue-green-red to output in little endianness */ 283 283 iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0); 284 284 iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8); ··· 291 291 static void drm_panic_blit32(struct iosys_map *dmap, unsigned int dpitch, 292 292 const u8 *sbuf8, unsigned int spitch, 293 293 unsigned int height, unsigned int width, 294 - u32 fg32) 294 + unsigned int scale, u32 fg32) 295 295 { 296 296 unsigned int y, x; 297 297 298 298 for (y = 0; y < height; y++) 299 299 for (x = 0; x < width; x++) 300 - if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y)) 300 + if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) 301 301 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32); 302 302 } 303 303 304 304 static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip, 305 - const u8 *sbuf8, unsigned int spitch, u32 fg_color) 305 + const u8 *sbuf8, unsigned int spitch, unsigned int scale, 306 + u32 fg_color) 306 307 { 307 308 unsigned int y, x; 308 309 309 310 for (y = 0; y < drm_rect_height(clip); y++) 310 311 for (x = 0; x < drm_rect_width(clip); x++) 311 - if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y)) 312 + if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) 312 313 sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color); 313 314 } 314 315 ··· 319 318 * @clip: destination rectangle 320 319 * @sbuf8: source buffer, in monochrome format, 8 pixels per byte. 321 320 * @spitch: source pitch in bytes 321 + * @scale: integer scale, source buffer is scale time smaller than destination 322 + * rectangle 322 323 * @fg_color: foreground color, in destination format 323 324 * 324 325 * This can be used to draw a font character, which is a monochrome image, to a 325 326 * framebuffer in other supported format. 326 327 */ 327 328 static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip, 328 - const u8 *sbuf8, unsigned int spitch, u32 fg_color) 329 + const u8 *sbuf8, unsigned int spitch, 330 + unsigned int scale, u32 fg_color) 331 + 329 332 { 330 333 struct iosys_map map; 331 334 332 335 if (sb->set_pixel) 333 - return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, fg_color); 336 + return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, scale, fg_color); 334 337 335 338 map = sb->map[0]; 336 339 iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); ··· 342 337 switch (sb->format->cpp[0]) { 343 338 case 2: 344 339 drm_panic_blit16(&map, sb->pitch[0], sbuf8, spitch, 345 - drm_rect_height(clip), drm_rect_width(clip), fg_color); 340 + drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); 346 341 break; 347 342 case 3: 348 343 drm_panic_blit24(&map, sb->pitch[0], sbuf8, spitch, 349 - drm_rect_height(clip), drm_rect_width(clip), fg_color); 344 + drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); 350 345 break; 351 346 case 4: 352 347 drm_panic_blit32(&map, sb->pitch[0], sbuf8, spitch, 353 - drm_rect_height(clip), drm_rect_width(clip), fg_color); 348 + drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); 354 349 break; 355 350 default: 356 351 WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); ··· 490 485 for (j = 0; j < line_len; j++) { 491 486 src = get_char_bitmap(font, msg[i].txt[j], font_pitch); 492 487 rec.x2 = rec.x1 + font->width; 493 - drm_panic_blit(sb, &rec, src, font_pitch, color); 488 + drm_panic_blit(sb, &rec, src, font_pitch, 1, color); 494 489 rec.x1 += font->width; 495 490 } 496 491 }