 |
 |
 |
 |
 |
 |
| |
|
Framebuffer ColoursNameColours -- formats and palette management Synopsis#include <cyg/io/framebuf.h>
typedef struct cyg_fb {
cyg_ucount16 fb_depth;
cyg_ucount16 fb_format;
cyg_uint32 fb_flags0;
…
} cyg_fb;
extern const cyg_uint8 cyg_fb_palette_ega[16 * 3];
extern const cyg_uint8 cyg_fb_palette_vga[256 * 3];
#define CYG_FB_DEFAULT_PALETTE_BLACK 0x00
#define CYG_FB_DEFAULT_PALETTE_BLUE 0x01
#define CYG_FB_DEFAULT_PALETTE_GREEN 0x02
#define CYG_FB_DEFAULT_PALETTE_CYAN 0x03
#define CYG_FB_DEFAULT_PALETTE_RED 0x04
#define CYG_FB_DEFAULT_PALETTE_MAGENTA 0x05
#define CYG_FB_DEFAULT_PALETTE_BROWN 0x06
#define CYG_FB_DEFAULT_PALETTE_LIGHTGREY 0x07
#define CYG_FB_DEFAULT_PALETTE_LIGHTGRAY 0x07
#define CYG_FB_DEFAULT_PALETTE_DARKGREY 0x08
#define CYG_FB_DEFAULT_PALETTE_DARKGRAY 0x08
#define CYG_FB_DEFAULT_PALETTE_LIGHTBLUE 0x09
#define CYG_FB_DEFAULT_PALETTE_LIGHTGREEN 0x0A
#define CYG_FB_DEFAULT_PALETTE_LIGHTCYAN 0x0B
#define CYG_FB_DEFAULT_PALETTE_LIGHTRED 0x0C
#define CYG_FB_DEFAULT_PALETTE_LIGHTMAGENTA 0x0D
#define CYG_FB_DEFAULT_PALETTE_YELLOW 0x0E
#define CYG_FB_DEFAULT_PALETTE_WHITE 0x0F
|
cyg_ucount16 CYG_FB_FORMAT(framebuf);
void cyg_fb_read_palette(cyg_fb* fb, cyg_ucount32 first, cyg_ucount32 count, void* data);
void cyg_fb_write_palette(cyg_fb* fb, cyg_ucount32 first, cyg_ucount32 count, const void* data, cyg_ucount16 when);
cyg_fb_colour cyg_fb_make_colour(cyg_fb* fb, cyg_ucount8 r, cyg_ucount8 g, cyg_ucount8 b);
void cyg_fb_break_colour(cyg_fb* fb, cyg_fb_colour colour, cyg_ucount8* r, cyg_ucount8* g, cyg_ucount8* b);
void CYG_FB_READ_PALETTE(FRAMEBUF, cyg_ucount32 first, cyg_ucount32 count, void* data);
void CYG_FB_WRITE_PALETTE(FRAMEBUF, cyg_ucount32 first, cyg_ucount32 count, const void* data, cyg_ucount16 when);
cyg_fb_colour CYG_FB_MAKE_COLOUR(FRAMEBUF, cyg_ucount8 r, cyg_ucount8 g, cyg_ucount8 b);
void CYG_FB_BREAK_COLOUR(FRAMEBUF, cyg_fb_colour colour, cyg_ucount8* r, cyg_ucount8* g, cyg_ucount8* b);
DescriptionManaging colours can be one of the most difficult aspects of writing
graphics code, especially if that code is intended to be portable to
many different platforms. Displays can vary from 1bpp monochrome, via
2bpp and 4bpp greyscale, through 4bpp and 8bpp paletted, and up to
16bpp and 32bpp true colour - and those are just the more common
scenarios. The various drawing
primitives like cyg_fb_write_pixel work in
terms of cyg_fb_colour values, usually an unsigned
integer. Exactly how the hardware interprets a
cyg_fb_colour depends on the format.
Colour FormatsThere are a number of ways of finding out how these values will be
interpreted by the hardware:
The CYG_FB_FLAGS0_TRUE_COLOUR flag is set for all
true colour displays. The format parameter can be examined for more
details but this is not usually necessary. Instead code can use
cyg_fb_make_colour
or CYG_FB_MAKE_COLOUR
to construct a cyg_fb_colour value from red, green and
blue components.
If the CYG_FB_FLAGS0_WRITEABLE_PALETTE flag is set
then a cyg_fb_colour value is an index into a lookup
table known as the palette, and this table contains red, green and
blue components. The size of the palette is determined by the display
depth, so 16 entries for a 4bpp display and 256 entries for an 8bpp
display. Application code or a graphics library can install its own palette so
can control exactly what colour each cyg_fb_colour value
corresponds to. Alternatively there is support for installing a
default palette.
If CYG_FB_FLAGS0_PALETTE is set but
CYG_FB_FLAGS0_WRITEABLE_PALETTE is clear then the
hardware uses a fixed palette. There is no easy way for portable
software to handle this case. The palette can be read at run-time,
allowing the application's desired colours to be mapped to whichever
palette entry provides the best match. However normally it will be
necessary to write code specifically for the fixed palette.
Otherwise the display is monochrome or greyscale, depending on the
depth. There are still variations, for example on a monochrome display
colour 0 can be either white or black.
As an alternative or to provide additional information, the exact
colour format is provided by the fb_format
field of the cyg_fb structure or by the
CYG_FB_FORMAT macro. It can be one of the
following (more entries may be added in future):
- CYG_FB_FORMAT_1BPP_MONO_0_BLACK
simple 1bpp monochrome display, with 0 as black or the darker of the
two colours, and 1 as white or the ligher colour.
- CYG_FB_FORMAT_1BPP_MONO_0_WHITE
simple 1bpp monochrome display, with 0 as white or the lighter of the
two colours, and 1 as black or the darker colour.
- CYG_FB_FORMAT_1BPP_PAL888
a 1bpp display which cannot easily be described as monochrome. This is
unusual and not readily supported by portable code. It can happen if
the framebuffer normally runs at a higher depth, for example 4bpp or
8bpp paletted, but is run at only 1bpp to save memory. Hence only two
of the palette entries are used, but can be set to arbitrary colours.
The palette may be read-only or read-write.
- CYG_FB_FORMAT_2BPP_GREYSCALE_0_BLACK
a 2bpp display offering four shades of grey, with 0 as black or the
darkest of the four shades, and 3 as white or the lightest.
- CYG_FB_FORMAT_2BPP_GREYSCALE_0_WHITE
a 2bpp display offering four shades of grey, with 0 as white or the
lightest of the four shades, and 3 as black or the darkest.
- CYG_FB_FORMAT_2BPP_PAL888
a 2bpp display which cannot easily be described as greyscale, for
example providing black, red, blue and white as the four colours.
This is unusual and not readily supported by portable code. It can
happen if the framebuffer normally runs at a higher depth, for example
4bpp or 8bpp paletted, but is run at only 2bpp to save memory. Hence
only four of the palette entries are used, but can be set to arbitrary
colours. The palette may be read-only or read-write.
- CYG_FB_FORMAT_4BPP_GREYSCALE_0_BLACK
a 4bpp display offering sixteen shades of grey, with 0 as black or the
darkest of the 16 shades, and 15 as white or the lighest.
- CYG_FB_FORMAT_4BPP_GREYSCALE_0_WHITE
a 4bpp display offering sixteen shades of grey, with 0 as white or the
lightest of the 16 shades, and 15 as black or the darkest.
- CYG_FB_FORMAT_4BPP_PAL888
a 4bpp paletted display, allowing for 16 different colours on screen
at the same time. The palette may be read-only or read-write.
- CYG_FB_FORMAT_8BPP_PAL888
an 8bpp paletted display, allowing for 256 different colours on screen
at the same time. The palette may be read-only or read-write.
- CYG_FB_FORMAT_8BPP_TRUE_332
an 8bpp true colour display. Bits 0 and 1 of each pixel value control
four levels of blue intensity, bits 2 to 4 control eight levels of
green, and bits 5 to 7 control eight levels of red.
- CYG_FB_FORMAT_16BPP_TRUE_565
a 16bpp true colour display. Bits 0 to 4 of each pixel value control
the blue intensity, bits 5 to 10 the green intensity, and bits 11 to
15 the red intensity.
- CYG_FB_FORMAT_16BPP_TRUE_555
a 16bpp true colour display, with the top bit unused. Bits 0 to 4 of
each pixel value control the blue intensity, bits 5 to 9 the green
intensity, and bits 10 to 14 the red intensity.
- CYG_FB_FORMAT_32BPP_TRUE_0888
a 32bpp true colour display, with the top byte unused. Bits 0 to 7 of
each pixel value control the blue intensity, bits 8 to 15 the green
intensity, and bits 16 to 23 the red intensity.
Paletted DisplaysPalettes are the common way of implementing low-end colour displays.
There are two variants. A read-only palette provides a fixed set of
colours and it is up to application code to use these colours
appropriately. A read-write palette allows the application to select
its own set of colours. Displays providing a read-write palette will
have the CYG_FB_FLAGS0_WRITEABLE_PALETTE flag set
in addition to CYG_FB_FLAGS0_PALETTE.
Even if application code can install its own palette, many
applications do not exploit this functionality and instead stick with
a default. There are two standard palettes: the 16-entry PC EGA for
4bpp displays; and the 256-entry PC VGA, a superset of the EGA one,
for 8bpp displays. This package provides the data for both, in the
form of arrays cyg_fb_palette_ega and
cyg_fb_palette_vga, and 16
#define's such as
CYG_FB_DEFAULT_PALETTE_BLACK for the EGA colours
and the first 16 VGA colours. By default device drivers for read-write
paletted displays will install the appropriate default palette, but
this can be suppressed using configuration option
CYGFUN_IO_FRAMEBUF_INSTALL_DEFAULT_PALETTE. If a
custom palette will be used then installing the default palette
involves wasting 48 or 768 bytes of memory.
It should be emphasized that displays vary widely. A colour such
as CYG_FB_DEFAULT_PALETTE_YELLOW may appear rather
differently on two different displays, although it should always be
recognizable as yellow. Developers may wish to fine-tune the palette
for specific hardware.
The current palette can be retrieved using
cyg_fb_read_palette or
CYG_FB_READ_PALETTE. The
first and count
arguments control which palette entries should be retrieved. For
example, to retrieve just palette entry 12
first should be set to 12 and
count should be set to 1. To retrieve all 256
entries for an 8bpp display, first should be
set to 0 and count should be set to 256. The
data argument should point at an array of
bytes, allowing three bytes for every entry. Byte 0 will contain the red
intensity for the first entry, byte 1 green and byte 2 blue.
For read-write palettes the palette can be updated using
cyg_fb_write_palette or
CYG_FB_WRITE_PALETTE. The
first and count arguments
are the same as for cyg_fb_read_palette, and the
data argument should point at a suitable byte
array packed in the same way. The when argument
should be one of CYG_FB_UPDATE_NOW or
CYG_FB_UPDATE_VERTICAL_RETRACE. With some displays
updating the palette in the middle of an update may result in visual
noise, so synchronizing to the vertical retrace avoids this. However
not all device drivers will support this.
There is an assumption that palette entries use 8 bits for each of the
red, green and blue colour intensities. This is not always the case,
but the device drivers will perform appropriate adjustments. Some
hardware may use only 6 bits per colour, and the device driver will
ignore the bottom two bits of the supplied intensity values.
Occasionally hardware may use more than 8 bits, in which case the
supplied 8 bits are shifted left appropriately and zero-padded. Device
drivers for such hardware may also provide device-specific routines to
manipulate the palette in a non-portable fashion.
True Colour displaysTrue colour displays are often easier to manage than paletted
displays. However this comes at the cost of extra memory. A 16bpp true
colour display requires twice as much memory as an 8bpp paletted
display, yet can offer only 32 or 64 levels of intensity for each
colour as opposed to the 256 levels provided by a palette. It also
requires twice as much video memory bandwidth to send all the pixel
data to the display for every refresh, which may impact the
performance of the rest of the system. A 32bpp true colour display
offers the same colour intensities but requires four times the memory
and four times the bandwidth.
There are two ways of determining a cyg_fb_colour pixel
value for a given colour. The first is to decode the colour format,
for example CYG_FB_FORMAT_16BPP_TRUE_565, and
perform the appropriate arithmetic. The second is to use the supplied
cyg_fb_make_colour or
CYG_FB_MAKE_COLOUR primitives. These take 8-bit
intensity levels for red, green and blue, and return the corresponding
cyg_fb_colour. When using the macro interface the
arithmetic happens at compile-time, for example:
#define BLACK CYG_FB_MAKE_COLOUR(FRAMEBUF, 0, 0, 0)
#define WHITE CYG_FB_MAKE_COLOUR(FRAMEBUF, 255, 255, 255)
#define RED CYG_FB_MAKE_COLOUR(FRAMEBUF, 255, 0, 0)
#define GREEN CYG_FB_MAKE_COLOUR(FRAMEBUF, 0, 255, 0)
#define BLUE CYG_FB_MAKE_COLOUR(FRAMEBUF, 0, 0, 255)
#define YELLOW CYG_FB_MAKE_COLOUR(FRAMEBUF, 255, 255, 80)
|
Displays vary widely so the numbers may need to be adjusted to give
the exact desired colours.
For symmetry there are also cyg_fb_break_colour
and CYG_FB_BREAK_COLOUR primitives. These take a
cyg_fb_colour value and decompose it into its red, green
and blue components.
|
|
|
| |
|
|
|
|
|