On Wed, 22 Jan 2003, Andreas Beck wrote:

> > > Think about something like a PDA. They have buttons to bring specific Apps
> > > to the front. That is pretty similar to a switchaway. Now such a PDA
> > > has no MMU usually ... so how do we transparently remap the VidRAM
> > > to some normal RAM there?
> > > Difficult - right?
>
> > Not at all! AROS does it, AmigaOS does it, exactly that way!
>
> Please detail. I would like to know how you do that _WITHOUT_AN_MMU_
> and with hard-mapped graphics RAM areas.

The general rule is that a shard HW resource has to be acquired in order
to use it, and released when done.

If an application requires access to a resource, it tries to acquire it,
and if that resource is already acquired in an exclusive way by anoter
application then it will have to wait for the other one to release it.

When VT switching (or screen switching on AmigaOS) happens, the
application that is going to be switched to the front, transparently and
trough the help of the framework, will try to acquire possession of the
screen and will wait until such acquisition is possible.

Bearing in mind this rule, we can consider a few cases:

1) The application uses an API to draw on screen (putpixel, drawline, and
   so on). Each API's function has to acquire the video surface in order
   to draw on it, and all other applications trying to draw on the screen
   would have to wait for the current application to exit the current
   function first. Since the application uses the API to access the
   framebuffer, VT switching can happen in between one API call and the
   other one. The frontmost application will either continue rendering
   on a backbuffer, or it will continue rendering in gfx memory if the
   screen's buffer is in such memory. It all happens transparently and
   the application doesn't notice anything. This is the way it happens
   on AmigaOS.

2) The application has required direct access to the framebuffer. To do so
   it has acquired it. VT switching, in this case, can be done in two
   ways:

   2.1) Just like in any other case, the switching won't happen until the
        application releases the framebuffer. Well behaved application
        won't keep possession of the framebuffer for too long anyway, and
        in case they do - AND ONLY IN THAT CASE - such applications will
        be put to sleep. It can be done by setting a timeout on the
        resource acquisition - say 5 secs. If the time goes up, the
        resource is temporarily released and the faulty application is
        put to sleep. This approach is user-friendly because
        in the majority of cases the application won't keep the resource
        allocated for so long.

   2.2) The other approach is the safest one, and the most userfriendly
        one: use the MMU to fake a framebuffer where it's not: no need for
        timeouts at all.

The 2.1 way is the one AmigaOS implements, so no MMU is used, unlike
someone guessed here.

However, I also suggest other methods in addition to this one, which
include notiification of switching to he application. Notification,
however, is asyncrhonous and the framework won't depend on an answer from
the application to continue its job: that would open to DOS.

As I wrote in another email, the application can tell the target that,
when it loses visibility, it wants to either

    1) Continue running on a backbuffer
    2) Continue running without backbuffer
    3) Be stopped with a backbuffer
    4) Be stopped without a backbuffer

Andreas rejected this approach because he said that if we are to list
things that an application can request to the framework then why not
include _everything_ in the list? Of course since that is impossible
Andreas suggested that no list is used altogether, and that the
application has to be always notified - synchronously! - and handle the
matter itself.

Beware, with synchronouse and asynchronous, there, I mean that the
framework will, respectively, wait and NOT wait for an answer from the
application.

Unsurprisingly I reject the Andreas' rejection, because it's not based on
a concrete reasoning: what I proposed is a list of options which make it
possible to satisfy _any_ applications' requirements: the only two
superfluous ones are 3 and 4, because they could be implemented without
any effort by the application itself given the options 1 and 2.

How's that possible? Very simply, indeed: the application will be notified
by the framework of events such as "hide" and "expose". The application is
_not_ forced to handle such events, specially if it requested to continue
running on a backbuffer, however it should always check for the expose
event because in some cases it might not be possible to provide backbuffer
(very seldomly, actually, but it's a possibility), and therefore it might
need to redraw some parts. In some cases such redrawing is just not
possible, and in those cases the application, if it's so important, will
have to forget about direct framebuffer access.

When the application receives a "hide" event it can take any actions it
thinks it's appropriate to take, and some applications might want to stop
rendering (those apps tipically won't request a backbuffer), or will want
to put themselves to sleep by simply waiting for the "expose" event.

When the application receives the "expose" event it will need to check
whether there are areas to refresh. These areas will be provided in a
linked list of rectangles, or a similar thing. Applications which
requested a backing store won't be required to check for an expose event,
although they still can.

----

I think that's all... maybe I missed something, so if you notice any
incongruencies please tell me about it.

Now let's see why the method Andreas and some others suggested won't
simply be better than the one I proposed. In short, it still has to cope
with a lot of situations which my model has to cope with, but doesn't
offer any of the "neat" things that my model does, yet it opens for
potential DOS's.

Why so? Well, first of all, putting the application to sleep on VT switch
will still require you to save the state of the gfx card and restore it
later on. Moreover, waiting for the application to reply before switching
VT will make the system fragile, because the application might _NEVER_
respond. If you think you could set a timeout, well, sorry, but I was
there first, so I don't see how your solution would be better than mine.

Then, Andreas says that applications will have to implement backingstore
themselves, however I don't see why such thing couldn't be provided by ggi
itself, so that's why there's also option (1) in my model: less hassle for
the programmer, no need to code over and over the same piece of code just
to make the application switch to an alternative framebuffer, when it can
all be done automatically.

The other, last point, is that my model does everything that Andreas'
does, whilst it cannot be said the opposite: as I showed already,
applications could put themselves to sleep in the most natural way:
waiting for the "expose" event. Applications which want to continue
running can just _check_ for the event once in a while, or spawn another
thread which waits for that event and notifies the running threads
accordingly, which should also be the usual way applications deal with
other ggi events.

Concluding, I think Andrea's approach is rough, and not friendly to the
programmer nor to the user. Mine tries to avoid hassles to both of them,
and it succeedes in it very well, also because it's collaudated by the OS
I myself code (together with other people), and by other 2 OS's, so it's
not like I'm speaking out of my arse, I really know the stuff I'm talking
about.

Regards,
Fabio Alemagna

Reply via email to