Index:
[thread]
[date]
[subject]
[author]
From: Andrew Apted <ajapted@netspace.net.au>
To : ggi-develop@eskimo.com
Date: Wed, 5 Aug 1998 14:39:26 +1000
Re: ggiGetPixelFormat and proposed new DirectBuffer scheme
Marcus writes:
> I've been hacking some headers and here's what I propose:
>
> /* Pixelformat for ggiGet/Put buffers etc. */
> typedef struct {
> int bits; /* Number of significant bits */
> int size; /* Physical size in bits */
>
> ggi_pixel red_mask; /* Bitmask of red bits */
> ggi_pixel green_mask; /* Bitmask of green bits */
> ggi_pixel blue_mask; /* Bitmask of blue bits */
> ggi_pixel alpha_mask; /* Bitmask of alphachannel bits */
>
> ggi_pixel clut_mask; /* Bitmask of bits for the clut */
> ggi_pixel fg_mask; /* Bitmask of foreground color */
> ggi_pixel bg_mask; /* Bitmask of background color */
> ggi_pixel texture_mask; /* Bitmask of the texture (for
> textmodes - the actual character) */
> uint32 flags; /* Pixelformat flags */
> } ggi_pixelformat;
>
> /* Pixelformat flags */
> #define GGI_PF_REVERSE_ENDIAN 0x01
> #define GGI_PF_HIGHBIT_LEFT 0x02
> #define GGI_PF_HIGHBIT_RIGHT 0x04
Nice.
First question, how does GGI_PF_REVERSE_ENDIAN relate to the masks ?
Does it mean that masks don't change (e.g. r5g5b5), and the program has
to byte swap *after* encoding a pixel using the masks ?
Second question, what about 1..7 bit modes ? For example, on a 1 bit
mode the above should have clut_mask == 0x01. I think that's OK, but it
does imply that ggiGetXXX/ggiPutXXX don't take packed data (e.g. 8
pixels packed in each byte) but *unpacked* data (one pixel per byte).
I prefer the unpacked case, it is so much easier to program for, since
you don't have to worry about packing the data (with LSBit vs MSBit).
The disadvantage is ggiPutXXX can't resort to memcpy _when the data is
aligned_. I'm not worried about this, applications can always access
the framebuffer directly to get a speed boost.
(I guess that 1 bit modes under X would be slower too -- but IMHO the
nicer interface for all depths < 8 is more important than the speed of
1 bit modes).
Also, I've got a bad feeling that 2 cases (MSBit vs LSBit) won't be
enough to cover all the 1/2/4 bit modes. There is probably hardware
with crap like "75316420" arrangements (Atari ? EGA ? C64 ? :)
> The ggi_info struct and ggiGetInfo() will be removed completely.
> The information in it is now supplied by the old functions:
> ggiDBGetBuffer(), ggiGetMode() and ggiGetFlags()
> and the new functions:
> const ggi_pixelformat *ggiGetPixelFormat(ggi_visual_t vis);
> int ggiGetSelectFD(ggi_visual_t vis);
Good.
> /***************************************************************
> * DirectBuffer
> ***************************************************************/
>
> typedef enum {
> blPixelLinearBuffer,
> blExtended,
>
> blLastBufferLayout
> } ggi_bufferlayout;
We're going to need blBitPlanarBuffer and blInterleavedPlanarBuffer soon
(when running LibGGI on linux/m68k). Just something to keep in mind.
> typedef struct {
> int stride; /* bytes per row */
> ggi_pixelformat *pixelformat; /* format of the pixels */
> } ggi_pixellinearbuffer;
>
> /* Buffer types */
> #define GGI_DB_NORMAL 0x01
> #define GGI_DB_EXTENDED 0x02
> #define GGI_DB_MULTI_LEFT 0x04
> #define GGI_DB_MULTI_RIGHT 0x08
Something else is needed here:
#define GGI_DB_PRIVATE 0x10
This is for direct buffers that remain internal to LibGGI, such as the
emulation targets (trueemu, tile, ...) where the buffers are not
"Direct" and shouldn't be given to applications. ggiGetNumBuffers()
should not count these, and ggiGetDBGetBuffer() should skip over them.
> typedef struct {
> int frame; /* framenumber */
> uint32 type; /* buffer type */
>
> /* access info */
> void *read; /* buffer address for reads */
> void *write; /* buffer address for writes */
> unsigned int access; /* supported access widths */
> unsigned int align; /* alignment requirements */
> unsigned int page_size; /* zero for true linear buffers */
>
> ggi_bufferlayout layout;
>
> /* The actual buffer info. Depends on layout. */
> union {
> ggi_pixellinearbuffer plb;
> void *extended;
> } buffer;
> } ggi_directbuffer;
Possible addition:
int non_standard; /* non standard framebuffer types */
which would normally be 0, but would take on special values if the
framebuffer was partically strange, e.g. :
#define GGI_DB_NONSTD_VGA_MODEX
#define GGI_DB_NONSTD_VGA_MODEY
#define GGI_DB_NONSTD_HAM6
#define GGI_DB_NONSTD_HAM8
(though maybe this could be handled by the extension mechanism)
> The frame entry is the framenumber (when double/tripplebuffering)
> The type entry contains one or more GGI_DB_* flags.
> This allows for things like doublebuffering on a pair of
> VR-goggles (in which case ggiDBGetNumBuffers() would return 4
> and we'd have two GGI_DB_MULTI_LEFT and two GGI_DB_MULTI_RIGHT
> buffers)
Right.
> ggiDBGetSimplePLB() will return a buffer with the following
> properties:
> frame=1
> type=GGI_DB_NORMAL
> read=write
> access=all widths supported by the host CPU
> align=any supported by the host CPU
> layout=blPixelLinearBuffer
This one I'm not sure about -- how does it relate to the frames ?
It looks like you don't get it whenever frames > 1.
I would suggest just having an extra flag in the DB types :
#define GGI_DB_SIMPLE 0x20
which means exactly what you said, read=write, access=all, align=any,
layout=plb. This would save us the extra function call and the extra
structure.
Cheers,
_____________________________________________ ____
\ /
Andrew Apted <andrew@ggi-project.org> \/
Index:
[thread]
[date]
[subject]
[author]