Difference between revisions of "GDISP"

From uGFX Wiki
Jump to: navigation, search
(Font rendering)
(API reference)
 
(32 intermediate revisions by 2 users not shown)
Line 4: Line 4:
 
Whilst most other graphics libraries require the use of a [[GDISP#Framebuffer|framebuffer]], GDISP does not necessarily need one. This allows to drive graphics displays on microcontrollers and other low-performance systems that have insufficient RAM for a frame buffer.
 
Whilst most other graphics libraries require the use of a [[GDISP#Framebuffer|framebuffer]], GDISP does not necessarily need one. This allows to drive graphics displays on microcontrollers and other low-performance systems that have insufficient RAM for a frame buffer.
  
Some LCD controllers offer [[#Hardware_acceleration|hardware accelerated]] drawings for complex drawing operations such as circles or ellipses. The GDISP module is based on a software emulation layer: When the LCD controller does not support these features (most cases), the GDISP module emulates these drawing operations. Therefore, the exact same application code can be used on very different hardware platforms.
+
Some LCD controllers offer hardware accelerated drawing for complex drawing operations such as circles or ellipses. The GDISP module is based on a software emulation layer: When the LCD controller does not support these features (most cases), the GDISP module emulates these drawing operations. The same application code can therefore be used on very different hardware platforms.
  
Furthermore, you can drive more than just one display with GDISP. They don't even need to have the same display driver. Please refer to the [[GDISP#Multiple_Displays|multiple displays]] section for more information.
+
To increase the performance of your application you can use [[GDISP#Pixmaps|Pixmaps]] to prepare multiple drawing operations in your RAM. This can speed up your application when you're either performing the same series of drawing operations over and over again or when you're using multiple drawing operations on the same display are (overwriting pixels). The finished buffer can be sent to the display using a burst write for maximum performance.
 +
 
 +
Furthermore, you can drive more than just one display with GDISP. They don't even need to use the same display driver. Please refer to the [[GDISP#Multiple_displays|multiple displays]] section for more information.
 
Especially interesting might be the use of one or more [[GDISP#Remote_Displays|remote displays]].
 
Especially interesting might be the use of one or more [[GDISP#Remote_Displays|remote displays]].
  
  
 
== API reference ==
 
== API reference ==
The API reference of the GDISP module can be found [http://ugfx.org/images/resources/doxygen/master/group___g_d_i_s_p.html here].
+
The API reference of the GDISP module can be found [http://api.ugfx.org/group___g_d_i_s_p.html here].
  
== Board file ==
+
== Drivers ==
The [[Board_File|board file]] API for the GDISP module looks like the following:
+
For more information about GDISP drivers see [[Display Driver Model]].
<syntaxhighlight lang=c>
+
static void    init_board(GDisplay *g);
+
static void    post_init_board(GDisplay *g);
+
static void    setpin_reset(GDisplay *g, bool_t state);
+
static void    set_backlight(GDisplay *g, uint8_t percent);
+
static void    acquire_bus(GDisplay *g);
+
static void    release_bus(GDisplay *g);
+
static void    write_index(GDisplay *g, uint16_t index);
+
static void    write_data(GDisplay *g, uint16_t data);
+
static void    setreadmode(GDisplay *g);
+
static void    setwritemode(GDisplay *g);
+
static uint16_t read_data(GDisplay *g);
+
</syntaxhighlight>
+
For more information about the, see [[#GDisplay|GDisplay]].<br/>
+
Examples and a template file can be found under ''/drivers/gdisp/xxx/''.
+
  
== Controlls ==
+
== Controls ==
It's possible to modify panel parameters such as the orientation, backlight or contrast through highlevel API. But before you can use any of the following features, you have to enable the <code>GDISP_NEED_CONTROLL</code> macro in your [[gfxconf.h]] first:
+
It's possible to modify panel parameters such as the orientation, backlight or contrast through highlevel API. Before you can use any of the following features, you have to enable the <code>GDISP_NEED_CONTROL</code> macro in your [[gfxconf.h]] first:
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#define GDISP_NEED_CONTROL TRUE
 
#define GDISP_NEED_CONTROL TRUE
Line 39: Line 26:
  
 
=== Rotate your screen ===
 
=== Rotate your screen ===
You can change the orientation of your screen in 90 degree steps. This way, you cannot only use it in portrait or landscape mode, but also in inverted portrait and inverted landscape mode:  
+
You can change the orientation of your screen in 90 degree steps. This way, you can use it not only in portrait or landscape mode, but also in inverted portrait and inverted landscape mode:  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
gdispSetOrientation(GDISP_ROTATE_0);    // default orientation
 
gdispSetOrientation(GDISP_ROTATE_0);    // default orientation
Line 45: Line 32:
 
gdispSetOrientation(GDISP_ROTATE_180);  // flip by 180 degrees
 
gdispSetOrientation(GDISP_ROTATE_180);  // flip by 180 degrees
 
gdispSetOrientation(GDISP_ROTATE_270);  // flip by 270 degrees
 
gdispSetOrientation(GDISP_ROTATE_270);  // flip by 270 degrees
 +
gdispSetOrientation(GDISP_ROTATE_PORTRAIT);  // set in a portrait orientation (width of the display is less than the height)
 +
gdispSetOrientation(GDISP_ROTATE_LANDSCAPE);  // set in a landscape orientation (width of the display is greater than the height)
 
</syntaxhighlight>
 
</syntaxhighlight>
In case of you're using the [[GINPUT#Calibration|calibration routine]] of the [[GINPUT]] module, you must keep the screen in the default orientation until the calibration has been completed. Furthermore, the default panel orientation can be set in the [[configuration]] file.
+
The default panel orientation can be set in the [[configuration]] file.
  
 
=== Power control ===
 
=== Power control ===
Line 73: Line 62:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Color format ==
+
== Colors ==
ToDo.
+
=== Color format ===
 +
GDISP supports any fixed color display ranging from monochrome through to full 32 bit color. All formats including monochrome, grayscale, BGR and RGB are supported.
 +
 
 +
uGFX does not support palettized drawing. An 8 bit palettized driver however could be written to appear as an 8 bit fixed color display with special <code>gdispControl()</code> calls to control the palette.
 +
 
 +
While packed color formats (where there are multiple pixels packed into a single byte/word - eg 4 level grayscale) are supported, the internal color format always currently treats them as unpacked (maximum one pixel per byte/word). In practice this only affects image blitting from a NATIVE format image.
 +
 
 +
For a single display system the internal color format will be the same as the controller color format. For multiple displays an internal color format is chosen in your [[gfxconf.h]] and the drivers translate that to the native format for each controller. See [[Multiple displays]].
 +
 
 +
The type for the internal color format is: <code>color_t</code>.
 +
Macro's have been provided so that the user application never needs to worry about the details of the internal color format.
 +
<syntaxhighlight lang="c">
 +
HTML2COLOR(h);      // Converts a 32 bit HTML color to a native color
 +
RGB2COLOR(r,g,b);    // Converts a RGB triplet to a native color (each triplet is 0 to 255)
 +
LUMA2COLOR(l);      // Convert a grayscale luma (0 to 255) to a native color
 +
 
 +
RED_OF(c);          // Return the red component (0 to 255) of a color
 +
GREEN_OF(c);        // Return the green component (0 to 255) of a color
 +
BLUE_OF(c);          // Return the blue component (0 to 255) of a color
 +
LUMA_OF(c);          // Return the grayscale luma (0 to 255) of a color
 +
EXACT_RED_OF(c);    // Return the red component (0 to 255) of a color. Uses multiplies and divides to get an exact figure
 +
EXACT_GREEN_OF(c);  // Return the green component (0 to 255) of a color. Uses multiplies and divides to get an exact figure
 +
EXACT_BLUE_OF(c);    // Return the blue component (0 to 255) of a color. Uses multiplies and divides to get an exact figure
 +
EXACT_LUMA_OF(c);    // Return the grayscale luma (0 to 255) of a color. Uses multiplies and divides to get an exact figure
 +
 
 +
COLOR_TYPE_BITS;    // The number of bits in color_t
 +
COLOR_BITS;          // The number of bits actually used in color_t
 +
COLOR_BITS_R;        // The number of bits used for the red component of the native color
 +
COLOR_BITS_G;        // The number of bits used for the green component of the native color
 +
COLOR_BITS_B;        // The number of bits used for the blue component of the native color
 +
COLOR_SHIFT_R;      // The first red component bit
 +
COLOR_SHIFT_G;      // The first green component bit
 +
COLOR_SHIFT_B;      // The first blue component bit
 +
</syntaxhighlight>
 +
 
 +
These are the following predefined colors:
 +
<syntaxhighlight lang=c>
 +
#define White HTML2COLOR(0xFFFFFF)
 +
#define Black HTML2COLOR(0x000000)
 +
#define Gray HTML2COLOR(0x808080)
 +
#define Grey Gray
 +
#define Blue HTML2COLOR(0x0000FF)
 +
#define Red HTML2COLOR(0xFF0000)
 +
#define Fuchsia HTML2COLOR(0xFF00FF)
 +
#define Magenta Fuchsia
 +
#define Green HTML2COLOR(0x008000)
 +
#define Yellow HTML2COLOR(0xFFFF00)
 +
#define Aqua HTML2COLOR(0x00FFFF)
 +
#define Cyan Aqua
 +
#define Lime HTML2COLOR(0x00FF00)
 +
#define Maroon HTML2COLOR(0x800000)
 +
#define Navy HTML2COLOR(0x000080)
 +
#define Olive HTML2COLOR(0x808000)
 +
#define Purple HTML2COLOR(0x800080)
 +
#define Silver HTML2COLOR(0xC0C0C0)
 +
#define Teal HTML2COLOR(0x008080)
 +
#define Orange HTML2COLOR(0xFFA500)
 +
#define Pink HTML2COLOR(0xFFC0CB)
 +
#define SkyBlue HTML2COLOR(0x87CEEB)
 +
</syntaxhighlight>
 +
 
 +
=== Color Blending ===
 +
Two colors can be blend together using ''gdispBlendColor()'':
 +
<syntaxhighlight lang=c>
 +
color_t gdispBlendColor(color_t color1, color_t color2, uint8_t ratio);
 +
</syntaxhighlight>
 +
The returned color will be a blend between the first color ''color1'' and the second color ''color2'' according to the specified ''ratio''. A ''ratio'' of '''0''' means all ''color2'', a ratio of '''255''' means all ''color1''.
 +
 
 +
== Validation ==
 +
Validation makes sure that no drawing takes place outside of the display area. This is especially for memory-mapped displays very critical. When writing outside of the framebuffer, any data can be modified which leads to undefined behavior.
 +
 
 +
The validation feature costs about 8 bytes per display and adds only very little processor overhead. In return, firmware safety is increased a lot. Therefore, it is strongly recommended to use the validation feature.
 +
 
 +
Validation is turned on by default.
 +
 
 +
== Clipping ==
 +
Clipping is the more generic implementation of [[GDISP#Validation|Validation]]. Clipping allows the application to specify a window region. Clipping will then make sure that no drawing occurs outside of this window, similar to how [[GDISP#Validation|Validation]] makes sure that no drawing happens outside the display area.
 +
 
 +
A clipping region can be set using <code>gdispSetClip()</code> and be cleared using <code>gdispUnsetClip()</code>:
 +
<syntaxhighlight lang=c>
 +
gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy);
 +
gdispUnsetClip();
 +
</syntaxhighlight>
 +
 
 +
Clipping is also used internally by the [[GWIN]] module when enabled.
 +
 
 +
=== Hardware clipping ===
 +
Many display controllers provide built-in hardware clipping. The [[GDISP]] module will automatically use hardware clipping when available.
  
 
== Drawing ==
 
== Drawing ==
Line 85: Line 161:
 
The GDISP module provides built-in decoders for a variety of image formats. See [[Images]].
 
The GDISP module provides built-in decoders for a variety of image formats. See [[Images]].
  
== FrameBuffer ==
+
== Pixmaps ==
ToDo
+
Using Pixmaps can increase the performance of your application drastically. See [[Pixmaps]].
  
== Hardware acceleration ==
+
== Multiple displays ==
ToDo
+
 
+
== Multipel displays ==
+
 
The GDISP module can drive more than just one display. See [[Multiple displays]].
 
The GDISP module can drive more than just one display. See [[Multiple displays]].
  
Line 98: Line 171:
  
 
== GDisplay ==
 
== GDisplay ==
ToDo
+
The GDisplay structure represents a display. All read, write and control access to a display happens through this structure.
<syntaxhighlight lang=c>
+
struct GDisplay {
+
// The public GDISP stuff - must be the first element
+
GDISPControl g;
+
  
#if GDISP_TOTAL_CONTROLLERS > 1
+
When dealing with a normal single display setup then the user does not have to handle this structure at all. All GDISP calls have a ''gdispGxxxx()'' equivalent that takes a GDisplay pointer as a parameter. When only one display is used the ''gdispXxx()'' calls will access the default display. See [[Multiple displays]].
const struct GDISPVMT const * vmt; // The Virtual Method Table
+
#endif
+
  
void * priv; // A private area just for the drivers use.
+
Note the contents of the GDisplay structure should be considered a black-box accessed only through the appropriate API calls.
void * board; // A private area just for the board interfaces use.
+
  
uint8_t systemdisplay;
+
[[Category:Module]]
uint8_t controllerdisplay;
+
uint16_t flags;
+
#define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation
+
#define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen
+
#define GDISP_FLG_DRIVER 0x0004 // This flags and above are for use by the driver
+
 
+
// Multithread Mutex
+
#if GDISP_NEED_MULTITHREAD
+
gfxMutex mutex;
+
#endif
+
 
+
// Software clipping
+
#if GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+
coord_t clipx0, clipy0;
+
coord_t clipx1, clipy1; /* not inclusive */
+
#endif
+
 
+
// Driver call parameters
+
struct {
+
coord_t x, y;
+
coord_t cx, cy;
+
coord_t x1, y1;
+
coord_t x2, y2;
+
color_t color;
+
void *ptr;
+
} p;
+
 
+
// In call working buffers
+
 
+
#if GDISP_NEED_TEXT
+
// Text rendering parameters
+
struct {
+
font_t font;
+
color_t color;
+
color_t bgcolor;
+
coord_t clipx0, clipy0;
+
coord_t clipx1, clipy1;
+
} t;
+
#endif
+
#if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM_WRITE && GDISP_HARDWARE_BITFILLS))
+
// A pixel line buffer
+
color_t linebuf[GDISP_LINEBUF_SIZE];
+
#endif
+
 
+
};
+
</syntaxhighlight>
+

Latest revision as of 15:50, 4 February 2016

GDISP module architecture.

The GDISP module provides a simple interface for graphic displays and a feature rich set of highlevel functions to draw primitive shapes such as lines, circles and rectangles, but also font rendering, clipping and other advanced features.

Whilst most other graphics libraries require the use of a framebuffer, GDISP does not necessarily need one. This allows to drive graphics displays on microcontrollers and other low-performance systems that have insufficient RAM for a frame buffer.

Some LCD controllers offer hardware accelerated drawing for complex drawing operations such as circles or ellipses. The GDISP module is based on a software emulation layer: When the LCD controller does not support these features (most cases), the GDISP module emulates these drawing operations. The same application code can therefore be used on very different hardware platforms.

To increase the performance of your application you can use Pixmaps to prepare multiple drawing operations in your RAM. This can speed up your application when you're either performing the same series of drawing operations over and over again or when you're using multiple drawing operations on the same display are (overwriting pixels). The finished buffer can be sent to the display using a burst write for maximum performance.

Furthermore, you can drive more than just one display with GDISP. They don't even need to use the same display driver. Please refer to the multiple displays section for more information. Especially interesting might be the use of one or more remote displays.


API reference

The API reference of the GDISP module can be found here.

Drivers

For more information about GDISP drivers see Display Driver Model.

Controls

It's possible to modify panel parameters such as the orientation, backlight or contrast through highlevel API. Before you can use any of the following features, you have to enable the GDISP_NEED_CONTROL macro in your gfxconf.h first:

#define GDISP_NEED_CONTROL TRUE

Please note that all these features are optional. Not every GDISP driver may have all of the features listed below. Calling any of these calls when the driver or the controller does not support them is still safe - just nothing will happen.

Rotate your screen

You can change the orientation of your screen in 90 degree steps. This way, you can use it not only in portrait or landscape mode, but also in inverted portrait and inverted landscape mode:

gdispSetOrientation(GDISP_ROTATE_0);    // default orientation
gdispSetOrientation(GDISP_ROTATE_90);   // flip by 90 degrees
gdispSetOrientation(GDISP_ROTATE_180);  // flip by 180 degrees
gdispSetOrientation(GDISP_ROTATE_270);  // flip by 270 degrees
gdispSetOrientation(GDISP_ROTATE_PORTRAIT);  // set in a portrait orientation (width of the display is less than the height)
gdispSetOrientation(GDISP_ROTATE_LANDSCAPE);  // set in a landscape orientation (width of the display is greater than the height)

The default panel orientation can be set in the configuration file.

Power control

Most LCD controllers allow it to change the power level of your LCD.

gdispSetPowerMode(powerOff);
gdispSetPowerMode(powerOn);
gdispSetPowerMode(powerSleep);

You can wake up the display after entering the sleep mode by calling gdispSetPowerMode(powerOn).

Backlight and Contrast

GDISP provides an interface to set the backlight brightness and the contrast of your LCD module in a percentage.

gdispSetBacklight(50);  // set backlight to 50%
gdispSetContrast(50);   // set contrast to 50%

Panel Parameters

There are a few functions which return different LCD panel paremeters such as the width and the height in pixels which make it easy to write code which works on different display resolutions.

gdispGetWdith();      // returns the width or the lcd panel in pixels
gdispGetHeight();     // returns the height of the lcd panel in pixels
gdispGetBacklight();  // returns the percent of the backlight
gdispGetContrast();   // returns the percent of the contrast

Colors

Color format

GDISP supports any fixed color display ranging from monochrome through to full 32 bit color. All formats including monochrome, grayscale, BGR and RGB are supported.

uGFX does not support palettized drawing. An 8 bit palettized driver however could be written to appear as an 8 bit fixed color display with special gdispControl() calls to control the palette.

While packed color formats (where there are multiple pixels packed into a single byte/word - eg 4 level grayscale) are supported, the internal color format always currently treats them as unpacked (maximum one pixel per byte/word). In practice this only affects image blitting from a NATIVE format image.

For a single display system the internal color format will be the same as the controller color format. For multiple displays an internal color format is chosen in your gfxconf.h and the drivers translate that to the native format for each controller. See Multiple displays.

The type for the internal color format is: color_t. Macro's have been provided so that the user application never needs to worry about the details of the internal color format.

HTML2COLOR(h);       // Converts a 32 bit HTML color to a native color
RGB2COLOR(r,g,b);    // Converts a RGB triplet to a native color (each triplet is 0 to 255)
LUMA2COLOR(l);       // Convert a grayscale luma (0 to 255) to a native color
 
RED_OF(c);           // Return the red component (0 to 255) of a color
GREEN_OF(c);         // Return the green component (0 to 255) of a color
BLUE_OF(c);          // Return the blue component (0 to 255) of a color
LUMA_OF(c);          // Return the grayscale luma (0 to 255) of a color
EXACT_RED_OF(c);     // Return the red component (0 to 255) of a color. Uses multiplies and divides to get an exact figure
EXACT_GREEN_OF(c);   // Return the green component (0 to 255) of a color. Uses multiplies and divides to get an exact figure
EXACT_BLUE_OF(c);    // Return the blue component (0 to 255) of a color. Uses multiplies and divides to get an exact figure
EXACT_LUMA_OF(c);    // Return the grayscale luma (0 to 255) of a color. Uses multiplies and divides to get an exact figure
 
COLOR_TYPE_BITS;     // The number of bits in color_t
COLOR_BITS;          // The number of bits actually used in color_t
COLOR_BITS_R;        // The number of bits used for the red component of the native color
COLOR_BITS_G;        // The number of bits used for the green component of the native color
COLOR_BITS_B;        // The number of bits used for the blue component of the native color
COLOR_SHIFT_R;       // The first red component bit
COLOR_SHIFT_G;       // The first green component bit
COLOR_SHIFT_B;       // The first blue component bit

These are the following predefined colors:

#define White			HTML2COLOR(0xFFFFFF)
#define Black			HTML2COLOR(0x000000)
#define Gray			HTML2COLOR(0x808080)
#define Grey			Gray
#define Blue			HTML2COLOR(0x0000FF)
#define Red			HTML2COLOR(0xFF0000)
#define Fuchsia			HTML2COLOR(0xFF00FF)
#define Magenta			Fuchsia
#define Green			HTML2COLOR(0x008000)
#define Yellow			HTML2COLOR(0xFFFF00)
#define Aqua			HTML2COLOR(0x00FFFF)
#define Cyan			Aqua
#define Lime			HTML2COLOR(0x00FF00)
#define Maroon			HTML2COLOR(0x800000)
#define Navy			HTML2COLOR(0x000080)
#define Olive			HTML2COLOR(0x808000)
#define Purple			HTML2COLOR(0x800080)
#define Silver			HTML2COLOR(0xC0C0C0)
#define Teal			HTML2COLOR(0x008080)
#define Orange			HTML2COLOR(0xFFA500)
#define Pink			HTML2COLOR(0xFFC0CB)
#define SkyBlue			HTML2COLOR(0x87CEEB)

Color Blending

Two colors can be blend together using gdispBlendColor():

color_t gdispBlendColor(color_t color1, color_t color2, uint8_t ratio);

The returned color will be a blend between the first color color1 and the second color color2 according to the specified ratio. A ratio of 0 means all color2, a ratio of 255 means all color1.

Validation

Validation makes sure that no drawing takes place outside of the display area. This is especially for memory-mapped displays very critical. When writing outside of the framebuffer, any data can be modified which leads to undefined behavior.

The validation feature costs about 8 bytes per display and adds only very little processor overhead. In return, firmware safety is increased a lot. Therefore, it is strongly recommended to use the validation feature.

Validation is turned on by default.

Clipping

Clipping is the more generic implementation of Validation. Clipping allows the application to specify a window region. Clipping will then make sure that no drawing occurs outside of this window, similar to how Validation makes sure that no drawing happens outside the display area.

A clipping region can be set using gdispSetClip() and be cleared using gdispUnsetClip():

gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy);
gdispUnsetClip();

Clipping is also used internally by the GWIN module when enabled.

Hardware clipping

Many display controllers provide built-in hardware clipping. The GDISP module will automatically use hardware clipping when available.

Drawing

The GDISP module provides many API calls to draw to a display. See Drawing.

Font rendering

The GDISP module provides a font rendering engine with features like unicode support, kerning, anti-aliasing and more. See Font rendering.

Images

The GDISP module provides built-in decoders for a variety of image formats. See Images.

Pixmaps

Using Pixmaps can increase the performance of your application drastically. See Pixmaps.

Multiple displays

The GDISP module can drive more than just one display. See Multiple displays.

Remote displays

The GDISP module can drive remote displays. See Remote displays.

GDisplay

The GDisplay structure represents a display. All read, write and control access to a display happens through this structure.

When dealing with a normal single display setup then the user does not have to handle this structure at all. All GDISP calls have a gdispGxxxx() equivalent that takes a GDisplay pointer as a parameter. When only one display is used the gdispXxx() calls will access the default display. See Multiple displays.

Note the contents of the GDisplay structure should be considered a black-box accessed only through the appropriate API calls.