Index:
[thread]
[date]
[subject]
[author]
From: Marcus Sundberg <e94_msu@e.kth.se>
To : ggi-develop@eskimo.com
Date: Wed, 05 Aug 1998 12:02:36 +0200
Re: ggiGetPixelFormat and proposed new DirectBuffer scheme
Andrew Apted wrote:
>
> 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 ?
Yes, I think this makes most sense.
Having masks like:
ggbbbbb0 rrrrrggg
would imply that gg in the left byte are the high-bits, which
is not correct. Thus we have:
rrrrrggg ggbbbbb0
and GGI_PF_REVERSE_ENDIAN tells us that we need to swap the
bytes.
Of course a smart application could spot this case and encode
the pixel directly so that no swapping is needed, but the most
common case will be that it encodes the pixel according to masks
and then does a swap.
Btw, doesn't many processors have an instruction to do byte
swapping? In that case I suggest we add some byte swapping
macros to the API, which will use inline-assembly on supported
platforms.
Also, I suggest we make GGI_PF_HIGHBIT_LEFT the default and
remove that flag. Agreed?
> 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).
3,5,6 and 7 bit modes should definitely be unpacked, because
I've never heard of any HW that supports such modes with a packed
chunky buffer. :)
For the other modes I suggest we have a GGI_PF_PACKED flag that
indicate that _aligned_ buffers uses packed format.
After all, <8 bit modes are almost only used on old hardware
where speed is always an issue.
> 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 "" arrangements (Atari ? EGA ? C64 ? :)
Well, we have 32 flags in there, so I suppose we can add
a GGI_PF_75316420 when there's actually support for any
such mode. ;)
> > /***************************************************************
> > * 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.
Yep. DirectBuffer should support planar modes out of the box.
For Get/Put buffers I think it makes most sense to use chunky
pixels even if the HW is planar, as it will allow applications
to run everywhere without needing to now anything about planar
modes. There should be a planar extension anyway supporting
things like Get/PutPlane, ScrollPlane and other things that
don't make sense on non-planar HW.
> > 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.
This was my originally planned changes to structs.h:
--- old/include/structs.h Thu Jul 23 09:35:59 1998
+++ ./include/structs.h Tue Aug 4 16:40:14 1998
@@ -77,6 +77,14 @@
void *private;
} ggi_extlist;
+/* Direct Buffer stuff */
+typedef struct {
+ int numbufs;
+ ggi_directbuffer **buffers;
+
+ void *dummy[8]; /* for future expansion */
+} ggi_db_internal;
+
/* Increment the version number every time you add
* new features.
*/
@@ -102,7 +110,12 @@
struct ggi_visual_opgc *opgc; /* GC operations */
void *opdummy[5];/* For future expansion */
- struct ggi_info info; /* Info on the mode */
+ ggi_pixelformat *pixfmt; /* Format of the pixels */
+ ggi_db_internal *dblist; /* List of DBs */
+ ggi_flags flags; /* Flags */
+ ggi_mode *mode; /* Current mode */
+ int select_fd;
+
int size; /* Size of all extensions */
ggi_dlhandle_l *extlib; /* Dynamic libs from extensions */
I suggest we add:
int numpriv;
ggi_directbuffer **privbufs;
to ggi_db_internal. That way application- and internal buffers are
completely separated.
> > 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)
Any reason why we shouldn't simply add the above four and
similiar modes to the ggi_bufferlayout enumeration ?
> > 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.
My idea was that it would return the first frame if there's more
than one. But your idea is even better, as i allows us to have
only simple buffers even when double/tripplebuffering.
//Marcus
--
-------------------------------+------------------------------------
Marcus Sundberg | http://www.stacken.kth.se/~mackan/
Royal Institute of Technology | Phone: +46 707 295404
Stockholm, Sweden | E-Mail: e94_msu@e.kth.se
Index:
[thread]
[date]
[subject]
[author]