eCos Reference Manual
Prev |  | Next

# Framebuffer Parameters

## Name

Parameters -- determining framebuffer capabilities

## Synopsis

    #include <cyg/io/framebuf.h>

    typedef struct cyg_fb {
        cyg_ucount16    fb_depth;
        cyg_ucount16    fb_format;
        cyg_ucount16    fb_width;
        cyg_ucount16    fb_height;
    #ifdef CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_VIEWPORT
        cyg_ucount16    fb_viewport_width;
        cyg_ucount16    fb_viewport_height;
    #endif
        void*           fb_base;
        cyg_ucount16    fb_stride;
        cyg_uint32      fb_flags0;
        …
    } cyg_fb;

``cyg_fb* CYG_FB_STRUCT`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_DEPTH`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_FORMAT`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_WIDTH`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_HEIGHT`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_VIEWPORT_WIDTH`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_VIEWPORT_HEIGHT`(FRAMEBUF);`

``void* CYG_FB_BASE`(FRAMEBUF);`

``cyg_ucount16 CYG_FB_STRIDE`(FRAMEBUF);`

``cyg_uint32 CYG_FB_FLAGS0`(FRAMEBUF);`

## Description

When developing an application for a specific platform the various framebuffer parameters such as width and height are known, and the code can be written accordingly. However when writing code that should work on many platforms with different framebuffer devices, for example a graphics library, the code must be able to get these parameters and adapt.

Code using the function API can extract the parameters from the `cyg_fb` structures at run-time. The macro API provides dedicated macros for each parameter. These do not follow the usual eCos convention where the result is provided via an extra argument. Instead the result is returned as normal, and is guaranteed to be a compile-time constant. This allows code like the following:

    #if CYG_FB_DEPTH(FRAMEBUF) < 8
        …
    #else
        …
    #endif

or alternatively:

        if (CYG_FB_DEPTH(FRAMEBUF) < 8) {
            …
        } else {
            …
        }

or:

        switch (CYG_FB_DEPTH(FRAMEBUF)) {
            case  1 : … break;
            case  2 : … break;
            case  4 : … break;
            case  8 : … break;
            case 16 : … break;
            case 32 : … break;
        }

In terms of the code actually generated by the compiler these approaches have much the same effect. The macros expand to a compile-time constant so unnecessary code can be easily eliminated.

The available parameters are as follows:

depth

  The number of bits per pixel or bpp. The common depths are 1, 2, 4, 8, 16 and 32.

format

  How the pixel values are mapped on to visible colours, for example true colour or paletted or greyscale.

width, height

  The number of framebuffer pixels horizontally and vertically.

viewport width, viewport height

  With some devices the framebuffer height and/or width are greater than what the display can actually show. The display is said to offer a viewport into the larger framebuffer. The number of visible pixels is determined from the viewport width and height. The position of the viewport is controlled via an `ioctl`. Within a `cyg_fb` structure these fields are only present if `CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_VIEWPORT` is defined, to avoid wasting data space on fields that are unnecessary for the current platform. For the macro API the viewport macros should only be used if `CYG_FB_FLAGS0_VIEWPORT` is set for the framebuffer:

      #if (CYG_FB_FLAGS0(FRAMEBUF) & CYG_FB_FLAGS0_VIEWPORT)
          …
      #endif

base, stride

  For linear framebuffers these parameters provide the information needed to access framebuffer memory. The stride is in bytes.

