1 /** 2 * @file lv_draw_buf.h 3 * 4 */ 5 6 #ifndef LV_DRAW_BUF_H 7 #define LV_DRAW_BUF_H 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 /********************* 14 * INCLUDES 15 *********************/ 16 #include "../misc/lv_types.h" 17 #include "../misc/lv_area.h" 18 #include "../misc/lv_color.h" 19 #include "../stdlib/lv_string.h" 20 #include "lv_image_dsc.h" 21 22 /********************* 23 * DEFINES 24 *********************/ 25 26 /** Use this value to let LVGL calculate stride automatically */ 27 #define LV_STRIDE_AUTO 0 28 LV_EXPORT_CONST_INT(LV_STRIDE_AUTO); 29 30 /** 31 * Stride alignment for draw buffers. 32 * It may vary between different color formats and hardware. 33 * Refine it to suit your needs. 34 */ 35 36 #define LV_DRAW_BUF_STRIDE(w, cf) \ 37 LV_ROUND_UP(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8, LV_DRAW_BUF_STRIDE_ALIGN) 38 39 /** Allocate a slightly larger buffer, so we can adjust the start address to meet alignment */ 40 #define LV_DRAW_BUF_SIZE(w, h, cf) \ 41 (LV_DRAW_BUF_STRIDE(w, cf) * (h) + LV_DRAW_BUF_ALIGN + \ 42 LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t)) 43 44 /** 45 * Define a static draw buffer with the given width, height, and color format. 46 * Stride alignment is set to LV_DRAW_BUF_STRIDE_ALIGN. 47 * 48 * For platform that needs special buffer alignment, call LV_DRAW_BUF_INIT_STATIC. 49 */ 50 #define LV_DRAW_BUF_DEFINE_STATIC(name, _w, _h, _cf) \ 51 static LV_ATTRIBUTE_MEM_ALIGN uint8_t buf_##name[LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \ 52 static lv_draw_buf_t name = { \ 53 .header = { \ 54 .magic = LV_IMAGE_HEADER_MAGIC, \ 55 .cf = (_cf), \ 56 .flags = LV_IMAGE_FLAGS_MODIFIABLE, \ 57 .w = (_w), \ 58 .h = (_h), \ 59 .stride = LV_DRAW_BUF_STRIDE(_w, _cf), \ 60 .reserved_2 = 0, \ 61 }, \ 62 .data_size = sizeof(buf_##name), \ 63 .data = buf_##name, \ 64 .unaligned_data = buf_##name, \ 65 } 66 67 #define LV_DRAW_BUF_INIT_STATIC(name) \ 68 do { \ 69 lv_image_header_t * header = &name.header; \ 70 lv_draw_buf_init(&name, header->w, header->h, (lv_color_format_t)header->cf, header->stride, buf_##name, sizeof(buf_##name)); \ 71 lv_draw_buf_set_flag(&name, LV_IMAGE_FLAGS_MODIFIABLE); \ 72 } while(0) 73 74 /********************** 75 * TYPEDEFS 76 **********************/ 77 78 typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format); 79 80 typedef void (*lv_draw_buf_free_cb)(void * draw_buf); 81 82 typedef void * (*lv_draw_buf_align_cb)(void * buf, lv_color_format_t color_format); 83 84 typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area); 85 86 typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format); 87 88 struct _lv_draw_buf_t { 89 lv_image_header_t header; 90 uint32_t data_size; /**< Total buf size in bytes */ 91 uint8_t * data; 92 void * unaligned_data; /**< Unaligned address of `data`, used internally by lvgl */ 93 const lv_draw_buf_handlers_t * handlers; /**< draw buffer alloc/free ops. */ 94 }; 95 96 /********************** 97 * GLOBAL PROTOTYPES 98 **********************/ 99 100 /** 101 * Initialize the draw buffer with the default handlers. 102 * 103 * @param handlers the draw buffer handlers to set 104 */ 105 void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers); 106 107 /** 108 * Initialize the draw buffer with given handlers. 109 * 110 * @param handlers the draw buffer handlers to set 111 * @param buf_malloc_cb the callback to allocate memory for the buffer 112 * @param buf_free_cb the callback to free memory of the buffer 113 * @param align_pointer_cb the callback to align the buffer 114 * @param invalidate_cache_cb the callback to invalidate the cache of the buffer 115 * @param flush_cache_cb the callback to flush buffer 116 * @param width_to_stride_cb the callback to calculate the stride based on the width and color format 117 */ 118 void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers, 119 lv_draw_buf_malloc_cb buf_malloc_cb, 120 lv_draw_buf_free_cb buf_free_cb, 121 lv_draw_buf_align_cb align_pointer_cb, 122 lv_draw_buf_cache_operation_cb invalidate_cache_cb, 123 lv_draw_buf_cache_operation_cb flush_cache_cb, 124 lv_draw_buf_width_to_stride_cb width_to_stride_cb); 125 126 /** 127 * Get the struct which holds the callbacks for draw buf management. 128 * Custom callback can be set on the returned value 129 * @return pointer to the struct of handlers 130 */ 131 lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void); 132 lv_draw_buf_handlers_t * lv_draw_buf_get_font_handlers(void); 133 lv_draw_buf_handlers_t * lv_draw_buf_get_image_handlers(void); 134 135 136 /** 137 * Align the address of a buffer. The buffer needs to be large enough for the real data after alignment 138 * @param buf the data to align 139 * @param color_format the color format of the buffer 140 * @return the aligned buffer 141 */ 142 void * lv_draw_buf_align(void * buf, lv_color_format_t color_format); 143 144 /** 145 * Align the address of a buffer with custom draw buffer handlers. 146 * The buffer needs to be large enough for the real data after alignment 147 * @param handlers the draw buffer handlers 148 * @param buf the data to align 149 * @param color_format the color format of the buffer 150 * @return the aligned buffer 151 */ 152 void * lv_draw_buf_align_ex(const lv_draw_buf_handlers_t * handlers, void * buf, lv_color_format_t color_format); 153 154 /** 155 * Invalidate the cache of the buffer 156 * @param draw_buf the draw buffer needs to be invalidated 157 * @param area the area to invalidate in the buffer, 158 * use NULL to invalidate the whole draw buffer address range 159 */ 160 void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); 161 162 /** 163 * Flush the cache of the buffer 164 * @param draw_buf the draw buffer needs to be flushed 165 * @param area the area to flush in the buffer, 166 * use NULL to flush the whole draw buffer address range 167 */ 168 void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); 169 170 /** 171 * Calculate the stride in bytes based on a width and color format 172 * @param w the width in pixels 173 * @param color_format the color format 174 * @return the stride in bytes 175 */ 176 uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format); 177 178 /** 179 * Calculate the stride in bytes based on a width and color format 180 * @param handlers the draw buffer handlers 181 * @param w the width in pixels 182 * @param color_format the color format 183 * @return the stride in bytes 184 */ 185 uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, 186 lv_color_format_t color_format); 187 188 /** 189 * Clear an area on the buffer 190 * @param draw_buf pointer to draw buffer 191 * @param a the area to clear, or NULL to clear the whole buffer 192 */ 193 void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a); 194 195 /** 196 * Copy an area from a buffer to another 197 * @param dest pointer to the destination draw buffer 198 * @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer 199 * @param src pointer to the source draw buffer 200 * @param src_area the area to copy from the destination buffer, if NULL, use the whole buffer 201 * @note `dest_area` and `src_area` should have the same width and height 202 * @note `dest` and `src` should have same color format. Color converting is not supported fow now. 203 */ 204 void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, 205 const lv_draw_buf_t * src, const lv_area_t * src_area); 206 207 /** 208 * Note: Eventually, lv_draw_buf_malloc/free will be kept as private. 209 * For now, we use `create` to distinguish with malloc. 210 * 211 * Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it 212 * that meets specified requirements. 213 * 214 * @param w the buffer width in pixels 215 * @param h the buffer height in pixels 216 * @param cf the color format for image 217 * @param stride the stride in bytes for image. Use 0 for automatic calculation based on 218 * w, cf, and global stride alignment configuration. 219 */ 220 lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride); 221 222 /** 223 * Note: Eventually, lv_draw_buf_malloc/free will be kept as private. 224 * For now, we use `create` to distinguish with malloc. 225 * 226 * Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it 227 * that meets specified requirements. 228 * 229 * @param handlers the draw buffer handlers 230 * @param w the buffer width in pixels 231 * @param h the buffer height in pixels 232 * @param cf the color format for image 233 * @param stride the stride in bytes for image. Use 0 for automatic calculation based on 234 * w, cf, and global stride alignment configuration. 235 */ 236 lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, uint32_t h, 237 lv_color_format_t cf, uint32_t stride); 238 239 /** 240 * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. 241 * @param draw_buf the draw buf to duplicate 242 * @return the duplicated draw buf on success, NULL if failed 243 */ 244 lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf); 245 246 /** 247 * Duplicate a draw buf with same image size, stride and color format. Copy the image data too. 248 * @param handlers the draw buffer handlers 249 * @param draw_buf the draw buf to duplicate 250 * @return the duplicated draw buf on success, NULL if failed 251 */ 252 lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf); 253 254 /** 255 * Initialize a draw buf with the given buffer and parameters. Clear draw buffer flag to zero. 256 * @param draw_buf the draw buf to initialize 257 * @param w the buffer width in pixels 258 * @param h the buffer height in pixels 259 * @param cf the color format 260 * @param stride the stride in bytes. Use 0 for automatic calculation 261 * @param data the buffer used for drawing. Unaligned `data` will be aligned internally 262 * @param data_size the size of the buffer in bytes 263 * @return return LV_RESULT_OK on success, LV_RESULT_INVALID otherwise 264 */ 265 lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride, 266 void * data, uint32_t data_size); 267 268 /** 269 * Keep using the existing memory, reshape the draw buffer to the given width and height. 270 * Return NULL if data_size is smaller than the required size. 271 * @param draw_buf pointer to a draw buffer 272 * @param cf the new color format, use 0 or LV_COLOR_FORMAT_UNKNOWN to keep using the original color format. 273 * @param w the new width in pixels 274 * @param h the new height in pixels 275 * @param stride the stride in bytes for image. Use 0 for automatic calculation. 276 */ 277 lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t cf, uint32_t w, uint32_t h, 278 uint32_t stride); 279 280 /** 281 * Destroy a draw buf by freeing the actual buffer if it's marked as LV_IMAGE_FLAGS_ALLOCATED in header. 282 * Then free the lv_draw_buf_t struct. 283 * 284 * @param draw_buf the draw buffer to destroy 285 */ 286 void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf); 287 288 /** 289 * Return pointer to the buffer at the given coordinates 290 */ 291 void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y); 292 293 /** 294 * Adjust the stride of a draw buf in place. 295 * @param src pointer to a draw buffer 296 * @param stride the new stride in bytes for image. Use LV_STRIDE_AUTO for automatic calculation. 297 * @return LV_RESULT_OK: success or LV_RESULT_INVALID: failed 298 */ 299 lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride); 300 301 /** 302 * Premultiply draw buffer color with alpha channel. 303 * If it's already premultiplied, return directly. 304 * Only color formats with alpha channel will be processed. 305 * 306 * @return LV_RESULT_OK: premultiply success 307 */ 308 lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf); 309 310 bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag); 311 312 void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); 313 314 void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); 315 316 /** 317 * As of now, draw buf share same definition as `lv_image_dsc_t`. 318 * And is interchangeable with `lv_image_dsc_t`. 319 */ 320 321 void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img); 322 323 void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img); 324 325 /** 326 * Set the palette color of an indexed image. Valid only for `LV_COLOR_FORMAT_I1/2/4/8` 327 * @param draw_buf pointer to an image descriptor 328 * @param index the palette color to set: 329 * - for `LV_COLOR_FORMAT_I1`: 0..1 330 * - for `LV_COLOR_FORMAT_I2`: 0..3 331 * - for `LV_COLOR_FORMAT_I4`: 0..15 332 * - for `LV_COLOR_FORMAT_I8`: 0..255 333 * @param color the color to set in lv_color32_t format 334 */ 335 void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32_t color); 336 337 /** 338 * @deprecated Use lv_draw_buf_set_palette instead. 339 */ 340 void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c); 341 342 /** 343 * @deprecated Use lv_draw_buffer_create/destroy instead. 344 * Free the data pointer and dsc struct of an image. 345 */ 346 void lv_image_buf_free(lv_image_dsc_t * dsc); 347 348 /********************** 349 * MACROS 350 **********************/ 351 352 #ifdef __cplusplus 353 } /*extern "C"*/ 354 #endif 355 356 #endif /*LV_DRAW_BUF_H*/ 357