Welcome, Guest. Please login or register.

Author Topic: Multiple buffering (general purpose)  (Read 935 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Multiple buffering (general purpose)
« on: February 19, 2005, 02:01:21 PM »
kas1e's recent thread got me thinking about multiple buffering in general.

Being lazy and using WaitBVOP() got me a telling off from Piru and I now have the issue that my DisplayScreenBuffered class uses this approach, which I have confirmed is a CPU eater.

Looking at the documentation for "proper" multiple buffering, it seems there are 2 messages you should wait for. One to say that the display is safe to switch buffers and another to say that it's safe to use the BitMap.

I couldn't help noticing, in the graphics.doc documentation that you wait for the BitMap first, then you may render to it, then you wait again before you swap the buffers.

I need to implement Display::refresh() for my class and I am now wondering about the best way to do it.

I am thinking of using a high priority child task that handles the physical swapping of buffers and all the waiting where needed, that is triggered by the parent task when it calls refresh().

My idea is that the very moment the BitMap is safe to use again, the child task will signal the parent again so that the refresh() method can return immediately allowing processing to continue, whilst the child task waits for the 'safe to switch buffers' message.

So the general idea for this is

1) Child task is waiting for parent to signal it.

2) Parent calls refresh(), which sends signal to child task.
The refresh() method now waits for child task to signal back that the BitMap is free.

3) Child task wakens then waits for BitMap "safe to use" message from graphics.library. On receiving this message, signals parent task that BitMap is free. The refresh() method is now complete and can return allowing the parent task to carry on rendering.

4) Child task waits for "safe to switch buffers" message from graphics.library. On receiving this message, the buffer switch is performed.

5) Child task now goes back to sleep again (1).

Has anybody tried something like this?
int p; // A
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Multiple buffering (general purpose)
« Reply #1 on: February 20, 2005, 12:52:25 AM »
:bump:

Piru, wherefore art thou? :-D
int p; // A
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Multiple buffering (general purpose)
« Reply #2 on: February 20, 2005, 02:06:20 AM »
@Karlos

Often the problem with such system is, that you still need to calculate certain amount of data before it can be displayed (say, some 3d shooter). Sure, using the "wait time" to calculate more data is a good idea, but quite hard to implement in a way you actually get better framerate. It will work better in a case where your framerate is always fixed, and the quality of each frame depends on how much calculations you manage to do, or you just need to do some other heavy calculations unrelated to graphics displayed.

Even if you don't separate the calculation and display control, using the full blown ScreenBuffer buffering helps by giving the "wait time" for other same or lower pri tasks (instead of just selflessly hogging the cpu time waiting for certain display position). This is always a Good Thing (TM).

Have I ever done it this way? No. I've always done the waiting inside the loop, and donated the CPU time for the good cause.
 

Offline KarlosTopic starter

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Multiple buffering (general purpose)
« Reply #3 on: February 20, 2005, 02:18:34 AM »
I guess I will have to "suck it and see" :-)

What I basically wanted to achieve with this was a way of allowing the task that calls the refresh() method of being able to return instantly the invisible Surface (a wrapper class for BitMap) is free for use, rather than waiting for the entire display update. Of course, depending on how fast the main task is chewing through whatever it is drawing it might still end up waiting on it anyway.

It was just a general idea to get some of the waiting time back.

As you say, there are other tasks that might benefit from that CPU time, but given the aim of my framework is for game type applications, hogging all the resources is something I dont mind doing - provided they are shared fairly within the context of the application istelf.

One of the other possible caveats is that my Display interface class actually has two methods to implement:

void Display::refresh()
void Display::waitSync()

Of course the method I was envisaging here would result in synchronized updates anyway, so waitSync() would end up being an empty function :-/
int p; // A