Flickering display - me or Pi?

Hi,

I’m experimenting with the console framebuffer on the Raspberry Pi…
(Small ARM based Linux box for those who’ve been living in a cave for the
past 6 months)

The Pi is running Debian stable (and I have another running the "Raspbian"
release of Wheezy) SDL is Debians 1.2

My app (the BASIC interpreter) runs fine under X on the Pi, but I’ve been
having an intersting time on the console - lots of crashes, etc. however
when I realised the Pi has a 16bpp framebuffer and switched it to 16bpp it
all started to beheve itself better, and it’s a lot faster (so I guess SDL
isn’t doing any framebuffer converts) however it’s also flickering.

2 things I’ve noticed - one is a program that draws lots of lines, then
prints text on-top, then calls Flip, and repeats. (think background line
animation with static text on-top). Under X it looks fine, however on the
Pi console, I actually see the lines being drawn under & between the text

  • if I stop the program it then looks OK, (no lines between the test) but
    when running, there is this flickering.

the text output is fairly simple 8x8 characters which overwrites
everything underneath them.

When it was running in 32bpp mode, it was slower and I didn’t see this
flickering. I’m at a loss to think why I even see the lines underneath the
text in the first place - it’s almost as if Flip is being ignored and I’m
writing directly to the framebuffer, however I’m really not, and stopping
the program always causes it to display the right thing - ie. the text
over the lines.

The other thing is very similar with sprites - my sprite update code does
up to 3 BLITs per sprite - one to restore the old backgound, one to save
the new background and one to plot the sprite (on top of the saved
backgound), however when running, they flicker and I see the background
under the sprites which I’m not supposed to see as those 3 operations
happen without a flip in-between them…

And of-course this never happens under X, even fullscreen under X. (Nor
full-screen on a laptop, etc. and I’ve just checked it again on my laptop

  • runs smoothly without flickering)

So is it me, the Pi, or …

Just FYI: I’m opening the screen with:

 myScreen = SDL_SetVideoMode (screenWidth, screenHeight, BYTES_PER_PIXEL * 8, SDL_DOUBLEBUF | SDL_SWSURFACE) ;

fiddling with SDL_FULLSCREEN and SDL_HWSURFACE doesn’t change anything.

Pi reports this from GetVideoInfo:

Video Info:
hw_available: Yes
wm_available: No
blit_hw: No, blit_hw_CC: No, blit_hw_A: No
blit_sw: No, blit_sw_CC: No, blit_sw_A: No
blit_fill: No
video_mem: 2560
current_w: 1280
current_h: 1024
PixelFormat:
BitsPerPixel: 16, BytesPerPixel: 2

(current width and height are dependant on what it’s plugged into - it has
HDMI output and composite video - this is HDMI into my monitor)

Any thoughts appreciated…

Thanks,

Gordon

What are you using to draw the lines? Make sure there’s no SDL_UpdateRect
or SDL_Flip happening between drawing calls in the same frame.

Jonny D

What are you using to draw the lines? Make sure there’s no SDL_UpdateRect
or SDL_Flip happening between drawing calls in the same frame.

Essentially, I’m poking pixels into the screen

     *((uint16_t *)myScreen->pixels + y * hgWidth + x)  = plotColour ;

and ye-olde Bresenham in-front of that.

I’ve gone through everything to check for a spurious UpdateRect or Flip
and not found anything - I have one “update” function in the code which
everything calls…

I know that if I did an update on every line then it would be as slow as a
slow thing…

GordonOn Tue, 29 May 2012, Jonathan Dearborn wrote:

Sounds like your screen is the actual framebuffer and the screen is updating in
the middle of your application.
You could try doing your own double buffering and draw the final buffer to the
screen.
Another option would be to use vsync.________________________________
From: gordon+sdl@drogon.net (Gordon Henderson)
To: SDL Development List
Sent: Tue, May 29, 2012 12:19:04 PM
Subject: Re: [SDL] Flickering display - me or Pi ?

On Tue, 29 May 2012, Jonathan Dearborn wrote:

What are you using to draw the lines? Make sure there’s no SDL_UpdateRect
or SDL_Flip happening between drawing calls in the same frame.

Essentially, I’m poking pixels into the screen

    *((uint16_t *)myScreen->pixels + y * hgWidth + x)  = plotColour ;

