VOGONS


Double Buffering (GP2X)

Topic actions

First post, by Pickle

User metadata
Rank Member
Rank
Member

Hi, im been working on the GP2X port of dosbox.

I am using the SDL ttf lib to create surfaces with info, for debug and ui.
Blitting these surfaces to the screen works fine, although we have problems with flickering and unless the location where the ttf surface changes, the pixels will remain showing the remains of the ttf surface.

I believe that double buffering would solve this, but I cant use this as our SDL port doesnt support the fullscreen option. I have following questions on the implementation:

1. Why does the double buffering require fullscreen to be active?
2. Why is there use of the second surface (sdl.blit.surface)? I thought turning on the flag for double buffering handles the second screen buffer?

Reply 1 of 23, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

doublebuffering is there to prevent tearing.

the flickering probably has nothing to do with double buffering. You are aware that dosbox works with partial screenupdates ?

Water flows down the stream
How to ask questions the smart way!

Reply 2 of 23, by Pickle

User metadata
Rank Member
Rank
Member

Yeah I have seen that you modify the pixel data directly and that only the pixels that change are updated.
I thought the flickering was a result of this. As soon dosbox updates the pixels it draws onto the screen, then I blit my surface to the screen, and then the pixels get updated again and so on.
To prevent this I thought I would need to add a buffer between the dosbox updates and the screen. Like this:

1. dosbox updates buffer
2, blit buffer to screen
3. blit ttf surfaces to screen

But it seemed to me the surface.blit.surface does the same thing?

Reply 3 of 23, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

the whole partial screenupdates is there (to some extend) to prevent blits of the entire buffer to the screen. This would slow down dosbox effectively. (even if it takes a lot of time audio problems might appear as the sdl audio thread might underrun)

but technically speaking your solution could work as the flickering mostlikely comes from what you described. (however not sure how nice it will be to do 70 screensplits per second just to have an osd)

are you sure that you are currently blitting the osd on the surface on every loop of partial updates ?

You might be able to let only the osd part blit to a buffer by adding an if into partial update loop.
(for example use the top 50 pixels for the osd). Check if the partial update is for the top 50 pixels. if so blit to a seperate buffer. set some flag. at the end of the loop if flag is set. blit osd on buffer. blit 50 pixels buffer to screen)

although partial blits for larger then 50 pixels might needs some splitting up....

Water flows down the stream
How to ask questions the smart way!

Reply 8 of 23, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Don't know if the caching scaler and the changed lines handling are related,
so ignore my comment above.

In GFX_EndUpdate, which path is taken? surface with locking?
If it's without locking (that is hitting that while (y < sdl.draw.height) loop)
then try to use something like SDL_UpdateRects( sdl.surface, 0,0,0,0);
instead of the current UpdateRects call, to update the whole screen.

Reply 9 of 23, by Pickle

User metadata
Rank Member
Rank
Member

No its been going through the Locking section, thats where some of the surfaces were being blitted.

Another idea is to keep the normal render structure if the OSD is off and then only use my buffer idea when the OSD is on. The way if any slowdown is introduced it's when the OSD is active. None of the OSD's should be on all the time anyway.

Reply 10 of 23, by Harekiet

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Probably best to let dosbox render in a shadow surface when the osd is active and trigger a full redraw before starting osd, then blit shadow, blit osd and dosbox can be unaware of what's going on with the final result.
The double buffer fullscreen solution also has to use a shadow buffer since you'd get issues with partial updates not creating a fullscreen update since you basically have to provide a full screen update each frame with the flipping buffers.

Reply 12 of 23, by Pickle

User metadata
Rank Member
Rank
Member

Well the results are good so far. I forced sdl.blit.surface to be created and the flickering has gotten better, I didnt notice a speed decrease, but I attribute this to our fast harware blitter.

I am still going to look into dynamically switching between the two methods.

Reply 13 of 23, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Any idea if it can be enabled without much trouble for non-gp2x builds, too?
Might come handy by times and would make troubleshooting a bit easier
(sdl_ttf should integrate rather fine).

Reply 14 of 23, by Pickle

User metadata
Rank Member
Rank
Member
			if (retFlags && (sdl.surface->flags & SDL_DOUBLEBUF)) {
sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE,
sdl.draw.width, sdl.draw.height,
sdl.surface->format->BitsPerPixel,
sdl.surface->format->Rmask,
sdl.surface->format->Gmask,
sdl.surface->format->Bmask,
0);
/* If this one fails be ready for some flickering... */
}

Well for me it as simple as commenting out the if.
I suppose if you created a [sdl] section parameter and OR'd it in the if condition you could turn it on that way.

Reply 16 of 23, by Pickle

User metadata
Rank Member
Rank
Member

I guess I should add that most of the changes we have made should be compatible with non-GP2X builds.

Adding ttf is not too difficult, no harder than adding SDL. Add the header and you should be able to call of the needed functions. I even think the windows dll version is available precompiled.
There are some instances where the GP2X controls are hardcoded, for example the virtual keyboard ttf interface uses the GP2X joystick buttons directly. But it wouldnt take much effort to add regular keyboard controls.

Once we get everything ironed out and make a release to our community at gp32x.com and you can get the source code. Actually the version we already released has the ttf stuff it. I just in this new extended it for use as a virtual keyboard interface.

You guys might also be interested in our virtual mouse controls. You can assign keys to handle mouse buttons and direction. Although the direction is handcoded to use the GP2X stick/dpad.

Reply 17 of 23, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

well harekiet commented on irc that we could probably easier/faster use our int10 font.

Water flows down the stream
How to ask questions the smart way!

Reply 19 of 23, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

ttf is already incorporated in the printer patch, so it's no problem, but was
just trying to figure out if you're currently using it only for the gp2x port.

The int10 font might indeed be a better choice as it would support different
codepages then 😉