1 /**
2  * @file lv_draw_buf_vglite.c
3  *
4  */
5 
6 /**
7  * Copyright 2023-2024 NXP
8  *
9  * SPDX-License-Identifier: MIT
10  */
11 
12 /*********************
13  *      INCLUDES
14  *********************/
15 
16 #include "lv_draw_vglite.h"
17 
18 #if LV_USE_DRAW_VGLITE
19 #include "../../lv_draw_buf_private.h"
20 #include "lv_vglite_buf.h"
21 #include "lv_vglite_utils.h"
22 
23 #include "lvgl_support.h"
24 
25 /*********************
26  *      DEFINES
27  *********************/
28 
29 /**********************
30  *      TYPEDEFS
31  **********************/
32 
33 /**********************
34  *  STATIC PROTOTYPES
35  **********************/
36 
37 static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
38 static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf);
39 
40 /**********************
41  *  STATIC VARIABLES
42  **********************/
43 
44 /**********************
45  *      MACROS
46  **********************/
47 
48 /**********************
49  *   GLOBAL FUNCTIONS
50  **********************/
51 
lv_draw_buf_vglite_init_handlers(void)52 void lv_draw_buf_vglite_init_handlers(void)
53 {
54     lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
55     lv_draw_buf_handlers_t * font_handlers = lv_draw_buf_get_font_handlers();
56     lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers();
57 
58     handlers->invalidate_cache_cb = _invalidate_cache;
59     font_handlers->invalidate_cache_cb = _invalidate_cache;
60     image_handlers->invalidate_cache_cb = _invalidate_cache;
61 
62     handlers->width_to_stride_cb = _width_to_stride;
63     font_handlers->width_to_stride_cb = _width_to_stride;
64     image_handlers->width_to_stride_cb = _width_to_stride;
65 
66 }
67 
68 /**********************
69  *   STATIC FUNCTIONS
70  **********************/
71 
_invalidate_cache(const lv_draw_buf_t * draw_buf,const lv_area_t * area)72 static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
73 {
74     const lv_image_header_t * header = &draw_buf->header;
75     uint32_t stride = header->stride;
76     lv_color_format_t cf = header->cf;
77 
78     if(area->y1 == 0) {
79         uint32_t size = stride * lv_area_get_height(area);
80 
81         /* Invalidate full buffer. */
82         DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size);
83         return;
84     }
85 
86     const uint8_t * buf_u8 = draw_buf->data;
87     /* ARM require a 32 byte aligned address. */
88     uint8_t align_bytes = 32;
89     uint8_t bits_per_pixel = lv_color_format_get_bpp(cf);
90 
91     uint16_t align_pixels = align_bytes * 8 / bits_per_pixel;
92     uint16_t offset_x = 0;
93 
94     if(area->x1 >= (int32_t)(area->x1 % align_pixels)) {
95         uint16_t shift_x = area->x1 - (area->x1 % align_pixels);
96 
97         offset_x = area->x1 - shift_x;
98         buf_u8 += (shift_x * bits_per_pixel) / 8;
99     }
100 
101     if(area->y1) {
102         uint16_t shift_y = area->y1;
103 
104         buf_u8 += shift_y * stride;
105     }
106 
107     /* Area to clear can start from a different offset in buffer.
108      * Invalidate the area line by line.
109      */
110     uint16_t line_pixels = offset_x + lv_area_get_width(area);
111     uint16_t line_size = (line_pixels * bits_per_pixel) / 8;
112     uint16_t area_height = lv_area_get_height(area);
113 
114     for(uint16_t y = 0; y < area_height; y++) {
115         const void * line_addr = buf_u8 + y * stride;
116 
117         DEMO_CleanInvalidateCacheByAddr((void *)line_addr, line_size);
118     }
119 }
120 
_width_to_stride(uint32_t w,lv_color_format_t cf)121 static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf)
122 {
123     uint8_t bits_per_pixel = lv_color_format_get_bpp(cf);
124     uint32_t width_bits = (w * bits_per_pixel + 7) & ~7;
125     uint32_t width_bytes = width_bits / 8;
126     uint8_t align_bytes = vglite_get_stride_alignment(cf);
127 
128     return (width_bytes + align_bytes - 1) & ~(align_bytes - 1);
129 }
130 
131 #endif /*LV_USE_DRAW_VGLITE*/
132