and ye-olde Bresenham in-front of that.

I’ve gone through everything to check for a spurious UpdateRect or Flip and not
found anything - I have one “update” function in the code which everything
calls…

I know that if I did an update on every line then it would be as slow as a slow
thing…

Gordon


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Sounds like your screen is the actual framebuffer and the screen is updating in
the middle of your application.
You could try doing your own double buffering and draw the final buffer to the
screen.
Another option would be to use vsync.

I may do a few more experiments - really just wanted to know if it was
something obvious…

Not sure the Pi has vsync - wouldn’t SDL use it if it had? Right now from
what I gather, it’s really just a dumb framebuffer without any
acelleration, etc.

GordonOn Tue, 29 May 2012, Scott Smith wrote:


From: Gordon Henderson <gordon+sdl at drogon.net>
To: SDL Development List
Sent: Tue, May 29, 2012 12:19:04 PM
Subject: Re: [SDL] Flickering display - me or Pi ?

On Tue, 29 May 2012, Jonathan Dearborn wrote:

What are you using to draw the lines? Make sure there’s no SDL_UpdateRect
or SDL_Flip happening between drawing calls in the same frame.

Essentially, I’m poking pixels into the screen

   *((uint16_t *)myScreen->pixels + y * hgWidth + x)  = plotColour ;

and ye-olde Bresenham in-front of that.

I’ve gone through everything to check for a spurious UpdateRect or Flip and not
found anything - I have one “update” function in the code which everything
calls…

I know that if I did an update on every line then it would be as slow as a slow
thing…

Gordon


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

The Raspberry Pi has OpenGL|ES 2.0 support and a PowerVR 3D chip (same chip
as iPhone if I recall). Ensuring that is enabled and that it is being used
by SDL, however, are a bit harder.

PatrickOn Tue, May 29, 2012 at 12:17 PM, Gordon Henderson <gordon+sdl at drogon.net>wrote:

On Tue, 29 May 2012, Scott Smith wrote:

Sounds like your screen is the actual framebuffer and the screen is

updating in
the middle of your application.
You could try doing your own double buffering and draw the final buffer
to the
screen.
Another option would be to use vsync.

I may do a few more experiments - really just wanted to know if it was
something obvious…

Not sure the Pi has vsync - wouldn’t SDL use it if it had? Right now from
what I gather, it’s really just a dumb framebuffer without any
acelleration, etc.

Gordon

____________________________**
From: Gordon Henderson <gordon+sdl at drogon.net>
To: SDL Development List
Sent: Tue, May 29, 2012 12:19:04 PM
Subject: Re: [SDL] Flickering display - me or Pi ?

On Tue, 29 May 2012, Jonathan Dearborn wrote:

What are you using to draw the lines? Make sure there’s no

SDL_UpdateRect
or SDL_Flip happening between drawing calls in the same frame.

Essentially, I’m poking pixels into the screen

  *((uint16_t *)myScreen->pixels + y * hgWidth + x)  = plotColour ;

and ye-olde Bresenham in-front of that.

I’ve gone through everything to check for a spurious UpdateRect or Flip
and not
found anything - I have one “update” function in the code which everything
calls…

I know that if I did an update on every line then it would be as slow as
a slow
thing…

Gordon
_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

No SDL has no support for vsync directly for software renders. On another device
which is similar to the rPi we use an ioctl through the framebuffer device. No
clue yet if it would work on rPi. But basically you call the ioctl right before
the flip/update.

global:
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>

#ifndef FBIO_WAITFORVSYNC
#define FBIO_WAITFORVSYNC _IOW(‘F’, 0x20, __u32)

int fbdev = -1;

open:
fbdev = open ("/dev/fb0", O_RDONLY /* O_RDWR */ );
if ( fbdev < 0 ) {
printf( “Couldn’t open /dev/fb0 for vsync\n” );
}

call before SDL update/flip:
if ( fbdev >= 0 ) {
int arg = 0;
ioctl( fbdev, FBIO_WAITFORVSYNC, &arg );
}

close:
close(fbdev);
fbdev = -1;________________________________
From: gordon+sdl@drogon.net (Gordon Henderson)
To: SDL Development List
Sent: Tue, May 29, 2012 1:17:58 PM
Subject: Re: [SDL] Flickering display - me or Pi ?

