1 /**
2 * @file lv_draw_pxp_fill.c
3 *
4 */
5
6 /**
7 * Copyright 2020-2024 NXP
8 *
9 * SPDX-License-Identifier: MIT
10 */
11
12 /*********************
13 * INCLUDES
14 *********************/
15
16 #include "lv_draw_pxp.h"
17
18 #if LV_USE_PXP
19 #if LV_USE_DRAW_PXP
20 #include "lv_pxp_cfg.h"
21 #include "lv_pxp_utils.h"
22
23 /*********************
24 * DEFINES
25 *********************/
26
27 /**********************
28 * TYPEDEFS
29 **********************/
30
31 /**********************
32 * STATIC PROTOTYPES
33 **********************/
34
35 static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
36 lv_color_format_t dest_cf, const lv_draw_fill_dsc_t * dsc);
37
38 /**********************
39 * STATIC VARIABLES
40 **********************/
41
42 /**********************
43 * MACROS
44 **********************/
45
46 /**********************
47 * GLOBAL FUNCTIONS
48 **********************/
49
lv_draw_pxp_fill(lv_draw_unit_t * draw_unit,const lv_draw_fill_dsc_t * dsc,const lv_area_t * coords)50 void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
51 const lv_area_t * coords)
52 {
53 if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
54 return;
55
56 lv_layer_t * layer = draw_unit->target_layer;
57 lv_draw_buf_t * draw_buf = layer->draw_buf;
58
59 lv_area_t rel_coords;
60 lv_area_copy(&rel_coords, coords);
61 lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1);
62
63 lv_area_t rel_clip_area;
64 lv_area_copy(&rel_clip_area, draw_unit->clip_area);
65 lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
66
67 lv_area_t blend_area;
68 if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
69 return; /*Fully clipped, nothing to do*/
70
71 _pxp_fill(draw_buf->data, &blend_area, draw_buf->header.stride, draw_buf->header.cf, dsc);
72 }
73
74 /**********************
75 * STATIC FUNCTIONS
76 **********************/
77
_pxp_fill(uint8_t * dest_buf,const lv_area_t * dest_area,int32_t dest_stride,lv_color_format_t dest_cf,const lv_draw_fill_dsc_t * dsc)78 static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
79 lv_color_format_t dest_cf, const lv_draw_fill_dsc_t * dsc)
80 {
81 int32_t dest_w = lv_area_get_width(dest_area);
82 int32_t dest_h = lv_area_get_height(dest_area);
83
84 lv_pxp_reset();
85
86 uint8_t px_size = lv_color_format_get_size(dest_cf);
87
88 /*OUT buffer configure*/
89 pxp_output_buffer_config_t outputConfig = {
90 .pixelFormat = pxp_get_out_px_format(dest_cf),
91 .interlacedMode = kPXP_OutputProgressive,
92 .buffer0Addr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + px_size * dest_area->x1),
93 .buffer1Addr = (uint32_t)NULL,
94 .pitchBytes = dest_stride,
95 .width = dest_w,
96 .height = dest_h
97 };
98
99 PXP_SetOutputBufferConfig(PXP_ID, &outputConfig);
100
101 if(dsc->opa >= (lv_opa_t)LV_OPA_MAX) {
102 /*Simple color fill without opacity - AS disabled*/
103 PXP_SetAlphaSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
104
105 }
106 else {
107 /*Fill with opacity - AS used as source (same as OUT)*/
108 pxp_as_buffer_config_t asBufferConfig = {
109 .pixelFormat = pxp_get_as_px_format(dest_cf),
110 .bufferAddr = outputConfig.buffer0Addr,
111 .pitchBytes = outputConfig.pitchBytes
112 };
113
114 PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
115 PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
116 }
117
118 /*Disable PS, use as color generator*/
119 PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
120 PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to_u32(dsc->color));
121
122 /**
123 * Configure Porter-Duff blending - src settings are unused for fill without opacity (opa = 0xff).
124 *
125 * Note: srcFactorMode and dstFactorMode are inverted in fsl_pxp.h:
126 * srcFactorMode is actually applied on PS alpha value
127 * dstFactorMode is actually applied on AS alpha value
128 */
129 pxp_porter_duff_config_t pdConfig = {
130 .enable = 1,
131 .dstColorMode = kPXP_PorterDuffColorNoAlpha,
132 .srcColorMode = kPXP_PorterDuffColorNoAlpha,
133 .dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha,
134 .srcGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha,
135 .dstFactorMode = kPXP_PorterDuffFactorStraight,
136 .srcFactorMode = (dsc->opa >= (lv_opa_t)LV_OPA_MAX) ? kPXP_PorterDuffFactorStraight : kPXP_PorterDuffFactorInversed,
137 .dstGlobalAlpha = dsc->opa,
138 .srcGlobalAlpha = dsc->opa,
139 .dstAlphaMode = kPXP_PorterDuffAlphaStraight, /*don't care*/
140 .srcAlphaMode = kPXP_PorterDuffAlphaStraight /*don't care*/
141 };
142
143 PXP_SetPorterDuffConfig(PXP_ID, &pdConfig);
144
145 lv_pxp_run();
146 }
147
148 #endif /*LV_USE_DRAW_PXP*/
149 #endif /*LV_USE_PXP*/
150