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