雖然司徒之前已經有上網找尋這個問題,不過沒有找到解答,所以司徒一直認為是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);