Heya,
Just throwing this to the gallery for comments.
We have three new lowlevel libraries which (along with LibGGIMISC)
will be forming the core of the intermediate API for the GGI Project,
LibBuf, LibBlt, and LibOvl.
1) We would like to allow folks to use each library separately when
they do not need the functionality of the others.
2) There is redundant structure between the three libraries. I have
listed below the structure and which libraries use it, and for what
purpose.
3) We want objects for these libraries to be leightweight in some
cases.
4) We'd probably like to have groups of objects that share a certain
set of attributes, such that 3) is acheived with the added advantage
that the whole group of objects can have that attribute modified
en-masse very cheaply.
Attribute list:
1) Objects can have a position and size on the visible screen, and may
be able to scale their content and pan around inside their content,
may be able to tesslate their content, and may have a priority
relative to other objects on the screen. All LibOvl objects have this
set of attributes because they have a persistant location. LibBuf
objects do not. LibBlt Objects might benefit from having these
attributes but it should be optional so as not to weigh the object
down (LibBlt's API can be used to position resources in a functionally
oriented manner rather than keeping these values inside the object.)
2) Objects that have content can have a stride specifying their buffer
layout, a current read/write pointer when using direct access, an
optional pointer to a ggi_directbuffer if thorough pixel and buffer
format information is needed, and a frame number, for N-buffering.
A single object can also be used to administer multiple chunks of
content, and so either a linear index or a "drawing origin" can exist.
("drawing origin" and frame number are not equivalent because frame
numbers may be tied to special vertical retrace/realtime
functionality). LibBuf objects always have these properties, LibBlt
objects can get away with merely copying from the screen, but it may
be desirable to have these attributes. Some LibOvl objects have these
attributes (those that have content).
3) Objects can have methods to access the data inside them, if it is
not as trivial as directly accessing the data directly. (Actually
even if it is, as this provides a consistant interface). Any object
that has 2) can have 3).
4) Objects providing a color channel or math channel can have a
default value for use when they are the destination of an operation
where the source has no such channel, or a second set of such values
when they are the source of an operation on an object which has no
such channel. For Alpha and Z, they may also have some "flags" to go
along with certain channels (e.g. designating the comparison rule and
blend rule). Some LibBuf objects have these attributes.
5) Objects can provide a mathematical substitute for color/math
channels if they do not have them, e.g. interpolated values between a
minimum and a maximum value. LibBlt objects can optionally carry
these values.
6) Objects can have a source raster operation and "keying values" and
mask. Actually, they can have two sets of two "keying values", each
set consists of a source and a destination key/mask. One set, the
"dest default" provides these values when used with a source object
that doesn't have a them, the other set provides them when the object
is used as a source, to override the "dest default" set if present.
LibOvl objects and LibBlt objects have these.
7) Objects have a set of resources with which they were negotiated via
LibGAlloc. These include restrictions and rules on their use, and
various items of data used to initialize the above attributes, and are
used to destroy the objects properly, returning chipset resources.
Now all these attributes require C structure, which raises the question
as to where to keep this structure. Since the structure itself does
not necessarily take any space as it is all header, we have three
options that I see:
A) Store it in the LibGGI core, in a lowlevel.h extra include file.
B) Store it in LibBuf and require LibBuf's development environment to
be present to build applications that use the other two libraries.
C) Create a new directory under lowlevel that has just the header.
In addition 3) requires actual sublibs, and we have to decide where to
best store those. C) would give us a place to keep those, but it
would also require yet another "make install". A) would also, but
would add unused sublibs to the LibGGI installation. B) would require
parts of LibBuf to be installed even when it is not being used.
Finally, we want to have leightwieght structures and sharing of common
attributes between groups of objects. However access to these
attributes needs to be relatively fast (not as fast as absolutely
possible, as LibBlt has other mechanisms to improve speed.) I was
thinking something like the following:
#define GGI_LL_OBJ(NUM_ATTRIBS) \
u_int32_t attribs; \
void *ptrs[NUM_ATTRIBS + 3];
/* ptrs always contains { NULL, NULL, NULL, ...data... } */
#define GGI_LL_ATTRIB_MASK 0x0000000f
#define GGI_LL_POS_SHIFT 28
#define GGI_LL_POS_NUMPTRS 3
#define GGI_LL_POS(obj) \
(ggi_ll_position_t)ptrs[(obj->attribs >> GGI_LL_POSITION_SHIFT) & GGI_LL_ATTRIB_MASK]
#define GGI_LL_CB(obj)
(ggi_ll_coordbase_t)ptrs[((obj->attribs >> GGI_LL_POSITION_SHIFT) &
GGI_LL_ATTRIB_MASK) + 1]
#define GGI_LL_LENSE(obj)
(ggi_ll_lense_t)ptrs[((obj->attribs >> GGI_LL_POSITION_SHIFT) & GGI_LL_ATTRIB_MASK) +
2]
#define GGI_LL_STORAGE_SHIFT 24
#define GGI_LL_STORAGE_NUMPTRS 2
/* ...and so on */
Thus the 32-bit integer is used to point eight types of attributes to
any of 16 void* pointers, the first three of which are always NULL (this
saves on a special case check to see if the attribute exists -- it exists
if the designated pointers are not NULL). This costs only 1 shift, 1 mask,
and 1 addition/index. Thus the container object can range in size
from 16 bytes to 80 bytes (or 28 to 188 bytes on 64-bit architectures).
The attributes in the first list would be grouped as such:
GGI_LL_POS_SHIFT indexes three pointers GGI_LL_POS(obj), GGI_LL_CB(obj)
and GGI_LL_LENSE(obj) for attributes listed in #1.
GGI_LL_STORAGE_SHIFT indexes two pointers GGI_LL_STSTATE(obj) and
GGI_LL_STOPS(obj) representing the attributes in #2 and #3
GGI_LL_GC_SHIFT indexes three pointers GGI_LL_FGBG_GC(obj) and
GGI_LL_FGBG2 representing #4 or #5, and GGI_LL_MATH_GC(obj) representing
#6 and the rules from #4.
GGI_LL_PRIV_SHIFT is for target-specific use
GGI_LL_RESOURCE_SHIFT indexes a single pointer for #7
Comments?
--
Brian