Created attachment 294525 [details] source code of the program There seems to be some issue with the /dev/fb0 device on my Lenovo Thinkpad X1 Carbon 7th gen. When I write to the framebuffer device using the API in linux/fb.h, the laptop screen can only pick up the first frame. The screen freezes until I use Ctrl-C to exit the program. Here is a minimal program that demonstrates the problem: /* compile with * $ cc fb.c -lm */ #include <stdint.h> #include <assert.h> #include <unistd.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <time.h> #include <math.h> enum { width = 256, height = 256 }; static float t(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec + ts.tv_nsec/1000000000.0; } /* draw anything that changes with time */ static void draw(uint32_t *fb, int pitch) { for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x) { uint8_t s = 255*(0.5 + 0.5 * sin(x*x + y*y + 5*t())); fb[y*pitch + x] = 0xff<<24 | s<<16 | s<<8 | s; } } int main(void) { struct fb_fix_screeninfo finfo; struct fb_var_screeninfo vinfo; int fd; size_t size; uint32_t *fb; fd = open("/dev/fb0", O_RDWR); if (fd < 0) return 1; if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) return 1; if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) return 1; /* we will only work with 32 bit color for simplicity */ assert(vinfo.bits_per_pixel == 32); /* set up our framebuffer */ size = vinfo.yres_virtual * finfo.line_length; fb = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (fb == MAP_FAILED) return 1; fb = (fb + vinfo.xoffset + vinfo.yoffset*finfo.line_length); while (1) { draw(fb, finfo.line_length/4); } munmap(fb, size); close(fd); } Make sure to run the program on TTY and you are in video group. Strangely, the HDMI output is not affected. I can see the animation on my monitor but not on the laptop screen (1080p non-touch). Kernel version: 5.10.4-arch2-1
This bug also affects some other programs using the /dev/fb0 device, such as mplayer, fbida, etc.