Arm-2D  
2D Image Processing Library for Cortex-M Processors
 
Loading...
Searching...
No Matches
arm_2d_helper_pfb.h
1/*
2 * Copyright (C) 2024 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: Arm-2D Library
21 * Title: #include "arm_2d_helper_pfb.h"
22 * Description: Public header file for the PFB helper service
23 *
24 * $Date: 22. August 2025
25 * $Revision: V.2.2.3
26 *
27 * Target Processor: Cortex-M cores
28 * -------------------------------------------------------------------- */
29
30#ifndef __ARM_2D_HELPER_PFB_H__
31#define __ARM_2D_HELPER_PFB_H__
32
33/*============================ INCLUDES ======================================*/
34#include "arm_2d.h"
35
36#include "./__arm_2d_helper_common.h"
37#include <stdint.h>
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43
44#if defined(__clang__)
45# pragma clang diagnostic push
46# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
47# pragma clang diagnostic ignored "-Wmissing-declarations"
48# pragma clang diagnostic ignored "-Wpadded"
49#endif
50
51/* OOC header, please DO NOT modify */
52#ifdef __ARM_2D_HELPER_PFB_IMPLEMENT__
53# define __ARM_2D_IMPL__
54# undef __ARM_2D_HELPER_PFB_IMPLEMENT__
55#elif defined(__ARM_2D_HELPER_PFB_INHERIT__)
56# undef __ARM_2D_HELPER_PFB_INHERIT__
57# define __ARM_2D_INHERIT__
58#endif
59#include "arm_2d_utils.h"
60
61
62
63/*============================ MACROS ========================================*/
64
65/*!
66 * \addtogroup Deprecated
67 * @{
68 */
69
70#define arm_2d_helper_ignore_low_level_flush arm_2d_helper_pfb_ignore_low_level_flush
71#define arm_2d_helper_resume_low_level_flush arm_2d_helper_pfb_resume_low_level_flush
72
73/*! @} */
74
75/*!
76 * \addtogroup gHelper 8 Helper Services
77 * @{
78 */
79#define ARM_2D_FPS_MODE_RENDER_ONLY 0
80#define ARM_2D_FPS_MODE_REAL 1
81
82/*============================ MACROFIED FUNCTIONS ===========================*/
83
84/*!
85 * \brief a macro wrapper in uppercase to help initialising PFB service
86 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
87 * \param[in] __SCREEN_WIDTH the width of the screen
88 * \param[in] __SCREEN_HEIGHT the hight of the screen
89 * \param[in] __PIXEL_TYPE the integer type of the pixel, i.e. uint8_t, uint16_t,
90 * uint32_t
91 * \param[in] __COLOUR_FORMAT the screen colour format, i.e. ARM_2D_COLOUR_CCCN888,
92 * ARM_2D_COLOUR_RGB565 etc.
93 * \param[in] __WIDTH the width of the PFB block
94 * \param[in] __HEIGHT the height of the PFB block
95 * \note For the same number of pixels in a PFB block, please priority the width
96 * over height, for example, 240 * 1 is better than 30 * 8
97 * \param[in] __PFB_NUM the number of PFB blocks in the built-in PFB pool.
98 * \param[in] ... a code block to add additional initializer, see example below:
99 * \return arm_2d_err_t the result of the initialisation process
100 *
101 * \code {.c}
102
103 static ARM_NOINIT arm_2d_helper_pfb_t s_tExamplePFB;
104 ...
105 // initialise FPB helper
106 if (ARM_2D_HELPER_PFB_INIT(
107 &s_tExamplePFB, // FPB Helper object
108 __GLCD_CFG_SCEEN_WIDTH__, // screen width
109 __GLCD_CFG_SCEEN_HEIGHT__, // screen height
110 uint16_t, // colour date type
111 ARM_2D_COLOUR_RGB565, // colour format
112 240, // PFB block width
113 1, // PFB block height
114 1, // number of PFB in the PFB pool
115 {
116 .evtOnLowLevelRendering = {
117 // callback for low level rendering
118 .fnHandler = &__pfb_render_handler,
119 },
120 .evtOnDrawing = {
121 // callback for drawing GUI
122 .fnHandler = &__pfb_draw_background_handler,
123 },
124 },
125 //.FrameBuffer.bSwapRGB16 = true,
126 ) < 0) {
127 //! error detected
128 assert(false);
129 }
130 * \endcode
131 *
132 */
133#define ARM_2D_HELPER_PFB_INIT( __CB_ADDR, /* PFB Helper object address */ \
134 __SCREEN_WIDTH, /* Screen width */ \
135 __SCREEN_HEIGHT,/* Screen height */ \
136 __PIXEL_TYPE, /* The type of the pixels */ \
137 __COLOUR_FORMAT,/* the colour format */ \
138 __PFB_WIDTH, /* The width of the PFB block */\
139 __PFB_HEIGHT, /* The height of the PFB block*/\
140 __PFB_NUM, /* Block count in the PFB pool*/\
141 ... /* Event Handler */ \
142 ) \
143 ({ \
144 ARM_SECTION(".bss.noinit.arm_2d_pfb_pool") \
145 static struct { \
146 arm_2d_pfb_t tFPB; \
147 __ALIGNED(4) \
148 __PIXEL_TYPE tBuffer[(__PFB_WIDTH) * (__PFB_HEIGHT)]; \
149 } s_tPFBs[__PFB_NUM]; \
150 \
151 arm_2d_helper_pfb_cfg_t tCFG = { \
152 .tDisplayArea.tSize = { \
153 .iWidth = (__SCREEN_WIDTH), \
154 .iHeight = (__SCREEN_HEIGHT), \
155 }, \
156 \
157 .FrameBuffer.ptPFBs = (arm_2d_pfb_t *)s_tPFBs, \
158 .FrameBuffer.tFrameSize = { \
159 .iWidth = (__PFB_WIDTH), \
160 .iHeight = (__PFB_HEIGHT), \
161 }, \
162 .FrameBuffer.wBufferSize = sizeof(s_tPFBs[0].tBuffer), \
163 .FrameBuffer.u7ColourFormat = (__COLOUR_FORMAT), \
164 .FrameBuffer.u8PFBNum = dimof(s_tPFBs), \
165 .Dependency = \
166 __VA_ARGS__ \
167 }; \
168 \
169 arm_2d_helper_pfb_init((__CB_ADDR), &tCFG); \
170 })
171
172/*!
173 * \brief a macro wrapper to update the evtOnDrawring event handler
174 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
175 * \param[in] __HANDLER the new handler
176 * \param[in] ... [Optional] an address (of user defined structure) passed to the
177 * event handler.
178 * \return arm_2d_err_t the process result
179 */
180#define ARM_2D_HELPER_PFB_UPDATE_ON_DRAW_HANDLER( \
181 __CB_ADDR, /* PFB Helper object address */ \
182 __HANDLER, /* new on-draw-handler function*/\
183 ...) /* An optional target address */ \
184 arm_2d_helper_pfb_update_dependency((__CB_ADDR), \
185 ARM_2D_PFB_DEPEND_ON_DRAWING, \
186 (arm_2d_helper_pfb_dependency_t []) {{ \
187 .evtOnDrawing = { \
188 .fnHandler = (__HANDLER), \
189 .pTarget = (NULL,##__VA_ARGS__),\
190 }, \
191 }})
192
193
194#define __IMPL_ARM_2D_REGION_LIST(__NAME, ...) \
195 enum { \
196 __NAME##_offset = __COUNTER__, \
197 }; \
198 __VA_ARGS__ \
199 arm_2d_region_list_item_t __NAME[] = {
200
201
202#define IMPL_ARM_2D_REGION_LIST(__NAME, ...) \
203 __IMPL_ARM_2D_REGION_LIST(__NAME,##__VA_ARGS__)
204
205
206#define END_IMPL_ARM_2D_REGION_LIST(...) \
207 }; \
208 /* In ANSI-C Standard, the local variable always hides a global */ \
209 /* of the same name as soon as it's declared. We use this feature */\
210 /* to provide a temporary fix for backward compatibility.*/ \
211 /* the following line should be removed in the future */ \
212 static const arm_2d_tile_t * const ptCurrentTile = NULL;
213
214#define __ADD_REGION_TO_LIST(__NAME, ...) \
215 { \
216 .ptNext = (arm_2d_region_list_item_t *) \
217 &(__NAME[__COUNTER__ - __NAME##_offset]), \
218 .tRegion = { \
219 __VA_ARGS__ \
220 }, \
221 }
222
223#define ADD_REGION_TO_LIST(__NAME, ...) \
224 __ADD_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
225
226
227#define __ADD_LAST_REGION_TO_LIST(__NAME, ...) \
228 { \
229 .ptNext = NULL, \
230 .tRegion = { \
231 __VA_ARGS__ \
232 }, \
233 }
234
235#define ADD_LAST_REGION_TO_LIST(__NAME, ...) \
236 __ADD_LAST_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
237
238
239#define IMPL_PFB_ON_DRAW(__NAME) IMPL_ON_DRAW_EVT(__NAME)
240
241
242#define IMPL_PFB_ON_LOW_LV_RENDERING(__NAME) \
243 void __NAME(void *pTarget, \
244 const arm_2d_pfb_t *ptPFB, \
245 bool bIsNewFrame)
246
247
248#define IMPL_PFB_ON_FRAME_SYNC_UP(__NAME) \
249 bool __NAME(void *pTarget)
250
251#define IMPL_PFB_BEFORE_FLUSHING(__NAME) \
252 bool __NAME(void *pTarget, \
253 arm_2d_pfb_t *ptOrigin, \
254 arm_2d_pfb_t *ptScratch)
255
256
257/*!
258 * \brief a macro wrapper in lowercase to help initialising PFB service
259 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
260 * \param[in] __SCREEN_WIDTH the width of the screen
261 * \param[in] __SCREEN_HEIGHT the hight of the screen
262 * \param[in] __PIXEL_TYPE the integer type of the pixel, i.e. uint8_t, uint16_t,
263 * uint32_t
264 * \param[in] __COLOUR_FORMAT the screen colour format, i.e. ARM_2D_COLOUR_CCCN888,
265 * ARM_2D_COLOUR_RGB565 etc.
266 * \param[in] __WIDTH the width of the PFB block
267 * \param[in] __HEIGHT the height of the PFB block
268 * \note For the same number of pixels in a PFB block, please priority the width
269 * over height, for example, 240 * 1 is better than 30 * 8
270 * \param[in] __PFB_NUM the number of PFB blocks in the built-in PFB pool.
271 * \param[in] ... a code block to add additional initializer, see example below:
272 * \return arm_2d_err_t the result of the initialisation process
273 *
274 * \code {.c}
275
276 static ARM_NOINIT arm_2d_helper_pfb_t s_tExamplePFB;
277 ...
278 // initialise FPB helper
279 if (init_arm_2d_helper_pfb(
280 &s_tExamplePFB, // FPB Helper object
281 __GLCD_CFG_SCEEN_WIDTH__, // screen width
282 __GLCD_CFG_SCEEN_HEIGHT__, // screen height
283 uint16_t, // colour date type
284 ARM_2D_COLOUR_RGB565, // colour format
285 240, // PFB block width
286 1, // PFB block height
287 1, // number of PFB in the PFB pool
288 {
289 .evtOnLowLevelRendering = {
290 // callback for low level rendering
291 .fnHandler = &__pfb_render_handler,
292 },
293 .evtOnDrawing = {
294 // callback for drawing GUI
295 .fnHandler = &__pfb_draw_background_handler,
296 },
297 },
298 //.FrameBuffer.bSwapRGB16 = true,
299 ) < 0) {
300 //! error detected
301 assert(false);
302 }
303 * \endcode
304 *
305 */
306#define init_arm_2d_helper_pfb( __CB_ADDR, \
307 __SCREEN_WIDTH, \
308 __SCREEN_HEIGHT, \
309 __PIXEL_TYPE, \
310 __COLOUR_FORMAT, \
311 __WIDTH, \
312 __HEIGHT, \
313 __PFB_NUM, \
314 ... \
315 ) \
316 ARM_2D_HELPER_PFB_INIT( \
317 __CB_ADDR, \
318 __SCREEN_WIDTH, \
319 __SCREEN_HEIGHT, \
320 __PIXEL_TYPE, \
321 __COLOUR_FORMAT, \
322 __WIDTH, \
323 __HEIGHT, \
324 __PFB_NUM, \
325 ##__VA_ARGS__ \
326 )
327
328/*!
329 * \brief a macro wrapper to update the evtOnDrawring event handler
330 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
331 * \param[in] __HANDLER the new handler
332 * \param[in] ... [Optional] an address (of user defined structure) passed to the
333 * event handler.
334 * \return arm_2d_err_t the process result
335 */
336#define update_arm_2d_helper_pfb_on_draw_handler( \
337 __CB_ADDR, /* PFB Helper object address */ \
338 __HANDLER, /* new on-draw-handler function*/\
339 ...) /* An optional target address */ \
340 ARM_2D_HELPER_PFB_UPDATE_ON_DRAW_HANDLER( \
341 (__CB_ADDR), \
342 (__HANDLER),##__VA_ARGRS__)
343
344/*!
345 * \brief tell PFB helper that a low level LCD flushing work is complete
346 * \note This function is THREAD-SAFE, You can call this function asynchronously,
347 * e.g.
348 * - A ISR to indicate DMA-transfer complete event or
349 * - A different Thread
350 * \param[in] ptThis the PFB helper control block
351 * \param[in] ... the used PFB block.
352 * \note please do not use this parameter, it is only kept for backward
353 * compatability.
354 */
355#define arm_2d_helper_pfb_report_rendering_complete(__PFB_HELPER_PTR,...) \
356 __arm_2d_helper_pfb_report_rendering_complete((__PFB_HELPER_PTR), \
357 (NULL,##__VA_ARGS__))
358
359
360#define __arm_2d_helper_dirty_region_update_dirty_regions0 \
361 __arm_2d_helper_dirty_region_update_dirty_regions
362
363/*!
364 * \brief update a specified new region while erase the previous region
365 *
366 * \param[in] ptThis the target helper
367 * \param[in] ptTargetTile the target tile to draw content
368 * \param[in] ptVisibleArea a visible region in the target tile used to clip
369 * the ptNewRegion, NULL means no clipping.
370 * \param[in] ptNewRegion the new region to update, NULL means nothing
371 * to update
372 * \param[in] bIsNewFrame unused, keep for backward compatibility
373 */
374#define __arm_2d_helper_dirty_region_update_dirty_regions3( __helper_ptr, \
375 __tile_ptr, \
376 __visible_area_ptr, \
377 __new_region_ptr, \
378 __is_new_frame) \
379 __arm_2d_helper_dirty_region_update_dirty_regions2( \
380 (__helper_ptr), \
381 (__tile_ptr), \
382 (__visible_area_ptr), \
383 (__new_region_ptr))
384
385/*!
386 * \brief update a specified new region while erase the previous region
387 *
388 * \param[in] ptThis the target helper
389 * \param[in] ptTargetTile the target tile to draw content
390 * \param[in] ptNewRegion the new region to update, NULL means nothing
391 * to update
392 */
393#define __arm_2d_helper_dirty_region_update_dirty_regions1( __helper_ptr, \
394 __tile_ptr, \
395 __new_region_ptr) \
396 __arm_2d_helper_dirty_region_update_dirty_regions2( \
397 (__helper_ptr), \
398 (__tile_ptr), \
399 NULL, \
400 (__new_region_ptr))
401
402
403/*!
404 * \brief update a specified new region while erase the previous region
405 *
406 * \param[in] __helper_ptr the target helper
407 * \param[in] __tile_ptr the target tile to draw content
408 * \param[in] ... optional parameters, and the following combinations are valid:
409 * a. new region ptr
410 * b. the canvas ptr and the new region ptr
411 * c. the canvas ptr, the new region ptr and a reserved option
412 * (bIsNewFrame)
413 */
414#define arm_2d_helper_dirty_region_update_dirty_regions( __helper_ptr, \
415 __tile_ptr, \
416 ...) \
417 ARM_CONNECT2(__arm_2d_helper_dirty_region_update_dirty_regions, \
418 __ARM_VA_NUM_ARGS(__VA_ARGS__))((__helper_ptr), \
419 (__tile_ptr) \
420 ,##__VA_ARGS__)
421
422/*!
423 * \brief update a specified new region while erase the previous region
424 *
425 * \param[in] __item_ptr the target region item
426 * \param[in] __target_tile_ptr the target tile to draw content
427 * \param[in] __visible_region_ptr a visible region in the target tile used to clip
428 * the ptNewRegion, NULL means no clipping.
429 * \param[in] __new_region_ptr the new region to update, NULL means nothing
430 * to update
431 */
432#define __arm_2d_helper_dirty_region_update_item4( __item_ptr, \
433 __target_tile_ptr, \
434 __visible_region_ptr, \
435 __new_region_ptr) \
436 __arm_2d_helper_dirty_region_item_update((__item_ptr), \
437 (__target_tile_ptr), \
438 (__visible_region_ptr), \
439 (__new_region_ptr))
440
441/*!
442 * \brief deprecated
443 *
444 */
445#define __arm_2d_helper_dirty_region_update_item5( __dirty_region_helper_ptr, \
446 __item_ptr, \
447 __target_tile_ptr, \
448 __visible_region_ptr, \
449 __new_region_ptr) \
450 __arm_2d_helper_dirty_region_item_update((__item_ptr), \
451 (__target_tile_ptr), \
452 (__visible_region_ptr), \
453 (__new_region_ptr))
454
455#define arm_2d_helper_dirty_region_update_item(...) \
456 ARM_CONNECT2( __arm_2d_helper_dirty_region_update_item, \
457 __ARM_VA_NUM_ARGS(__VA_ARGS__) \
458 )(__VA_ARGS__)
459
460
461#define arm_2d_helper_pfb_is_region_active( __target_tile_ptr, \
462 __target_region_ptr, \
463 __consider_dry_run, \
464 ...) \
465 ARM_CONNECT2( __arm_2d_helper_pfb_is_region_active, \
466 __ARM_VA_NUM_ARGS(__VA_ARGS__))( \
467 (__target_tile_ptr), \
468 (__target_region_ptr), \
469 (__consider_dry_run),##__VA_ARGS__)
470
471#define arm_2d_helper_dirty_region_transform_update_value( __HELPER_PTR, \
472 __ANGLE, \
473 __SCALE, \
474 ...) \
475 ARM_CONNECT2( __arm_2d_helper_dirty_region_transform_update_value,\
476 __ARM_VA_NUM_ARGS(__VA_ARGS__))((__HELPER_PTR), \
477 (__ANGLE), \
478 __SCALE, \
479 ##__VA_ARGS__)
480
481#define impl_arm_2d_region_list(__NAME, ...) \
482 IMPL_ARM_2D_REGION_LIST(__NAME,##__VA_ARGS__)
483#define add_region_to_list(__NAME, ...) \
484 ADD_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
485#define add_last_region_to_list(__NAME, ...) \
486 ADD_LAST_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
487#define end_impl_arm_2d_region_list(...) \
488 END_IMPL_ARM_2D_REGION_LIST(__VA_ARGS__)
489
490#define impl_pfb_on_draw(__NAME) IMPL_PFB_ON_DRAW(__NAME)
491#define impl_pfb_on_low_lv_rendering(__NAME) \
492 IMPL_PFB_ON_LOW_LV_RENDERING(__NAME)
493
494/*============================ TYPES =========================================*/
495
496/*!
497 * \brief direct mode helper service frame-buffer control block states
498 *
499 * \note state transition diagram
500 * <<< service initialization >>>
501 * |
502 * ARM_3FB_STATE_READY_FOR_FLUSH <------+
503 * | |
504 * ARM_3FB_STATE_FLUSHING |
505 * | |
506 * ARM_3FB_STATUS_UNUSED ---> ARM_3FB_STATE_READY_TO_DRAW |
507 * | |
508 * ARM_3FB_STATE_COPYING_AS_TARGET |
509 * |
510 * ARM_3FB_STATE_DRAWING |
511 * | |
512 * ARM_3FB_STATE_COPYING_AS_SOURCE -----+
513 *
514 */
515enum {
516 ARM_3FB_STATE_UNUSED = 0, //!< the FB hasn't been used
517 ARM_3FB_STATE_COPYING_AS_TARGET, //!< the FB is used as the target of frame copy, the previous state is ARM_3FB_STATE_FLUSHING (or ARM_3FB_STATE_UNUSED)
518 ARM_3FB_STATE_READY_TO_DRAW, //!< the FB is ready to draw, the previous state is ARM_3FB_STATE_COPYING_AS_TARGET
519 ARM_3FB_STATE_DRAWING, //!< the FB is used for drawing, the previous state is ARM_3FB_STATE_READY_TO_DRAW
520 ARM_3FB_STATE_COPYING_AS_SOURCE, //!< the FB is used as the source of frame copy, the previous state is ARM_3FB_STATE_READY_FOR_FLUSH
521 ARM_3FB_STATE_READY_TO_FLUSH, //!< the FB is ready for flushing and waiting for a v-sync event, the previous state is ARM_3FB_STATE_COPYING_AS_SOURCE
522 ARM_3FB_STATE_FLUSHING, //!< the FB is used for flushing, the previous state is ARM_3FB_STATE_READY_FOR_FLUSH
523};
524
526
527/*!
528 * \brief An interface for 2D-Copy.
529 * \param[in] pnSource the source image address
530 * \param[in] wSourceStride the stride of the source image
531 * \param[in] pnTarget the address in the target framebuffer
532 * \param[in] wTargetStride the stride of the target framebuffer
533 * \param[in] iWidth the safe width of the source image
534 * \param[in] iHeight the safe height of the source image
535 * \retval true the 2D copy is complete when leaving this function
536 * \retval false An async 2D copy request is sent to the DMA
537 */
538typedef
540 void *pObj,
541 uintptr_t pnSource,
542 uint32_t wSourceStride,
543 uintptr_t pnTarget,
544 uint32_t wTargetStride,
545 int16_t iWidth,
546 int16_t iHeight,
547 uint_fast8_t chBytePerPixel );
548
551 void *pObj;
553
554/*!
555 * \brief An interface for DMA memory-to-memory copy.
556 * If you have a DMA, you can implement this function by using
557 * __OVERRIDE_WEAK.
558 * You should implement an ISR for copy-complete event and call
559 * arm_2d_helper_3fb_report_dma_copy_complete() to notify the
560 * 3FB (direct mode) helper service.
561 *
562 * \param[in] ptThis the helper service control block
563 * \param[in] pObj the address of the user object
564 * \param[in] pnSource the source address of the memory block
565 * \param[in] pnTarget the target address
566 * \param[in] nDataItemCount the number of date items
567 * \param[in] chDataItemSize the size of each data item
568 */
569typedef
571 void *pObj,
572 uintptr_t pnSource,
573 uintptr_t pnTarget,
574 uint32_t nDataItemCount,
575 uint_fast8_t chDataItemSize);
576
579 void *pObj;
581
582/*!
583 * \brief configuration structure for the 3fb (direct mode) helper service
584 */
586 arm_2d_size_t tScreenSize; //!< the screen size
587 uint8_t chPixelBits; //!< the number of bits in one pixel
588 uintptr_t pnAddress[3]; //!< addresses of the 3 full-frame-buffer
589
590 arm_2d_helper_2d_copy_evt_t evtOn2DCopy;
591 arm_2d_helper_dma_copy_evt_t evtOnDMACopy;
593
594#define ARM_2D_3FB_INVALID_IDX 3
595
596/*!
597 * \brief the control block of the 3FB (direct mode) service
598 */
599typedef struct arm_2d_helper_3fb_t {
600ARM_PRIVATE(
602
603 struct {
604 uint8_t u2Drawing : 2; //!< FB pointer for drawing
605 uint8_t u2Flushing : 2; //!< FB pointer for flushing
606 uint8_t u2ReadyToFlush : 2; //!< FB pointer of ready to flush
607 uint8_t u2ReadyToDraw : 2; //!< FB pointer of ready to draw
608 uint8_t tState[3];
609 uintptr_t tSemaphore; //!< semaphore for async access
610 bool bFBCopyComplete; //!< a flag to indicate the completion of a DMA copy
611 } Runtime;
614
616
617/*!
618 * \brief the header of a PFB block
619 */
620typedef struct arm_2d_pfb_t {
621 struct arm_2d_pfb_t *ptNext; //!< next pfb block
622 arm_2d_helper_pfb_t *ptPFBHelper; //!< the pfb helper service current PFB block comes from
623 arm_2d_tile_t tTile; //!< descriptor
624 uint32_t u24Size : 24;
625 uint32_t u7ColourFormat : 7; //!< colour format
626 uint32_t bIsNewFrame : 1; //!< a flag to indicate the starting of a frame
628
629/*!
630 * \brief the node of a region list
631 *
632 */
634 struct arm_2d_region_list_item_t *ptNext; //!< the next node
635ARM_PRIVATE(
636 struct arm_2d_region_list_item_t *ptInternalNext; //!< the next node in the internal list
638 arm_2d_region_t tRegion; //!< the region
639
640ARM_PROTECTED(
641 uint8_t chUserRegionIndex; //!< User Region Index, used to indicate updating which dynamic dirty regions
642 uint8_t bIgnore : 1; //!< ignore this region
643 uint8_t bUpdated : 1; //!< this region item has been updated, PFB helper should refresh it again.
644 uint8_t : 6; //!< reserved for the future
645
646 uint16_t bFromInternalPool : 1; //!< a flag indicating whether this list item coming from the internal pool
647 uint16_t bFromHeap : 1; //!< whether this item comes from the HEAP
648 uint16_t u2UpdateState : 2; //!< reserved for internal FSM
649 uint16_t u12KEY : 12; //!< KEY
650)
651
653
654/*!
655 * \brief the On Low Level Rendering event handler for the low level (LCD Driver)
656 *
657 * \param[in] pTarget a user attached target address
658 * \param[in] ptPFB the PFB block
659 * \param[in] bIsNewFrame a flag indicate the starting of a new frame
660 */
662 void *pTarget,
663 const arm_2d_pfb_t *ptPFB,
664 bool bIsNewFrame);
665
666/*!
667 * \brief low level render event
668 */
670 arm_2d_helper_render_handler_t *fnHandler; //!< event handler function
671 void *pTarget; //!< user attached target
673
674/*!
675 * \brief before-flushing event handler
676 * \param[in] ptOrigin the original PFB
677 * \param[in] ptScratch A scratch PFB
678 * \return true the new content is stored in ptScratch
679 * \return false the new content is stored in ptOrigin
680 */
681typedef bool arm_2d_helper_before_flushing_handler_t( void *pTarget,
682 arm_2d_pfb_t *ptOrigin,
683 arm_2d_pfb_t *ptScratch);
684
685/*!
686 * \brief screen rotation event
687 */
690 void *pTarget;
692
693/*!
694 * \brief the enumeration for events
695 *
696 */
697enum {
698 ARM_2D_PFB_DEPEND_ON_LOW_LEVEL_RENDERING = _BV(0), //!< On Low Level Rendering Event
699 ARM_2D_PFB_DEPEND_ON_DRAWING = _BV(1), //!< On Drawing Event
700 ARM_2D_PFB_DEPEND_ON_LOW_LEVEL_SYNC_UP = _BV(2), //!< On Low Level Sync-up Event
701 ARM_2D_PFB_DEPEND_ON_FRAME_SYNC_UP = _BV(3), //!< On Frame Sync-up Event
702 ARM_2D_PFB_DEPEND_ON_EACH_FRAME_CPL = _BV(4), //!< On Each Frame Complete Event
703 ARM_2D_PFB_DEPEND_ON_NAVIGATION = _BV(5), //!< On Drawing Navigation Event
704};
705
706/*!
707 * \brief The PFB Helper Service Dependency
708 *
709 */
711 //! event handler for low level rendering
713
714 //! event handler for drawing GUI
715 arm_2d_helper_draw_evt_t evtOnDrawing;
716
717 /*! event handler for waiting LCD finish rendering previous frame
718 * \note when then handler return false, the refresh task will yield and return
719 * arm_fsm_rt_async.
720 * when the handler return true, it means the display device finished
721 * rendering the previous frame and the refresh task will continue the
722 * following steps.
723 */
725
726 //! event handler for each frame complete
728
729 //! event handler for drawing GUI
730 struct {
731 arm_2d_helper_draw_evt_t evtOnDrawing;
732 arm_2d_region_list_item_t *ptDirtyRegion;
734
735 //! event handler for screen rotation
737
739
740/*!
741 * \brief PFB Helper configuration
742 *
743 */
745
746 arm_2d_region_t tDisplayArea; //!< screen description
747
748 struct {
749 arm_2d_pfb_t *ptPFBs; //!< PFB blocks for the internal PFB pool
750 arm_2d_size_t tFrameSize; //!< the size of the frame
751 uint32_t wBufferSize; //!< the buffer size
752
753 uint32_t u7ColourFormat : 7 ; //!< the colour format
754 uint32_t : 1 ; //!< reserved
755 uint32_t u8PFBNum : 8; //!< the number of PFB
756
757 uint32_t bDoNOTUpdateDefaultFrameBuffer : 1; //!< A flag to disable automatically default-framebuffer-registration
758 uint32_t bDisableDynamicFPBSize : 1; //!< A flag to disable resize of the PFB block
759 uint32_t bSwapRGB16 : 1; //!< A flag to enable swapping high and low bytes of an RGB16 pixel
760 uint32_t bDebugDirtyRegions : 1; //!< A flag to show dirty regions on screen for debug
761 uint32_t : 2;
762 uint32_t u3PixelWidthAlign : 3; //!< Pixel alignment in Width for dirty region (2^n)
763 uint32_t u3PixelHeightAlign : 3; //!< Pixel alignment in Height for dirty region (2^n)
764 uint32_t u4PoolReserve : 4; //!< reserve specific number of PFB for other helper services
765
766 } FrameBuffer; //!< frame buffer context
767
768 struct {
769 arm_2d_region_list_item_t *ptRegions; //!< dirty region list item for internal pool
770 uint8_t chCount; //!< number of dirty region list items
771 } DirtyRegion;
772
773 arm_2d_size_t tAntiNoiseScanSize; //!< the region size of anti-noise-scanning mode
774
775 arm_2d_helper_pfb_dependency_t Dependency; //!< user registered dependency
776
778
779/*!
780 * \brief the type of perf counter
781 *
782 */
783typedef enum {
784 ARM_2D_PERFC_RENDER = 0,
785 ARM_2D_PERFC_DRIVER,
786
787 __ARM_2D_PERFC_COUNT,
789
790typedef enum {
791
792 ARM_2D_PFB_SCAN_POLICY_HORIZONTAL_FIRST = (0 << 0), /* left to right first, then top to down */
793 ARM_2D_PFB_SCAN_POLICY_VERTICAL_FIRST = (1 << 0), /* top to down first, then left to right */
794
795 /* default */
796 ARM_2D_PFB_SCAN_POLICY_NORMAL = 0,
797
798} arm_2d_pfb_scan_policy_t;
799
800/*!
801 * \brief the PFB helper control block
802 *
803 */
805
806ARM_PRIVATE(
807 arm_2d_helper_pfb_cfg_t tCFG; //!< user configuration
808
809 struct {
810 arm_2d_location_t tScanOffset;
811 arm_2d_region_t tTargetRegion;
812
813 arm_2d_region_list_item_t *ptDirtyRegion;
814
815 struct {
816 arm_2d_region_list_item_t *ptWorkingList;
817 arm_2d_region_list_item_t *ptCandidateList;
818 arm_2d_region_list_item_t *ptFreeList;
819 arm_2d_region_list_item_t tWorkingItem;
820 } OptimizedDirtyRegions;
821
822 arm_2d_tile_t tPFBTile;
823 arm_2d_size_t tFrameSize;
824 uint32_t wPFBPixelCount;
825
826 uint8_t chPT;
827 uint8_t chFreePFBCount;
828 int16_t iDirtyRegionFreeCount;
829
830 struct {
831 uint32_t bIsNewFrame : 1;
832 uint32_t bIsDryRun : 1;
833 uint32_t bFirstIteration : 1;
834 uint32_t bIsRegionChanged : 1;
835 uint32_t bNoAdditionalDirtyRegionList : 1;
836 uint32_t bPFBScanPolicyVerticalFirst : 1;
837 uint32_t bSyncWithLowLevel : 1;
838 uint32_t : 2;
839
840
841 uint32_t bEnableDirtyRegionOptimizationRequest : 1;
842 uint32_t bDisableDirtyRegionOptimizationRequest : 1;
843 uint32_t bFullFrameRefreshModeRequest : 1;
844 uint32_t bAntiNoiseScanRequest : 1;
845 uint32_t : 4;
846
847 uint32_t bIsDirtyRegionOptimizationEnabled : 1;
848 uint32_t bEncounterDynamicDirtyRegion : 1;
849 uint32_t bFailedToOptimizeDirtyRegion : 1;
850 uint32_t bIsUsingOptimizedDirtyRegionList : 1;
851 uint32_t bDirtyRegionDebugModeSkipFrame : 1;
852 uint32_t : 3;
853
854 uint32_t bIgnoreLowLevelSyncUp : 1;
855 uint32_t bIgnoreCanvasColour : 1;
856 uint32_t bIgnoreLowLevelFlush : 1;
857 uint32_t bHideNavigationLayer : 1;
858 uint32_t bFullFrameRefreshModeEnabled : 1;
859 uint32_t bAntiNoiseScanEnabled : 1;
860 uint32_t : 3;
861
862 };
863
864 arm_2d_region_list_item_t tAntiNoiseScanItem;
865
866 arm_2d_colour_t tCanvas;
867
868 uintptr_t pFPBPoolAvailable;
869 arm_2d_pfb_t *ptCurrent;
870 arm_2d_pfb_t *ptFreeList;
871 arm_2d_pfb_t *ptFlushing;
872 struct {
873 arm_2d_pfb_t *ptHead;
874 arm_2d_pfb_t *ptTail;
875 }FlushFIFO;
876 arm_2d_tile_t *ptFrameBuffer;
877 } Adapter;
879
880 struct {
881 int64_t lTimestamp; //!< PLEASE DO NOT USE
882 int32_t nTotalCycle; //!< cycles used by drawing
883 int32_t nRenderingCycle; //!< cycles used in LCD flushing
884 } Statistics; //!< performance statistics
885
886};
887
890
892
893ARM_PRIVATE(
896
897 union {
898 arm_2d_region_t tRegions[2];
899 struct {
900 arm_2d_region_t tNewRegion;
901 union {
902 arm_2d_region_t tOldRegion;
903 arm_2d_region_t tEnclosureArea;
904 };
905 };
906 };
907
908 arm_2d_region_t tExtraAreaToInclude;
909
910 uint8_t bForceToUseMinimalEnclosure : 1;
911 uint8_t bSuspendUpdate : 1;
912 uint8_t bIgnore : 1;
913 uint8_t bOnlyUpdateMinimalEnclosure : 1;
914 uint8_t : 4;
915 uint8_t chUpdateLifeCycle; /* a life cycle counter used to avoid repeated update operations in the same frame.*/
916
917 uint16_t u16Key;
919 arm_2d_region_t tRegionPatch;
920
921
922};
923
925
926ARM_PRIVATE(
927 arm_2d_region_list_item_t tDirtyRegion;
928 arm_2d_region_list_item_t **ppDirtyRegionList;
929
930 /* region items */
932
933 uint8_t chUpdateLifeCycle;
934 uint8_t : 8;
935 uint16_t : 16;
937
939
940} ;
941
942/*!
943 * \brief the Transform helper control block
944 *
945 */
947
948 float fAngle;
949 union {
950 float fScale;
951 float fScaleX;
952 };
953 float fScaleY;
954
956ARM_PRIVATE(
957
958 arm_2d_op_t *ptTransformOP;
959
961
962 struct {
963 float fValue;
964 float fStep;
965 } Angle;
966
967 struct {
968 float fValue;
969 float fStep;
970 } ScaleX;
971
972 struct {
973 float fValue;
974 float fStep;
975 } ScaleY;
976
977 bool bNeedUpdate;
979
981
982
983/*!
984 * \brief the Transform helper control block
985 * \note Deprecated.
986 */
987typedef struct {
989
990 float fAngle;
991 float fScale;
992
993ARM_PRIVATE(
994
995 arm_2d_op_t *ptTransformOP;
996
997 struct {
998 float fValue;
999 float fStep;
1000 } Angle;
1001
1002 struct {
1003 float fValue;
1004 float fStep;
1005 } Scale;
1006
1007 bool bNeedUpdate;
1009
1011
1012
1013
1014/*============================ GLOBAL VARIABLES ==============================*/
1015/*============================ LOCAL VARIABLES ===============================*/
1016/*============================ PROTOTYPES ====================================*/
1017
1018/*!
1019 * \brief initialize pfb helper service
1020 * \param[in] ptThis the pfb helper control block
1021 * \param[in] ptCFG the configuration
1022 * \return arm_2d_err_t the process result
1023 */
1024extern
1025ARM_NONNULL(1,2)
1028/*!
1029 * \brief uninitialize pfb helper service
1030 * \param[in] ptThis the pfb helper control block
1031 * \return none
1032 */
1033extern
1034ARM_NONNULL(1)
1036
1037/*!
1038 * \brief set PFB working policy
1039 * \param[in] ptThis the pfb helper control block
1040 * \param[in] chPolicyMask new policies defined in arm_2d_pfb_scan_policy_t
1041 */
1042extern
1043ARM_NONNULL(1)
1044void arm_2d_helper_pfb_policy(arm_2d_helper_pfb_t *ptThis, uint8_t chPolicyMask);
1045
1046/*!
1047 * \brief get the display (screen) region
1048 * \param[in] ptThis the pfb helper control block
1049 * \return arm_2d_region_t the screen region
1050 */
1051extern
1052ARM_NONNULL(1)
1054
1055/*!
1056 * \brief get the absolute location for a given location on the target tile canvas
1057 * \param[in] ptTile the target tile
1058 * \param[in] tLocation the location on the target tile canvas
1059 * \return arm_2d_location_t the absolute location on a (virtual) screen or on
1060 * a root tile canvas
1061 */
1062extern
1063ARM_NONNULL(1)
1065 arm_2d_tile_t *ptTile,
1066 arm_2d_location_t tLocation);
1067
1068/*!
1069 * \brief get the inital PFB size
1070 * \param[in] ptThis the pfb helper control block
1071 * \return arm_2d_size_t the PFB size
1072 */
1073extern
1074ARM_NONNULL(1)
1076
1077extern
1078/*!
1079 * \brief test whether specified region is being drawing
1080 *
1081 * \param[in] ptTarget the target tile
1082 * \param[in] ptRegion the target region to test
1083 * \param[out] ppVirtualScreen the address of the pointer that used to point
1084 * the virtual screen tile
1085 * \return true the specified region is currently being drawing
1086 * \return false the PFB is out of the range.
1087 */
1089 const arm_2d_region_t *ptRegion,
1090 const arm_2d_tile_t **ppVirtualScreen);
1091
1092extern
1093ARM_NONNULL(2)
1094/*!
1095 * \brief test whether the target region is active (used by PFB service)
1096 *
1097 * \param[in] ptTarget the target tile
1098 * \param[in] ptRegion the target region to test
1099 * \param[in] bConsiderDryRun whether taking dry run into consideration
1100 * \return true the region is active
1101 * \return false the region is inactive
1102 */
1104 const arm_2d_region_t *ptRegion,
1105 bool bConsiderDryRun);
1106
1107extern
1108ARM_NONNULL(2,4)
1109/*!
1110 * \brief test whether the target region is active (used by PFB service)
1111 *
1112 * \param[in] ptTarget the target tile
1113 * \param[in] ptRegion the target region to test
1114 * \param[in] bConsiderDryRun whether taking dry run into consideration
1115 * \param[in] pptScreen a 2rd level pointer to get the virtual screen
1116 * \return true the region is active
1117 * \return false the region is inactive
1118 */
1120 const arm_2d_region_t *ptRegion,
1121 bool bConsiderDryRun,
1122 const arm_2d_tile_t **pptScreen);
1123/*!
1124 * \brief the task function for pfb helper
1125 * \param[in] ptThis an initialised PFB helper control block
1126 * \param[in] ptDirtyRegions a region list pending for refresh, NULL means
1127 * refreshing the whole screen
1128 * \retval arm_fsm_rt_cpl complete refreshing one frame
1129 * \retval arm_fsm_rt_on_going the refreshing work is on-going
1130 * \retval arm_fsm_rt_wait_for_obj user's OnDrawing event handler wants to wait
1131 * for some objects, e.g. semaphore etc.
1132 * \retval <0 An error is detected
1133 */
1134extern
1135ARM_NONNULL(1)
1137 arm_2d_region_list_item_t *ptDirtyRegions);
1138
1139/*!
1140 * \brief flush the FPB FIFO
1141 * \note This function is THREAD-SAFE
1142 * \note For normal usage, please DO NOT use this function unless you know what
1143 * you are doing.
1144 * \param[in] ptThis an initialised PFB helper control block
1145 */
1146extern
1147ARM_NONNULL(1)
1149
1150/*!
1151 * \brief indicate whether a most recent completed frame is a skipped one or not
1152 * \param[in] ptThis an initialised PFB helper control block
1153 * \retval true the most recent completed frame is an skipped one
1154 * \retval false the most recent completed frame is flushed
1155 */
1156ARM_NONNULL(1)
1158
1159/*!
1160 * \brief hide the navigation layer
1161 * \param[in] ptThis an initialised PFB helper control block
1162 */
1163extern
1164ARM_NONNULL(1)
1166
1167/*!
1168 * \brief show the navigation layer if there is a valid one
1169 * \param[in] ptThis an initialised PFB helper control block
1170 */
1171extern
1172ARM_NONNULL(1)
1174
1175
1176/*!
1177 * \brief enable filling canvas with specified colour
1178 *
1179 * \param[in] ptThis an initialised PFB helper control block
1180 * \param[in] tColour the target canvas colour
1181 */
1182extern
1183ARM_NONNULL(1)
1185 arm_2d_colour_t tColour);
1186
1187extern
1188ARM_NONNULL(1)
1189/*!
1190 * \brief disable filling canvas with specified colour
1191 *
1192 * \param[in] ptThis an initialised PFB helper control block
1193 */
1195
1196/*!
1197 * \brief ignore the low level PFB flushing only
1198 * \param[in] ptThis an initialised PFB helper control block
1199 */
1200extern
1201ARM_NONNULL(1)
1203
1204
1205/*!
1206 * \brief resume the low level PFB flushing
1207 * \param[in] ptThis an initialised PFB helper control block
1208 */
1209extern
1210ARM_NONNULL(1)
1212
1213/*!
1214 * \brief Enable or disable full-frame-refresh mode
1215 * \param[in] ptThis an initialised PFB helper control block
1216 * \param[in] bEnabled enable or disable this option
1217 * \return boolean previous setting.
1218 */
1219extern
1220ARM_NONNULL(1)
1222 bool bEnabled);
1223
1224/*!
1225 * \brief Enable or disable anti-noise-scanning mode
1226 *
1227 * \note when enabled, the PFB will clean(update) the screen with a small region across
1228 * frames. The region size is configurable in arm_2d_helper_pfb_cfg_t.
1229 * \param[in] ptThis an initialised PFB helper control block
1230 * \param[in] bEnabled enable or disable this option
1231 * \return boolean previous setting.
1232 */
1233extern
1234ARM_NONNULL(1)
1236
1237/*!
1238 * \brief update PFB dependency (event handlers)
1239 * \param[in] ptThis the PFB helper control block
1240 * \param[in] chMask the bit mask for event handlers
1241 * \param[in] ptDependency the new dependency description
1242 * \return arm_2d_err_t the process result
1243 */
1244extern
1245ARM_NONNULL(1,3)
1247 arm_2d_helper_pfb_t *ptThis,
1248 uint_fast8_t chMask,
1249 const arm_2d_helper_pfb_dependency_t *ptDependency);
1250
1251/*!
1252 * \brief tell PFB helper that a low level LCD flushing work is complete
1253 * \note This function is THREAD-SAFE, You can call this function asynchronously,
1254 * e.g.
1255 * - A ISR to indicate DMA-transfer complete event or
1256 * - A different Thread
1257 * \param[in] ptThis the PFB helper control block
1258 * \param[in] ptPFB the used PFB block
1259 */
1260extern
1261ARM_NONNULL(1)
1263 arm_2d_pfb_t *ptPFB);
1264
1265/*!
1266 * \brief try to get a PFB block from the pool
1267 * \param[in] ptThis the PFB helper control block
1268 * \retval NULL the pool is empty
1269 * \retval !NULL a valid pfb block
1270 */
1271extern
1272ARM_NONNULL(1)
1274
1275/*!
1276 * \brief free a PFB block to the pool
1277 * \param[in] ptThis the PFB helper control block
1278 * \param[in] ptPFB the target PFB block
1279 */
1280extern
1281ARM_NONNULL(1)
1283
1284/*!
1285 * \brief initialize the 3FB (direct mode) service
1286 * \param[in] ptThis the helper service control block
1287 * \param[in] ptCFG the configuration structure
1288 */
1289extern
1290ARM_NONNULL(1,2)
1292 const arm_2d_helper_3fb_cfg_t *ptCFG);
1293
1294
1295/*!
1296 * \brief report the copy-completion event to the 3FB (direct mode) service
1297 * \note see function __arm_2d_helper_3fb_dma_copy for details
1298 * \param[in] ptThis the helper service control block
1299 */
1300extern
1301ARM_NONNULL(1)
1303
1304/*!
1305 * \brief get a pointer for flushing
1306 * \param[in] ptThis the helper service control block
1307 * \return void * the address of a framebuffer
1308 *
1309 * \note please only call this function when on vsync event.
1310 */
1311extern
1312ARM_NONNULL(1)
1314
1315/*!
1316 * \brief please do NOT use this function. It is used by the display adapter.
1317 */
1318extern
1319ARM_NONNULL(1,2)
1321 const arm_2d_pfb_t *ptPFB);
1322
1323extern
1324ARM_NONNULL(1)
1325uintptr_t arm_2d_helper_3fb_flush_frame(arm_2d_helper_3fb_t *ptThis);
1326
1327/*!
1328 * \brief rotate a given c8bit PFB for 90 degree
1329 * \param[in] ptOrigin the original PFB
1330 * \param[in] ptScratch A scratch PFB
1331 * \param[in] ptScreenSize the screen size
1332 * \return arm_2d_pfb_t * the output PFB
1333 */
1334ARM_NONNULL(1,2,3)
1336 arm_2d_pfb_t *ptOrigin,
1337 arm_2d_pfb_t *ptScratch,
1338 const arm_2d_size_t *ptScreenSize);
1339/*!
1340 * \brief rotate a given c8bit PFB for 180 degree
1341 * \param[in] ptOrigin the original PFB
1342 * \param[in] ptScratch A scratch PFB
1343 * \param[in] ptScreenSize the screen size
1344 * \return arm_2d_pfb_t * the output PFB
1345 */
1346ARM_NONNULL(1,2,3)
1348 arm_2d_pfb_t *ptOrigin,
1349 arm_2d_pfb_t *ptScratch,
1350 const arm_2d_size_t *ptScreenSize);
1351/*!
1352 * \brief rotate a given c8bit PFB for 270 degree
1353 * \param[in] ptOrigin the original PFB
1354 * \param[in] ptScratch A scratch PFB
1355 * \param[in] ptScreenSize the screen size
1356 * \return arm_2d_pfb_t * the output PFB
1357 */
1358ARM_NONNULL(1,2,3)
1360 arm_2d_pfb_t *ptOrigin,
1361 arm_2d_pfb_t *ptScratch,
1362 const arm_2d_size_t *ptScreenSize);
1363
1364/*!
1365 * \brief rotate a given rgb16 PFB for 90 degree
1366 * \param[in] ptOrigin the original PFB
1367 * \param[in] ptScratch A scratch PFB
1368 * \param[in] ptScreenSize the screen size
1369 * \return arm_2d_pfb_t * the output PFB
1370 */
1371ARM_NONNULL(1,2,3)
1373 arm_2d_pfb_t *ptOrigin,
1374 arm_2d_pfb_t *ptScratch,
1375 const arm_2d_size_t *ptScreenSize);
1376
1377/*!
1378 * \brief rotate a given rgb16 PFB for 180 degree
1379 * \param[in] ptOrigin the original PFB
1380 * \param[in] ptScratch A scratch PFB
1381 * \param[in] ptScreenSize the screen size
1382 * \return arm_2d_pfb_t * the output PFB
1383 */
1384ARM_NONNULL(1,2,3)
1386 arm_2d_pfb_t *ptOrigin,
1387 arm_2d_pfb_t *ptScratch,
1388 const arm_2d_size_t *ptScreenSize);
1389
1390/*!
1391 * \brief rotate a given rgb16 PFB for 270 degree
1392 * \param[in] ptOrigin the original PFB
1393 * \param[in] ptScratch A scratch PFB
1394 * \param[in] ptScreenSize the screen size
1395 * \return arm_2d_pfb_t * the output PFB
1396 */
1397ARM_NONNULL(1,2,3)
1399 arm_2d_pfb_t *ptOrigin,
1400 arm_2d_pfb_t *ptScratch,
1401 const arm_2d_size_t *ptScreenSize);
1402
1403/*!
1404 * \brief rotate a given rgb32 PFB for 90 degree
1405 * \param[in] ptOrigin the original PFB
1406 * \param[in] ptScratch A scratch PFB
1407 * \param[in] ptScreenSize the screen size
1408 * \return arm_2d_pfb_t * the output PFB
1409 */
1410ARM_NONNULL(1,2,3)
1412 arm_2d_pfb_t *ptOrigin,
1413 arm_2d_pfb_t *ptScratch,
1414 const arm_2d_size_t *ptScreenSize);
1415/*!
1416 * \brief rotate a given rgb32 PFB for 180 degree
1417 * \param[in] ptOrigin the original PFB
1418 * \param[in] ptScratch A scratch PFB
1419 * \param[in] ptScreenSize the screen size
1420 * \return arm_2d_pfb_t * the output PFB
1421 */
1422ARM_NONNULL(1,2,3)
1424 arm_2d_pfb_t *ptOrigin,
1425 arm_2d_pfb_t *ptScratch,
1426 const arm_2d_size_t *ptScreenSize);
1427
1428/*!
1429 * \brief rotate a given rgb32 PFB for 270 degree
1430 * \param[in] ptOrigin the original PFB
1431 * \param[in] ptScratch A scratch PFB
1432 * \param[in] ptScreenSize the screen size
1433 * \return arm_2d_pfb_t * the output PFB
1434 */
1435ARM_NONNULL(1,2,3)
1437 arm_2d_pfb_t *ptOrigin,
1438 arm_2d_pfb_t *ptScratch,
1439 const arm_2d_size_t *ptScreenSize);
1440
1441/*----------------------------------------------------------------------------*
1442 * Dirty Regions *
1443 *----------------------------------------------------------------------------*/
1444
1445/*!
1446 * \brief append dirty regions to the a specified list
1447 * \param[in] ppDirtyRegionList the target list
1448 * \param[in] ptItems the dirty regions
1449 * \param[in] tCount the number of dirty regions
1450 * \retval true operation is successful
1451 * \retval false the operation is failed.
1452 */
1453extern
1454ARM_NONNULL(1,2)
1456 arm_2d_region_list_item_t **ppDirtyRegionList,
1458 size_t tCount);
1459
1460/*!
1461 * \brief remove dirty regions from the a specified list
1462 * \param[in] ppDirtyRegionList the target list
1463 * \param[in] ptItems the dirty regions
1464 * \param[in] tCount the number of dirty regions
1465 * \retval true operation is successful
1466 * \retval false the operation is failed.
1467 */
1468extern
1469ARM_NONNULL(1,2)
1471 arm_2d_region_list_item_t **ppDirtyRegionList,
1473 size_t tCount);
1474
1475/*!
1476 * \brief decide whether ignore the specified dirty region item
1477 *
1478 * \param[in] ptThis the target dirty region item object
1479 * \param[in] bIgnore whether ignore
1480 * \return bool the previous ignore status
1481 */
1482extern
1483ARM_NONNULL(1)
1485
1486
1487/*!
1488 * \brief get the ignore status of a given dirty region item
1489 *
1490 * \param[in] ptThis the target dirty region item object
1491 * \retval true the dirty region item is ignored.
1492 * \retval false the dirty region item is in-use.
1493 */
1494extern
1495ARM_NONNULL(1)
1497
1498/*!
1499 * \brief enable dirty region optimization service
1500 * \param[in] ptThis the PFB helper control block
1501 * \param[in] ptRegions an optional array of dirty region items, which will be
1502 * added to the dirty region item pool. NULL is acceptable.
1503 * \param[in] chCount the number of items in the array.
1504 */
1505extern
1506ARM_NONNULL(1)
1508 arm_2d_helper_pfb_t *ptThis,
1509 arm_2d_region_list_item_t *ptRegions,
1510 uint_fast8_t chCount);
1511/*!
1512 * \brief disable dirty region optimization service
1513 * \param[in] ptThis the PFB helper control block
1514 * \return previous status
1515 */
1516extern
1517ARM_NONNULL(1)
1519 arm_2d_helper_pfb_t *ptThis);
1520
1521/*----------------------------------------------------------------------------*
1522 * The Dynamic Dirty Region Service *
1523 *----------------------------------------------------------------------------*/
1524/*!
1525 * \brief the on-frame-start event handler for a given user dynamic dirty region
1526 *
1527 * \param[in] ptThis the target region list item.
1528 * \param[in] chUserRegionIndex a specified user region index. When 0xFF is given,
1529 * the existing user region index will not be changed.
1530 *
1531 */
1532extern
1533ARM_NONNULL(1)
1536 uint8_t chUserRegionIndex);
1537
1538/*!
1539 * \brief initialize a dynamic dirty region
1540 *
1541 * \param[in] ptThis the target region list item. If it is NULL, this function will
1542 * allocate an object from the heap
1543 * \return arm_2d_region_list_item_t* the target region list item
1544 */
1545extern
1548
1549/*!
1550 * \brief depose a given dynamic dirty region
1551 *
1552 * \param[in] ptThis the target region list item.
1553 */
1554extern
1555ARM_NONNULL(1)
1557
1558/*!
1559 * \brief wait for the PFB helper service requesting the next region
1560 *
1561 * \param[in] ptThis the target region list item.
1562 * \return uint_fast8_t the user region index
1563 *
1564 * \note You can use the return value, i.e. the user region index to address
1565 * the new region you want to cover.
1566 */
1567extern
1568ARM_NONNULL(1)
1571
1572/*!
1573 * \brief update a given user dynamic dirty region with a new region
1574 *
1575 * \param[in] ptThis the target region list item.
1576 * \param[in] ptTarget the target tile (the frame-buffer to draw)
1577 * \param[in] ptRegion the new region
1578 * \note - when the ptTarget isn't NULL, the ptRegion should points a region inside
1579 * the canvas of the ptTarget (i.e. an relative region of the ptTarget)
1580 * - when the ptTarget is NULL, this function will get the default framebuffer
1581 * by calling the function arm_2d_get_default_frame_buffer().
1582 *
1583 * \param[in] chNextUserIndex the next user region index, 0xFF means complete.
1584 */
1585extern
1586ARM_NONNULL(1)
1588 arm_2d_tile_t *ptTarget,
1589 arm_2d_region_t *ptRegion,
1590 uint8_t chNextUserIndex);
1591
1592/*!
1593 * \brief only change the user region index without update the dynamic dirty region
1594 *
1595 * \param[in] ptThis the target region list item.
1596 * \param[in] chNextUserIndex the next user region index. When encounter 0xFF, the
1597 * user region index will be reset to zero.
1598 */
1599extern
1600ARM_NONNULL(1)
1603 uint8_t chNextUserIndex);
1604
1605/*----------------------------------------------------------------------------*
1606 * The Dirty Region Helper Service *
1607 *----------------------------------------------------------------------------*/
1608
1609/*!
1610 * \brief initialize a given dirtt region helper
1611 * \param[in] ptThis the target helper
1612 * \param[in] ppDirtyRegionList the address of the dirty region list
1613 */
1614extern
1615ARM_NONNULL(1,2)
1618 arm_2d_region_list_item_t **ppDirtyRegionList);
1619extern
1620ARM_NONNULL(1,2)
1621/*!
1622 * \brief add an array of region items to a dirty region helper
1623 *
1624 * \param[in] ptThis the target helper
1625 * \param[in] ptItems the array of the region items
1626 * \param[in] hwCount the number of items in the array
1627 */
1631 uint_fast16_t hwCount);
1632extern
1633ARM_NONNULL(1,2)
1634/*!
1635 * \brief remove an array of region items to a dirty region helper
1636 *
1637 * \param[in] ptThis the target helper
1638 * \param[in] ptItems the array of the region items
1639 * \param[in] hwCount the number of items in the array
1640 */
1644 uint_fast16_t hwCount);
1645
1646/*!
1647 * \brief depose a given dirty region helper
1648 * \param[in] ptThis the target helper
1649 * \return arm_2d_helper_dirty_region_item_t * the region list items
1650 */
1651extern
1652ARM_NONNULL(1)
1654
1655/*!
1656 * \brief the on-frame-start event handler for a given dirty region helper
1657 * \param[in] ptThis the target helper
1658 * \note Usually this event handler should be insert the frame start event
1659 * handler of a target scene.
1660 */
1661extern
1662ARM_NONNULL(1)
1665
1666/*!
1667 * \brief update a specified new region while erase the previous region
1668 *
1669 * \param[in] ptThis the target region item
1670 * \param[in] ptTargetTile the target tile to draw content
1671 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1672 * the ptNewRegion, NULL means no clipping.
1673 * \param[in] ptNewRegion the new region to update, NULL means nothing
1674 * to update
1675 */
1676extern
1677ARM_NONNULL(1,2)
1680 const arm_2d_tile_t *ptTargetTile,
1681 const arm_2d_region_t *ptVisibleArea,
1682 const arm_2d_region_t *ptNewRegion);
1683
1684/*!
1685 * \brief update the "extra area" of a specified dirty region item
1686 *
1687 * \param[in] ptThis the target region item
1688 * \param[in] ptTargetTile the target tile to draw content
1689 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1690 * the ptNewRegion, NULL means no clipping.
1691 * \param[in] ptExtraRegion the new extra region
1692 */
1693extern
1694ARM_NONNULL(1,2)
1697 const arm_2d_tile_t *ptTargetTile,
1698 const arm_2d_region_t *ptVisibleArea,
1699 const arm_2d_region_t *ptExtraRegion);
1700
1701/*!
1702 * \brief update a specified new region while erase the previous region
1703 *
1704 * \param[in] ptThis the target helper
1705 * \param[in] ptTargetTile the target tile to draw content
1706 */
1707ARM_NONNULL(1,2)
1708extern
1711 const arm_2d_tile_t *ptTargetTile);
1712
1713/*!
1714 * \brief update a specified new region while erase the previous region
1715 *
1716 * \param[in] ptThis the target helper
1717 * \param[in] ptTargetTile the target tile to draw content
1718 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1719 * the ptNewRegion, NULL means no clipping.
1720 * \param[in] ptNewRegion the new region to update, NULL means nothing
1721 * to update
1722 */
1723extern
1724ARM_NONNULL(1,2)
1727 const arm_2d_tile_t *ptTargetTile,
1728 const arm_2d_region_t *ptVisibleArea,
1729 const arm_2d_region_t *ptNewRegion);
1730
1731/*!
1732 * \brief force an arm_2d_helper_dirty_region_item_t object to use the minimal
1733 * enclosure region to update.
1734 *
1735 * \param[in] ptThis the target item
1736 * \param[in] bEnable whether enable this feature.
1737 * \return boolean the original setting
1738 */
1739ARM_NONNULL(1)
1742 bool bEnable);
1743
1744/*!
1745 * \brief force the dirty region helper to use the minimal enclosure region to
1746 * update.
1747 *
1748 * \param[in] ptThis the target helper
1749 * \param[in] bEnable whether enable this feature.
1750 * \return boolean the original setting
1751 */
1752extern
1753ARM_NONNULL(1)
1756 bool bEnable);
1757
1758/*!
1759 * \brief force the dirty region helper to suspend the dirty region update.
1760 *
1761 * \param[in] ptThis the target helper
1762 * \param[in] bEnable whether enable this feature.
1763 * \return boolean the original setting
1764 */
1765extern
1766ARM_NONNULL(1)
1769 bool bEnable);
1770
1771/*!
1772 * \brief force the arm_2d_helper_dirty_region_item_t object to suspend the
1773 * dirty region update.
1774 *
1775 * \param[in] ptThis the target item
1776 * \param[in] bEnable whether enable this feature.
1777 * \return boolean the original setting
1778 */
1779ARM_NONNULL(1)
1782 bool bEnable);
1783
1784/*----------------------------------------------------------------------------*
1785 * The Transform Helper Service (Deprecated) *
1786 *----------------------------------------------------------------------------*/
1787/*!
1788 * \brief initialize a given transform helper
1789 * \note Deprecated.
1790 * \param[in] ptThis the target helper
1791 * \param[in] ptTransformOP the target transform OP, NULL is not accepted.
1792 * \param[in] fAngleStep the minimal acceptable angle change.
1793 * \param[in] fScaleStep the minimal acceptable scale ratio change.
1794 * \param[in] ppDirtyRegionList the address of the dirty region list
1795 */
1796extern
1797ARM_NONNULL(1,2,5)
1799 arm_2d_op_t *ptTransformOP,
1800 float fAngleStep,
1801 float fScaleStep,
1802 arm_2d_region_list_item_t **ppDirtyRegionList);
1803
1804/*!
1805 * \brief depose a given transform helper
1806 * \note Deprecated.
1807 * \param[in] ptThis the target helper
1808 */
1809extern
1810ARM_NONNULL(1)
1812
1813/*!
1814 * \brief the on-frame-begin event handler for a given transform helper
1815 * \note Deprecated.
1816 * \param[in] ptThis the target helper
1817 * \note Usually this event handler should be insert the frame start event
1818 * handler of a target scene.
1819 */
1820extern
1821ARM_NONNULL(1)
1823
1824/*!
1825 * \brief force transform helper to update dirty region
1826 * \note Deprecated.
1827 * \note sometimes, we want to force transform helper to update dirty regions
1828 * even if both the angel and scale keep the same, for example, the pivots
1829 * are updated.
1830 * \param[in] ptThis the target helper
1831 */
1832extern
1833ARM_NONNULL(1)
1835
1836/*!
1837 * \brief force the transform helper to use the minimal enclosure region as
1838 * the dirty region.
1839 * \note Deprecated.
1840 * \param[in] ptThis the target helper
1841 * \param[in] bEnable whether enable this feature.
1842 * \return boolean the original setting
1843 */
1844extern
1845ARM_NONNULL(1)
1848 bool bEnable);
1849
1850/*!
1851 * \brief force the transform helper to suspend the dirty region update.
1852 * \note Deprecated.
1853 * \param[in] ptThis the target helper
1854 * \param[in] bEnable whether enable this feature.
1855 * \return boolean the original setting
1856 */
1857extern
1858ARM_NONNULL(1)
1860 bool bEnable);
1861
1862/*!
1863 * \brief update a given transform helper with new values
1864 * \note Deprecated.
1865 * \param[in] ptThis the target helper
1866 * \param[in] fAngle the new angle value
1867 * \param[in] fScale the new scale ratio
1868 * \note The new value is only accepted when the change between the old value
1869 * and the new value is larger than the minimal acceptable mount.
1870 */
1871extern
1872ARM_NONNULL(1)
1874 float fAngle,
1875 float fScale);
1876
1877/*!
1878 * \brief update the dirty region after a transform operation
1879 * \note Deprecated.
1880 * \param[in] ptThis the target helper
1881 * \param[in] ptCanvas the canvas
1882 * \param[in] bIsNewFrame whether this is a new frame
1883 */
1884extern
1885ARM_NONNULL(1)
1888 const arm_2d_region_t *ptCanvas,
1889 bool bIsNewFrame);
1890
1891
1892/*----------------------------------------------------------------------------*
1893 * The Dirty Region Transform Helper Service *
1894 *----------------------------------------------------------------------------*/
1895/*!
1896 * \brief initialize a given dirty region transform helper
1897 *
1898 * \param[in] ptThis the target helper
1899 * \param[in] ptHelper the host arm_2d_helper_dirty_region_t object.
1900 * \param[in] ptTransformOP the target transform OP, NULL is not accepted.
1901 * \param[in] fAngleStep the minimal acceptable angle change.
1902 * \param[in] fScaleStep the minimal acceptable scale ratio change.
1903 */
1904extern
1905ARM_NONNULL(1,2,3)
1909 arm_2d_op_t *ptTransformOP,
1910 float fAngleStep,
1911 float fScaleStep);
1912
1913/*!
1914 * \brief depose a given dirty region transform helper
1915 *
1916 * \param[in] ptThis the target helper
1917 */
1918extern
1919ARM_NONNULL(1)
1922
1923/*!
1924 * \brief the on-frame-begin event handler for a given dirty region transform
1925 * helper
1926 *
1927 * \param[in] ptThis the target helper
1928 * \note Usually this event handler should be insert the frame start event
1929 * handler of a target scene.
1930 */
1931extern
1932ARM_NONNULL(1)
1935
1936/*!
1937 * \brief force a dirty region transform helper to update its dirty region
1938 *
1939 * \note sometimes, we want to force transform helper to update dirty regions
1940 * even if both the angel and scale keep the same, for example, the pivots
1941 * are updated.
1942 * \param[in] ptThis the target helper
1943 */
1944extern
1945ARM_NONNULL(1)
1948
1949/*!
1950 * \brief force a dirty region transform helper to use the minimal enclosure
1951 * region as the dirty region.
1952 *
1953 * \param[in] ptThis the target helper
1954 * \param[in] bEnable whether enable this feature.
1955 * \return boolean the original setting
1956 */
1957extern
1958ARM_NONNULL(1)
1961 bool bEnable);
1962
1963/*!
1964 * \brief force a dirty region transform helper to suspend updating.
1965 *
1966 * \param[in] ptThis the target helper
1967 * \param[in] bEnable whether enable this feature.
1968 * \return boolean the original setting
1969 */
1970extern
1971ARM_NONNULL(1)
1974 bool bEnable);
1975
1976/*!
1977 * \brief update a given dirty region transform helper with new values
1978 *
1979 * \param[in] ptThis the target helper
1980 * \param[in] fAngle the new angle value
1981 * \param[in] fScale the new scale ratio
1982 * \note The new value is only accepted when the change between the old value
1983 * and the new value is larger than the minimal acceptable mount.
1984 */
1985extern
1986ARM_NONNULL(1)
1989 float fAngle,
1990 float fScale);
1991
1992/*!
1993 * \brief update a given dirty region transform helper with new values
1994 *
1995 * \param[in] ptThis the target helper
1996 * \param[in] fAngle the new angle value
1997 * \param[in] fScaleX the new scale ratio for X axis
1998 * \param[in] fScaleY the new scale ratio for Y axis
1999 * \note The new value is only accepted when the change between the old value
2000 * and the new value is larger than the minimal acceptable mount.
2001 */
2002extern
2003ARM_NONNULL(1)
2006 float fAngle,
2007 float fScaleX,
2008 float fScaleY);
2009
2010/*!
2011 * \brief update the dirty region after a transform operation
2012 *
2013 * \param[in] ptThis the target helper
2014 * \param[in] ptCanvas the canvas
2015 * \param[in] bIsNewFrame whether this is a new frame
2016 */
2017extern
2018ARM_NONNULL(1)
2021 const arm_2d_region_t *ptCanvas,
2022 bool bIsNewFrame);
2023
2024
2025/*! @} */
2026
2027#if defined(__clang__)
2028# pragma clang diagnostic pop
2029#endif
2030
2031#ifdef __cplusplus
2032}
2033#endif
2034
2035
2036
2037#endif