On Tue, 29 May 2012, Scott Smith wrote:

Sounds like your screen is the actual framebuffer and the screen is updating
in
the middle of your application.
You could try doing your own double buffering and draw the final buffer to the
screen.
Another option would be to use vsync.

I may do a few more experiments - really just wanted to know if it was
something obvious…

Not sure the Pi has vsync - wouldn’t SDL use it if it had? Right now from
what I gather, it’s really just a dumb framebuffer without any
acelleration, etc.

Gordon


From: Gordon Henderson <gordon+sdl at drogon.net>
To: SDL Development List
Sent: Tue, May 29, 2012 12:19:04 PM
Subject: Re: [SDL] Flickering display - me or Pi ?

On Tue, 29 May 2012, Jonathan Dearborn wrote:

What are you using to draw the lines? Make sure there’s no SDL_UpdateRect
or SDL_Flip happening between drawing calls in the same frame.

Essentially, I’m poking pixels into the screen

   *((uint16_t *)myScreen->pixels + y * hgWidth + x)  = plotColour ;

and ye-olde Bresenham in-front of that.

I’ve gone through everything to check for a spurious UpdateRect or Flip and
not
found anything - I have one “update” function in the code which everything
calls…

I know that if I did an update on every line then it would be as slow as a
slow
thing…

Gordon


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hello !

What about the test examples that come with SDL ? testsprite, testwin ?
Do they behave the same way ?

CU

Hello !

What about the test examples that come with SDL ? testsprite, testwin ?
Do they behave the same way ?

Er, test examples… I’ll need to find them and check!

However it seems detecting vsync might not be possible on the Pi…

GordonOn Tue, 29 May 2012, Torsten Giebl wrote:

Hello !

Er, test examples… I’ll need to find them and check!

Just, download the latest SDL 1.2 source from libsdl.org
and look into the test directory or look at hg :

http://hg.libsdl.org/SDL/file/2b923729fd01/test

However it seems detecting vsync might not be possible on the Pi…

Using Linux without real OpenGL, VSync is always a problem :frowning:

Also i would guess the framebuffer driver is not the
highest priority of the Pi people. They are mainly working on
the X driver to provide good performance, this is what they say
in the videos.

CU

Using Linux without real OpenGL, VSync is always a problem :frowning:

Seems like it…

Also i would guess the framebuffer driver is not the
highest priority of the Pi people. They are mainly working on
the X driver to provide good performance, this is what they say
in the videos.

From what I understand, getting faster X means improving the framebuffer
driver - and from my limited understanding, just providing basic 2D
acelleration into it (ie. calling the GPU to blit/move the memory would be
a start)

However…

So from some experiments tonight, it seems that the framebuffer on the Pi
is being accessed directly by SDL and not buffering it at all.

This BASIC program:

HGR
CYCLE
LINE (0, 0, 0, GHEIGHT - 1)
LINE (23, 0, 23, GHEIGHT - 1)
FOR i = 1 TO 10 CYCLE
HVTAB (0, i)
PRINT “Hello”;
REPEAT
//UPDATE
REPEAT
END

when run under X, (on the Pi, or desktop) or on my laptop on the console
produces a blank screen - the update instruction is commented out, and
that’s what I’d expect. (a blank screen) When I hit the ESC key, the
program stops running, an update (SDL_Flip) is called and I see it.

However on the console on the Pi, I get a flickering display with the 2
vertical lines interfering with the text. ie. it’s somehowe updating the
display, or even writing directly into the framebuffer.

So something’s not right somewhere!

GordonOn Tue, 29 May 2012, Torsten Giebl wrote:

Hello,

Even if you use “SDL_SWSURFACE” on the flags, you obtain a hardware
surface as that’s a requirement for double buffering.

If you want to prevent the flickering, you can remove the
"SDL_DOUBLEBUF" flag and use only the “SDL_SWSURFACE” one.

The best option, however, would be to stick with a hardware surface and
double buffering, and fix SDL, that doesn’t use the correct ioctl to
wait for the VSYNC refresh (in hope that the Pi’s framebuffer driver
provides that ioctl). See the attached patch.

Best regards,

Paul Cercueil

-------------- next part --------------
A non-text attachment was scrubbed…
Name: sdl-fbcon-waitforvsync.patch
Type: text/x-patch
Size: 624 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20120529/56f59f72/attachment.bin

