On Tue, 27 Feb 2001, Christoph Egger wrote:
> > Right, and the order that the resources appear in the list is the
> > order of importance, so suppose you wanted to say this:
> > 
> > "I want to use 640x480 at the highest bit depth I can get, but I 
> > definitely need a sprite even if it means using a lower bit depth.
> > And an off-screen scratch area would be nice, but is not necessary."
> > 
> > You would have a linked list in this order:
> > 
> > (Resource with type RT_SPRITE) -->
> > (Resource with type RT_FRAME with the ggi_mode set to 640x480/GT_AUTO) -->
> > (Resource with type RT_SWATCH) --> 
> > NULL
> > 
> > The function that does the work might look ahead in the list for
> > example to choose a better VRAM layout, but it would always satisfy
> > the requirements of the entries at the top of the list first.  You
> > can also put more than one RT_FRAME resource in -- this:
> > 
> > (Resource with type RT_SPRITE) -->
> > (Resource with type RT_FRAME with the ggi_mode set to 640x480/GT_8BIT) -->
> > (Resource with type RT_SWATCH) --> 
> > (Resource with type RT_FRAME with the ggi_mode set to GGI_AUTO/GT_AUTO) -->
> > NULL
> > 
> > Means:
> > 
> > "I absolutely need a sprite, and I need at least 640x480x8, and I want
> > a swatch.  Better than 8bit colors and more resolution would be nice, 
> > but I prefer to have the swatch even if it means I only get 640x480x8."
> 
> I know, what you want. I have tried to thought this deeply out.
> 
> As a result I can say, you can NOT do this WITHOUT having at least
> one thread in each (non-)extension like libovl, libblit, libxmi,
> libbse, etc. And this would eat everything up, what GGI gains out of
> the hardware, except you have a SMP-machine with 4 CPU's or more...

Hmm... I think we're reading different editions of the same book...  
I don't see any need for any threads.  But to clarify my last few
emails, most of my suggestions are for long term expansion of 
GAlloc.  For the immediate short term, we would only need to implement the 
on-the-spot functionality, where a single feature is requested at 
a time with the video mode already having been set with ggiSetMode, 
it is allocated, and the necessary information for the higher level 
libraries is provided, and the higher level libraries use this 
information to build one of their objects.  All with a single 
higher level library function call.  This is all you need to
worry about right now to get the structure up.  Since this will
likely be ALPHA software for a while, adding the stuff to the
GAResource_t later won't disrupt things too much.

But to look ahead, what we would do in the libs like libOVL is
have two functions, one on-the-spot function, and another that 
simply adds a resource to the "extended mode request".  So the
advanced programmers could do something like this *instead of*
calling the regular ggiCheckMode/ggiSetMode:

ggiGAInit(vis);
ggiOVLInit(vis);
ggiMISCInit(vis);

ggi_GAResource_t mymode;
/* Put 640x480x8 first in the requested feature list */
mymode = ggiGASimpleGraphModeAddRequest(640, 480, GT_8BIT);
/* The accesses to ->next could actually be dome with
   convenience functions, I left them this way for clarity. */
/* Put the ability to wait for vertical retrace in the feature list. */
mymode->next = ggiMISCAddRequest(GAT_WAITRETRACE);
/* Put a request for a hardware pointer (of any size) in the feature list. */
mymode->next->next = 
        ggiOVLOverlayAddRequest(GAT_SPRITE_POINTER, GGI_AUTO, GGI_AUTO);
if (GGIGACheck(vis, mymode)) {
        ggiGADeallocRequests(mymode->next->next);
        mymode->next->next = NULL
        if (GGIGACheck(vis, mymode)) {
                fprintf(stderr, "Need 640x480x8 and waitretrace\n");
                fprintf(stderr, "...and you don't have it, sorry.\n");
                GGIExit();
        }
        fprintf(stderr, "No mouse pointer available.  Will have to emulate.");
        emulate_pointer = 1;
}
/* This does the setmode, as GAlloc implements it's own setmode, which
   is why we need both set/check. */
if (ggiGASet(vis, mymode)) {
        fprintf(stderr, "FIXME: Something unexpected happened\n");
}
/* Deallocs/clears whole list of requests. */
ggiGADeallocRequests(mymode);
/* Gets the current set of allocated resources, which if there were 
   any GGI_AUTOs or other "don't care's" in the request, this will contain 
   the values we actually ended up getting for these fields, which is 
   why we need the "get" function. */
