1 /*
2 * Copyright 2019-2023 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_lcdifv2.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.lcdifv2"
18 #endif
19
20 #define LCDIFV2_LUT_MEM(base) \
21 ((volatile uint32_t *)(((uint32_t)(base)) + (uint32_t)FSL_FEATURE_LCDIFV2_CLUT_RAM_OFFSET))
22
23 /*******************************************************************************
24 * Prototypes
25 ******************************************************************************/
26
27 /*!
28 * @brief Get instance number for LCDIF module.
29 *
30 * @param base LCDIF peripheral base address
31 */
32 static uint32_t LCDIFV2_GetInstance(const LCDIFV2_Type *base);
33
34 /*!
35 * @brief Reset register value to default status.
36 *
37 * @param base LCDIF peripheral base address
38 */
39 static void LCDIFV2_ResetRegister(LCDIFV2_Type *base);
40
41 /*******************************************************************************
42 * Variables
43 ******************************************************************************/
44
45 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
46 /*! @brief Pointers to LCDIF clock for each instance. */
47 static const clock_ip_name_t s_lcdifv2Clocks[] = LCDIFV2_CLOCKS;
48 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
49
50 /*******************************************************************************
51 * Codes
52 ******************************************************************************/
LCDIFV2_GetInstance(const LCDIFV2_Type * base)53 static uint32_t LCDIFV2_GetInstance(const LCDIFV2_Type *base)
54 {
55 static LCDIFV2_Type *const s_lcdifv2Bases[] = LCDIFV2_BASE_PTRS;
56
57 uint32_t instance;
58
59 /* Find the instance index from base address mappings. */
60 for (instance = 0; instance < ARRAY_SIZE(s_lcdifv2Bases); instance++)
61 {
62 if (s_lcdifv2Bases[instance] == base)
63 {
64 break;
65 }
66 }
67
68 assert(instance < ARRAY_SIZE(s_lcdifv2Bases));
69
70 return instance;
71 }
72
LCDIFV2_ResetRegister(LCDIFV2_Type * base)73 static void LCDIFV2_ResetRegister(LCDIFV2_Type *base)
74 {
75 uint32_t i;
76
77 base->DISP_PARA = 0U;
78 base->CTRL = 0x80000000U;
79 base->DISP_SIZE = 0U;
80 base->HSYN_PARA = 0x00C01803U;
81 base->VSYN_PARA = 0x00C01803U;
82 base->INT[0].INT_ENABLE = 0U;
83 base->INT[1].INT_ENABLE = 0U;
84
85 for (i = 0; i < (uint32_t)LCDIFV2_LAYER_COUNT; i++)
86 {
87 base->LAYER[i].CTRLDESCL5 = 0U;
88 base->LAYER[i].CTRLDESCL1 = 0U;
89 base->LAYER[i].CTRLDESCL2 = 0U;
90 base->LAYER[i].CTRLDESCL3 = 0U;
91 base->LAYER[i].CTRLDESCL4 = 0U;
92 base->LAYER[i].CTRLDESCL6 = 0U;
93 }
94
95 for (i = 0; i < (uint32_t)LCDIFV2_LAYER_CSC_COUNT; i++)
96 {
97 base->LAYER[i].CSC_COEF0 = 0x04000000U;
98 base->LAYER[i].CSC_COEF1 = 0x01230208U;
99 base->LAYER[i].CSC_COEF2 = 0x076B079CU;
100 }
101
102 /* Clear interrupt status. */
103 base->INT[0].INT_STATUS = 0xFFFFFFFFU;
104 base->INT[1].INT_STATUS = 0xFFFFFFFFU;
105 }
106
107 /*!
108 * brief Initializes the LCDIF v2.
109 *
110 * This function ungates the LCDIF v2 clock and release the peripheral reset.
111 *
112 * param base LCDIF v2 peripheral base address.
113 */
LCDIFV2_Init(LCDIFV2_Type * base)114 void LCDIFV2_Init(LCDIFV2_Type *base)
115 {
116 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
117 uint32_t instance = LCDIFV2_GetInstance(base);
118 /* Enable the clock. */
119 CLOCK_EnableClock(s_lcdifv2Clocks[instance]);
120 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
121
122 LCDIFV2_ResetRegister(base);
123
124 /* Out of reset. */
125 base->CTRL = 0U;
126 }
127
128 /*!
129 * brief Deinitializes the LCDIF peripheral.
130 *
131 * param base LCDIF peripheral base address.
132 */
LCDIFV2_Deinit(LCDIFV2_Type * base)133 void LCDIFV2_Deinit(LCDIFV2_Type *base)
134 {
135 LCDIFV2_ResetRegister(base);
136
137 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
138 uint32_t instance = LCDIFV2_GetInstance(base);
139 /* Disable the clock. */
140 CLOCK_DisableClock(s_lcdifv2Clocks[instance]);
141 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
142 }
143
144 /*!
145 * brief Reset the LCDIF v2.
146 *
147 * param base LCDIF peripheral base address.
148 */
LCDIFV2_Reset(LCDIFV2_Type * base)149 void LCDIFV2_Reset(LCDIFV2_Type *base)
150 {
151 LCDIFV2_ResetRegister(base);
152
153 /* Release and ready to work. */
154 base->CTRL = 0U;
155 }
156
157 /*!
158 * brief Gets the LCDIF display default configuration structure.
159 *
160 * param config Pointer to the LCDIF configuration structure.
161 */
LCDIFV2_DisplayGetDefaultConfig(lcdifv2_display_config_t * config)162 void LCDIFV2_DisplayGetDefaultConfig(lcdifv2_display_config_t *config)
163 {
164 assert(NULL != config);
165
166 config->panelWidth = 0U;
167 config->panelHeight = 0U;
168 config->hsw = 3U;
169 config->hfp = 3U;
170 config->hbp = 3U;
171 config->vsw = 3U;
172 config->vfp = 3U;
173 config->vbp = 3U;
174 config->polarityFlags = (uint32_t)kLCDIFV2_VsyncActiveHigh | (uint32_t)kLCDIFV2_HsyncActiveHigh |
175 (uint32_t)kLCDIFV2_DataEnableActiveHigh | (uint32_t)kLCDIFV2_DriveDataOnRisingClkEdge |
176 (uint32_t)kLCDIFV2_DataActiveHigh;
177 config->lineOrder = kLCDIFV2_LineOrderRGB;
178 }
179
180 /*!
181 * brief Set the LCDIF v2 display configurations.
182 *
183 * param base LCDIF peripheral base address.
184 * param config Pointer to the LCDIF configuration structure.
185 */
LCDIFV2_SetDisplayConfig(LCDIFV2_Type * base,const lcdifv2_display_config_t * config)186 void LCDIFV2_SetDisplayConfig(LCDIFV2_Type *base, const lcdifv2_display_config_t *config)
187 {
188 assert(NULL != config);
189
190 /* Configure the parameters. */
191 base->DISP_SIZE = ((uint32_t)config->panelWidth << LCDIFV2_DISP_SIZE_DELTA_X_SHIFT) |
192 ((uint32_t)config->panelHeight << LCDIFV2_DISP_SIZE_DELTA_Y_SHIFT);
193
194 base->HSYN_PARA = ((uint32_t)config->hsw << LCDIFV2_HSYN_PARA_PW_H_SHIFT) |
195 ((uint32_t)config->hbp << LCDIFV2_HSYN_PARA_BP_H_SHIFT) |
196 ((uint32_t)config->hfp << LCDIFV2_HSYN_PARA_FP_H_SHIFT);
197
198 base->VSYN_PARA = ((uint32_t)config->vsw << LCDIFV2_VSYN_PARA_PW_V_SHIFT) |
199 ((uint32_t)config->vbp << LCDIFV2_VSYN_PARA_BP_V_SHIFT) |
200 ((uint32_t)config->vfp << LCDIFV2_VSYN_PARA_FP_V_SHIFT);
201
202 base->DISP_PARA = LCDIFV2_DISP_PARA_LINE_PATTERN((uint32_t)config->lineOrder);
203
204 base->CTRL = (uint32_t)(config->polarityFlags);
205 }
206
207 /*!
208 * brief Set the color space conversion mode.
209 *
210 * Supports YUV2RGB and YCbCr2RGB.
211 *
212 * param base LCDIFv2 peripheral base address.
213 * param layerIndex Index of the layer.
214 * param mode The conversion mode.
215 */
LCDIFV2_SetCscMode(LCDIFV2_Type * base,uint8_t layerIndex,lcdifv2_csc_mode_t mode)216 void LCDIFV2_SetCscMode(LCDIFV2_Type *base, uint8_t layerIndex, lcdifv2_csc_mode_t mode)
217 {
218 assert(layerIndex < (uint32_t)LCDIFV2_LAYER_CSC_COUNT);
219
220 /*
221 * The equations used for Colorspace conversion are:
222 *
223 * R = C0*(Y+Y_OFFSET) + C1(V+UV_OFFSET)
224 * G = C0*(Y+Y_OFFSET) + C3(U+UV_OFFSET) + C2(V+UV_OFFSET)
225 * B = C0*(Y+Y_OFFSET) + C4(U+UV_OFFSET)
226 */
227
228 if (kLCDIFV2_CscYUV2RGB == mode)
229 {
230 base->LAYER[layerIndex].CSC_COEF0 = LCDIFV2_CSC_COEF0_ENABLE_MASK | LCDIFV2_CSC_COEF0_C0(0x100U) /* 1.00. */
231 | LCDIFV2_CSC_COEF0_Y_OFFSET(0x0U) /* 0. */
232 | LCDIFV2_CSC_COEF0_UV_OFFSET(0x0U); /* 0. */
233
234 base->LAYER[layerIndex].CSC_COEF1 = LCDIFV2_CSC_COEF1_C1(0x0123U) /* 1.140. */
235 | LCDIFV2_CSC_COEF1_C4(0x0208U); /* 2.032. */
236 base->LAYER[layerIndex].CSC_COEF2 = LCDIFV2_CSC_COEF2_C2(0x076BU) /* -0.851. */
237 | LCDIFV2_CSC_COEF2_C3(0x079BU); /* -0.394. */
238 }
239 else if (kLCDIFV2_CscYCbCr2RGB == mode)
240 {
241 base->LAYER[layerIndex].CSC_COEF0 = LCDIFV2_CSC_COEF0_ENABLE_MASK | LCDIFV2_CSC_COEF0_YCBCR_MODE_MASK |
242 LCDIFV2_CSC_COEF0_C0(0x12AU) /* 1.164. */
243 | LCDIFV2_CSC_COEF0_Y_OFFSET(0x1F0U) /* -16. */
244 | LCDIFV2_CSC_COEF0_UV_OFFSET(0x180U); /* -128. */
245 base->LAYER[layerIndex].CSC_COEF1 = LCDIFV2_CSC_COEF1_C1(0x0198U) /* 1.596. */
246 | LCDIFV2_CSC_COEF1_C4(0x0204U); /* 2.017. */
247 base->LAYER[layerIndex].CSC_COEF2 = LCDIFV2_CSC_COEF2_C2(0x0730U) /* -0.813. */
248 | LCDIFV2_CSC_COEF2_C3(0x079CU); /* -0.392. */
249 }
250 else
251 {
252 base->LAYER[layerIndex].CSC_COEF0 = 0U;
253 base->LAYER[layerIndex].CSC_COEF1 = 0U;
254 base->LAYER[layerIndex].CSC_COEF2 = 0U;
255 }
256 }
257
258 /*!
259 * brief Set the layer source buffer configuration.
260 *
261 * param base LCDIFv2 peripheral base address.
262 * param layerIndex Layer layerIndex.
263 * param config Pointer to the configuration.
264 */
LCDIFV2_SetLayerBufferConfig(LCDIFV2_Type * base,uint8_t layerIndex,const lcdifv2_buffer_config_t * config)265 void LCDIFV2_SetLayerBufferConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_buffer_config_t *config)
266 {
267 assert(NULL != config);
268 uint32_t reg;
269
270 base->LAYER[layerIndex].CTRLDESCL3 = config->strideBytes;
271
272 reg = base->LAYER[layerIndex].CTRLDESCL5;
273 reg = (reg & ~(LCDIFV2_CTRLDESCL5_BPP_MASK | LCDIFV2_CTRLDESCL5_YUV_FORMAT_MASK)) | (uint32_t)config->pixelFormat;
274
275 if (0U == (reg & LCDIFV2_CTRLDESCL5_AB_MODE_MASK))
276 {
277 reg |= LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK;
278 }
279
280 base->LAYER[layerIndex].CTRLDESCL5 = reg;
281 }
282
283 /*!
284 * brief Set the LUT data.
285 *
286 * This function sets the specific layer LUT data, if useShadowLoad is true,
287 * call LCDIFV2_TriggerLayerShadowLoad after this function, the
288 * LUT will be loaded to the hardware during next vertical blanking period.
289 * If useShadowLoad is false, the LUT data is loaded to hardware directly.
290 *
291 * param base LCDIF v2 peripheral base address.
292 * param layerIndex Which layer to set.
293 * param lutData The LUT data to load.
294 * param count Count of lutData.
295 * retval kStatus_Success Set success.
296 * retval kStatus_Fail Previous LUT data is not loaded to hardware yet.
297 */
LCDIFV2_SetLut(LCDIFV2_Type * base,uint8_t layerIndex,const uint32_t * lutData,uint16_t count,bool useShadowLoad)298 status_t LCDIFV2_SetLut(
299 LCDIFV2_Type *base, uint8_t layerIndex, const uint32_t *lutData, uint16_t count, bool useShadowLoad)
300 {
301 assert(count <= LCDIFV2_LUT_ENTRY_NUM);
302
303 uint16_t i;
304 status_t status;
305
306 /* Previous setting is not updated. */
307 if ((base->CLUT_LOAD & LCDIFV2_CLUT_LOAD_CLUT_UPDATE_EN_MASK) != 0U)
308 {
309 status = kStatus_Fail;
310 }
311 else
312 {
313 if (useShadowLoad)
314 {
315 base->CLUT_LOAD = LCDIFV2_CLUT_LOAD_SEL_CLUT_NUM(layerIndex) | LCDIFV2_CLUT_LOAD_CLUT_UPDATE_EN_MASK;
316 }
317 else
318 {
319 base->CLUT_LOAD = LCDIFV2_CLUT_LOAD_SEL_CLUT_NUM(layerIndex);
320 }
321
322 for (i = 0; i < count; i++)
323 {
324 (LCDIFV2_LUT_MEM(base))[i + (LCDIFV2_LUT_ENTRY_NUM * layerIndex)] = lutData[i];
325 }
326
327 status = kStatus_Success;
328 }
329
330 return status;
331 }
332
333 /*!
334 * brief Set the layer alpha blend mode.
335 *
336 * param base LCDIFv2 peripheral base address.
337 * param layerIndex Index of the CSC unit.
338 * param config Pointer to the blend configuration.
339 */
LCDIFV2_SetLayerBlendConfig(LCDIFV2_Type * base,uint8_t layerIndex,const lcdifv2_blend_config_t * config)340 void LCDIFV2_SetLayerBlendConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_blend_config_t *config)
341 {
342 assert(NULL != config);
343
344 uint32_t reg;
345
346 reg = base->LAYER[layerIndex].CTRLDESCL5;
347 reg &= ~(LCDIFV2_CTRLDESCL5_GLOBAL_ALPHA_MASK | LCDIFV2_CTRLDESCL5_AB_MODE_MASK |
348 LCDIFV2_CTRLDESCL5_PD_FACTOR_MODE_MASK | LCDIFV2_CTRLDESCL5_PD_ALPHA_MODE_MASK |
349 LCDIFV2_CTRLDESCL5_PD_COLOR_MODE_MASK | LCDIFV2_CTRLDESCL5_PD_GLOBAL_ALPHA_MODE_MASK |
350 LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK);
351
352 reg |=
353 (LCDIFV2_CTRLDESCL5_GLOBAL_ALPHA(config->globalAlpha) | LCDIFV2_CTRLDESCL5_AB_MODE(config->alphaMode) |
354 LCDIFV2_CTRLDESCL5_PD_FACTOR_MODE(config->pdFactorMode) |
355 LCDIFV2_CTRLDESCL5_PD_ALPHA_MODE(config->pdAlphaMode) | LCDIFV2_CTRLDESCL5_PD_COLOR_MODE(config->pdColorMode) |
356 LCDIFV2_CTRLDESCL5_PD_GLOBAL_ALPHA_MODE(config->pdGlobalAlphaMode));
357
358 if (config->alphaMode == kLCDIFV2_AlphaDisable)
359 {
360 reg |= LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK;
361 }
362
363 base->LAYER[layerIndex].CTRLDESCL5 = reg;
364 }
365
366 /*
367 * brief Get the blend configuration for Porter Duff blend.
368 *
369 * This is the basic Porter Duff blend configuration, user still could
370 * modify the configurations after this function.
371 *
372 * param mode Porter Duff blend mode.
373 * param layer The configuration for source layer or destination layer.
374 * param config Pointer to the configuration.
375 * retval kStatus_Success Get the configuration successfully.
376 * retval kStatus_InvalidArgument The argument is invalid.
377 */
LCDIFV2_GetPorterDuffConfig(lcdifv2_pd_blend_mode_t mode,lcdifv2_pd_layer_t layer,lcdifv2_blend_config_t * config)378 status_t LCDIFV2_GetPorterDuffConfig(lcdifv2_pd_blend_mode_t mode,
379 lcdifv2_pd_layer_t layer,
380 lcdifv2_blend_config_t *config)
381 {
382 static const lcdifv2_pd_factor_mode_t s_lcdifv2PdLayerFactors[][2] = {
383 /* kLCDIFV2_PD_Src */
384 {
385 /* s1_s0_factor_mode. */
386 kLCDIFV2_PD_FactorZero,
387
388 /* s0_s1_factor_mode. */
389 kLCDIFV2_PD_FactorOne,
390 },
391
392 /* kLCDIFV2_PD_Atop */
393 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorStraightAlpha},
394
395 /* kLCDIFV2_PD_Over */
396 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorOne},
397
398 /* kLCDIFV2_PD_In */
399 {kLCDIFV2_PD_FactorZero, kLCDIFV2_PD_FactorStraightAlpha},
400
401 /* kLCDIFV2_PD_Out */
402 {kLCDIFV2_PD_FactorZero, kLCDIFV2_PD_FactorInversedAlpha},
403
404 /* kLCDIFV2_PD_Dst */
405 {kLCDIFV2_PD_FactorOne, kLCDIFV2_PD_FactorZero},
406
407 /* kLCDIFV2_PD_DstAtop */
408 {kLCDIFV2_PD_FactorStraightAlpha, kLCDIFV2_PD_FactorInversedAlpha},
409
410 /* kLCDIFV2_PD_DstOver */
411 {kLCDIFV2_PD_FactorOne, kLCDIFV2_PD_FactorInversedAlpha},
412
413 /* kLCDIFV2_PD_DstIn */
414 {kLCDIFV2_PD_FactorStraightAlpha, kLCDIFV2_PD_FactorZero},
415
416 /* kLCDIFV2_PD_DstOut */
417 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorZero},
418
419 /* kLCDIFV2_PD_Xor */
420 {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorInversedAlpha},
421
422 /* kLCDIFV2_PD_Clear */
423 {
424 kLCDIFV2_PD_FactorZero,
425 kLCDIFV2_PD_FactorZero,
426 },
427 };
428
429 status_t status;
430
431 if ((NULL == config) || (mode >= kLCDIFV2_PD_Max) || (layer >= kLCDIFV2_PD_LayerMax))
432 {
433 status = kStatus_InvalidArgument;
434 }
435 else
436 {
437 config->pdAlphaMode = kLCDIFV2_PD_AlphaStraight;
438 config->pdColorMode = kLCDIFV2_PD_ColorWithAlpha;
439 config->pdGlobalAlphaMode = kLCDIFV2_PD_LocalAlpha;
440 config->pdFactorMode = s_lcdifv2PdLayerFactors[mode][(uint8_t)layer];
441 config->alphaMode = kLCDIFV2_AlphaPoterDuff;
442
443 status = kStatus_Success;
444 }
445
446 return status;
447 }
448
449 /*
450 * brief Get the global alpha values for multiple layer blend.
451 *
452 * When all layers use the global alpha, the relationship blended alpha
453 * and global alpha of each layer is:
454 *
455 * Layer 7: ba7 = ga7
456 * Layer 6: ba6 = ga6 * (1-ga7)
457 * Layer 5: ba5 = ga5 * (1-ga6) * (1-ga7)
458 * Layer 4: ba4 = ga4 * (1-ga5) * (1-ga6) * (1-ga7)
459 * Layer 3: ba3 = ga3 * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
460 * Layer 2: ba2 = ga2 * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
461 * Layer 1: ba1 = ga1 * (1-ga2) * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
462 * Layer 0: ba0 = 1 * (1-ga1) * (1-ga2) * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
463 *
464 * Here baN is the blended alpha of layer N, gaN is the global alpha configured to layer N.
465 *
466 * This function calculates the global alpha based on the blended alpha. The blendedAlpha and
467 * globalAlpha are all arrays of size layerCount. The first layer is a background layer,
468 * so blendedAlpha[0] is useless, globalAlpha[0] is always 255.
469 *
470 * param blendedAlpha The desired blended alpha value, alpha range 0~255.
471 * param globalAlpha Calculated global alpha set to each layer register.
472 * param layerCount Total layer count.
473 * retval kStatus_Success Get successfully.
474 * retval kStatus_InvalidArgument The argument is invalid.
475 */
LCDIFV2_GetMultiLayerGlobalAlpha(const uint8_t blendedAlpha[],uint8_t globalAlpha[],uint8_t layerCount)476 status_t LCDIFV2_GetMultiLayerGlobalAlpha(const uint8_t blendedAlpha[], uint8_t globalAlpha[], uint8_t layerCount)
477 {
478 status_t status = kStatus_Success;
479 int16_t curLayer = (int16_t)layerCount - 1;
480 int left = 255;
481 int tmpAlpha;
482
483 assert((layerCount > 1U) && (layerCount <= (uint8_t)LCDIFV2_LAYER_COUNT));
484
485 /*
486 * Assume the layer counter is 7, and alpha range is 0~1, define:
487 *
488 * left_7 = 1
489 * left_i = (1-ga_(i+1)) * ... * (1-ga7)
490 *
491 * Then:
492 * ba_i = ga_i * left_i
493 * left_i = left_(i+1) - ba_i
494 * ga_i = ba_i / left_i
495 *
496 * Now change alpha range to 0~255, then:
497 *
498 * ga_i = ba_i * 255 / left_i
499 * left_i = left_(i+1) - ba_i
500 */
501
502 globalAlpha[0] = 255U;
503
504 while (curLayer > 0)
505 {
506 tmpAlpha = (int)blendedAlpha[curLayer] * 255 / left;
507 if (tmpAlpha > 255)
508 {
509 status = kStatus_InvalidArgument;
510 break;
511 }
512
513 globalAlpha[curLayer] = (uint8_t)tmpAlpha;
514 left -= (int)blendedAlpha[curLayer];
515
516 if (left <= 0)
517 {
518 status = kStatus_InvalidArgument;
519 break;
520 }
521
522 curLayer--;
523 }
524
525 return status;
526 }
527