Hello,

Even if you use “SDL_SWSURFACE” on the flags, you obtain a hardware
surface as that’s a requirement for double buffering.

If you want to prevent the flickering, you can remove the
"SDL_DOUBLEBUF" flag and use only the “SDL_SWSURFACE” one.

The best option, however, would be to stick with a hardware surface and
double buffering, and fix SDL, that doesn’t use the correct ioctl to
wait for the VSYNC refresh (in hope that the Pi’s framebuffer driver
provides that ioctl). See the attached patch.

Best regards,

Paul Cercueil
-------------- next part --------------
A non-text attachment was scrubbed…
Name: sdl-fbcon-waitforvsync.patch
Type: text/x-patch
Size: 624 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20120529/ab4cf436/attachment.bin

Hello !

Even if you use “SDL_SWSURFACE” on the flags, you obtain a hardware surface as that’s a requirement for double buffering.

If you want to prevent the flickering, you can remove the “SDL_DOUBLEBUF” flag and use only the “SDL_SWSURFACE” one.

I always thought when using SDL_DOUBLEBUF with SDL_SWSURFACE, the SDL_DOUBLEBUF option is simply ignored.
Would be great if Sam Lantinga could explain, what the priorities are in SDL 1.2 ?

CU

SDL_SWSURFACE is 0, so it cannot take precedence.

Jonny DOn Tue, May 29, 2012 at 8:11 PM, Torsten Giebl wrote:

Hello !

Even if you use “SDL_SWSURFACE” on the flags, you obtain a hardware
surface as that’s a requirement for double buffering.

If you want to prevent the flickering, you can remove the
"SDL_DOUBLEBUF" flag and use only the “SDL_SWSURFACE” one.

I always thought when using SDL_DOUBLEBUF with SDL_SWSURFACE, the
SDL_DOUBLEBUF option is simply ignored.
Would be great if Sam Lantinga could explain, what the priorities are in
SDL 1.2 ?

CU


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hallo !

SDL_SWSURFACE is 0, so it cannot take precedence.

SDL_SWSURFACE and SDL_HWSURFACE are using the same bit in the flag mask,
but SDL_DOUBLEBUF is not, so

SDL_DOUBLEBUF | SDL_SWSURFACE would still be not equal to SDL_DOUBLEBUF | SDL_HWSURFACE,
but i found that part in SDL_video.c in the SDL_SetVideoMode function :

if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
	/* Use hardware surfaces when double-buffering */
	flags |= SDL_HWSURFACE;
}

so Sam is setting the bit for SDL_HWSURFACEs manually.

CU

Well, what I was implying is that SDL_DOUBLEBUF with no SDL_HWSURFACE means
SDL_DOUBLEBUF | SDL_SWSURFACE. So, just using SDL_DOUBLEBUF would have
been a no-op, which would be yucky semantics.

Jonny D

Hello,

Even if you use “SDL_SWSURFACE” on the flags, you obtain a hardware surface
as that’s a requirement for double buffering.

If you want to prevent the flickering, you can remove the "SDL_DOUBLEBUF"
flag and use only the “SDL_SWSURFACE” one.

OK. I think I have found the following:

If I use SDL_DOUBLEBUF then I get the flickering. SDL (or whatever)
appears to be writing directly to the visible framebuffer regardless of
any calls to SDL_Flip or _UpdateRect.

So not trying SDL_DOUBLEBUF is what makes it work.

The best option, however, would be to stick with a hardware surface and
double buffering, and fix SDL, that doesn’t use the correct ioctl to wait for
the VSYNC refresh (in hope that the Pi’s framebuffer driver provides that
ioctl). See the attached patch.

A quick grep of FBIO_WAITFORVSYNC in linux/drivers/video shows a
depressing number of drivers that appear to support it, and the
bcm2708_fb.c doesn’t appear to be one of them )-:

I think the Pi’s driver still has some issues though - I can still cause
the framebuffer to “go away” after running/exiting/running my program
serveral times in a row )-:

Still, I have an acceptable solution for now - and the last bit of the
puzzle to make my sprite handling go faster was using 16bpp for the
background store for each sprite - that gave a 3x improvement in speed!

Thanks,

GordonOn Tue, 29 May 2012, Paul Cercueil wrote: