Nokia N900 >> Sbox

解決"Screen Tearing"問題


雖然司徒之前已經有上網找尋這個問題,不過看到的解答都是無解,所以司徒便一直認定是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[])
{
  int fd = open("/dev/fb0", O_RDWR);
  SDL_Init(SDL_INIT_VIDEO);
 
  SDL_Surface* screen;
  screen = SDL_SetVideoMode(800, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
  SDL_ShowCursor(0);

  int index=0, cnt=200;
  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問題

ioctl(fd, OMAPFB_WAITFORVSYNC, &zero);


返回上一頁