diff options
author | inmarket <andrewh@inmarket.com.au> | 2013-09-18 23:46:37 +1000 |
---|---|---|
committer | inmarket <andrewh@inmarket.com.au> | 2013-09-18 23:46:37 +1000 |
commit | b25ac5e667d98f2915831a74707f6ec198a4498b (patch) | |
tree | 5cff480e6f12421ccb043de280be69b46f1fa56f /include/gdisp | |
parent | 85aa1f03edd406f1499e4835e1591ad545e5354e (diff) | |
download | uGFX-b25ac5e667d98f2915831a74707f6ec198a4498b.tar.gz uGFX-b25ac5e667d98f2915831a74707f6ec198a4498b.tar.bz2 uGFX-b25ac5e667d98f2915831a74707f6ec198a4498b.zip |
Scrolling emulation when not supported by hardware
Start of new multiple display support
GDISP performance optimisations
Documentation updates
Win32 driver updates
Diffstat (limited to 'include/gdisp')
-rw-r--r-- | include/gdisp/gdisp.h | 140 | ||||
-rw-r--r-- | include/gdisp/lld/gdisp_lld.h | 613 | ||||
-rw-r--r-- | include/gdisp/options.h | 136 |
3 files changed, 595 insertions, 294 deletions
diff --git a/include/gdisp/gdisp.h b/include/gdisp/gdisp.h index 3a1968ed..cb98b46d 100644 --- a/include/gdisp/gdisp.h +++ b/include/gdisp/gdisp.h @@ -43,21 +43,15 @@ typedef int16_t coord_t; /** * @brief Type for a 2D point on the screen. */ -typedef struct point_t { - coord_t x, y; - } point; +typedef struct point { coord_t x, y; } point, point_t; /** * @brief Type for the text justification. */ -typedef enum justify { - justifyLeft = 0, - justifyCenter = 1, - justifyRight = 2 -} justify_t; +typedef enum justify { justifyLeft=0, justifyCenter=1, justifyRight=2 } justify_t; /** * @brief Type for the font metric. */ -typedef enum fontmetric {fontHeight, fontDescendersHeight, fontLineSpacing, fontCharPadding, fontMinWidth, fontMaxWidth} fontmetric_t; +typedef enum fontmetric { fontHeight, fontDescendersHeight, fontLineSpacing, fontCharPadding, fontMinWidth, fontMaxWidth } fontmetric_t; /** * @brief The type of a font. */ @@ -65,11 +59,11 @@ typedef const struct mf_font_s* font_t; /** * @brief Type for the screen orientation. */ -typedef enum orientation {GDISP_ROTATE_0, GDISP_ROTATE_90, GDISP_ROTATE_180, GDISP_ROTATE_270} gdisp_orientation_t; +typedef enum orientation { GDISP_ROTATE_0=0, GDISP_ROTATE_90=90, GDISP_ROTATE_180=180, GDISP_ROTATE_270=270 } orientation_t; /** * @brief Type for the available power modes for the screen. */ -typedef enum powermode {powerOff, powerSleep, powerDeepSleep, powerOn} gdisp_powermode_t; +typedef enum powermode { powerOff, powerSleep, powerDeepSleep, powerOn } powermode_t; /* * This is not documented in Doxygen as it is meant to be a black-box. @@ -79,8 +73,8 @@ typedef enum powermode {powerOff, powerSleep, powerDeepSleep, powerOn} gdisp_pow typedef struct GDISPControl { coord_t Width; coord_t Height; - gdisp_orientation_t Orientation; - gdisp_powermode_t Powermode; + orientation_t Orientation; + powermode_t Powermode; uint8_t Backlight; uint8_t Contrast; } GDISPControl; @@ -112,15 +106,6 @@ extern GDISPControl *GDISP; #define GDISP_CONTROL_LLD 1000 /** - * @brief Driver Query Constants - * @details Unsupported query codes return (void *)-1. - * @note The result should be typecast the required type. - * @note GDISP_QUERY_LLD - Low level driver control constants start at - * this value. - */ -#define GDISP_QUERY_LLD 1000 - -/** * @brief Driver Pixel Format Constants */ #define GDISP_PIXELFORMAT_MONO 1 @@ -162,6 +147,80 @@ extern GDISPControl *GDISP; /** @} */ /*===========================================================================*/ +/* Defines relating to the display hardware */ +/*===========================================================================*/ + +#if GDISP_MULTIPLE_DRIVERS || defined(__DOXYGEN__) + /** + * @name GDISP pixel format choices + * @{ + */ + /** + * @brief The pixel format. + * @default It generally defaults to the hardware pixel format. + * @note This doesn't need to match the hardware pixel format. + * It is definitely more efficient when it does. + * @note When GDISP_MULTIPLE_DRIVERS is defined, this should + * also be explicitly defined to ensure the best match + * with your hardware across all devices. + * @note Should be set to one of the following: + * GDISP_PIXELFORMAT_RGB565 + * GDISP_PIXELFORMAT_BGR565 + * GDISP_PIXELFORMAT_RGB888 + * GDISP_PIXELFORMAT_RGB444 + * GDISP_PIXELFORMAT_RGB332 + * GDISP_PIXELFORMAT_RGB666 + * GDISP_PIXELFORMAT_CUSTOM + * @note If you set GDISP_PIXELFORMAT_CUSTOM you need to also define + * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h), + * RED_OF(c), GREEN_OF(c), BLUE_OF(c), + * COLOR(c) and MASKCOLOR. + */ + #ifndef GDISP_PIXELFORMAT + #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR + #endif + /** + * @brief Do pixels require packing for a blit + * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats: + * GDISP_PIXELFORMAT_RGB888 + * GDISP_PIXELFORMAT_RGB444 + * GDISP_PIXELFORMAT_RGB666 + * GDISP_PIXELFORMAT_CUSTOM + * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills + * you need to also define @p gdispPackPixels(buf,cx,x,y,c) + * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel + * format must not be a packed format as the software blit does + * not support packed pixels + * @note Very few cases should actually require packed pixels as the low + * level driver can also pack on the fly as it is sending it + * to the graphics device. + */ + #ifndef GDISP_PACKED_PIXELS + #define GDISP_PACKED_PIXELS FALSE + #endif + + /** + * @brief Do lines of pixels require packing for a blit + * @note Ignored if GDISP_PACKED_PIXELS is FALSE + */ + #ifndef GDISP_PACKED_LINES + #define GDISP_PACKED_LINES FALSE + #endif + /** @} */ +#else + #include "gdisp_lld_config.h" + #ifndef GDISP_PIXELFORMAT + #define GDISP_PIXELFORMAT GDISP_LLD_PIXELFORMAT + #endif + #ifndef GDISP_PACKED_PIXELS + #define GDISP_PACKED_PIXELS FALSE + #endif + #ifndef GDISP_PACKED_LINES + #define GDISP_PACKED_LINES FALSE + #endif +#endif + +/*===========================================================================*/ /* Defines related to the pixel format */ /*===========================================================================*/ @@ -274,26 +333,6 @@ extern GDISPControl *GDISP; #error "GDISP: No supported pixel format has been specified." #endif -/* Verify information for packed pixels and define a non-packed pixel macro */ -#if !GDISP_PACKED_PIXELS - #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); } -#elif !GDISP_HARDWARE_BITFILLS - #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers." -#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \ - && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \ - && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \ - && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM - #error "GDISP: A packed pixel format has been specified for an unsupported pixel format." -#endif - -#if GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL - #error "GDISP: Hardware scrolling is wanted but not supported." -#endif - -#if GDISP_NEED_PIXELREAD && !GDISP_HARDWARE_PIXELREAD - #error "GDISP: Pixel read-back is wanted but not supported." -#endif - /** * @brief The type of a pixel. */ @@ -775,23 +814,6 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color); #endif -/* Support routine for packed pixel formats */ -#if !defined(gdispPackPixels) || defined(__DOXYGEN__) - /** - * @brief Pack a pixel into a pixel buffer. - * @note This function performs no buffer boundary checking - * regardless of whether GDISP_NEED_CLIP has been specified. - * - * @param[in] buf The buffer to put the pixel in - * @param[in] cx The width of a pixel line - * @param[in] x, y The location of the pixel to place - * @param[in] color The color to put into the buffer - * - * @api - */ - void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color); -#endif - /* * Macro definitions */ diff --git a/include/gdisp/lld/gdisp_lld.h b/include/gdisp/lld/gdisp_lld.h index 46d5488a..38c0ccc0 100644 --- a/include/gdisp/lld/gdisp_lld.h +++ b/include/gdisp/lld/gdisp_lld.h @@ -18,188 +18,141 @@ #if GFX_USE_GDISP || defined(__DOXYGEN__) +#if GDISP_MULTIPLE_DRIVERS && defined(GDISP_LLD_DECLARATIONS) + // include hardware definitions + #include "gdisp_lld_config.h" +#endif + /*===========================================================================*/ /* Error checks. */ /*===========================================================================*/ -/** - * @name GDISP hardware accelerated support - * @{ - */ - /** - * @brief Hardware streaming interface is supported. - * @details If set to @p FALSE software emulation is used. - * @note Either GDISP_HARDWARE_STREAM or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver - */ - #ifndef GDISP_HARDWARE_STREAM - #define GDISP_HARDWARE_STREAM FALSE - #endif - - /** - * @brief Hardware streaming requires an explicit end call. - * @details If set to @p FALSE if an explicit stream end call is not required. - */ - #ifndef GDISP_HARDWARE_STREAM_END - #define GDISP_HARDWARE_STREAM_END FALSE - #endif - +#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) /** - * @brief Hardware accelerated draw pixel. - * @details If set to @p FALSE software emulation is used. - * @note Either GDISP_HARDWARE_STREAM or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver + * @name GDISP hardware accelerated support + * @{ */ - #ifndef GDISP_HARDWARE_DRAWPIXEL - #define GDISP_HARDWARE_DRAWPIXEL FALSE - #endif - - /** - * @brief Hardware accelerated screen clears. - * @details If set to @p FALSE software emulation is used. - * @note This clears the entire display surface regardless of the clipping area currently set - */ - #ifndef GDISP_HARDWARE_CLEARS - #define GDISP_HARDWARE_CLEARS FALSE - #endif - - /** - * @brief Hardware accelerated rectangular fills. - * @details If set to @p FALSE software emulation is used. - */ - #ifndef GDISP_HARDWARE_FILLS - #define GDISP_HARDWARE_FILLS FALSE - #endif + /** + * @brief Hardware streaming interface is supported. + * @details If set to @p FALSE software emulation is used. + * @note Either GDISP_HARDWARE_STREAM or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver + */ + #ifndef GDISP_HARDWARE_STREAM + #define GDISP_HARDWARE_STREAM FALSE + #endif - /** - * @brief Hardware accelerated fills from an image. - * @details If set to @p FALSE software emulation is used. - */ - #ifndef GDISP_HARDWARE_BITFILLS - #define GDISP_HARDWARE_BITFILLS FALSE - #endif + /** + * @brief Hardware streaming requires an explicit end call. + * @details If set to @p FALSE if an explicit stream end call is not required. + */ + #ifndef GDISP_HARDWARE_STREAM_END + #define GDISP_HARDWARE_STREAM_END FALSE + #endif - /** - * @brief Hardware accelerated scrolling. - * @details If set to @p FALSE there is no support for scrolling. - */ - #ifndef GDISP_HARDWARE_SCROLL - #define GDISP_HARDWARE_SCROLL FALSE - #endif + /** + * @brief Hardware accelerated draw pixel. + * @details If set to @p FALSE software emulation is used. + * @note Either GDISP_HARDWARE_STREAM or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver + */ + #ifndef GDISP_HARDWARE_DRAWPIXEL + #define GDISP_HARDWARE_DRAWPIXEL FALSE + #endif - /** - * @brief Reading back of pixel values. - * @details If set to @p FALSE there is no support for pixel read-back. - */ - #ifndef GDISP_HARDWARE_PIXELREAD - #define GDISP_HARDWARE_PIXELREAD FALSE - #endif + /** + * @brief Hardware accelerated screen clears. + * @details If set to @p FALSE software emulation is used. + * @note This clears the entire display surface regardless of the clipping area currently set + */ + #ifndef GDISP_HARDWARE_CLEARS + #define GDISP_HARDWARE_CLEARS FALSE + #endif - /** - * @brief The driver supports one or more control commands. - * @details If set to @p FALSE there is no support for control commands. - */ - #ifndef GDISP_HARDWARE_CONTROL - #define GDISP_HARDWARE_CONTROL FALSE - #endif + /** + * @brief Hardware accelerated rectangular fills. + * @details If set to @p FALSE software emulation is used. + */ + #ifndef GDISP_HARDWARE_FILLS + #define GDISP_HARDWARE_FILLS FALSE + #endif - /** - * @brief The driver supports a non-standard query. - * @details If set to @p FALSE there is no support for non-standard queries. - */ - #ifndef GDISP_HARDWARE_QUERY - #define GDISP_HARDWARE_QUERY FALSE - #endif + /** + * @brief Hardware accelerated fills from an image. + * @details If set to @p FALSE software emulation is used. + */ + #ifndef GDISP_HARDWARE_BITFILLS + #define GDISP_HARDWARE_BITFILLS FALSE + #endif - /** - * @brief The driver supports a clipping in hardware. - * @details If set to @p FALSE there is no support for non-standard queries. - * @note If this is defined the driver must perform its own clipping on all calls to - * the driver and respond appropriately if a parameter is outside the display area. - * @note If this is not defined then the software ensures that all calls to the - * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION - * has been set). - */ - #ifndef GDISP_HARDWARE_CLIP - #define GDISP_HARDWARE_CLIP FALSE - #endif -/** @} */ + /** + * @brief Hardware accelerated scrolling. + * @details If set to @p FALSE there is no support for scrolling. + */ + #ifndef GDISP_HARDWARE_SCROLL + #define GDISP_HARDWARE_SCROLL FALSE + #endif -/** - * @name GDISP software algorithm choices - * @{ - */ -/** @} */ + /** + * @brief Reading back of pixel values. + * @details If set to @p FALSE there is no support for pixel read-back. + */ + #ifndef GDISP_HARDWARE_PIXELREAD + #define GDISP_HARDWARE_PIXELREAD FALSE + #endif -/** - * @name GDISP pixel format choices - * @{ - */ - /** - * @brief The native pixel format for this device - * @note Should be set to one of the following: - * GDISP_PIXELFORMAT_RGB565 - * GDISP_PIXELFORMAT_BGR565 - * GDISP_PIXELFORMAT_RGB888 - * GDISP_PIXELFORMAT_RGB444 - * GDISP_PIXELFORMAT_RGB332 - * GDISP_PIXELFORMAT_RGB666 - * GDISP_PIXELFORMAT_CUSTOM - * @note If you set GDISP_PIXELFORMAT_CUSTOM you need to also define - * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h), - * RED_OF(c), GREEN_OF(c), BLUE_OF(c), - * COLOR(c) and MASKCOLOR. - */ - #ifndef GDISP_PIXELFORMAT - #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR - #endif + /** + * @brief The driver supports one or more control commands. + * @details If set to @p FALSE there is no support for control commands. + */ + #ifndef GDISP_HARDWARE_CONTROL + #define GDISP_HARDWARE_CONTROL FALSE + #endif - /** - * @brief Do pixels require packing for a blit - * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats: - * GDISP_PIXELFORMAT_RGB888 - * GDISP_PIXELFORMAT_RGB444 - * GDISP_PIXELFORMAT_RGB666 - * GDISP_PIXELFORMAT_CUSTOM - * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills - * you need to also define @p gdispPackPixels(buf,cx,x,y,c) - * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel - * format must not be a packed format as the software blit does - * not support packed pixels - * @note Very few cases should actually require packed pixels as the low - * level driver can also pack on the fly as it is sending it - * to the graphics device. - */ - #ifndef GDISP_PACKED_PIXELS - #define GDISP_PACKED_PIXELS FALSE - #endif + /** + * @brief The driver supports a non-standard query. + * @details If set to @p FALSE there is no support for non-standard queries. + */ + #ifndef GDISP_HARDWARE_QUERY + #define GDISP_HARDWARE_QUERY FALSE + #endif - /** - * @brief Do lines of pixels require packing for a blit - * @note Ignored if GDISP_PACKED_PIXELS is FALSE - */ - #ifndef GDISP_PACKED_LINES - #define GDISP_PACKED_LINES FALSE - #endif -/** @} */ + /** + * @brief The driver supports a clipping in hardware. + * @details If set to @p FALSE there is no support for non-standard queries. + * @note If this is defined the driver must perform its own clipping on all calls to + * the driver and respond appropriately if a parameter is outside the display area. + * @note If this is not defined then the software ensures that all calls to the + * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION + * has been set). + */ + #ifndef GDISP_HARDWARE_CLIP + #define GDISP_HARDWARE_CLIP FALSE + #endif + /** @} */ +#endif /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ typedef struct GDISPDriver { - GDISPControl g; + GDISPControl g; + + #if GDISP_MULTIPLE_DRIVERS + const struct GDISPVMT const * vmt; + #endif - uint16_t flags; + uint16_t flags; #define GDISP_FLG_INSTREAM 0x0001 // Multithread Mutex #if GDISP_NEED_MULTITHREAD - gfxMutex mutex; + gfxMutex mutex; #endif // Software clipping - #if !GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) - coord_t clipx0, clipy0; - coord_t clipx1, clipy1; /* not inclusive */ + #if (GDISP_MULTIPLE_DRIVERS || !GDISP_HARDWARE_CLIP) && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) + coord_t clipx0, clipy0; + coord_t clipx1, clipy1; /* not inclusive */ #endif // Driver call parameters @@ -212,8 +165,10 @@ typedef struct GDISPDriver { void *ptr; } p; - // Text rendering parameters + // In call working buffers + #if GDISP_NEED_TEXT + // Text rendering parameters struct { font_t font; color_t color; @@ -222,53 +177,363 @@ typedef struct GDISPDriver { coord_t clipx1, clipy1; } t; #endif + #if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM && GDISP_HARDWARE_BITFILLS)) + // A pixel line buffer + color_t linebuf[GDISP_LINEBUF_SIZE]; + #endif + } GDISPDriver; -extern GDISPDriver GDISP_DRIVER_STRUCT; +#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) + #if GDISP_MULTIPLE_DRIVERS + #define LLDSPEC static + #else + #define LLDSPEC + #endif -#ifdef __cplusplus -extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif + + /** + * @brief Initialize the driver. + * @return TRUE if successful. + * @param[in] g The driver structure + * @param[out] g->g The driver must fill in the GDISPControl structure + */ + LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g); - bool_t gdisp_lld_init(void); #if GDISP_HARDWARE_STREAM - void gdisp_lld_stream_start(void); // Uses p.x,p.y p.cx,p.cy - void gdisp_lld_stream_color(void); // Uses p.color + /** + * @brief Start a streamed operation + * @pre GDISP_HARDWARE_STREAM is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The window position + * @param[in] g->p.cx,g->p.cy The window size + * + * @note The parameter variables must not be altered by the driver. + * @note Streaming operations that wrap the defined window have + * undefined results. + */ + LLDSPEC void gdisp_lld_stream_start(GDISPDriver *g); + /** + * @brief Send a pixel to the current streaming position and then increment that position + * @pre GDISP_HARDWARE_STREAM is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.color The color to display at the curent position + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_stream_color(GDISPDriver *g); + + #if GDISP_HARDWARE_STREAM_READ + /** + * @brief Read a pixel from the current streaming position and then increment that position + * @return The color at the current position + * @pre GDISP_HARDWARE_STREAM and GDISP_HARDWARE_STREAM_READ is TRUE + * + * @param[in] g The driver structure + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC color_t gdisp_lld_stream_read(GDISPDriver *g); + #endif + #if GDISP_HARDWARE_STREAM_END - void gdisp_lld_stream_stop(void); // Uses no parameters + /** + * @brief End the current streaming operation + * @pre GDISP_HARDWARE_STREAM and GDISP_HARDWARE_STREAM_END is TRUE + * + * @param[in] g The driver structure + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_stream_stop(GDISPDriver *g); #endif #endif + #if GDISP_HARDWARE_DRAWPIXEL - void gdisp_lld_draw_pixel(void); // Uses p.x,p.y p.color + /** + * @brief Draw a pixel + * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The pixel position + * @param[in] g->p.color The color to set + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_draw_pixel(GDISPDriver *g); #endif + #if GDISP_HARDWARE_CLEARS - void gdisp_lld_clear(void); // Uses p.color + /** + * @brief Clear the screen using the defined color + * @pre GDISP_HARDWARE_CLEARS is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.color The color to set + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_clear(GDISPDriver *g); #endif + #if GDISP_HARDWARE_FILLS - void gdisp_lld_fill_area(void); // Uses p.x,p.y p.cx,p.cy p.color + /** + * @brief Fill an area with a single color + * @pre GDISP_HARDWARE_FILLS is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * @param[in] g->p.color The color to set + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_fill_area(GDISPDriver *g); #endif + #if GDISP_HARDWARE_BITFILLS - void gdisp_lld_blit_area_ex(void); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer) + /** + * @brief Fill an area using a bitmap + * @pre GDISP_HARDWARE_BITFILLS is TRUE + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * @param[in] g->p.x1,g->p.y1 The starting position in the bitmap + * @param[in] g->p.x2 The width of a bitmap line + * @param[in] g->p.ptr The pointer to the bitmap + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_blit_area(GDISPDriver *g); #endif - #if GDISP_HARDWARE_PIXELREAD && GDISP_NEED_PIXELREAD - color_t gdisp_lld_get_pixel_color(void); // Uses p.x,p.y + + #if GDISP_HARDWARE_PIXELREAD + /** + * @brief Read a pixel from the display + * @return The color at the defined position + * @pre GDISP_HARDWARE_PIXELREAD is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The pixel position + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC color_t gdisp_lld_get_pixel_color(GDISPDriver *g); #endif + #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL - void gdisp_lld_vertical_scroll(void); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color + /** + * @brief Scroll an area of the screen + * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * @param[in] g->p.y1 The number of lines to scroll (positive or negative) + * + * @note The parameter variables must not be altered by the driver. + * @note This can be easily implemented if the hardware supports + * display area to display area copying. + * @note Clearing the exposed area on the scroll operation is not + * needed as the high level code handles this. + */ + LLDSPEC void gdisp_lld_vertical_scroll(GDISPDriver *g); #endif + #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL - void gdisp_lld_control(void); // Uses p.x (=what) p.ptr (=value) + /** + * @brief Control some feature of the hardware + * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x The operation to perform + * @param[in] g->p.ptr The operation parameter + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_control(GDISPDriver *g); #endif + #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY - void *gdisp_lld_query(void); // Uses p.x (=what); + /** + * @brief Query some feature of the hardware + * @return The information requested (typecast as void *) + * @pre GDISP_HARDWARE_QUERY is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x What to query + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void *gdisp_lld_query(GDISPDriver *g); // Uses p.x (=what); #endif + #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) - void gdisp_lld_set_clip(void); // Uses p.x,p.y p.cx,p.cy + /** + * @brief Set the hardware clipping area + * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it) + * + * @param[in] g The driver structure + * @param[in] g->p.x,g->p.y The area position + * @param[in] g->p.cx,g->p.cy The area size + * + * @note The parameter variables must not be altered by the driver. + */ + LLDSPEC void gdisp_lld_set_clip(GDISPDriver *g); #endif -#ifdef __cplusplus -} -#endif + #ifdef __cplusplus + } + #endif +#endif // !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) + + +#if GDISP_MULTIPLE_DRIVERS + + typedef struct GDISPVMT { + bool_t (*init)(GDISPDriver *g); + void (*streamstart)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy + void (*streamcolor)(GDISPDriver *g); // Uses p.color + color_t (*streamread)(GDISPDriver *g); // Uses no parameters + void (*streamstop)(GDISPDriver *g); // Uses no parameters + void (*pixel)(GDISPDriver *g); // Uses p.x,p.y p.color + void (*clear)(GDISPDriver *g); // Uses p.color + void (*fill)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy p.color + void (*blit)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer) + color_t (*get)(GDISPDriver *g); // Uses p.x,p.y + void (*vscroll)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color + void (*control)(GDISPDriver *g); // Uses p.x (=what) p.ptr (=value) + void *(*query)(GDISPDriver *g); // Uses p.x (=what); + void (*setclip)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy + } GDISPVMT; + + #ifdef GDISP_LLD_DECLARATIONS + #define GDISP_DRIVER_STRUCT_INIT {{0}, &VMT} + static const GDISPVMT VMT = { + gdisp_lld_init, + #if GDISP_HARDWARE_STREAM + gdisp_lld_stream_start, + gdisp_lld_stream_color, + gdisp_lld_stream_read, + #if GDISP_HARDWARE_STREAM_END + gdisp_lld_stream_stop, + #else + 0, + #endif + #else + 0, 0, 0, + #endif + #if GDISP_HARDWARE_DRAWPIXEL + gdisp_lld_draw_pixel, + #else + 0, + #endif + #if GDISP_HARDWARE_CLEARS + gdisp_lld_clear, + #else + 0, + #endif + #if GDISP_HARDWARE_FILLS + gdisp_lld_fill_area, + #else + 0, + #endif + #if GDISP_HARDWARE_BITFILLS + gdisp_lld_blit_area, + #else + 0, + #endif + #if GDISP_HARDWARE_PIXELREAD + gdisp_lld_get_pixel_color, + #else + 0, + #endif + #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL + gdisp_lld_vertical_scroll, + #else + 0, + #endif + #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL + gdisp_lld_control, + #else + 0, + #endif + #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY + gdisp_lld_query, + #else + 0, + #endif + #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) + gdisp_lld_set_clip, + #else + 0, + #endif + }; + GDISPDriver GDISP_DRIVER_STRUCT = {{0}, &VMT}; + + #else + #define gdisp_lld_init(g) g->vmt->init(g) + #define gdisp_lld_stream_start(g) g->vmt->streamstart(g) + #define gdisp_lld_stream_color(g) g->vmt->streamcolor(g) + #define gdisp_lld_stream_read(g) g->vmt->streamread(g) + #define gdisp_lld_stream_stop(g) g->vmt->streamstop(g) + #define gdisp_lld_draw_pixel(g) g->vmt->pixel(g) + #define gdisp_lld_clear(g) g->vmt->clear(g) + #define gdisp_lld_fill_area(g) g->vmt->fill(g) + #define gdisp_lld_blit_area(g) g->vmt->blit(g) + #define gdisp_lld_get_pixel_color(g) g->vmt->get(g) + #define gdisp_lld_vertical_scroll(g) g->vmt->vscroll(g) + #define gdisp_lld_control(g) g->vmt->control(g) + #define gdisp_lld_query(g) g->vmt->query(g) + #define gdisp_lld_set_clip(g) g->vmt->setclip(g) + + extern GDISPDriver GDISP_DRIVER_STRUCT; + + #endif // GDISP_LLD_DECLARATIONS + +#else // GDISP_MULTIPLE_DRIVERS + #ifdef GDISP_LLD_DECLARATIONS + GDISPDriver GDISP_DRIVER_STRUCT; + #else + extern GDISPDriver GDISP_DRIVER_STRUCT; + #endif + +#endif // GDISP_MULTIPLE_DRIVERS + + /* Verify information for packed pixels and define a non-packed pixel macro */ + #if !GDISP_PACKED_PIXELS + #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); } + #elif !GDISP_HARDWARE_BITFILLS + #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers." + #elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \ + && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \ + && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \ + && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM + #error "GDISP: A packed pixel format has been specified for an unsupported pixel format." + #endif + + /* Support routine for packed pixel formats */ + #if !defined(gdispPackPixels) || defined(__DOXYGEN__) + /** + * @brief Pack a pixel into a pixel buffer. + * @note This function performs no buffer boundary checking + * regardless of whether GDISP_NEED_CLIP has been specified. + * + * @param[in] buf The buffer to put the pixel in + * @param[in] cx The width of a pixel line + * @param[in] x, y The location of the pixel to place + * @param[in] color The color to put into the buffer + * + * @api + */ + void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color); + #endif #endif /* GFX_USE_GDISP */ diff --git a/include/gdisp/options.h b/include/gdisp/options.h index d5818284..1a0f6907 100644 --- a/include/gdisp/options.h +++ b/include/gdisp/options.h @@ -21,54 +21,85 @@ * @{ */ /** + * @brief Should support for multiple displays be provided. + * @details Defaults to FALSE. + * @note Setting this to TRUE can significantly increase code size as many + * optimizations that remove code through conditional compilation can't + * be done. It may also slow some graphics operations as extra tests must + * be performed to determine how to do a particular operation. For these + * reasons do not set it to TRUE unless you really need multiple display + * support. + */ + #ifndef GDISP_MULTIPLE_DRIVERS + #define GDISP_MULTIPLE_DRIVERS FALSE + #endif + /** * @brief Should all operations be clipped to the screen and colors validated. * @details Defaults to TRUE. * @note If this is FALSE, any operations that extend beyond the * edge of the screen will have undefined results. Any * out-of-range colors will produce undefined results. - * @note If defined then all low level and high level GDISP driver routines - * must check the validity of inputs and do something sensible - * if they are out of range. It doesn't have to be efficient, - * just valid. + * @note This should always be left as the default (TRUE) unless you + * are a maniac for speed and you have thoroughly tested your code + * and it never overwrites the edges of the screen. + * @note Setting GDISP_NEED_CLIP to TRUE internally uses the same mechanism + * as this validation. There is no advantage in setting this FALSE if + * GDISP_NEED_CLIP is TRUE. */ #ifndef GDISP_NEED_VALIDATION - #define GDISP_NEED_VALIDATION TRUE + #define GDISP_NEED_VALIDATION TRUE #endif /** * @brief Are clipping functions needed. * @details Defaults to TRUE */ #ifndef GDISP_NEED_CLIP - #define GDISP_NEED_CLIP TRUE + #define GDISP_NEED_CLIP TRUE + #endif + /** + * @brief Streaming functions are needed + * @details Defaults to FALSE. + */ + #ifndef GDISP_NEED_STREAMING + #define GDISP_NEED_STREAMING FALSE #endif /** * @brief Are text functions needed. * @details Defaults to TRUE + * @note You must also define at least one font. */ #ifndef GDISP_NEED_TEXT - #define GDISP_NEED_TEXT TRUE + #define GDISP_NEED_TEXT TRUE #endif /** * @brief Are circle functions needed. - * @details Defaults to TRUE + * @details Defaults to FALSE + * @note Uses integer algorithms only. It does not use any trig or floating point. */ #ifndef GDISP_NEED_CIRCLE - #define GDISP_NEED_CIRCLE TRUE + #define GDISP_NEED_CIRCLE FALSE #endif /** * @brief Are ellipse functions needed. - * @details Defaults to TRUE + * @details Defaults to FALSE + * @note Uses integer algorithms only. It does not use any trig or floating point. */ #ifndef GDISP_NEED_ELLIPSE - #define GDISP_NEED_ELLIPSE TRUE + #define GDISP_NEED_ELLIPSE FALSE #endif /** * @brief Are arc functions needed. * @details Defaults to FALSE - * @note Requires the maths library to be included in the link. ie -lm + * @note This can be compiled using fully integer mathematics by + * defining GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG as TRUE. + * @note This can be compiled to use floating point but no trig functions + * by defining GFX_USE_GMISC and GMISC_NEED_FASTTRIG as TRUE. + * @note If neither of the above are defined it requires the maths library + * to be included in the link to provide floating point and trig support. + * ie include -lm in your compiler flags. */ #ifndef GDISP_NEED_ARC - #define GDISP_NEED_ARC FALSE + #define GDISP_NEED_ARC FALSE #endif /** * @brief Are convex polygon functions needed. @@ -88,7 +119,7 @@ * option will cause a compile error. */ #ifndef GDISP_NEED_SCROLL - #define GDISP_NEED_SCROLL FALSE + #define GDISP_NEED_SCROLL FALSE #endif /** * @brief Is the capability to read pixels back needed. @@ -98,7 +129,7 @@ * option will cause a compile error. */ #ifndef GDISP_NEED_PIXELREAD - #define GDISP_NEED_PIXELREAD FALSE + #define GDISP_NEED_PIXELREAD FALSE #endif /** * @brief Control some aspect of the hardware operation. @@ -107,7 +138,7 @@ * screen rotation, backlight levels, contrast etc */ #ifndef GDISP_NEED_CONTROL - #define GDISP_NEED_CONTROL FALSE + #define GDISP_NEED_CONTROL FALSE #endif /** * @brief Query some aspect of the hardware operation. @@ -115,21 +146,14 @@ * @note This allows query of hardware specific features */ #ifndef GDISP_NEED_QUERY - #define GDISP_NEED_QUERY FALSE + #define GDISP_NEED_QUERY FALSE #endif /** * @brief Is the image interface required. * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE - #define GDISP_NEED_IMAGE FALSE - #endif - /** - * @brief Is the messaging api interface required. - * @details Defaults to FALSE - */ - #ifndef GDISP_NEED_MSGAPI - #define GDISP_NEED_MSGAPI FALSE + #define GDISP_NEED_IMAGE FALSE #endif /** * @} @@ -143,42 +167,42 @@ * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE_NATIVE - #define GDISP_NEED_IMAGE_NATIVE FALSE + #define GDISP_NEED_IMAGE_NATIVE FALSE #endif /** * @brief Is GIF image decoding required. * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE_GIF - #define GDISP_NEED_IMAGE_GIF FALSE + #define GDISP_NEED_IMAGE_GIF FALSE #endif /** * @brief Is BMP image decoding required. * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE_BMP - #define GDISP_NEED_IMAGE_BMP FALSE + #define GDISP_NEED_IMAGE_BMP FALSE #endif /** * @brief Is JPG image decoding required. * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE_JPG - #define GDISP_NEED_IMAGE_JPG FALSE + #define GDISP_NEED_IMAGE_JPG FALSE #endif /** * @brief Is PNG image decoding required. * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE_PNG - #define GDISP_NEED_IMAGE_PNG FALSE + #define GDISP_NEED_IMAGE_PNG FALSE #endif /** * @brief Is memory accounting required during image decoding. * @details Defaults to FALSE */ #ifndef GDISP_NEED_IMAGE_ACCOUNTING - #define GDISP_NEED_IMAGE_ACCOUNTING FALSE + #define GDISP_NEED_IMAGE_ACCOUNTING FALSE #endif /** * @} @@ -191,7 +215,7 @@ * @details Defaults to FALSE */ #ifndef GDISP_NEED_UTF8 - #define GDISP_NEED_UTF8 FALSE + #define GDISP_NEED_UTF8 FALSE #endif /** @@ -199,7 +223,7 @@ * @details Defaults to FALSE */ #ifndef GDISP_NEED_TEXT_KERNING - #define GDISP_NEED_TEXT_KERNING FALSE + #define GDISP_NEED_TEXT_KERNING FALSE #endif /** @@ -207,7 +231,7 @@ * @details Defaults to FALSE */ #ifndef GDISP_NEED_ANTIALIAS - #define GDISP_NEED_ANTIALIAS FALSE + #define GDISP_NEED_ANTIALIAS FALSE #endif /** @@ -219,27 +243,10 @@ /** * @brief Do the drawing functions need to be thread-safe. * @details Defaults to FALSE - * @note Both GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC make - * the gdisp API thread-safe. - * @note This is more efficient than GDISP_NEED_ASYNC as it only - * requires a context switch if something else is already - * drawing. */ #ifndef GDISP_NEED_MULTITHREAD #define GDISP_NEED_MULTITHREAD FALSE #endif - /** - * @brief Use asynchronous calls (multi-thread safe). - * @details Defaults to FALSE - * @note Both GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC make - * the gdisp API thread-safe. - * @note Turning this on adds two context switches per transaction - * so it can significantly slow graphics drawing but it allows - * drawing operations to continue in the background. - */ - #ifndef GDISP_NEED_ASYNC - #define GDISP_NEED_ASYNC FALSE - #endif /** * @} * @@ -257,6 +264,23 @@ * @name GDISP Optional Sizing Parameters * @{ */ + /** + * @brief The size of pixel buffer (in pixels) used for optimization. + * @details Set to zero to guarantee disabling of the buffer. + * @note Depending on the driver and what operations the application + * needs, this buffer may never be allocated. + * @note Setting the size to zero may cause some operations to not + * compile eg. Scrolling if there is no hardware scroll support. + * @note Increasing the size will speedup certain operations + * at the expense of RAM. + * @note Currently only used to support scrolling on hardware without + * scrolling support, and to increase the speed of streaming + * operations on non-streaming hardware where there is a + * hardware supported bit-blit. + */ + #ifndef GDISP_LINEBUF_SIZE + #define GDISP_LINEBUF_SIZE 128 + #endif /** * @} * @@ -282,12 +306,6 @@ /* #define GDISP_SCREEN_WIDTH nnnn */ /* #define GDISP_SCREEN_HEIGHT nnnn */ /** - * @brief Define which threading model to use. - * @details Optional for the X11 driver. - * @note Defaults to TRUE. Setting to FALSE causes POSIX threads to be used - */ - /* #define GDISP_THREAD_CHIBIOS FALSE */ - /** * @brief Define which bus interface to use. * @details Only required by the SSD1963 driver. * @note This will be replaced eventually by board definition files @@ -296,10 +314,6 @@ /* #define GDISP_USE_GPIO */ /** @} */ -#if GFX_USE_GDISP - #include "gdisp_lld_config.h" -#endif - #endif /* _GDISP_OPTIONS_H */ /** @} */ |