1 /**
2  * @file lv_draw_sw_layer.h
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_draw_sw.h"
10 #include "../../hal/lv_hal_disp.h"
11 #include "../../misc/lv_area.h"
12 #include "../../core/lv_refr.h"
13 
14 /*********************
15  *      DEFINES
16  *********************/
17 
18 /**********************
19  *      TYPEDEFS
20  **********************/
21 
22 /**********************
23  *  STATIC PROTOTYPES
24  **********************/
25 
26 /**********************
27  *  STATIC VARIABLES
28  **********************/
29 
30 /**********************
31  *  GLOBAL VARIABLES
32  **********************/
33 
34 /**********************
35  *      MACROS
36  **********************/
37 
38 /**********************
39  *   GLOBAL FUNCTIONS
40  **********************/
41 
42 
lv_draw_sw_layer_create(struct _lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx,lv_draw_layer_flags_t flags)43 struct _lv_draw_layer_ctx_t * lv_draw_sw_layer_create(struct _lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx,
44                                                       lv_draw_layer_flags_t flags)
45 {
46     if(LV_COLOR_SCREEN_TRANSP == 0 && (flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA)) {
47         LV_LOG_WARN("Rendering this widget needs LV_COLOR_SCREEN_TRANSP 1");
48         return NULL;
49     }
50 
51     lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
52     uint32_t px_size = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
53     if(flags & LV_DRAW_LAYER_FLAG_CAN_SUBDIVIDE) {
54         layer_sw_ctx->buf_size_bytes = LV_LAYER_SIMPLE_BUF_SIZE;
55         uint32_t full_size = lv_area_get_size(&layer_sw_ctx->base_draw.area_full) * px_size;
56         if(layer_sw_ctx->buf_size_bytes > full_size) layer_sw_ctx->buf_size_bytes = full_size;
57         layer_sw_ctx->base_draw.buf = lv_mem_alloc(layer_sw_ctx->buf_size_bytes);
58         if(layer_sw_ctx->base_draw.buf == NULL) {
59             LV_LOG_WARN("Cannot allocate %"LV_PRIu32" bytes for layer buffer. Allocating %"LV_PRIu32" bytes instead. (Reduced performance)",
60                         (uint32_t)layer_sw_ctx->buf_size_bytes, (uint32_t)LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE * px_size);
61             layer_sw_ctx->buf_size_bytes = LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE;
62             layer_sw_ctx->base_draw.buf = lv_mem_alloc(layer_sw_ctx->buf_size_bytes);
63             if(layer_sw_ctx->base_draw.buf == NULL) {
64                 return NULL;
65             }
66         }
67         layer_sw_ctx->base_draw.area_act = layer_sw_ctx->base_draw.area_full;
68         layer_sw_ctx->base_draw.area_act.y2 = layer_sw_ctx->base_draw.area_full.y1;
69         lv_coord_t w = lv_area_get_width(&layer_sw_ctx->base_draw.area_act);
70         layer_sw_ctx->base_draw.max_row_with_alpha = layer_sw_ctx->buf_size_bytes / w / LV_IMG_PX_SIZE_ALPHA_BYTE;
71         layer_sw_ctx->base_draw.max_row_with_no_alpha = layer_sw_ctx->buf_size_bytes / w / sizeof(lv_color_t);
72     }
73     else {
74         layer_sw_ctx->base_draw.area_act = layer_sw_ctx->base_draw.area_full;
75         layer_sw_ctx->buf_size_bytes = lv_area_get_size(&layer_sw_ctx->base_draw.area_full) * px_size;
76         layer_sw_ctx->base_draw.buf = lv_mem_alloc(layer_sw_ctx->buf_size_bytes);
77         lv_memset_00(layer_sw_ctx->base_draw.buf, layer_sw_ctx->buf_size_bytes);
78         layer_sw_ctx->has_alpha = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
79         if(layer_sw_ctx->base_draw.buf == NULL) {
80             return NULL;
81         }
82 
83         draw_ctx->buf = layer_sw_ctx->base_draw.buf;
84         draw_ctx->buf_area = &layer_sw_ctx->base_draw.area_act;
85         draw_ctx->clip_area = &layer_sw_ctx->base_draw.area_act;
86 
87         lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
88         disp_refr->driver->screen_transp = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
89     }
90 
91     return layer_ctx;
92 }
93 
lv_draw_sw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx,struct _lv_draw_layer_ctx_t * layer_ctx,lv_draw_layer_flags_t flags)94 void lv_draw_sw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
95                              lv_draw_layer_flags_t flags)
96 {
97 
98     lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
99     lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
100     if(flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA) {
101         lv_memset_00(layer_ctx->buf, layer_sw_ctx->buf_size_bytes);
102         layer_sw_ctx->has_alpha = 1;
103         disp_refr->driver->screen_transp = 1;
104     }
105     else {
106         layer_sw_ctx->has_alpha = 0;
107         disp_refr->driver->screen_transp = 0;
108     }
109 
110     draw_ctx->buf = layer_ctx->buf;
111     draw_ctx->buf_area = &layer_ctx->area_act;
112     draw_ctx->clip_area = &layer_ctx->area_act;
113 }
114 
lv_draw_sw_layer_blend(struct _lv_draw_ctx_t * draw_ctx,struct _lv_draw_layer_ctx_t * layer_ctx,const lv_draw_img_dsc_t * draw_dsc)115 void lv_draw_sw_layer_blend(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
116                             const lv_draw_img_dsc_t * draw_dsc)
117 {
118     lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
119 
120     lv_img_dsc_t img;
121     img.data = draw_ctx->buf;
122     img.header.always_zero = 0;
123     img.header.w = lv_area_get_width(draw_ctx->buf_area);
124     img.header.h = lv_area_get_height(draw_ctx->buf_area);
125     img.header.cf = layer_sw_ctx->has_alpha ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;
126 
127     /*Restore the original draw_ctx*/
128     draw_ctx->buf = layer_ctx->original.buf;
129     draw_ctx->buf_area = layer_ctx->original.buf_area;
130     draw_ctx->clip_area = layer_ctx->original.clip_area;
131     lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
132     disp_refr->driver->screen_transp = layer_ctx->original.screen_transp;
133 
134     /*Blend the layer*/
135     lv_draw_img(draw_ctx, draw_dsc, &layer_ctx->area_act, &img);
136     lv_draw_wait_for_finish(draw_ctx);
137     lv_img_cache_invalidate_src(&img);
138 }
139 
lv_draw_sw_layer_destroy(lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx)140 void lv_draw_sw_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
141 {
142     LV_UNUSED(draw_ctx);
143 
144     lv_mem_free(layer_ctx->buf);
145 }
146 
147 
148 /**********************
149  *   STATIC FUNCTIONS
150  **********************/
151