flags0

  This gives further information about the hardware capabilities. Some of this overlaps with other parameters, especially when it comes to colour, because it is often easier to test for a single flag than for a range of colour modes. The current flags are:

  `CYG_FB_FLAGS0_LINEAR_FRAMEBUFFER`

    Framebuffer memory is organized in a conventional fashion and can be accessed directly by higher-level code using the base and stride parameters.

  `CYG_FB_FLAGS0_LE`

    This flag is only relevant for 1bpp, 2bpp and 4bpp devices and controls how the pixels are organized within each byte. If the flag is set then the layout is little-endian: for a 1bpp device pixel (0,0) occupies bit 0 of the first byte of framebuffer memory. The more common layout is big-endian where pixel (0,0) occupies bit 7 of the first byte.

  `CYG_FB_FLAGS0_TRUE_COLOUR`

    The framebuffer uses a true colour format where the value of each pixel directly encodes the red, green and blue intensities. This is common for 16bpp and 32bpp devices, and is occasionally used for 8bpp devices.

  `CYG_FB_FLAGS0_PALETTE`

    The framebuffer uses a palette. A pixel value does not directly encode the colours, but instead acts as an index into a separate table of colour values. That table may be read-only or read-write. Paletted displays are common for 8bpp and some 4bpp displays.

  `CYG_FB_FLAGS0_WRITEABLE_PALETTE`

    The palette is read-write.

  `CYG_FB_FLAGS0_DELAYED_PALETTE_UPDATE`

    Palette updates can be synchronized to a vertical blank, in other words a brief time period when the display is not being updated, by using `CYG_FB_UPDATE_VERTICAL_RETRACE` as the last argument to `cyg_fb_write_palette` or `CYG_FB_WRITE_PALETTE`. With some hardware updating the palette in the middle of a screen update may result in visual noise.

  `CYG_FB_FLAGS0_VIEWPORT`

    The framebuffer contains more pixels than can be shown on the display. Instead the display provides a viewport into the framebuffer. An `ioctl` can be used to move the viewport.

  `CYG_FB_FLAGS0_DOUBLE_BUFFER`

    The display does not show the current contents of the framebuffer, so the results of drawing into the framebuffer are not immediately visible. Instead higher-level code needs to perform an explicit synch operation to update the display.

  `CYG_FB_FLAGS0_PAGE_FLIPPING`

    The hardware supports two or more pages, each of width*height pixels, only one of which is visible on the display. This allows higher-level code to update one page without disturbing what is currently visible. An `ioctl` is used to switch the visible page.

  `CYG_FB_FLAGS0_BLANK`

    The display can be blanked without affecting the framebuffer contents or settings.

  `CYG_FB_FLAGS0_BACKLIGHT`

    There is a backlight which can be switched on or off. Some hardware provides finer-grained control over the backlight intensity.

  `CYG_FB_FLAGS0_MUST_BE_ON`

    Often it is desirable to perform some initialization such as clearing the screen or setting the palette before the display is switched on, to avoid visual noise. However not all hardware allows this. If this flag is set then it is possible to access framebuffer memory and the palette before the `cyg_fb_on` or `CYG_FB_ON` operation. It may also be possible to perform some other operations such as activating the backlight, but that is implementation-defined.

To allow for future expansion there are also flags1, flags2, and flags3 fields. These may get used for encoding additional `ioctl` functionality, support for hardware acceleration, and similar features.

## Linear Framebuffers

There are drawing primitives for writing and reading individual pixels. However these involve a certain amount of arithmetic each time to get from a position to an address within the frame buffer, plus function call overhead if the function API is used, and this will slow down graphics operations.

When the framebuffer device is known at compile-time and the macro API is used then there are additional macros specifically for iterating over parts of the frame buffer. These should prove very efficient for many graphics operations. However if the device is selected at run-time then the macros are not appropriate and code may want to manipulate framebuffer memory directly. This is possible if two conditions are satisfied:

1. The `CYG_FB_FLAGS0_LINEAR_FRAMEBUFFER` flag must be set. Otherwise framebuffer memory is either not directly accessible or has a non-linear layout.

2. The `CYG_FB_FLAGS0_DOUBLE_BUFFER` flag must be clear. An efficient double buffer synch operation requires knowing what part of the framebuffer have been updated, and the various drawing primitives will keep track of this. If higher-level code then starts manipulating the framebuffer directly the synch operation may perform only a partial update.

The base, stride, depth, width and height parameters, plus the `CYG_FB_FLAGS0_LE` flag for 1bpp, 2bpp and 4bpp devices, provide all the information needed to access framebuffer memory. A linear framebuffer has pixel (0,0) at the base address. Incrementing y means adding stride bytes to the pointer.

The base and stride parameters may be set even if `CYG_FB_FLAGS0_LINEAR_FRAMEBUFFER` is clear. This can be useful if for example the display is rotated in software from landscape to portrait mode. However the meaning of these parameters for non-linear framebuffers is implementation-defined.

Prev | Home | Next
Overview | Up | Framebuffer Control Operations