Horizontal scrolling surface Tearing

Hi all,

I’m experiencing a tearing effect with my application. Is is an horizontal
scrolling surface on top of a fixed BG and is running in fullscreen . Using
an LCD display I see an annoing tearing. I’m basically doing a loop like
this:

draw initial surface to screen
while(1)
1)SDL_Flip
2)blit the scrolled surface to screen
3)SDL_delay(frame_period-elapsed_time)

I’ve tried with both HW and SW surface (double buffering too). My
application is running on top of X server.

I’ve performed some tests in the following conditions:

1-linux on top of X11
2-windows on top of directX
3-windows default mode;
4-linux directFB

the same code running on the same HW (intel 945) produce the following
results:

  1. tearing;
  2. NO tearing;
  3. tearing;
  4. tearing.

The problems seems to be that in linux (both cases) and windows without
directx I cannot make it run in doublebuffering (it’s a full screen
application with a right to left horizontal scrolling surface). Can you
please help finding a fix to make it running in linux? The videocard is an
integrated one GMA950 i945. The distribution is debian 5.0.

I’ve also tried with SDL_VIDEODRIVER set to glSDL and directFB without
success. Same issue with SDL 1.3 downloaded from the SVN, moreover with this
I was not able to set fullscreen mode.

Thank you in advance,

Andrea

Den Tue, 24 Mar 2009 22:15:47 +0100
skrev Andrea Zinicola :

The problems seems to be that in linux (both cases) and windows
without directx I cannot make it run in doublebuffering (it’s a full
screen application with a right to left horizontal scrolling
surface). Can you please help finding a fix to make it running in
linux? The videocard is an integrated one GMA950 i945. The
distribution is debian 5.0.

Double-buffering isn’t enough, actually. You also need vsync, ie sync
the flipping of the buffers to the monitor’s retrace period (lcds
doesn’t really have those, but they still require vsync), otherwise
the flip can occur in the middle of the screen and cause tearing.

Anyway, as far as I know, there’s no way to actually get vsync with
plain X11 (rather huge oversight there), but you can get it with
OpenGL. glSDL and SDL 1.3 with the opengl driver should give you
that. Then, to tell OpenGL to use double-buffering and vsync, call
these before SDL_SetVideoMode:

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);

This doesn’t guarantee vsync (eg you probably won’t get it on a
composited desktop unless that also has vsync (at least not in windowed
mode), or if the drivers doesn’t support vsync or force it off, etc),
but the chances of getting it increase dramatically =). It works here,
at least. Haven’t tried it with glSDL or SDL 1.3 yet, but hopefully
that works too. You could also do a SDL_putenv("__GL_SYNC_TO_VBLANK=1")
(before SDL_Init?) to nudge nvidia drivers a little more, but that
shouldn’t be necessary (specially since you’re not using nvidia).
Doesn’t hurt either though =)

This doesn’t help with directx, though. (Maybe SDL 1.3 has a more
portable way of requesting vsync?)

  • Gerry