/* * Copyright (c) 2020 Actions Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Public API for display graphics */ #ifndef ZEPHYR_INCLUDE_DRIVERS_DISPLAY_DISPLAY_GRAPHICS_H_ #define ZEPHYR_INCLUDE_DRIVERS_DISPLAY_DISPLAY_GRAPHICS_H_ /** * @brief Display Graphics * @defgroup display_graphics Display Graphics * @ingroup display_interfaces * @{ */ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @enum display_blending_type * @brief Enumeration with possible display blending type * */ enum display_blending_type { /* no blending */ DISPLAY_BLENDING_NONE = 0x0, /* ONE / ONE_MINUS_SRC_ALPHA */ DISPLAY_BLENDING_PREMULT = 0x1, /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */ DISPLAY_BLENDING_COVERAGE = 0x2 }; /** * @enum display_transform_type * @brief Enumeration with possible display transform type * * IMPORTANT NOTE: * DISPLAY_TRANSFORM_ROT_90 is applied CLOCKWISE and AFTER DISPLAY_TRANSFORM_FLIP_{H|V}. */ enum { /* flip source image horizontally (around the vertical axis) */ DISPLAY_TRANSFORM_FLIP_H = 0x01, /* flip source image vertically (around the horizontal axis)*/ DISPLAY_TRANSFORM_FLIP_V = 0x02, /* rotate source image 90 degrees clockwise */ DISPLAY_TRANSFORM_ROT_90 = 0x04, /* rotate source image 180 degrees */ DISPLAY_TRANSFORM_ROT_180 = 0x03, /* rotate source image 270 degrees clockwise */ DISPLAY_TRANSFORM_ROT_270 = 0x07, /* don't use. see system/window.h */ DISPLAY_TRANSFORM_RESERVED = 0x08, }; /** * @struct display_color * @brief Structure holding display color * */ typedef struct display_color { union { /* access as per-channel name for ARGB-8888 */ struct { uint8_t b; /* blue component */ uint8_t g; /* green component */ uint8_t r; /* red component */ uint8_t a; /* alpha component */ }; uint8_t c8[4]; /* access as 8-bit byte array */ uint16_t c16[2]; /* access as 16-bit half word array */ uint32_t c32[1]; /* access as 32-bit word array */ uint32_t full; /* access as 32-bit full value */ }; } display_color_t; /** * @struct display_point * @brief Structure holding display point * */ typedef struct display_point { int16_t x; /* x coord */ int16_t y; /* y coord */ } display_point_t; /** * @struct display_point_fx * @brief Structure holding display point in fixed format * */ typedef struct display_point_fx_t { int32_t x; /* x coord in fixed point */ int32_t y; /* x coord in fixed point*/ } display_point_fx_t; /** * @struct display_rect * @brief Structure holding display retangle * */ typedef struct display_rect { int16_t x; /* x coord */ int16_t y; /* y coord */ int16_t w; /* row width in pixel */ int16_t h; /* column height in pixel */ } display_rect_t; /** * @struct display_buffer * @brief Structure holding display buffer * */ typedef struct display_buffer { /* buffer descriptor */ struct display_buffer_descriptor desc; /** * Pixel offset of each row only for A1/2/4 and I1/2/4 color formats, accepted values: * 0, 1 for A4, I4 * 0, 1, 2, 3 for A2, I2 * 0, 1, 2, 3, 4, 5, 6, 7 for A1, I1 * 0 for others */ uint8_t px_ofs; /* buffer address*/ union { uint32_t addr; /* pointer in integer */ void * pbuf; /* pointer to a buffer */ uint8_t * pbuf8; /* pointer to a buffer in a 8-bit color type */ uint16_t * pbuf16; /* pointer to a buffer in a 16-bit color type */ uint32_t * pbuf32; /* pointer to a buffer in a 32-bit color type */ }; } display_buffer_t; /** * @struct display_matrix * @brief Structure holding 2x3 affine transform matrix. * * [ sx shx tx ] * [ shy sy ty ] * [ 0 0 1 ] * * Where: * sx and sy define scaling in the x and y directions, respectively; * shx and shy define shearing in the x and y directions, respectively; * tx and ty define translation in the x and y directions, respectively; * * An affine transformation maps a point (x, y) into the point (x', y') using * matrix multiplication: * * [ sx shx tx ] [x] [ x * sx + y * shx + tx ] * [ shy sy ty ] [y] = [ x * shy + y * sy + ty ] * [ 0 0 1 ] [1] [ 1 ] * * that is: * x' = sx * x + shx * y + tx * y' = shy * x + sy * y + ty */ typedef struct display_matrix { int32_t sx; int32_t shx; int32_t tx; int32_t sy; int32_t shy; int32_t ty; } display_matrix_t; /** * @struct display_layer * @brief Structure holding display layer for composition * */ typedef struct display_layer { /* display buffer */ const display_buffer_t *buffer; /* * plane color applied to the whole layer: * 1) For buffer == NULL, use color.argb as the default pixel color value * 2) For buffer != NULL, use color.a as the global alpha value * 3) For buffer with format A1/2/4/8, use color.rgb as the pixel rgb value */ display_color_t color; /* where to composite the buffer onto the display, the origin is the top-left corner * of the screen. */ display_rect_t frame; /* blending to apply during composition */ uint8_t blending; /* reserved for future */ uint8_t _pad[3]; /* * the transform matrix that maps the display coodinate system to the * transformed source image coordinate system whose origin is at the * top-left corner of the transformed source image. */ const display_matrix_t *matrix; } display_layer_t; /** * @brief Query display format is opaque * * @param pixel_format Display format, see@enum display_pixel_format * * @return the query result */ static inline bool display_format_is_opaque(uint32_t pixel_format) { return (pixel_format & (PIXEL_FORMAT_ARGB_8888 | PIXEL_FORMAT_BGRA_5658 | PIXEL_FORMAT_BGRA_6666 | PIXEL_FORMAT_RGBA_6666 | PIXEL_FORMAT_BGRA_5551 | PIXEL_FORMAT_I8 | PIXEL_FORMAT_I4 | PIXEL_FORMAT_I2 | PIXEL_FORMAT_I1 | PIXEL_FORMAT_A8 | PIXEL_FORMAT_A4 | PIXEL_FORMAT_A2 | PIXEL_FORMAT_A1 | PIXEL_FORMAT_A4_LE | PIXEL_FORMAT_A1_LE)) ? false : true; } /** * @brief Query display format bits per pixel * * @param pixel_format Display format, see@enum display_pixel_format * * @return the query result */ uint8_t display_format_get_bits_per_pixel(uint32_t pixel_format); /** * @brief Get display format name string * * @param pixel_format hal pixel format, see@enum hal_pixel_format * * @return the name string */ const char * display_format_get_name(uint32_t pixel_format); /** * @brief Construct display color * * @param r r component * @param g g component * @param b b component * @param a a component * * @return display color structure */ static inline display_color_t display_color_make(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { display_color_t color = { .r = r, .g = g, .b = b, .a = a, }; return color; } /** * @brief Construct display color from 32-bit hex value * * @param c 32-bit color value argb-8888 * * @return display color structure */ static inline display_color_t display_color_hex(uint32_t c) { display_color_t color = { .full = c, }; return color; } /** * @brief Construct display color from 16-bit hex value * * @param c 16-bit color value rgb-565 * * @return display color structure */ static inline display_color_t display_color_hex16(uint16_t c) { display_color_t color = { .a = 0xff, .r = (c & 0xf800) >> 8, .g = (c & 0x07f0) >> 3, .b = (c & 0x001f) << 3, }; color.r = color.r | ((color.r >> 3) & 0x7); color.g = color.g | ((color.g >> 2) & 0x3); color.b = color.b | ((color.b >> 3) & 0x7); return color; } static inline display_color_t display_color_black(void) { return display_color_make(0x00, 0x00, 0x00, 0xff); } static inline display_color_t display_color_white(void) { return display_color_make(0xff, 0xff, 0xff, 0xff); } static inline display_color_t display_color_red(void) { return display_color_make(0xff, 0x00, 0x00, 0xff); } static inline display_color_t display_color_green(void) { return display_color_make(0x00, 0xff, 0x00, 0xff); } static inline display_color_t display_color_blue(void) { return display_color_make(0x00, 0x00, 0xff, 0xff); } /** * @brief Fill color to display buffer * * @param buffer pointer to structure display_buffer * @param color color to fill * @param pad_byte padded byte to fill if non-negative value else ignored * * @retval 0 on success else negative errno code */ int display_buffer_fill_color(const display_buffer_t *buffer, display_color_t color, int pad_byte); /** * @brief Fill image data to display buffer * * @param buffer pointer to structure display_buffer * @param data image data to fill * @param data_stride_bytes image stride in bytes. If 0, the stride is consider * the same as the buffer's width in bytes. * @param pad_byte padded byte to fill if non-negative value else ignored * * @retval 0 on success else negative errno code */ int display_buffer_fill_image(const display_buffer_t *buffer, const void *data, uint16_t data_stride_bytes, int pad_byte); /** * @brief Flush cache of display buffer after cpu write * * @param buffer pointer to structure display_buffer * * @retval N/A */ void display_buffer_cpu_write_flush(const display_buffer_t *buffer); /** * @brief Invalidate cache of display buffer after device write * * @param buffer pointer to structure display_buffer * * @retval N/A */ void display_buffer_dev_write_flush(const display_buffer_t *buffer); /** * @brief Set display rectangle * * @param rect Pointer to display rectangle structure * * @return N/A */ static inline void display_rect_set(display_rect_t *rect, int16_t x, int16_t y, int16_t width, int16_t height) { rect->x = x; rect->y = y; rect->w = width; rect->h = height; } /** * @brief Move display rectangle * * @param rect Pointer to display rectangle structure * @param dx delta X to move * @param dy delta Y to move * * @return N/A */ static inline void display_rect_move(display_rect_t *rect, int16_t dx, int16_t dy) { rect->x += dx; rect->y += dy; } /** * @brief Get display rectangle width * * @param rect Pointer to display rectangle structure * * @return the rectangle width */ static inline int16_t display_rect_get_width(const display_rect_t *rect) { return rect->w; } /** * @brief Get display rectangle height * * @param rect Pointer to display rectangle structure * * @return the rectangle height */ static inline int16_t display_rect_get_height(const display_rect_t *rect) { return rect->h; } /** * @brief Set display rectangle width * * @param rect Pointer to display rectangle structure * @param width rect width * * @return N/A */ static inline void display_rect_set_width(display_rect_t *rect, int16_t width) { rect->w = width; } /** * @brief Set display rectangle height * * @param rect Pointer to display rectangle structure * @param height rect height * * @return N/A */ static inline void display_rect_set_height(display_rect_t *rect, int16_t height) { rect->h = height; } /** * @brief Query display rectangle is valid * * @param rect Pointer to display rectangle structure * * @return the query result */ static inline bool display_rect_is_valid(const display_rect_t *rect) { return (rect->w >= 0) && (rect->h >= 0); } /** * @brief Query display rectangle is empty * * @param rect Pointer to display rectangle structure * * @return the query result */ static inline bool display_rect_is_empty(const display_rect_t *rect) { return (rect->w <= 0) || (rect->h <= 0); } /** * @brief Intersec two display rectangles * * @param dest Pointer to dest display rectangle * @param src Pointer to src display rectangle * * @return N/A */ void display_rect_intersect(display_rect_t *dest, const display_rect_t *src); /** * @brief Merge two display rectangles * * @param dest Pointer to dest display rectangle * @param src Pointer to src display rectangle * * @return N/A */ void display_rect_merge(display_rect_t *dest, const display_rect_t *src); #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_DRIVERS_DISPLAY_DISPLAY_GRAPHICS_H_ */