|
From: Geert U. <ge...@li...> - 2001-12-15 14:32:24
|
Sorry for the delay. Finally I found time to read the document and write my
comments...
Caveat: some comments are random thoughts...
On Fri, 30 Nov 2001, Sottek, Matthew J wrote:
> struct fb_display_info {
> u32 id;
> u32 xres;
> u32 yres;
Are these visible xres and yres?
> u32 xoffset;
> u32 yoffset;
> u32 orientation;
> u32 refresh;
> u32 left_margin;
> u32 right_margin;
> u32 top_margin;
> u32 bottom_margin;
Are these the sync margins? What about hsync_len and vsync_len?
> u32 status;
> u32 flags;
> }
> struct fb_mode_info {
> u32 width;
> u32 height;
Are these virtual width and height?
> u32 pixel_format;
> u32 flags;
> }
> pixel_format: This is a unique identifier for the arrangement of
> data in the framebuffer. The pixel_format values will be defined
> in a logically grouped fashion so that a user-space table can be
> used to obtain descriptions of the bits within the format. i.e.
>
> #define DEVICE 0x80000000
> #define NONSTD 0x40000000
> #define RGB 0x20000000
> #define YUV 0x10000000
> #define GRAY 0x08000000
There exist many different variants of YUV: 4:4:4, 4:2:2, 4:2:0, ...
Depending on the hardware, YUV modes can be interlaced and/or interleaved.
E.g. some Set Top Box S(TB) hardware splits the YUV data in four parts: Y even,
Y odd, UV even, and UV odd.
What about RGBA?
> #define PSEUDO 0x04000000
> #define TRUE 0x02000000
> #define DIRECT 0x01000000
>
> #define 1BIT 0x00000001
> #define 2BIT 0x00000002
> #define 4BIT 0x00000004
> #define 8BIT 0x00000008
> #define 12BIT 0x0000000c
> #define 16BIT 0x00000010
> #define 24BIT 0x00000018
> #define 32BIT 0x00000020
> #define 64BIT 0x00000040
Are these all packed?
What about planar modes and interleaved planes?
> #define ID_MASK 0x000fff00
>
> #define PSEUDO_RGB_8 (PSEUDO | RGB | 8BIT)
>
> formats that are only usable by device drivers, such as depth
> buffers, should use a pixel_type with bit 31 == 1 (device
> specific). Well defined, but not easy to describe, pixel formats
> should be numbered sequentially with the NONSTD bit turned on.
> The defined bits are not expected to uniquely define a pixel
> type, rather they allow for a user application to deal with an
> unknown type based on its attributes and additional information
> from a table or library.
So Amiga HAM6 and HAM8 can be considered NONSTD.
What about weird endianness? E.g. RGB565 can look very weird
(GGGBBBBBRRRRRGGG) if bytes have to be swapped, but not 16-bit words.
On some architectures (e.g. ARM), video memory accesses must always be x-bit
wide.
> For instance. If only the above example definitions are present,
> both 24 bit packed (RGBR GBRG BRGB) and 24 bit sparse (RGB_ RGB_
> RGB_) have the same attributes. RGB | TRUE | 24BIT. However the
> bits available from (pixel_format & ID_MASK) will be different.
> Even if the user application was not familiar with the bit field
> locations in 24 bit sparse, it could look up such information in
> a relatively small table of 24 bit RGB pixel format bit
> definitions.
Don't you need bit field positions? Other fields than R, G, B, and A.
> fb_cursor_info
> If the framebuffer supports a hardware cursor the pixel format
> and location of the cursor can be set with this data structure.
> As with other structures the hardware will alter the values if
> an exact match cannot be supported.
>
> struct fb_cursor_info {
> u32 width;
> u32 height;
> u32 pixel_format;
> u32 status;
> struct fb_palette_info palette;
> }
No XOR index (index of the color entry that inverts the underlying pixel)?
Flashing cursors?
Perhaps hardware animation (some STBs have that)?
> fb_surface_info
> The framebuffer provides a generic surface view of all
> framebuffer and non framebuffer graphics memory. For simplicity
> sake the framebuffer will not provide complex surface allocation
> and management schemes, only the most basic representation of
> available memory will be provided such that a higher level
> graphics interface can make intelligent use of the available
> resources.
This part I found quite interesting...
> #define FB_SURFACE_TYPE_FB 0x00000000
> #define FB_SURFACE_TYPE_CURSOR 0x00000001
> #define FB_SURFACE_TYPE_OVERLAY 0x00000002
> #define FB_SURFACE_TYPE_BACK 0x00000003
> #define FB_SURFACE_TYPE_DEPTH 0x00000004
> #define FB_SURFACE_TYPE_COMMAND 0x00000005
> #define FB_SURFACE_TYPE_SCRATCH 0x0fffffff
So different layers/planes are different surfaces.
STBs can do different layers (a few YUV, a few RGB/CLUT for OSD, cursor), with
alpha blending between the layers, changeable order, ...
> pitch: The length in bytes from a point on the framebuffer to
> the same point one line below. This value may not be the same as
> (width*bytes_per_pixel) as it is common in graphics hardware to
> optimize operations by limiting pitch to powers of 2. When using
> the physical address in another driver or hardware care must be
> taken to make sure that the correct pitch is used.
This is for packed pixels only. For (interleaved) bitplanes you need an offset
to the next line and next plane.
> At this time it is expected that a command will be issued in
> this manner:
> 1: The command file is opened read/write, if already opened
> the client can lseek the file back to the 0 position.
> command_fd = open("/dev/gfx/fb0/command", O_RDWR);
> 2: The 4 byte command number (each command will have a well
> defined number) is written to the file followed by the data
> needed for the command. Pointers are worthless here because
> in order to insure network transparency the kernel cannot
> do a copy_from_user(). If the value returned is -1 errno
> will contain the return value.
> buf[0] = command_number;
> memcpy(&buf[1],&data_struct, sizeof(data_struct));
> ret_val = write(command_fb, buf,
> sizeof(data_structure) + 4);
> if(ret_val == -1) {ERROR!}
> 4: If the return value indicates that data will be returned
> the client should seek the file back to 0 and read the
> returned data.
> lseek(command_fd, 0, SEEK_SET);
> size = read(command_fd, &data_structure,
> sizeof(data_structure));
Is the lseek() really needed? This means we need 2 syscalls (context switches)
instead of 1.
> KERNEL INTERFACE:
> The kernel interface is that which is used by the kernel outside
> of the framebuffer infrastructure to access the display device.
> The kernel should not be permitted to access any of the graphics
> hardware directly. The kernel can only write to surface 0 (The
> actual framebuffer) so it is not necessary to supply surface
> information to functions who's user-space counterparts require
> such information.
No overlay console? ;-)
> fb_set_palette(struct fb_cmap *cmap): Sets the internal palette
> or pseudo-palette to the values indicated by the provided
> fb_cmap structure.
>
> fb_set(u32 value, u16 x, u16 y, u16 width, u16 height, u32 rop):
> Sets a region of the framebuffer to the value provided. Raster
> operations as specified will also be applied to the data.
>
> fb_put(u8 *data, u16 srcx, u16 srcy, u16 width, u16 height, u16
^^^^
void *?
> destx, u16 desty): Puts the data provided in the framebuffer at
> the location provided. (Raster ops?)
>
> fb_copy(u16 srcx, u16 srcy, u16 width, u16 height,
> u16 destx, u16 desty, u32 rop): Copies the one area of
> the framebuffer or a surface to another possibly applying a
> raster operation.
>
> fb_get(u8 *data, u16 x, u16 y, u16 width, u16 height): Get a
^^^^
void *?
> region of the framebuffer and store it at the provided data
> pointer.
>
> Additionally the framebuffer infrastructure will provide a
> "struct consw" interface for console operations if the
> underlying driver is able to support it.
> fb_console
> This structure represents a console being displayed on the
> framebuffer device. There can only be one console on the
> framebuffer device at a time, but the console does not have to
> occupy the entire visible area. The console rendering will
> contain itself to the boundaries specified in the fb_console
> structure. There will be a different struct fb_console for each
> active console.
>
> struct fb_console {
> u32 xoffset;
> u32 yoffset;
> u32 width;
> u32 height;
> u32 fontwidth;
> u32 fontheight;
> u8 *fontdata;
> u8 fg;
> u8 bg;
> struct fb_cmap *cmap;
> void *priv;
> }
BTW, on many STBs, the whole screen is not one pixmap, but you can have
multiple non-overlapping regions (windows), using different pixel formats.
Perhaps this can be considered a generalization of fb_console?
> fbcon_ops
> Provides the entry points such that the di layer can access the
> console operations functions.
> bmove: Move an area represented by the source region to the
> location represented by the destination region. All coordinates
> are in character units. QUESTION: Is this really a move? Or is
> it a copy? A move would imply that it sets the area left
-> copyrect
> uncovered with zeros. FIXME: This should be "copy". If it really
> is a move then we should break that up into "copy" + "set".
-> fillrect
> putc: Put a character represented by "c" at the location
> specified. FIXME: Is it too slow to make this a special case of
> putcs?
No, console mainly uses putcs
> putcs: Put the line of characters references by *s at the
> location provided.
-> imageblit
> fb_base: This is a kernel-virtual address that points to the
^^^^^^^^^^^^^^^^^^^^^^^^???
> beginning of the framebuffer. This address can be written to in
> a manner such as this "*fb_base = 0;". Typically this is an
> ioremapped version of the physical base address of the
> framebuffer.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|