ggiGAGet(vis, &mymode);
/* Actually this whole while loop would be more like this:
   mypointer = ggiOVLTieItem(mymode, 0); Gets first sprite in list,
                                         ignores stuff for other extensions 
   ggiMISCTieItems(mymode);  Initialize any features LibGGIMISC handles
                             which appear in the response list.
*/
while(mymode) {
        switch (mymode->res_type) {
        case GAT_SPRITE_POINTER:
          /* Grabs the info like the hardware address of the sprite/etc,
             and asks the target to do any pre-use initialization. */
          mypointer = ggiOVLTieItem(mymode);
          break;
        case GAT_MISC_VERTRETRACE;
          ggiMISCTieItem(mymode);
          break;
        }
        /* Note -- "Resource", not "Resources" -- returns rest of list. */
        mymode = ggiGAFreeResource(mymode);
}

Note that the functions other than ggiGACheck above do not have a vis
argument, because all they do is allocate and construct the request object.
No target specific functions get called until ggiGACheck.

> I think, the best way is leave the order of importance to the
> application. It knows, what it needs and has to say, what it needs in
> the order of importance. When it does crap, then it gets crap. :)
> 
> LibGalloc just checks, if the resources are available or not and
> allocate them if possible.

Yes, but it knows how to figure out how to get the resources out of the
target.  That's the whole point of GAlloc.  Now granted, our actual 
implementations of the set/check functions may never be so thorough 
that they can squeeze every last drop out of a target, but the potential 
is there.

> Yep. But now I think, that this function isn't needed anymore.
> See above.

I see why you wanted it now; I was thinking that the amount of
effort to keep the API users' grubby fingers out of the data 
structure was a bit extreme, but, I think that it can be done
more easily now that I've thought about it, and even though I
don't expect the people that will be using things at the
low level GAlloc API will have grubby fingers :), being opaque 
can't hurt. 

I'm stingy when it comes to defining actual functions vs macros, 
but I can see that linked list management functions probably 
deserve to be real functions.

> I thought, that the access to the resources is left to the extensions
> as they know about the special format of them.

Right, but GAlloc has to pass back information to them; some of it is 
feature specific.  We can pretend that all our features will all be
able to be defined with nothing but a DB struct/mode/size/etc., but really
I think we are deluding ourselves that way, and we have to realize that
there's a certain amount of the intraface for each extension (the 
request/response structures) that will have to be in/come from GAlloc.

GAlloc will keep this to a minimum, so that most stuff will be in the
extension.  For example, when you get a sprite, Galloc would probably
provide ONLY the hardware address of the sprite.  It would leave it
to the higher level library's target specific sublib to fill out the 
db struct with the proper pixel and memory layout of the buffer.

> I thought that libGalloc is intended for (de)allocation of resources,
> because of its name...

Yep.  It does no actual initialization of hardware, it's only job is
to know what the target can do.

> > This is a bit of a sticky situation: LibGAlloc is supposed to be a 
> > core library,
> 
> So the right place for it in the CVS would be
> libggi/extensions/libgalloc, right?

Not sure.  Personally I think that entire directory should be 
retired and all extensions moved down to the peer level with libGGI.
But if we are keeping that directory, then GAlloc deserves to be there
even more than ggiMISC does.

> This way is much better:
> 
> > I think I like what you're doing in this sense: the headers that 
> > define the feature properties that are needed to negotiate the 
> > feature are part of LibGAlloc, and extensions include the LibGAlloc
> > headers.  This would make LibGAlloc able to build without the extensions
> > present.  But rather than change the resource structure all the time,
> > maybe we are best off defining a bunch of unions with the common
> > properties, which all keep track of their size/type so they can be
> > copied blindly.  That way when a new "frag" feature that needs a property
> > called "fragalisticness" has to be added, you just need to add a header
> > in /usr/include/galloc/extensions/frag.h, and modify just the 
> > LibGAlloc target sublibs that support the "frag" extension to include
> > this file, along with the code to help them negotiate the feature on
> > their target.

I am in full agreement now; this is the way to go.


> > "Aspect" has other graphical meanings, so that's out.  Maybe we
> > should just use "thing" :-P
> 
> That's too common.

I was half serious. :)

> What about GA as a prefix? Then we would have GA_ResourceType,
> GA_ResourceOption, etc...

OK.

--
Brian

Reply via email to