雖然司徒之前已經有上網找尋這個問題,不過沒有找到解答,所以司徒一直認為是N900的驅動問題,直到最近,司徒再度心血來潮,想說來解解看這個問題,這才發現OMAP2的顯示驅動似乎怪怪的,過程如下說明
main.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdint.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/mman.h> #include <string.h> #include <linux/fb.h> #include <linux/omapfb.h> #include <SDL.h> #include <SDL_image.h> #include <SDL_ttf.h> int main(int argc, char* args[]) { SDL_Surface* screen = NULL; int index = 0, cnt = 200; int fd = open("/dev/fb0", O_RDWR); SDL_Init(SDL_INIT_VIDEO); screen = SDL_SetVideoMode(800, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN); SDL_ShowCursor(0); while (cnt--) { switch (index) { case 0: SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xff, 0x00, 0x00)); break; case 1: SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0x00, 0xff, 0x00)); break; case 2: SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0x00, 0x00, 0xff)); break; } index += 1; if (index >= 3) { index = 0; } SDL_Flip(screen); int zero = 0; ioctl(fd, FBIO_WAITFORVSYNC, &zero); SDL_Delay(30); } close(fd); SDL_Quit(); return 0; }
$ dmesg
Kernel
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) { struct omapfb_info *ofbi = FB2OFB(fbi); struct omapfb2_device *fbdev = ofbi->fbdev; struct omap_display *display = fb2display(fbi); ... switch (cmd) { ... case OMAPFB_WAITFORVSYNC: DBG("ioctl WAITFORVSYNC\n"); if (!display) { r = -EINVAL; break; } omap_dss_lock(); r = display->wait_vsync(display); omap_dss_unlock(); break; ... default: dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd); r = -EINVAL; } if (r < 0) DBG("ioctl failed: %d\n", r); return r; }
最後改成使用OMAPFB_WAITFORVSYNC即可解決Screen Tearing問題,而不是使用FBIO_WAITFORVSYNC
ioctl(fd, OMAPFB_WAITFORVSYNC, &zero);