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: 16. Nov 2025
25 * $Revision: V.2.4.4
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
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 bNewRegionIsDifferent : 1;
915 uint8_t : 3;
916 uint8_t chUpdateLifeCycle; /* a life cycle counter used to avoid repeated update operations in the same frame.*/
917
918 uint16_t u16Key;
920 arm_2d_region_t tRegionPatch;
921
922
923};
924
926
927ARM_PRIVATE(
928 arm_2d_region_list_item_t tDirtyRegion;
929 arm_2d_region_list_item_t **ppDirtyRegionList;
930
931 /* region items */
933
934 uint8_t chUpdateLifeCycle;
935 uint8_t : 8;
936 uint16_t : 16;
938
940
941} ;
942
943/*!
944 * \brief the Transform helper control block
945 *
946 */
948
949 float fAngle;
950 union {
951 float fScale;
952 float fScaleX;
953 };
954 float fScaleY;
955
957
958 struct {
959 arm_2d_location_t *ptPoints;
960 uint8_t chCount;
961 } SourceReference;
962
963ARM_PRIVATE(
964
965 arm_2d_op_t *ptTransformOP;
966
968
969 struct {
970 float fValue;
971 float fStep;
972 } Angle;
973
974 struct {
975 float fValue;
976 float fStep;
977 } ScaleX;
978
979 struct {
980 float fValue;
981 float fStep;
982 } ScaleY;
983
984 bool bNeedUpdate;
986
988
989
990/*!
991 * \brief the Transform helper control block
992 * \note Deprecated.
993 */
994typedef struct {
996
997 float fAngle;
998 float fScale;
999
1000ARM_PRIVATE(
1001
1002 arm_2d_op_t *ptTransformOP;
1003
1004 struct {
1005 float fValue;
1006 float fStep;
1007 } Angle;
1008
1009 struct {
1010 float fValue;
1011 float fStep;
1012 } Scale;
1013
1014 bool bNeedUpdate;
1016
1018
1019
1020
1021/*============================ GLOBAL VARIABLES ==============================*/
1022/*============================ LOCAL VARIABLES ===============================*/
1023/*============================ PROTOTYPES ====================================*/
1024
1025/*!
1026 * \brief initialize pfb helper service
1027 * \param[in] ptThis the pfb helper control block
1028 * \param[in] ptCFG the configuration
1029 * \return arm_2d_err_t the process result
1030 */
1031extern
1032ARM_NONNULL(1,2)
1035/*!
1036 * \brief uninitialize pfb helper service
1037 * \param[in] ptThis the pfb helper control block
1038 * \return none
1039 */
1040extern
1041ARM_NONNULL(1)
1043
1044/*!
1045 * \brief set PFB working policy
1046 * \param[in] ptThis the pfb helper control block
1047 * \param[in] chPolicyMask new policies defined in arm_2d_pfb_scan_policy_t
1048 */
1049extern
1050ARM_NONNULL(1)
1051void arm_2d_helper_pfb_policy(arm_2d_helper_pfb_t *ptThis, uint8_t chPolicyMask);
1052
1053/*!
1054 * \brief get the display (screen) region
1055 * \param[in] ptThis the pfb helper control block
1056 * \return arm_2d_region_t the screen region
1057 */
1058extern
1059ARM_NONNULL(1)
1061
1062/*!
1063 * \brief get the absolute location for a given location on the target tile canvas
1064 * \param[in] ptTile the target tile
1065 * \param[in] tLocation the location on the target tile canvas
1066 * \return arm_2d_location_t the absolute location on a (virtual) screen or on
1067 * a root tile canvas
1068 */
1069extern
1070ARM_NONNULL(1)
1072 arm_2d_tile_t *ptTile,
1073 arm_2d_location_t tLocation);
1074
1075/*!
1076 * \brief get the inital PFB size
1077 * \param[in] ptThis the pfb helper control block
1078 * \return arm_2d_size_t the PFB size
1079 */
1080extern
1081ARM_NONNULL(1)
1083
1084/*!
1085 * \brief get the current frame buffer
1086 * \param[in] ptThis the pfb helper control block
1087 * \param[in] pptTile a pointer of the pointer for the current frame buffer
1088 * (const arm_2d_tile_t *)
1089 * \retval true it is a new frame
1090 * \retval false it is not a new frame
1091 */
1092extern
1093ARM_NONNULL(1)
1095 const arm_2d_tile_t **pptTile);
1096
1097extern
1098/*!
1099 * \brief test whether specified region is being drawing
1100 *
1101 * \param[in] ptTarget the target tile
1102 * \param[in] ptRegion the target region to test
1103 * \param[out] ppVirtualScreen the address of the pointer that used to point
1104 * the virtual screen tile
1105 * \return true the specified region is currently being drawing
1106 * \return false the PFB is out of the range.
1107 */
1109 const arm_2d_region_t *ptRegion,
1110 const arm_2d_tile_t **ppVirtualScreen);
1111
1112extern
1113ARM_NONNULL(2)
1114/*!
1115 * \brief test whether the target region is active (used by PFB service)
1116 *
1117 * \param[in] ptTarget the target tile
1118 * \param[in] ptRegion the target region to test
1119 * \param[in] bConsiderDryRun whether taking dry run into consideration
1120 * \return true the region is active
1121 * \return false the region is inactive
1122 */
1124 const arm_2d_region_t *ptRegion,
1125 bool bConsiderDryRun);
1126
1127extern
1128ARM_NONNULL(2,4)
1129/*!
1130 * \brief test whether the target region is active (used by PFB service)
1131 *
1132 * \param[in] ptTarget the target tile
1133 * \param[in] ptRegion the target region to test
1134 * \param[in] bConsiderDryRun whether taking dry run into consideration
1135 * \param[in] pptScreen a 2rd level pointer to get the virtual screen
1136 * \return true the region is active
1137 * \return false the region is inactive
1138 */
1140 const arm_2d_region_t *ptRegion,
1141 bool bConsiderDryRun,
1142 const arm_2d_tile_t **pptScreen);
1143/*!
1144 * \brief the task function for pfb helper
1145 * \param[in] ptThis an initialised PFB helper control block
1146 * \param[in] ptDirtyRegions a region list pending for refresh, NULL means
1147 * refreshing the whole screen
1148 * \retval arm_fsm_rt_cpl complete refreshing one frame
1149 * \retval arm_fsm_rt_on_going the refreshing work is on-going
1150 * \retval arm_fsm_rt_wait_for_obj user's OnDrawing event handler wants to wait
1151 * for some objects, e.g. semaphore etc.
1152 * \retval <0 An error is detected
1153 */
1154extern
1155ARM_NONNULL(1)
1157 arm_2d_region_list_item_t *ptDirtyRegions);
1158
1159/*!
1160 * \brief flush the FPB FIFO
1161 * \note This function is THREAD-SAFE
1162 * \note For normal usage, please DO NOT use this function unless you know what
1163 * you are doing.
1164 * \param[in] ptThis an initialised PFB helper control block
1165 */
1166extern
1167ARM_NONNULL(1)
1169
1170/*!
1171 * \brief indicate whether a most recent completed frame is a skipped one or not
1172 * \param[in] ptThis an initialised PFB helper control block
1173 * \retval true the most recent completed frame is an skipped one
1174 * \retval false the most recent completed frame is flushed
1175 */
1176ARM_NONNULL(1)
1178
1179/*!
1180 * \brief hide the navigation layer
1181 * \param[in] ptThis an initialised PFB helper control block
1182 */
1183extern
1184ARM_NONNULL(1)
1186
1187/*!
1188 * \brief show the navigation layer if there is a valid one
1189 * \param[in] ptThis an initialised PFB helper control block
1190 */
1191extern
1192ARM_NONNULL(1)
1194
1195
1196/*!
1197 * \brief enable filling canvas with specified colour
1198 *
1199 * \param[in] ptThis an initialised PFB helper control block
1200 * \param[in] tColour the target canvas colour
1201 */
1202extern
1203ARM_NONNULL(1)
1205 arm_2d_colour_t tColour);
1206
1207extern
1208ARM_NONNULL(1)
1209/*!
1210 * \brief disable filling canvas with specified colour
1211 *
1212 * \param[in] ptThis an initialised PFB helper control block
1213 */
1215
1216/*!
1217 * \brief ignore the low level PFB flushing only
1218 * \param[in] ptThis an initialised PFB helper control block
1219 */
1220extern
1221ARM_NONNULL(1)
1223
1224
1225/*!
1226 * \brief resume the low level PFB flushing
1227 * \param[in] ptThis an initialised PFB helper control block
1228 */
1229extern
1230ARM_NONNULL(1)
1232
1233/*!
1234 * \brief Enable or disable full-frame-refresh mode
1235 * \param[in] ptThis an initialised PFB helper control block
1236 * \param[in] bEnabled enable or disable this option
1237 * \return boolean previous setting.
1238 */
1239extern
1240ARM_NONNULL(1)
1242 bool bEnabled);
1243
1244/*!
1245 * \brief Enable or disable anti-noise-scanning mode
1246 *
1247 * \note when enabled, the PFB will clean(update) the screen with a small region across
1248 * frames. The region size is configurable in arm_2d_helper_pfb_cfg_t.
1249 * \param[in] ptThis an initialised PFB helper control block
1250 * \param[in] bEnabled enable or disable this option
1251 * \return boolean previous setting.
1252 */
1253extern
1254ARM_NONNULL(1)
1256
1257/*!
1258 * \brief update PFB dependency (event handlers)
1259 * \param[in] ptThis the PFB helper control block
1260 * \param[in] chMask the bit mask for event handlers
1261 * \param[in] ptDependency the new dependency description
1262 * \return arm_2d_err_t the process result
1263 */
1264extern
1265ARM_NONNULL(1,3)
1267 arm_2d_helper_pfb_t *ptThis,
1268 uint_fast8_t chMask,
1269 const arm_2d_helper_pfb_dependency_t *ptDependency);
1270
1271/*!
1272 * \brief tell PFB helper that a low level LCD flushing work is complete
1273 * \note This function is THREAD-SAFE, You can call this function asynchronously,
1274 * e.g.
1275 * - A ISR to indicate DMA-transfer complete event or
1276 * - A different Thread
1277 * \param[in] ptThis the PFB helper control block
1278 * \param[in] ptPFB the used PFB block
1279 */
1280extern
1281ARM_NONNULL(1)
1283 arm_2d_pfb_t *ptPFB);
1284
1285/*!
1286 * \brief try to get a PFB block from the pool
1287 * \param[in] ptThis the PFB helper control block
1288 * \retval NULL the pool is empty
1289 * \retval !NULL a valid pfb block
1290 */
1291extern
1292ARM_NONNULL(1)
1294
1295/*!
1296 * \brief free a PFB block to the pool
1297 * \param[in] ptThis the PFB helper control block
1298 * \param[in] ptPFB the target PFB block
1299 */
1300extern
1301ARM_NONNULL(1)
1303
1304/*!
1305 * \brief initialize the 3FB (direct mode) service
1306 * \param[in] ptThis the helper service control block
1307 * \param[in] ptCFG the configuration structure
1308 */
1309extern
1310ARM_NONNULL(1,2)
1312 const arm_2d_helper_3fb_cfg_t *ptCFG);
1313
1314
1315/*!
1316 * \brief report the copy-completion event to the 3FB (direct mode) service
1317 * \note see function __arm_2d_helper_3fb_dma_copy for details
1318 * \param[in] ptThis the helper service control block
1319 */
1320extern
1321ARM_NONNULL(1)
1323
1324/*!
1325 * \brief get a pointer for flushing
1326 * \param[in] ptThis the helper service control block
1327 * \return void * the address of a framebuffer
1328 *
1329 * \note please only call this function when on vsync event.
1330 */
1331extern
1332ARM_NONNULL(1)
1334
1335/*!
1336 * \brief please do NOT use this function. It is used by the display adapter.
1337 */
1338extern
1339ARM_NONNULL(1,2)
1341 const arm_2d_pfb_t *ptPFB);
1342
1343extern
1344ARM_NONNULL(1)
1345uintptr_t arm_2d_helper_3fb_flush_frame(arm_2d_helper_3fb_t *ptThis);
1346
1347/*!
1348 * \brief rotate a given c8bit PFB for 90 degree
1349 * \param[in] ptOrigin the original PFB
1350 * \param[in] ptScratch A scratch PFB
1351 * \param[in] ptScreenSize the screen size
1352 * \return arm_2d_pfb_t * the output PFB
1353 */
1354ARM_NONNULL(1,2,3)
1356 arm_2d_pfb_t *ptOrigin,
1357 arm_2d_pfb_t *ptScratch,
1358 const arm_2d_size_t *ptScreenSize);
1359/*!
1360 * \brief rotate a given c8bit PFB for 180 degree
1361 * \param[in] ptOrigin the original PFB
1362 * \param[in] ptScratch A scratch PFB
1363 * \param[in] ptScreenSize the screen size
1364 * \return arm_2d_pfb_t * the output PFB
1365 */
1366ARM_NONNULL(1,2,3)
1368 arm_2d_pfb_t *ptOrigin,
1369 arm_2d_pfb_t *ptScratch,
1370 const arm_2d_size_t *ptScreenSize);
1371/*!
1372 * \brief rotate a given c8bit PFB for 270 degree
1373 * \param[in] ptOrigin the original PFB
1374 * \param[in] ptScratch A scratch PFB
1375 * \param[in] ptScreenSize the screen size
1376 * \return arm_2d_pfb_t * the output PFB
1377 */
1378ARM_NONNULL(1,2,3)
1380 arm_2d_pfb_t *ptOrigin,
1381 arm_2d_pfb_t *ptScratch,
1382 const arm_2d_size_t *ptScreenSize);
1383
1384/*!
1385 * \brief rotate a given rgb16 PFB for 90 degree
1386 * \param[in] ptOrigin the original PFB
1387 * \param[in] ptScratch A scratch PFB
1388 * \param[in] ptScreenSize the screen size
1389 * \return arm_2d_pfb_t * the output PFB
1390 */
1391ARM_NONNULL(1,2,3)
1393 arm_2d_pfb_t *ptOrigin,
1394 arm_2d_pfb_t *ptScratch,
1395 const arm_2d_size_t *ptScreenSize);
1396
1397/*!
1398 * \brief rotate a given rgb16 PFB for 180 degree
1399 * \param[in] ptOrigin the original PFB
1400 * \param[in] ptScratch A scratch PFB
1401 * \param[in] ptScreenSize the screen size
1402 * \return arm_2d_pfb_t * the output PFB
1403 */
1404ARM_NONNULL(1,2,3)
1406 arm_2d_pfb_t *ptOrigin,
1407 arm_2d_pfb_t *ptScratch,
1408 const arm_2d_size_t *ptScreenSize);
1409
1410/*!
1411 * \brief rotate a given rgb16 PFB for 270 degree
1412 * \param[in] ptOrigin the original PFB
1413 * \param[in] ptScratch A scratch PFB
1414 * \param[in] ptScreenSize the screen size
1415 * \return arm_2d_pfb_t * the output PFB
1416 */
1417ARM_NONNULL(1,2,3)
1419 arm_2d_pfb_t *ptOrigin,
1420 arm_2d_pfb_t *ptScratch,
1421 const arm_2d_size_t *ptScreenSize);
1422
1423/*!
1424 * \brief rotate a given rgb32 PFB for 90 degree
1425 * \param[in] ptOrigin the original PFB
1426 * \param[in] ptScratch A scratch PFB
1427 * \param[in] ptScreenSize the screen size
1428 * \return arm_2d_pfb_t * the output PFB
1429 */
1430ARM_NONNULL(1,2,3)
1432 arm_2d_pfb_t *ptOrigin,
1433 arm_2d_pfb_t *ptScratch,
1434 const arm_2d_size_t *ptScreenSize);
1435/*!
1436 * \brief rotate a given rgb32 PFB for 180 degree
1437 * \param[in] ptOrigin the original PFB
1438 * \param[in] ptScratch A scratch PFB
1439 * \param[in] ptScreenSize the screen size
1440 * \return arm_2d_pfb_t * the output PFB
1441 */
1442ARM_NONNULL(1,2,3)
1444 arm_2d_pfb_t *ptOrigin,
1445 arm_2d_pfb_t *ptScratch,
1446 const arm_2d_size_t *ptScreenSize);
1447
1448/*!
1449 * \brief rotate a given rgb32 PFB for 270 degree
1450 * \param[in] ptOrigin the original PFB
1451 * \param[in] ptScratch A scratch PFB
1452 * \param[in] ptScreenSize the screen size
1453 * \return arm_2d_pfb_t * the output PFB
1454 */
1455ARM_NONNULL(1,2,3)
1457 arm_2d_pfb_t *ptOrigin,
1458 arm_2d_pfb_t *ptScratch,
1459 const arm_2d_size_t *ptScreenSize);
1460
1461/*----------------------------------------------------------------------------*
1462 * Dirty Regions *
1463 *----------------------------------------------------------------------------*/
1464
1465/*!
1466 * \brief append dirty regions to the a specified list
1467 * \param[in] ppDirtyRegionList the target list
1468 * \param[in] ptItems the dirty regions
1469 * \param[in] tCount the number of dirty regions
1470 * \retval true operation is successful
1471 * \retval false the operation is failed.
1472 */
1473extern
1474ARM_NONNULL(1,2)
1476 arm_2d_region_list_item_t **ppDirtyRegionList,
1478 size_t tCount);
1479
1480/*!
1481 * \brief remove dirty regions from the a specified list
1482 * \param[in] ppDirtyRegionList the target list
1483 * \param[in] ptItems the dirty regions
1484 * \param[in] tCount the number of dirty regions
1485 * \retval true operation is successful
1486 * \retval false the operation is failed.
1487 */
1488extern
1489ARM_NONNULL(1,2)
1491 arm_2d_region_list_item_t **ppDirtyRegionList,
1493 size_t tCount);
1494
1495/*!
1496 * \brief decide whether ignore the specified dirty region item
1497 *
1498 * \param[in] ptThis the target dirty region item object
1499 * \param[in] bIgnore whether ignore
1500 * \return bool the previous ignore status
1501 */
1502extern
1503ARM_NONNULL(1)
1505
1506
1507/*!
1508 * \brief get the ignore status of a given dirty region item
1509 *
1510 * \param[in] ptThis the target dirty region item object
1511 * \retval true the dirty region item is ignored.
1512 * \retval false the dirty region item is in-use.
1513 */
1514extern
1515ARM_NONNULL(1)
1517
1518/*!
1519 * \brief enable dirty region optimization service
1520 * \param[in] ptThis the PFB helper control block
1521 * \param[in] ptRegions an optional array of dirty region items, which will be
1522 * added to the dirty region item pool. NULL is acceptable.
1523 * \param[in] chCount the number of items in the array.
1524 */
1525extern
1526ARM_NONNULL(1)
1528 arm_2d_helper_pfb_t *ptThis,
1529 arm_2d_region_list_item_t *ptRegions,
1530 uint_fast8_t chCount);
1531/*!
1532 * \brief disable dirty region optimization service
1533 * \param[in] ptThis the PFB helper control block
1534 * \return previous status
1535 */
1536extern
1537ARM_NONNULL(1)
1539 arm_2d_helper_pfb_t *ptThis);
1540
1541/*----------------------------------------------------------------------------*
1542 * The Dynamic Dirty Region Service *
1543 *----------------------------------------------------------------------------*/
1544/*!
1545 * \brief the on-frame-start event handler for a given user dynamic dirty region
1546 *
1547 * \param[in] ptThis the target region list item.
1548 * \param[in] chUserRegionIndex a specified user region index. When 0xFF is given,
1549 * the existing user region index will not be changed.
1550 *
1551 */
1552extern
1553ARM_NONNULL(1)
1556 uint8_t chUserRegionIndex);
1557
1558/*!
1559 * \brief initialize a dynamic dirty region
1560 *
1561 * \param[in] ptThis the target region list item. If it is NULL, this function will
1562 * allocate an object from the heap
1563 * \return arm_2d_region_list_item_t* the target region list item
1564 */
1565extern
1568
1569/*!
1570 * \brief depose a given dynamic dirty region
1571 *
1572 * \param[in] ptThis the target region list item.
1573 */
1574extern
1575ARM_NONNULL(1)
1577
1578/*!
1579 * \brief wait for the PFB helper service requesting the next region
1580 *
1581 * \param[in] ptThis the target region list item.
1582 * \return uint_fast8_t the user region index
1583 *
1584 * \note You can use the return value, i.e. the user region index to address
1585 * the new region you want to cover.
1586 */
1587extern
1588ARM_NONNULL(1)
1591
1592/*!
1593 * \brief update a given user dynamic dirty region with a new region
1594 *
1595 * \param[in] ptThis the target region list item.
1596 * \param[in] ptTarget the target tile (the frame-buffer to draw)
1597 * \param[in] ptRegion the new region
1598 * \note - when the ptTarget isn't NULL, the ptRegion should points a region inside
1599 * the canvas of the ptTarget (i.e. an relative region of the ptTarget)
1600 * - when the ptTarget is NULL, this function will get the default framebuffer
1601 * by calling the function arm_2d_get_default_frame_buffer().
1602 *
1603 * \param[in] chNextUserIndex the next user region index, 0xFF means complete.
1604 */
1605extern
1606ARM_NONNULL(1)
1608 arm_2d_tile_t *ptTarget,
1609 arm_2d_region_t *ptRegion,
1610 uint8_t chNextUserIndex);
1611
1612/*!
1613 * \brief only change the user region index without update the dynamic dirty region
1614 *
1615 * \param[in] ptThis the target region list item.
1616 * \param[in] chNextUserIndex the next user region index. When encounter 0xFF, the
1617 * user region index will be reset to zero.
1618 */
1619extern
1620ARM_NONNULL(1)
1623 uint8_t chNextUserIndex);
1624
1625/*----------------------------------------------------------------------------*
1626 * The Dirty Region Helper Service *
1627 *----------------------------------------------------------------------------*/
1628
1629/*!
1630 * \brief initialize a given dirtt region helper
1631 * \param[in] ptThis the target helper
1632 * \param[in] ppDirtyRegionList the address of the dirty region list
1633 */
1634extern
1635ARM_NONNULL(1,2)
1638 arm_2d_region_list_item_t **ppDirtyRegionList);
1639extern
1640ARM_NONNULL(1,2)
1641/*!
1642 * \brief add an array of region items to a dirty region helper
1643 *
1644 * \param[in] ptThis the target helper
1645 * \param[in] ptItems the array of the region items
1646 * \param[in] hwCount the number of items in the array
1647 */
1651 uint_fast16_t hwCount);
1652extern
1653ARM_NONNULL(1,2)
1654/*!
1655 * \brief remove an array of region items to a dirty region helper
1656 *
1657 * \param[in] ptThis the target helper
1658 * \param[in] ptItems the array of the region items
1659 * \param[in] hwCount the number of items in the array
1660 */
1664 uint_fast16_t hwCount);
1665
1666/*!
1667 * \brief depose a given dirty region helper
1668 * \param[in] ptThis the target helper
1669 * \return arm_2d_helper_dirty_region_item_t * the region list items
1670 */
1671extern
1672ARM_NONNULL(1)
1674
1675/*!
1676 * \brief the on-frame-start event handler for a given dirty region helper
1677 * \param[in] ptThis the target helper
1678 * \note Usually this event handler should be insert the frame start event
1679 * handler of a target scene.
1680 */
1681extern
1682ARM_NONNULL(1)
1685
1686/*!
1687 * \brief update a specified new region while erase the previous region
1688 *
1689 * \param[in] ptThis the target region item
1690 * \param[in] ptTargetTile the target tile to draw content
1691 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1692 * the ptNewRegion, NULL means no clipping.
1693 * \param[in] ptNewRegion the new region to update, NULL means nothing
1694 * to update
1695 * \return boolean whether the old region and the new region are different.
1696 */
1697extern
1698ARM_NONNULL(1,2)
1701 const arm_2d_tile_t *ptTargetTile,
1702 const arm_2d_region_t *ptVisibleArea,
1703 const arm_2d_region_t *ptNewRegion);
1704
1705/*!
1706 * \brief update the "extra area" of a specified dirty region item
1707 *
1708 * \param[in] ptThis the target region item
1709 * \param[in] ptTargetTile the target tile to draw content
1710 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1711 * the ptNewRegion, NULL means no clipping.
1712 * \param[in] ptExtraRegion the new extra region
1713 */
1714extern
1715ARM_NONNULL(1,2)
1718 const arm_2d_tile_t *ptTargetTile,
1719 const arm_2d_region_t *ptVisibleArea,
1720 const arm_2d_region_t *ptExtraRegion);
1721
1722/*!
1723 * \brief update a specified new region while erase the previous region
1724 *
1725 * \param[in] ptThis the target helper
1726 * \param[in] ptTargetTile the target tile to draw content
1727 */
1728ARM_NONNULL(1,2)
1729extern
1732 const arm_2d_tile_t *ptTargetTile);
1733
1734/*!
1735 * \brief update a specified new region while erase the previous region
1736 *
1737 * \param[in] ptThis the target helper
1738 * \param[in] ptTargetTile the target tile to draw content
1739 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1740 * the ptNewRegion, NULL means no clipping.
1741 * \param[in] ptNewRegion the new region to update, NULL means nothing
1742 * to update
1743 */
1744extern
1745ARM_NONNULL(1,2)
1748 const arm_2d_tile_t *ptTargetTile,
1749 const arm_2d_region_t *ptVisibleArea,
1750 const arm_2d_region_t *ptNewRegion);
1751
1752/*!
1753 * \brief force an arm_2d_helper_dirty_region_item_t object to use the minimal
1754 * enclosure region to update.
1755 *
1756 * \param[in] ptThis the target item
1757 * \param[in] bEnable whether enable this feature.
1758 * \return boolean the original setting
1759 */
1760ARM_NONNULL(1)
1763 bool bEnable);
1764
1765/*!
1766 * \brief force the dirty region helper to use the minimal enclosure region to
1767 * update.
1768 *
1769 * \param[in] ptThis the target helper
1770 * \param[in] bEnable whether enable this feature.
1771 * \return boolean the original setting
1772 */
1773extern
1774ARM_NONNULL(1)
1777 bool bEnable);
1778
1779/*!
1780 * \brief force the dirty region helper to suspend the dirty region update.
1781 *
1782 * \param[in] ptThis the target helper
1783 * \param[in] bSuspend whether suspend the update.
1784 * \return boolean the original setting
1785 */
1786extern
1787ARM_NONNULL(1)
1790 bool bSuspend);
1791
1792/*!
1793 * \brief force the arm_2d_helper_dirty_region_item_t object to suspend the
1794 * dirty region update.
1795 *
1796 * \param[in] ptThis the target item
1797 * \param[in] bSuspend whether suspend the update.
1798 * \return boolean the original setting
1799 */
1800ARM_NONNULL(1)
1803 bool bSuspend);
1804
1805/*----------------------------------------------------------------------------*
1806 * The Transform Helper Service (Deprecated) *
1807 *----------------------------------------------------------------------------*/
1808/*!
1809 * \brief initialize a given transform helper
1810 * \note Deprecated.
1811 * \param[in] ptThis the target helper
1812 * \param[in] ptTransformOP the target transform OP, NULL is not accepted.
1813 * \param[in] fAngleStep the minimal acceptable angle change.
1814 * \param[in] fScaleStep the minimal acceptable scale ratio change.
1815 * \param[in] ppDirtyRegionList the address of the dirty region list
1816 */
1817extern
1818ARM_NONNULL(1,2,5)
1820 arm_2d_op_t *ptTransformOP,
1821 float fAngleStep,
1822 float fScaleStep,
1823 arm_2d_region_list_item_t **ppDirtyRegionList);
1824
1825/*!
1826 * \brief depose a given transform helper
1827 * \note Deprecated.
1828 * \param[in] ptThis the target helper
1829 */
1830extern
1831ARM_NONNULL(1)
1833
1834/*!
1835 * \brief the on-frame-begin event handler for a given transform helper
1836 * \note Deprecated.
1837 * \param[in] ptThis the target helper
1838 * \note Usually this event handler should be insert the frame start event
1839 * handler of a target scene.
1840 */
1841extern
1842ARM_NONNULL(1)
1844
1845/*!
1846 * \brief force transform helper to update dirty region
1847 * \note Deprecated.
1848 * \note sometimes, we want to force transform helper to update dirty regions
1849 * even if both the angel and scale keep the same, for example, the pivots
1850 * are updated.
1851 * \param[in] ptThis the target helper
1852 */
1853extern
1854ARM_NONNULL(1)
1856
1857/*!
1858 * \brief force the transform helper to use the minimal enclosure region as
1859 * the dirty region.
1860 * \note Deprecated.
1861 * \param[in] ptThis the target helper
1862 * \param[in] bEnable whether enable this feature.
1863 * \return boolean the original setting
1864 */
1865extern
1866ARM_NONNULL(1)
1869 bool bEnable);
1870
1871/*!
1872 * \brief force the transform helper to suspend the dirty region update.
1873 * \note Deprecated.
1874 * \param[in] ptThis the target helper
1875 * \param[in] bEnable whether enable this feature.
1876 * \return boolean the original setting
1877 */
1878extern
1879ARM_NONNULL(1)
1881 bool bEnable);
1882
1883/*!
1884 * \brief update a given transform helper with new values
1885 * \note Deprecated.
1886 * \param[in] ptThis the target helper
1887 * \param[in] fAngle the new angle value
1888 * \param[in] fScale the new scale ratio
1889 * \note The new value is only accepted when the change between the old value
1890 * and the new value is larger than the minimal acceptable mount.
1891 */
1892extern
1893ARM_NONNULL(1)
1895 float fAngle,
1896 float fScale);
1897
1898/*!
1899 * \brief update the dirty region after a transform operation
1900 * \note Deprecated.
1901 * \param[in] ptThis the target helper
1902 * \param[in] ptCanvas the canvas
1903 * \param[in] bIsNewFrame whether this is a new frame
1904 */
1905extern
1906ARM_NONNULL(1)
1909 const arm_2d_region_t *ptCanvas,
1910 bool bIsNewFrame);
1911
1912
1913/*----------------------------------------------------------------------------*
1914 * The Dirty Region Transform Helper Service *
1915 *----------------------------------------------------------------------------*/
1916/*!
1917 * \brief initialize a given dirty region transform helper
1918 *
1919 * \param[in] ptThis the target helper
1920 * \param[in] ptHelper the host arm_2d_helper_dirty_region_t object.
1921 * \param[in] ptTransformOP the target transform OP, NULL is not accepted.
1922 * \param[in] fAngleStep the minimal acceptable angle change.
1923 * \param[in] fScaleStep the minimal acceptable scale ratio change.
1924 */
1925extern
1926ARM_NONNULL(1,2,3)
1930 arm_2d_op_t *ptTransformOP,
1931 float fAngleStep,
1932 float fScaleStep);
1933
1934/*!
1935 * \brief depose a given dirty region transform helper
1936 *
1937 * \param[in] ptThis the target helper
1938 */
1939extern
1940ARM_NONNULL(1)
1943
1944/*!
1945 * \brief the on-frame-begin event handler for a given dirty region transform
1946 * helper
1947 *
1948 * \param[in] ptThis the target helper
1949 * \note Usually this event handler should be insert the frame start event
1950 * handler of a target scene.
1951 */
1952extern
1953ARM_NONNULL(1)
1956
1957/*!
1958 * \brief force a dirty region transform helper to update its dirty region
1959 *
1960 * \note sometimes, we want to force transform helper to update dirty regions
1961 * even if both the angel and scale keep the same, for example, the pivots
1962 * are updated.
1963 * \param[in] ptThis the target helper
1964 */
1965extern
1966ARM_NONNULL(1)
1969
1970/*!
1971 * \brief force a dirty region transform helper to use the minimal enclosure
1972 * region as the dirty region.
1973 *
1974 * \param[in] ptThis the target helper
1975 * \param[in] bEnable whether enable this feature.
1976 * \return boolean the original setting
1977 */
1978extern
1979ARM_NONNULL(1)
1982 bool bEnable);
1983
1984/*!
1985 * \brief force a dirty region transform helper to suspend updating.
1986 *
1987 * \param[in] ptThis the target helper
1988 * \param[in] bEnable whether enable this feature.
1989 * \return boolean the original setting
1990 */
1991extern
1992ARM_NONNULL(1)
1995 bool bEnable);
1996
1997/*!
1998 * \brief update a given dirty region transform helper with new values
1999 *
2000 * \param[in] ptThis the target helper
2001 * \param[in] fAngle the new angle value
2002 * \param[in] fScale the new scale ratio
2003 * \note The new value is only accepted when the change between the old value
2004 * and the new value is larger than the minimal acceptable mount.
2005 */
2006extern
2007ARM_NONNULL(1)
2010 float fAngle,
2011 float fScale);
2012
2013/*!
2014 * \brief update a given dirty region transform helper with new values
2015 *
2016 * \param[in] ptThis the target helper
2017 * \param[in] fAngle the new angle value
2018 * \param[in] fScaleX the new scale ratio for X axis
2019 * \param[in] fScaleY the new scale ratio for Y axis
2020 * \note The new value is only accepted when the change between the old value
2021 * and the new value is larger than the minimal acceptable mount.
2022 */
2023extern
2024ARM_NONNULL(1)
2027 float fAngle,
2028 float fScaleX,
2029 float fScaleY);
2030
2031/*!
2032 * \brief update the dirty region after a transform operation
2033 *
2034 * \param[in] ptThis the target helper
2035 * \param[in] ptCanvas the canvas
2036 * \param[in] bIsNewFrame whether this is a new frame
2037 */
2038extern
2039ARM_NONNULL(1)
2042 const arm_2d_region_t *ptCanvas,
2043 bool bIsNewFrame);
2044
2045
2046/*! @} */
2047
2048#if defined(__clang__)
2049# pragma clang diagnostic pop
2050#endif
2051
2052#ifdef __cplusplus
2053}
2054#endif
2055
2056
2057
2058#endif