Arm-2D  
2D Image Processing Library for Cortex-M Processors
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: 05. Dec 2024
25 * $Revision: V.1.12.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 * \addtogroup gHelper 8 Helper Services
63 * @{
64 */
65
66/*============================ MACROS ========================================*/
67
68#define ARM_2D_FPS_MODE_RENDER_ONLY 0
69#define ARM_2D_FPS_MODE_REAL 1
70
71/*============================ MACROFIED FUNCTIONS ===========================*/
72
73/*!
74 * \brief a macro wrapper in uppercase to help initialising PFB service
75 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
76 * \param[in] __SCREEN_WIDTH the width of the screen
77 * \param[in] __SCREEN_HEIGHT the hight of the screen
78 * \param[in] __PIXEL_TYPE the integer type of the pixel, i.e. uint8_t, uint16_t,
79 * uint32_t
80 * \param[in] __COLOUR_FORMAT the screen colour format, i.e. ARM_2D_COLOUR_CCCN888,
81 * ARM_2D_COLOUR_RGB565 etc.
82 * \param[in] __WIDTH the width of the PFB block
83 * \param[in] __HEIGHT the height of the PFB block
84 * \note For the same number of pixels in a PFB block, please priority the width
85 * over height, for example, 240 * 1 is better than 30 * 8
86 * \param[in] __PFB_NUM the number of PFB blocks in the built-in PFB pool.
87 * \param[in] ... a code block to add additional initializer, see example below:
88 * \return arm_2d_err_t the result of the initialisation process
89 *
90 * \code {.c}
91
92 static ARM_NOINIT arm_2d_helper_pfb_t s_tExamplePFB;
93 ...
94 // initialise FPB helper
95 if (ARM_2D_HELPER_PFB_INIT(
96 &s_tExamplePFB, // FPB Helper object
97 __GLCD_CFG_SCEEN_WIDTH__, // screen width
98 __GLCD_CFG_SCEEN_HEIGHT__, // screen height
99 uint16_t, // colour date type
100 ARM_2D_COLOUR_RGB565, // colour format
101 240, // PFB block width
102 1, // PFB block height
103 1, // number of PFB in the PFB pool
104 {
105 .evtOnLowLevelRendering = {
106 // callback for low level rendering
107 .fnHandler = &__pfb_render_handler,
108 },
109 .evtOnDrawing = {
110 // callback for drawing GUI
111 .fnHandler = &__pfb_draw_background_handler,
112 },
113 },
114 //.FrameBuffer.bSwapRGB16 = true,
115 ) < 0) {
116 //! error detected
117 assert(false);
118 }
119 * \endcode
120 *
121 */
122#define ARM_2D_HELPER_PFB_INIT( __CB_ADDR, /* PFB Helper object address */ \
123 __SCREEN_WIDTH, /* Screen width */ \
124 __SCREEN_HEIGHT,/* Screen height */ \
125 __PIXEL_TYPE, /* The type of the pixels */ \
126 __COLOUR_FORMAT,/* the colour format */ \
127 __PFB_WIDTH, /* The width of the PFB block */\
128 __PFB_HEIGHT, /* The height of the PFB block*/\
129 __PFB_NUM, /* Block count in the PFB pool*/\
130 ... /* Event Handler */ \
131 ) \
132 ({ \
133 ARM_SECTION(".bss.noinit.arm_2d_pfb_pool") \
134 static struct { \
135 arm_2d_pfb_t tFPB; \
136 __ALIGNED(4) \
137 __PIXEL_TYPE tBuffer[(__PFB_WIDTH) * (__PFB_HEIGHT)]; \
138 } s_tPFBs[__PFB_NUM]; \
139 \
140 arm_2d_helper_pfb_cfg_t tCFG = { \
141 .tDisplayArea.tSize = { \
142 .iWidth = (__SCREEN_WIDTH), \
143 .iHeight = (__SCREEN_HEIGHT), \
144 }, \
145 \
146 .FrameBuffer.ptPFBs = (arm_2d_pfb_t *)s_tPFBs, \
147 .FrameBuffer.tFrameSize = { \
148 .iWidth = (__PFB_WIDTH), \
149 .iHeight = (__PFB_HEIGHT), \
150 }, \
151 .FrameBuffer.u24BufferSize = sizeof(s_tPFBs[0].tBuffer), \
152 .FrameBuffer.u7ColourFormat = (__COLOUR_FORMAT), \
153 .FrameBuffer.u8PFBNum = dimof(s_tPFBs), \
154 .Dependency = \
155 __VA_ARGS__ \
156 }; \
157 \
158 arm_2d_helper_pfb_init((__CB_ADDR), &tCFG); \
159 })
160
161/*!
162 * \brief a macro wrapper to update the evtOnDrawring event handler
163 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
164 * \param[in] __HANDLER the new handler
165 * \param[in] ... [Optional] an address (of user defined structure) passed to the
166 * event handler.
167 * \return arm_2d_err_t the process result
168 */
169#define ARM_2D_HELPER_PFB_UPDATE_ON_DRAW_HANDLER( \
170 __CB_ADDR, /* PFB Helper object address */ \
171 __HANDLER, /* new on-draw-handler function*/\
172 ...) /* An optional target address */ \
173 arm_2d_helper_pfb_update_dependency((__CB_ADDR), \
174 ARM_2D_PFB_DEPEND_ON_DRAWING, \
175 (arm_2d_helper_pfb_dependency_t []) {{ \
176 .evtOnDrawing = { \
177 .fnHandler = (__HANDLER), \
178 .pTarget = (NULL,##__VA_ARGS__),\
179 }, \
180 }})
181
182
183#define __IMPL_ARM_2D_REGION_LIST(__NAME, ...) \
184 enum { \
185 __NAME##_offset = __COUNTER__, \
186 }; \
187 __VA_ARGS__ \
188 arm_2d_region_list_item_t __NAME[] = {
189
190
191#define IMPL_ARM_2D_REGION_LIST(__NAME, ...) \
192 __IMPL_ARM_2D_REGION_LIST(__NAME,##__VA_ARGS__)
193
194
195#define END_IMPL_ARM_2D_REGION_LIST(...) \
196 };
197
198#define __ADD_REGION_TO_LIST(__NAME, ...) \
199 { \
200 .ptNext = (arm_2d_region_list_item_t *) \
201 &(__NAME[__COUNTER__ - __NAME##_offset]), \
202 .tRegion = { \
203 __VA_ARGS__ \
204 }, \
205 }
206
207#define ADD_REGION_TO_LIST(__NAME, ...) \
208 __ADD_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
209
210
211#define __ADD_LAST_REGION_TO_LIST(__NAME, ...) \
212 { \
213 .ptNext = NULL, \
214 .tRegion = { \
215 __VA_ARGS__ \
216 }, \
217 }
218
219#define ADD_LAST_REGION_TO_LIST(__NAME, ...) \
220 __ADD_LAST_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
221
222
223#define IMPL_PFB_ON_DRAW(__NAME) IMPL_ON_DRAW_EVT(__NAME)
224
225
226#define IMPL_PFB_ON_LOW_LV_RENDERING(__NAME) \
227 void __NAME(void *pTarget, \
228 const arm_2d_pfb_t *ptPFB, \
229 bool bIsNewFrame)
230
231
232#define IMPL_PFB_ON_FRAME_SYNC_UP(__NAME) \
233 bool __NAME(void *pTarget)
234
235#define IMPL_PFB_BEFORE_FLUSHING(__NAME) \
236 bool __NAME(void *pTarget, \
237 arm_2d_pfb_t *ptOrigin, \
238 arm_2d_pfb_t *ptScratch)
239
240
241/*!
242 * \brief a macro wrapper in lowercase to help initialising PFB service
243 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
244 * \param[in] __SCREEN_WIDTH the width of the screen
245 * \param[in] __SCREEN_HEIGHT the hight of the screen
246 * \param[in] __PIXEL_TYPE the integer type of the pixel, i.e. uint8_t, uint16_t,
247 * uint32_t
248 * \param[in] __COLOUR_FORMAT the screen colour format, i.e. ARM_2D_COLOUR_CCCN888,
249 * ARM_2D_COLOUR_RGB565 etc.
250 * \param[in] __WIDTH the width of the PFB block
251 * \param[in] __HEIGHT the height of the PFB block
252 * \note For the same number of pixels in a PFB block, please priority the width
253 * over height, for example, 240 * 1 is better than 30 * 8
254 * \param[in] __PFB_NUM the number of PFB blocks in the built-in PFB pool.
255 * \param[in] ... a code block to add additional initializer, see example below:
256 * \return arm_2d_err_t the result of the initialisation process
257 *
258 * \code {.c}
259
260 static ARM_NOINIT arm_2d_helper_pfb_t s_tExamplePFB;
261 ...
262 // initialise FPB helper
263 if (init_arm_2d_helper_pfb(
264 &s_tExamplePFB, // FPB Helper object
265 __GLCD_CFG_SCEEN_WIDTH__, // screen width
266 __GLCD_CFG_SCEEN_HEIGHT__, // screen height
267 uint16_t, // colour date type
268 ARM_2D_COLOUR_RGB565, // colour format
269 240, // PFB block width
270 1, // PFB block height
271 1, // number of PFB in the PFB pool
272 {
273 .evtOnLowLevelRendering = {
274 // callback for low level rendering
275 .fnHandler = &__pfb_render_handler,
276 },
277 .evtOnDrawing = {
278 // callback for drawing GUI
279 .fnHandler = &__pfb_draw_background_handler,
280 },
281 },
282 //.FrameBuffer.bSwapRGB16 = true,
283 ) < 0) {
284 //! error detected
285 assert(false);
286 }
287 * \endcode
288 *
289 */
290#define init_arm_2d_helper_pfb( __CB_ADDR, \
291 __SCREEN_WIDTH, \
292 __SCREEN_HEIGHT, \
293 __PIXEL_TYPE, \
294 __COLOUR_FORMAT, \
295 __WIDTH, \
296 __HEIGHT, \
297 __PFB_NUM, \
298 ... \
299 ) \
300 ARM_2D_HELPER_PFB_INIT( \
301 __CB_ADDR, \
302 __SCREEN_WIDTH, \
303 __SCREEN_HEIGHT, \
304 __PIXEL_TYPE, \
305 __COLOUR_FORMAT, \
306 __WIDTH, \
307 __HEIGHT, \
308 __PFB_NUM, \
309 ##__VA_ARGS__ \
310 )
311
312/*!
313 * \brief a macro wrapper to update the evtOnDrawring event handler
314 * \param[in] __CB_ADDR the address of the arm_2d_helper_pfb_t object
315 * \param[in] __HANDLER the new handler
316 * \param[in] ... [Optional] an address (of user defined structure) passed to the
317 * event handler.
318 * \return arm_2d_err_t the process result
319 */
320#define update_arm_2d_helper_pfb_on_draw_handler( \
321 __CB_ADDR, /* PFB Helper object address */ \
322 __HANDLER, /* new on-draw-handler function*/\
323 ...) /* An optional target address */ \
324 ARM_2D_HELPER_PFB_UPDATE_ON_DRAW_HANDLER( \
325 (__CB_ADDR), \
326 (__HANDLER),##__VA_ARGRS__)
327
328/*!
329 * \brief tell PFB helper that a low level LCD flushing work is complete
330 * \note This function is THREAD-SAFE, You can call this function asynchronously,
331 * e.g.
332 * - A ISR to indicate DMA-transfer complete event or
333 * - A different Thread
334 * \param[in] ptThis the PFB helper control block
335 * \param[in] ... the used PFB block.
336 * \note please do not use this parameter, it is only kept for backward
337 * compatability.
338 */
339#define arm_2d_helper_pfb_report_rendering_complete(__PFB_HELPER_PTR,...) \
340 __arm_2d_helper_pfb_report_rendering_complete((__PFB_HELPER_PTR), \
341 (NULL,##__VA_ARGS__))
342
343
344#define __arm_2d_helper_dirty_region_update_dirty_regions0 \
345 __arm_2d_helper_dirty_region_update_dirty_regions
346
347/*!
348 * \brief update a specified new region while erase the previous region
349 *
350 * \param[in] ptThis the target helper
351 * \param[in] ptTargetTile the target tile to draw content
352 * \param[in] ptVisibleArea a visible region in the target tile used to clip
353 * the ptNewRegion, NULL means no clipping.
354 * \param[in] ptNewRegion the new region to update, NULL means nothing
355 * to update
356 * \param[in] bIsNewFrame unused, keep for backward compatibility
357 */
358#define __arm_2d_helper_dirty_region_update_dirty_regions3( __helper_ptr, \
359 __tile_ptr, \
360 __visible_area_ptr, \
361 __new_region_ptr, \
362 __is_new_frame) \
363 __arm_2d_helper_dirty_region_update_dirty_regions2( \
364 (__helper_ptr), \
365 (__tile_ptr), \
366 (__visible_area_ptr), \
367 (__new_region_ptr))
368
369/*!
370 * \brief update a specified new region while erase the previous region
371 *
372 * \param[in] ptThis the target helper
373 * \param[in] ptTargetTile the target tile to draw content
374 * \param[in] ptNewRegion the new region to update, NULL means nothing
375 * to update
376 */
377#define __arm_2d_helper_dirty_region_update_dirty_regions1( __helper_ptr, \
378 __tile_ptr, \
379 __new_region_ptr) \
380 __arm_2d_helper_dirty_region_update_dirty_regions2( \
381 (__helper_ptr), \
382 (__tile_ptr), \
383 NULL, \
384 (__new_region_ptr))
385
386
387/*!
388 * \brief update a specified new region while erase the previous region
389 *
390 * \param[in] __helper_ptr the target helper
391 * \param[in] __tile_ptr the target tile to draw content
392 * \param[in] ... optional parameters, and the following combinations are valid:
393 * a. new region ptr
394 * b. the canvas ptr and the new region ptr
395 * c. the canvas ptr, the new region ptr and a reserved option
396 * (bIsNewFrame)
397 */
398#define arm_2d_helper_dirty_region_update_dirty_regions( __helper_ptr, \
399 __tile_ptr, \
400 ...) \
401 ARM_CONNECT2(__arm_2d_helper_dirty_region_update_dirty_regions, \
402 __ARM_VA_NUM_ARGS(__VA_ARGS__))((__helper_ptr), \
403 (__tile_ptr) \
404 ,##__VA_ARGS__)
405
406/*!
407 * \brief update a specified new region while erase the previous region
408 *
409 * \param[in] __item_ptr the target region item
410 * \param[in] __target_tile_ptr the target tile to draw content
411 * \param[in] __visible_region_ptr a visible region in the target tile used to clip
412 * the ptNewRegion, NULL means no clipping.
413 * \param[in] __new_region_ptr the new region to update, NULL means nothing
414 * to update
415 */
416#define __arm_2d_helper_dirty_region_update_item4( __item_ptr, \
417 __target_tile_ptr, \
418 __visible_region_ptr, \
419 __new_region_ptr) \
420 __arm_2d_helper_dirty_region_item_update((__item_ptr), \
421 (__target_tile_ptr), \
422 (__visible_region_ptr), \
423 (__new_region_ptr))
424
425/*!
426 * \brief deprecated
427 *
428 */
429#define __arm_2d_helper_dirty_region_update_item5( __dirty_region_helper_ptr, \
430 __item_ptr, \
431 __target_tile_ptr, \
432 __visible_region_ptr, \
433 __new_region_ptr) \
434 __arm_2d_helper_dirty_region_item_update((__item_ptr), \
435 (__target_tile_ptr), \
436 (__visible_region_ptr), \
437 (__new_region_ptr))
438
439#define arm_2d_helper_dirty_region_update_item(...) \
440 ARM_CONNECT2( __arm_2d_helper_dirty_region_update_item, \
441 __ARM_VA_NUM_ARGS(__VA_ARGS__) \
442 )(__VA_ARGS__)
443
444
445#define impl_arm_2d_region_list(__NAME, ...) \
446 IMPL_ARM_2D_REGION_LIST(__NAME,##__VA_ARGS__)
447#define add_region_to_list(__NAME, ...) \
448 ADD_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
449#define add_last_region_to_list(__NAME, ...) \
450 ADD_LAST_REGION_TO_LIST(__NAME, ##__VA_ARGS__)
451#define end_impl_arm_2d_region_list(...) \
452 END_IMPL_ARM_2D_REGION_LIST(__VA_ARGS__)
453
454#define impl_pfb_on_draw(__NAME) IMPL_PFB_ON_DRAW(__NAME)
455#define impl_pfb_on_low_lv_rendering(__NAME) \
456 IMPL_PFB_ON_LOW_LV_RENDERING(__NAME)
457
458/*============================ TYPES =========================================*/
459
460/*!
461 * \brief direct mode helper service frame-buffer control block states
462 *
463 * \note state transition diagram
464 * <<< service initialization >>>
465 * |
466 * ARM_3FB_STATE_READY_FOR_FLUSH <------+
467 * | |
468 * ARM_3FB_STATE_FLUSHING |
469 * | |
470 * ARM_3FB_STATUS_UNUSED ---> ARM_3FB_STATE_READY_TO_DRAW |
471 * | |
472 * ARM_3FB_STATE_COPYING_AS_TARGET |
473 * |
474 * ARM_3FB_STATE_DRAWING |
475 * | |
476 * ARM_3FB_STATE_COPYING_AS_SOURCE -----+
477 *
478 */
479enum {
480 ARM_3FB_STATE_UNUSED = 0, //!< the FB hasn't been used
481 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)
482 ARM_3FB_STATE_READY_TO_DRAW, //!< the FB is ready to draw, the previous state is ARM_3FB_STATE_COPYING_AS_TARGET
483 ARM_3FB_STATE_DRAWING, //!< the FB is used for drawing, the previous state is ARM_3FB_STATE_READY_TO_DRAW
484 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
485 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
486 ARM_3FB_STATE_FLUSHING, //!< the FB is used for flushing, the previous state is ARM_3FB_STATE_READY_FOR_FLUSH
487};
488
490
491/*!
492 * \brief An interface for 2D-Copy.
493 * \param[in] pnSource the source image address
494 * \param[in] wSourceStride the stride of the source image
495 * \param[in] pnTarget the address in the target framebuffer
496 * \param[in] wTargetStride the stride of the target framebuffer
497 * \param[in] iWidth the safe width of the source image
498 * \param[in] iHeight the safe height of the source image
499 * \retval true the 2D copy is complete when leaving this function
500 * \retval false An async 2D copy request is sent to the DMA
501 */
502typedef
504 void *pObj,
505 uintptr_t pnSource,
506 uint32_t wSourceStride,
507 uintptr_t pnTarget,
508 uint32_t wTargetStride,
509 int16_t iWidth,
510 int16_t iHeight,
511 uint_fast8_t chBytePerPixel );
512
515 void *pObj;
517
518/*!
519 * \brief An interface for DMA memory-to-memory copy.
520 * If you have a DMA, you can implement this function by using
521 * __OVERRIDE_WEAK.
522 * You should implement an ISR for copy-complete event and call
523 * arm_2d_helper_3fb_report_dma_copy_complete() to notify the
524 * 3FB (direct mode) helper service.
525 *
526 * \param[in] ptThis the helper service control block
527 * \param[in] pObj the address of the user object
528 * \param[in] pnSource the source address of the memory block
529 * \param[in] pnTarget the target address
530 * \param[in] nDataItemCount the number of date items
531 * \param[in] chDataItemSize the size of each data item
532 */
533typedef
535 void *pObj,
536 uintptr_t pnSource,
537 uintptr_t pnTarget,
538 uint32_t nDataItemCount,
539 uint_fast8_t chDataItemSize);
540
543 void *pObj;
545
546/*!
547 * \brief configuration structure for the 3fb (direct mode) helper service
548 */
550 arm_2d_size_t tScreenSize; //!< the screen size
551 uint8_t chPixelBits; //!< the number of bits in one pixel
552 uintptr_t pnAddress[3]; //!< addresses of the 3 full-frame-buffer
553
554 arm_2d_helper_2d_copy_evt_t evtOn2DCopy;
555 arm_2d_helper_dma_copy_evt_t evtOnDMACopy;
557
558#define ARM_2D_3FB_INVALID_IDX 3
559
560/*!
561 * \brief the control block of the 3FB (direct mode) service
562 */
563typedef struct arm_2d_helper_3fb_t {
564ARM_PRIVATE(
566
567 struct {
568 uint8_t u2Drawing : 2; //!< FB pointer for drawing
569 uint8_t u2Flushing : 2; //!< FB pointer for flushing
570 uint8_t u2ReadyToFlush : 2; //!< FB pointer of ready to flush
571 uint8_t u2ReadyToDraw : 2; //!< FB pointer of ready to draw
572 uint8_t tState[3];
573 uintptr_t tSemaphore; //!< semaphore for async access
574 bool bFBCopyComplete; //!< a flag to indicate the completion of a DMA copy
575 } Runtime;
578
580
581/*!
582 * \brief the header of a PFB block
583 */
584typedef struct arm_2d_pfb_t {
585 struct arm_2d_pfb_t *ptNext; //!< next pfb block
586 arm_2d_helper_pfb_t *ptPFBHelper; //!< the pfb helper service current PFB block comes from
587 arm_2d_tile_t tTile; //!< descriptor
588 uint32_t u24Size : 24;
589 uint32_t u7ColourFormat : 7; //!< colour format
590 uint32_t bIsNewFrame : 1; //!< a flag to indicate the starting of a frame
592
593/*!
594 * \brief the node of a region list
595 *
596 */
598 struct arm_2d_region_list_item_t *ptNext; //!< the next node
599ARM_PRIVATE(
600 struct arm_2d_region_list_item_t *ptInternalNext; //!< the next node in the internal list
602 arm_2d_region_t tRegion; //!< the region
603
604ARM_PROTECTED(
605 uint8_t chUserRegionIndex; //!< User Region Index, used to indicate updating which dynamic dirty regions
606 uint8_t bIgnore : 1; //!< ignore this region
607 uint8_t bUpdated : 1; //!< this region item has been updated, PFB helper should refresh it again.
608 uint8_t : 6; //!< reserved for the future
609
610 uint16_t bFromInternalPool : 1; //!< a flag indicating whether this list item coming from the internal pool
611 uint16_t bFromHeap : 1; //!< whether this item comes from the HEAP
612 uint16_t u2UpdateState : 2; //!< reserved for internal FSM
613 uint16_t u12KEY : 12; //!< KEY
614)
615
617
618/*!
619 * \brief the On Low Level Rendering event handler for the low level (LCD Driver)
620 *
621 * \param[in] pTarget a user attached target address
622 * \param[in] ptPFB the PFB block
623 * \param[in] bIsNewFrame a flag indicate the starting of a new frame
624 */
626 void *pTarget,
627 const arm_2d_pfb_t *ptPFB,
628 bool bIsNewFrame);
629
630/*!
631 * \brief low level render event
632 */
634 arm_2d_helper_render_handler_t *fnHandler; //!< event handler function
635 void *pTarget; //!< user attached target
637
638/*!
639 * \brief before-flushing event handler
640 * \param[in] ptOrigin the original PFB
641 * \param[in] ptScratch A scratch PFB
642 * \return true the new content is stored in ptScratch
643 * \return false the new content is stored in ptOrigin
644 */
645typedef bool arm_2d_helper_before_flushing_handler_t( void *pTarget,
646 arm_2d_pfb_t *ptOrigin,
647 arm_2d_pfb_t *ptScratch);
648
649/*!
650 * \brief screen rotation event
651 */
654 void *pTarget;
656
657/*!
658 * \brief the enumeration for events
659 *
660 */
661enum {
662 ARM_2D_PFB_DEPEND_ON_LOW_LEVEL_RENDERING = _BV(0), //!< On Low Level Rendering Event
663 ARM_2D_PFB_DEPEND_ON_DRAWING = _BV(1), //!< On Drawing Event
664 ARM_2D_PFB_DEPEND_ON_LOW_LEVEL_SYNC_UP = _BV(2), //!< On Low Level Sync-up Event
665 ARM_2D_PFB_DEPEND_ON_FRAME_SYNC_UP = _BV(3), //!< On Frame Sync-up Event
666 ARM_2D_PFB_DEPEND_ON_EACH_FRAME_CPL = _BV(4), //!< On Each Frame Complete Event
667 ARM_2D_PFB_DEPEND_ON_NAVIGATION = _BV(5), //!< On Drawing Navigation Event
668};
669
670/*!
671 * \brief The PFB Helper Service Dependency
672 *
673 */
675 //! event handler for low level rendering
677
678 //! event handler for drawing GUI
679 arm_2d_helper_draw_evt_t evtOnDrawing;
680
681 //! low level rendering handler wants to sync-up (return arm_fsm_rt_wait_for_obj)
683
684 //! event handler for each frame complete
686
687 //! event handler for drawing GUI
688 struct {
689 arm_2d_helper_draw_evt_t evtOnDrawing;
690 arm_2d_region_list_item_t *ptDirtyRegion;
692
693 //! event handler for screen rotation
695
697
698/*!
699 * \brief PFB Helper configuration
700 *
701 */
703
704 arm_2d_region_t tDisplayArea; //!< screen description
705
706 struct {
707 arm_2d_pfb_t *ptPFBs; //!< PFB blocks for the internal PFB pool
708 arm_2d_size_t tFrameSize; //!< the size of the frame
709 uint32_t u24BufferSize : 24; //!< the buffer size
710 uint32_t u7ColourFormat : 7 ; //!< the colour format
711 uint32_t : 1 ; //!< reserved
712 uint32_t u8PFBNum : 8; //!< the number of PFB
713 uint32_t bDoNOTUpdateDefaultFrameBuffer : 1; //!< A flag to disable automatically default-framebuffer-registration
714 uint32_t bDisableDynamicFPBSize : 1; //!< A flag to disable resize of the PFB block
715 uint32_t bSwapRGB16 : 1; //!< A flag to enable swapping high and low bytes of an RGB16 pixel
716 uint32_t bDebugDirtyRegions : 1; //!< A flag to show dirty regions on screen for debug
717 uint32_t : 10;
718 uint32_t u3PixelWidthAlign : 3; //!< Pixel alignment in Width for dirty region (2^n)
719 uint32_t u3PixelHeightAlign : 3; //!< Pixel alignment in Height for dirty region (2^n)
720 uint32_t u4PoolReserve : 4; //!< reserve specific number of PFB for other helper services
721
722 } FrameBuffer; //!< frame buffer context
723
724 struct {
725 arm_2d_region_list_item_t *ptRegions; //!< dirty region list item for internal pool
726 uint8_t chCount; //!< number of dirty region list items
727 } DirtyRegion;
728
729 arm_2d_helper_pfb_dependency_t Dependency; //!< user registered dependency
730
732
733/*!
734 * \brief the type of perf counter
735 *
736 */
737typedef enum {
738 ARM_2D_PERFC_RENDER = 0,
739 ARM_2D_PERFC_DRIVER,
740
741 __ARM_2D_PERFC_COUNT,
743
744/*!
745 * \brief the PFB helper control block
746 *
747 */
749
750ARM_PRIVATE(
751 arm_2d_helper_pfb_cfg_t tCFG; //!< user configuration
752
753 struct {
754 arm_2d_location_t tScanOffset;
755 arm_2d_region_t tTargetRegion;
756
757 arm_2d_region_list_item_t *ptDirtyRegion;
758
759 struct {
760 arm_2d_region_list_item_t *ptWorkingList;
761 arm_2d_region_list_item_t *ptOriginalList;
762 arm_2d_region_list_item_t *ptCandidateList;
763 arm_2d_region_list_item_t *ptFreeList;
764 arm_2d_region_list_item_t tWorkingItem;
765 int16_t iFreeCount;
766 } OptimizedDirtyRegions;
767
768 arm_2d_tile_t tPFBTile;
769 arm_2d_size_t tFrameSize;
770 uint32_t wPFBPixelCount;
771
772 uint8_t chPT;
773 uint8_t chFreePFBCount;
774 struct {
775 uint16_t bIsDirtyRegionOptimizationEnabled : 1;
776 uint16_t bEnableDirtyRegionOptimizationRequest : 1;
777 uint16_t bDisableDirtyRegionOptimizationRequest : 1;
778 uint16_t bEncounterDynamicDirtyRegion : 1;
779 uint16_t bFailedToOptimizeDirtyRegion : 1;
780 uint16_t bIsUsingOptimizedDirtyRegionList : 1;
781 uint16_t bDirtyRegionDebugModeSkipFrame : 1;
782 uint16_t : 1;
783
784 uint16_t bIsNewFrame : 1;
785 uint16_t bIgnoreCanvasColour : 1;
786 uint16_t bIgnoreLowLevelFlush : 1;
787 uint16_t bHideNavigationLayer : 1;
788 uint16_t bIsDryRun : 1; //!< A flag to indicate whether the first iteration was a dry run
789 uint16_t bNoAdditionalDirtyRegionList : 1;
790 uint16_t bFirstIteration : 1;
791 uint16_t bIsRegionChanged : 1;
792 };
793
794 arm_2d_colour_t tCanvas;
795
796 uintptr_t pFPBPoolAvailable;
797 arm_2d_pfb_t *ptCurrent;
798 arm_2d_pfb_t *ptFreeList;
799 arm_2d_pfb_t *ptFlushing;
800 struct {
801 arm_2d_pfb_t *ptHead;
802 arm_2d_pfb_t *ptTail;
803 }FlushFIFO;
804 arm_2d_tile_t *ptFrameBuffer;
805 } Adapter;
807
808 struct {
809 int64_t lTimestamp; //!< PLEASE DO NOT USE
810 int32_t nTotalCycle; //!< cycles used by drawing
811 int32_t nRenderingCycle; //!< cycles used in LCD flushing
812 } Statistics; //!< performance statistics
813
814};
815
818
820
821ARM_PRIVATE(
824
825 union {
826 arm_2d_region_t tRegions[2];
827 struct {
828 arm_2d_region_t tNewRegion;
829 union {
830 arm_2d_region_t tOldRegion;
831 arm_2d_region_t tEnclosureArea;
832 };
833 };
834 };
835
836 arm_2d_region_t tExtraAreaToInclude;
837
838 uint8_t bForceToUseMinimalEnclosure : 1;
839 uint8_t bSuspendUpdate : 1;
840 uint8_t bIgnore : 1;
841 uint8_t bOnlyUpdateMinimalEnclosure : 1;
842 uint8_t : 4;
843 uint8_t chUpdateLifeCycle; /* a life cycle counter used to avoid repeated update operations in the same frame.*/
844
845 uint16_t u16Key;
847 arm_2d_region_t tRegionPatch;
848
849
850};
851
853
854ARM_PRIVATE(
855 arm_2d_region_list_item_t tDirtyRegion;
856 arm_2d_region_list_item_t **ppDirtyRegionList;
857
858 /* region items */
860
861 uint8_t chUpdateLifeCycle;
862 uint8_t : 8;
863 uint16_t : 16;
865
867
868} ;
869
870/*!
871 * \brief the Transform helper control block
872 *
873 */
875
876 float fAngle;
877 float fScale;
879ARM_PRIVATE(
880
881 arm_2d_op_t *ptTransformOP;
882
884
885 struct {
886 float fValue;
887 float fStep;
888 } Angle;
889
890 struct {
891 float fValue;
892 float fStep;
893 } Scale;
894
895 bool bNeedUpdate;
897
899
900
901/*!
902 * \brief the Transform helper control block
903 * \note Deprecated.
904 */
905typedef struct {
907
908 float fAngle;
909 float fScale;
910
911ARM_PRIVATE(
912
913 arm_2d_op_t *ptTransformOP;
914
915 struct {
916 float fValue;
917 float fStep;
918 } Angle;
919
920 struct {
921 float fValue;
922 float fStep;
923 } Scale;
924
925 bool bNeedUpdate;
927
929
930
931
932/*============================ GLOBAL VARIABLES ==============================*/
933/*============================ LOCAL VARIABLES ===============================*/
934/*============================ PROTOTYPES ====================================*/
935
936/*!
937 * \brief initialize pfb helper service
938 * \param[in] ptThis the pfb helper control block
939 * \param[in] ptCFG the configuration
940 * \return arm_2d_err_t the process result
941 */
942extern
943ARM_NONNULL(1,2)
946/*!
947 * \brief uninitialize pfb helper service
948 * \param[in] ptThis the pfb helper control block
949 * \return none
950 */
951extern
952ARM_NONNULL(1)
954
955/*!
956 * \brief get the display (screen) region
957 * \param[in] ptThis the pfb helper control block
958 * \return arm_2d_region_t the screen region
959 */
960extern
961ARM_NONNULL(1)
963
964/*!
965 * \brief get the absolute location for a given location on the target tile canvas
966 * \param[in] ptTile the target tile
967 * \param[in] tLocation the location on the target tile canvas
968 * \return arm_2d_location_t the absolute location on a (virtual) screen or on
969 * a root tile canvas
970 */
971extern
972ARM_NONNULL(1)
974 arm_2d_tile_t *ptTile,
975 arm_2d_location_t tLocation);
976
977/*!
978 * \brief get the inital PFB size
979 * \param[in] ptThis the pfb helper control block
980 * \return arm_2d_size_t the PFB size
981 */
982extern
983ARM_NONNULL(1)
985
986extern
987/*!
988 * \brief test whether specified region is being drawing
989 *
990 * \param[in] ptTarget the target tile
991 * \param[in] ptRegion the target region to test
992 * \param[out] ppVirtualScreen the address of the pointer that used to point
993 * the virtual screen tile
994 * \return true the specified region is currently being drawing
995 * \return false the PFB is out of the range.
996 */
998 const arm_2d_region_t *ptRegion,
999 const arm_2d_tile_t **ppVirtualScreen);
1000
1001extern
1002/*!
1003 * \brief test whether the target region is active (used by PFB service)
1004 *
1005 * \param[in] ptTarget the target tile
1006 * \param[in] ptRegion the target region to test
1007 * \param bConsiderDryRun whether taking dry run into consideration
1008 * \return true the region is active
1009 * \return false the region is inactive
1010 */
1012 const arm_2d_region_t *ptRegion,
1013 bool bConsiderDryRun);
1014
1015/*!
1016 * \brief the task function for pfb helper
1017 * \param[in] ptThis an initialised PFB helper control block
1018 * \param[in] ptDirtyRegions a region list pending for refresh, NULL means
1019 * refreshing the whole screen
1020 * \retval arm_fsm_rt_cpl complete refreshing one frame
1021 * \retval arm_fsm_rt_on_going the refreshing work is on-going
1022 * \retval arm_fsm_rt_wait_for_obj user's OnDrawing event handler wants to wait
1023 * for some objects, e.g. semaphore etc.
1024 * \retval <0 An error is detected
1025 */
1026extern
1027ARM_NONNULL(1)
1029 arm_2d_region_list_item_t *ptDirtyRegions);
1030
1031/*!
1032 * \brief flush the FPB FIFO
1033 * \note This function is THREAD-SAFE
1034 * \note For normal usage, please DO NOT use this function unless you know what
1035 * you are doing.
1036 * \param[in] ptThis an initialised PFB helper control block
1037 */
1038extern
1039ARM_NONNULL(1)
1041
1042/*!
1043 * \brief hide the navigation layer
1044 * \param[in] ptThis an initialised PFB helper control block
1045 */
1046extern
1047ARM_NONNULL(1)
1049
1050/*!
1051 * \brief show the navigation layer if there is a valid one
1052 * \param[in] ptThis an initialised PFB helper control block
1053 */
1054extern
1055ARM_NONNULL(1)
1057
1058
1059/*!
1060 * \brief enable filling canvas with specified colour
1061 *
1062 * \param[in] ptThis an initialised PFB helper control block
1063 * \param[in] tColour the target canvas colour
1064 */
1065extern
1066ARM_NONNULL(1)
1068 arm_2d_colour_t tColour);
1069
1070extern
1071ARM_NONNULL(1)
1072/*!
1073 * \brief disable filling canvas with specified colour
1074 *
1075 * \param[in] ptThis an initialised PFB helper control block
1076 */
1078
1079/*!
1080 * \brief ignore the low level PFB flushing only
1081 * \param[in] ptThis an initialised PFB helper control block
1082 */
1083extern
1084ARM_NONNULL(1)
1086
1087/*!
1088 * \brief resume the low level PFB flushing
1089 * \param[in] ptThis an initialised PFB helper control block
1090 */
1091extern
1092ARM_NONNULL(1)
1094
1095/*!
1096 * \brief update PFB dependency (event handlers)
1097 * \param[in] ptThis the PFB helper control block
1098 * \param[in] chMask the bit mask for event handlers
1099 * \param[in] ptDependency the new dependency description
1100 * \return arm_2d_err_t the process result
1101 */
1102extern
1103ARM_NONNULL(1,3)
1105 arm_2d_helper_pfb_t *ptThis,
1106 uint_fast8_t chMask,
1107 const arm_2d_helper_pfb_dependency_t *ptDependency);
1108
1109/*!
1110 * \brief tell PFB helper that a low level LCD flushing work is complete
1111 * \note This function is THREAD-SAFE, You can call this function asynchronously,
1112 * e.g.
1113 * - A ISR to indicate DMA-transfer complete event or
1114 * - A different Thread
1115 * \param[in] ptThis the PFB helper control block
1116 * \param[in] ptPFB the used PFB block
1117 */
1118extern
1119ARM_NONNULL(1)
1121 arm_2d_pfb_t *ptPFB);
1122
1123/*!
1124 * \brief try to get a PFB block from the pool
1125 * \param[in] ptThis the PFB helper control block
1126 * \retval NULL the pool is empty
1127 * \retval !NULL a valid pfb block
1128 */
1129extern
1130ARM_NONNULL(1)
1132
1133/*!
1134 * \brief free a PFB block to the pool
1135 * \param[in] ptThis the PFB helper control block
1136 * \param[in] ptPFB the target PFB block
1137 */
1138extern
1139ARM_NONNULL(1)
1141
1142/*!
1143 * \brief initialize the 3FB (direct mode) service
1144 * \param[in] ptThis the helper service control block
1145 * \param[in] ptCFG the configuration structure
1146 */
1147extern
1148ARM_NONNULL(1,2)
1150 const arm_2d_helper_3fb_cfg_t *ptCFG);
1151
1152
1153/*!
1154 * \brief report the copy-completion event to the 3FB (direct mode) service
1155 * \note see function __arm_2d_helper_3fb_dma_copy for details
1156 * \param[in] ptThis the helper service control block
1157 */
1158extern
1159ARM_NONNULL(1)
1161
1162/*!
1163 * \brief get a pointer for flushing
1164 * \param[in] ptThis the helper service control block
1165 * \return void * the address of a framebuffer
1166 *
1167 * \note please only call this function when on vsync event.
1168 */
1169extern
1170ARM_NONNULL(1)
1172
1173/*!
1174 * \brief please do NOT use this function. It is used by the display adapter.
1175 */
1176extern
1177ARM_NONNULL(1,2)
1179 const arm_2d_pfb_t *ptPFB);
1180
1181
1182/*!
1183 * \brief rotate a given c8bit PFB for 90 degree
1184 * \param[in] ptOrigin the original PFB
1185 * \param[in] ptScratch A scratch PFB
1186 * \param[in] ptScreenSize the screen size
1187 * \return arm_2d_pfb_t * the output PFB
1188 */
1189ARM_NONNULL(1,2,3)
1191 arm_2d_pfb_t *ptOrigin,
1192 arm_2d_pfb_t *ptScratch,
1193 const arm_2d_size_t *ptScreenSize);
1194/*!
1195 * \brief rotate a given c8bit PFB for 180 degree
1196 * \param[in] ptOrigin the original PFB
1197 * \param[in] ptScratch A scratch PFB
1198 * \param[in] ptScreenSize the screen size
1199 * \return arm_2d_pfb_t * the output PFB
1200 */
1201ARM_NONNULL(1,2,3)
1203 arm_2d_pfb_t *ptOrigin,
1204 arm_2d_pfb_t *ptScratch,
1205 const arm_2d_size_t *ptScreenSize);
1206/*!
1207 * \brief rotate a given c8bit PFB for 270 degree
1208 * \param[in] ptOrigin the original PFB
1209 * \param[in] ptScratch A scratch PFB
1210 * \param[in] ptScreenSize the screen size
1211 * \return arm_2d_pfb_t * the output PFB
1212 */
1213ARM_NONNULL(1,2,3)
1215 arm_2d_pfb_t *ptOrigin,
1216 arm_2d_pfb_t *ptScratch,
1217 const arm_2d_size_t *ptScreenSize);
1218
1219/*!
1220 * \brief rotate a given rgb16 PFB for 90 degree
1221 * \param[in] ptOrigin the original PFB
1222 * \param[in] ptScratch A scratch PFB
1223 * \param[in] ptScreenSize the screen size
1224 * \return arm_2d_pfb_t * the output PFB
1225 */
1226ARM_NONNULL(1,2,3)
1228 arm_2d_pfb_t *ptOrigin,
1229 arm_2d_pfb_t *ptScratch,
1230 const arm_2d_size_t *ptScreenSize);
1231
1232/*!
1233 * \brief rotate a given rgb16 PFB for 180 degree
1234 * \param[in] ptOrigin the original PFB
1235 * \param[in] ptScratch A scratch PFB
1236 * \param[in] ptScreenSize the screen size
1237 * \return arm_2d_pfb_t * the output PFB
1238 */
1239ARM_NONNULL(1,2,3)
1241 arm_2d_pfb_t *ptOrigin,
1242 arm_2d_pfb_t *ptScratch,
1243 const arm_2d_size_t *ptScreenSize);
1244
1245/*!
1246 * \brief rotate a given rgb16 PFB for 270 degree
1247 * \param[in] ptOrigin the original PFB
1248 * \param[in] ptScratch A scratch PFB
1249 * \param[in] ptScreenSize the screen size
1250 * \return arm_2d_pfb_t * the output PFB
1251 */
1252ARM_NONNULL(1,2,3)
1254 arm_2d_pfb_t *ptOrigin,
1255 arm_2d_pfb_t *ptScratch,
1256 const arm_2d_size_t *ptScreenSize);
1257
1258/*!
1259 * \brief rotate a given rgb32 PFB for 90 degree
1260 * \param[in] ptOrigin the original PFB
1261 * \param[in] ptScratch A scratch PFB
1262 * \param[in] ptScreenSize the screen size
1263 * \return arm_2d_pfb_t * the output PFB
1264 */
1265ARM_NONNULL(1,2,3)
1267 arm_2d_pfb_t *ptOrigin,
1268 arm_2d_pfb_t *ptScratch,
1269 const arm_2d_size_t *ptScreenSize);
1270/*!
1271 * \brief rotate a given rgb32 PFB for 180 degree
1272 * \param[in] ptOrigin the original PFB
1273 * \param[in] ptScratch A scratch PFB
1274 * \param[in] ptScreenSize the screen size
1275 * \return arm_2d_pfb_t * the output PFB
1276 */
1277ARM_NONNULL(1,2,3)
1279 arm_2d_pfb_t *ptOrigin,
1280 arm_2d_pfb_t *ptScratch,
1281 const arm_2d_size_t *ptScreenSize);
1282
1283/*!
1284 * \brief rotate a given rgb32 PFB for 270 degree
1285 * \param[in] ptOrigin the original PFB
1286 * \param[in] ptScratch A scratch PFB
1287 * \param[in] ptScreenSize the screen size
1288 * \return arm_2d_pfb_t * the output PFB
1289 */
1290ARM_NONNULL(1,2,3)
1292 arm_2d_pfb_t *ptOrigin,
1293 arm_2d_pfb_t *ptScratch,
1294 const arm_2d_size_t *ptScreenSize);
1295
1296/*----------------------------------------------------------------------------*
1297 * Dirty Regions *
1298 *----------------------------------------------------------------------------*/
1299
1300/*!
1301 * \brief append dirty regions to the a specified list
1302 * \param[in] ppDirtyRegionList the target list
1303 * \param[in] ptItems the dirty regions
1304 * \param[in] tCount the number of dirty regions
1305 * \retval true operation is successful
1306 * \retval false the operation is failed.
1307 */
1308extern
1309ARM_NONNULL(1,2)
1311 arm_2d_region_list_item_t **ppDirtyRegionList,
1313 size_t tCount);
1314
1315/*!
1316 * \brief remove dirty regions from the a specified list
1317 * \param[in] ppDirtyRegionList the target list
1318 * \param[in] ptItems the dirty regions
1319 * \param[in] tCount the number of dirty regions
1320 * \retval true operation is successful
1321 * \retval false the operation is failed.
1322 */
1323extern
1324ARM_NONNULL(1,2)
1326 arm_2d_region_list_item_t **ppDirtyRegionList,
1328 size_t tCount);
1329
1330/*!
1331 * \brief decide whether ignore the specified dirty region item
1332 *
1333 * \param[in] ptThis the target dirty region item object
1334 * \param[in] bIgnore whether ignore
1335 * \return bool the previous ignore status
1336 */
1337extern
1338ARM_NONNULL(1)
1340
1341
1342/*!
1343 * \brief get the ignore status of a given dirty region item
1344 *
1345 * \param[in] ptThis the target dirty region item object
1346 * \retval true the dirty region item is ignored.
1347 * \retval false the dirty region item is in-use.
1348 */
1349extern
1350ARM_NONNULL(1)
1352
1353/*!
1354 * \brief enable dirty region optimization service
1355 * \param[in] ptThis the PFB helper control block
1356 * \param[in] ptRegions an optional array of dirty region items, which will be
1357 * added to the dirty region item pool. NULL is acceptable.
1358 * \param[in] chCount the number of items in the array.
1359 */
1360extern
1361ARM_NONNULL(1)
1363 arm_2d_helper_pfb_t *ptThis,
1364 arm_2d_region_list_item_t *ptRegions,
1365 uint_fast8_t chCount);
1366/*!
1367 * \brief disable dirty region optimization service
1368 * \param[in] ptThis the PFB helper control block
1369 */
1370extern
1371ARM_NONNULL(1)
1373 arm_2d_helper_pfb_t *ptThis);
1374
1375/*----------------------------------------------------------------------------*
1376 * The Dynamic Dirty Region Service *
1377 *----------------------------------------------------------------------------*/
1378/*!
1379 * \brief the on-frame-start event handler for a given user dynamic dirty region
1380 *
1381 * \param[in] ptThis the target region list item.
1382 * \param[in] chUserRegionIndex a specified user region index. When 0xFF is given,
1383 * the existing user region index will not be changed.
1384 *
1385 */
1386extern
1387ARM_NONNULL(1)
1390 uint8_t chUserRegionIndex);
1391
1392/*!
1393 * \brief initialize a dynamic dirty region
1394 *
1395 * \param[in] ptThis the target region list item. If it is NULL, this function will
1396 * allocate an object from the heap
1397 * \return arm_2d_region_list_item_t* the target region list item
1398 */
1399extern
1402
1403/*!
1404 * \brief depose a given dynamic dirty region
1405 *
1406 * \param[in] ptThis the target region list item.
1407 */
1408extern
1409ARM_NONNULL(1)
1411
1412/*!
1413 * \brief wait for the PFB helper service requesting the next region
1414 *
1415 * \param[in] ptThis the target region list item.
1416 * \return uint_fast8_t the user region index
1417 *
1418 * \note You can use the return value, i.e. the user region index to address
1419 * the new region you want to cover.
1420 */
1421extern
1422ARM_NONNULL(1)
1425
1426/*!
1427 * \brief update a given user dynamic dirty region with a new region
1428 *
1429 * \param[in] ptThis the target region list item.
1430 * \param[in] ptTarget the target tile (the frame-buffer to draw)
1431 * \param[in] ptRegion the new region
1432 * \note - when the ptTarget isn't NULL, the ptRegion should points a region inside
1433 * the canvas of the ptTarget (i.e. an relative region of the ptTarget)
1434 * - when the ptTarget is NULL, this function will get the default framebuffer
1435 * by calling the function arm_2d_get_default_frame_buffer().
1436 *
1437 * \param[in] chNextUserIndex the next user region index, 0xFF means complete.
1438 */
1439extern
1440ARM_NONNULL(1)
1442 arm_2d_tile_t *ptTarget,
1443 arm_2d_region_t *ptRegion,
1444 uint8_t chNextUserIndex);
1445
1446/*!
1447 * \brief only change the user region index without update the dynamic dirty region
1448 *
1449 * \param[in] ptThis the target region list item.
1450 * \param[in] chNextUserIndex the next user region index. When encounter 0xFF, the
1451 * user region index will be reset to zero.
1452 */
1453extern
1454ARM_NONNULL(1)
1457 uint8_t chNextUserIndex);
1458
1459/*----------------------------------------------------------------------------*
1460 * The Dirty Region Helper Service *
1461 *----------------------------------------------------------------------------*/
1462
1463/*!
1464 * \brief initialize a given dirtt region helper
1465 * \param[in] ptThis the target helper
1466 * \param[in] ppDirtyRegionList the address of the dirty region list
1467 */
1468extern
1469ARM_NONNULL(1,2)
1472 arm_2d_region_list_item_t **ppDirtyRegionList);
1473extern
1474ARM_NONNULL(1,2)
1475/*!
1476 * \brief add an array of region items to a dirty region helper
1477 *
1478 * \param[in] ptThis the target helper
1479 * \param[in] ptItems the array of the region items
1480 * \param[in] hwCount the number of items in the array
1481 */
1485 uint_fast16_t hwCount);
1486extern
1487ARM_NONNULL(1,2)
1488/*!
1489 * \brief remove an array of region items to a dirty region helper
1490 *
1491 * \param[in] ptThis the target helper
1492 * \param[in] ptItems the array of the region items
1493 * \param[in] hwCount the number of items in the array
1494 */
1498 uint_fast16_t hwCount);
1499
1500/*!
1501 * \brief depose a given dirty region helper
1502 * \param[in] ptThis the target helper
1503 * \return arm_2d_helper_dirty_region_item_t * the region list items
1504 */
1505extern
1506ARM_NONNULL(1)
1508
1509/*!
1510 * \brief the on-frame-start event handler for a given dirty region helper
1511 * \param[in] ptThis the target helper
1512 * \note Usually this event handler should be insert the frame start event
1513 * handler of a target scene.
1514 */
1515extern
1516ARM_NONNULL(1)
1519
1520/*!
1521 * \brief update a specified new region while erase the previous region
1522 *
1523 * \param[in] ptThis the target region item
1524 * \param[in] ptTargetTile the target tile to draw content
1525 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1526 * the ptNewRegion, NULL means no clipping.
1527 * \param[in] ptNewRegion the new region to update, NULL means nothing
1528 * to update
1529 */
1530extern
1531ARM_NONNULL(1,2)
1534 const arm_2d_tile_t *ptTargetTile,
1535 const arm_2d_region_t *ptVisibleArea,
1536 const arm_2d_region_t *ptNewRegion);
1537
1538/*!
1539 * \brief update the "extra area" of a specified dirty region item
1540 *
1541 * \param[in] ptThis the target region item
1542 * \param[in] ptTargetTile the target tile to draw content
1543 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1544 * the ptNewRegion, NULL means no clipping.
1545 * \param[in] ptExtraRegion the new extra region
1546 */
1547extern
1548ARM_NONNULL(1,2)
1551 const arm_2d_tile_t *ptTargetTile,
1552 const arm_2d_region_t *ptVisibleArea,
1553 const arm_2d_region_t *ptExtraRegion);
1554
1555/*!
1556 * \brief update a specified new region while erase the previous region
1557 *
1558 * \param[in] ptThis the target helper
1559 * \param[in] ptTargetTile the target tile to draw content
1560 */
1561ARM_NONNULL(1,2)
1562extern
1565 const arm_2d_tile_t *ptTargetTile);
1566
1567/*!
1568 * \brief update a specified new region while erase the previous region
1569 *
1570 * \param[in] ptThis the target helper
1571 * \param[in] ptTargetTile the target tile to draw content
1572 * \param[in] ptVisibleArea a visible region in the target tile used to clip
1573 * the ptNewRegion, NULL means no clipping.
1574 * \param[in] ptNewRegion the new region to update, NULL means nothing
1575 * to update
1576 */
1577extern
1578ARM_NONNULL(1,2)
1581 const arm_2d_tile_t *ptTargetTile,
1582 const arm_2d_region_t *ptVisibleArea,
1583 const arm_2d_region_t *ptNewRegion);
1584
1585/*!
1586 * \brief force an arm_2d_helper_dirty_region_item_t object to use the minimal
1587 * enclosure region to update.
1588 *
1589 * \param[in] ptThis the target item
1590 * \param[in] bEnable whether enable this feature.
1591 * \return boolean the original setting
1592 */
1593ARM_NONNULL(1)
1596 bool bEnable);
1597
1598/*!
1599 * \brief force the dirty region helper to use the minimal enclosure region to
1600 * update.
1601 *
1602 * \param[in] ptThis the target helper
1603 * \param[in] bEnable whether enable this feature.
1604 * \return boolean the original setting
1605 */
1606extern
1607ARM_NONNULL(1)
1610 bool bEnable);
1611
1612/*!
1613 * \brief force the dirty region helper to suspend the dirty region update.
1614 *
1615 * \param[in] ptThis the target helper
1616 * \param[in] bEnable whether enable this feature.
1617 * \return boolean the original setting
1618 */
1619extern
1620ARM_NONNULL(1)
1623 bool bEnable);
1624
1625/*!
1626 * \brief force the arm_2d_helper_dirty_region_item_t object to suspend the
1627 * dirty region update.
1628 *
1629 * \param[in] ptThis the target item
1630 * \param[in] bEnable whether enable this feature.
1631 * \return boolean the original setting
1632 */
1633ARM_NONNULL(1)
1636 bool bEnable);
1637
1638/*----------------------------------------------------------------------------*
1639 * The Transform Helper Service (Deprecated) *
1640 *----------------------------------------------------------------------------*/
1641/*!
1642 * \brief initialize a given transform helper
1643 * \note Deprecated.
1644 * \param[in] ptThis the target helper
1645 * \param[in] ptTransformOP the target transform OP, NULL is not accepted.
1646 * \param[in] fAngleStep the minimal acceptable angle change.
1647 * \param[in] fScaleStep the minimal acceptable scale ratio change.
1648 * \param[in] ppDirtyRegionList the address of the dirty region list
1649 */
1650extern
1651ARM_NONNULL(1,2,5)
1653 arm_2d_op_t *ptTransformOP,
1654 float fAngleStep,
1655 float fScaleStep,
1656 arm_2d_region_list_item_t **ppDirtyRegionList);
1657
1658/*!
1659 * \brief depose a given transform helper
1660 * \note Deprecated.
1661 * \param[in] ptThis the target helper
1662 */
1663extern
1664ARM_NONNULL(1)
1666
1667/*!
1668 * \brief the on-frame-begin event handler for a given transform helper
1669 * \note Deprecated.
1670 * \param[in] ptThis the target helper
1671 * \note Usually this event handler should be insert the frame start event
1672 * handler of a target scene.
1673 */
1674extern
1675ARM_NONNULL(1)
1677
1678/*!
1679 * \brief force transform helper to update dirty region
1680 * \note Deprecated.
1681 * \note sometimes, we want to force transform helper to update dirty regions
1682 * even if both the angel and scale keep the same, for example, the pivots
1683 * are updated.
1684 * \param[in] ptThis the target helper
1685 */
1686extern
1687ARM_NONNULL(1)
1689
1690/*!
1691 * \brief force the transform helper to use the minimal enclosure region as
1692 * the dirty region.
1693 * \note Deprecated.
1694 * \param[in] ptThis the target helper
1695 * \param[in] bEnable whether enable this feature.
1696 * \return boolean the original setting
1697 */
1698extern
1699ARM_NONNULL(1)
1702 bool bEnable);
1703
1704/*!
1705 * \brief force the transform helper to suspend the dirty region update.
1706 * \note Deprecated.
1707 * \param[in] ptThis the target helper
1708 * \param[in] bEnable whether enable this feature.
1709 * \return boolean the original setting
1710 */
1711extern
1712ARM_NONNULL(1)
1714 bool bEnable);
1715
1716/*!
1717 * \brief update a given transform helper with new values
1718 * \note Deprecated.
1719 * \param[in] ptThis the target helper
1720 * \param[in] fAngle the new angle value
1721 * \param[in] fScale the new scale ratio
1722 * \note The new value is only accepted when the change between the old value
1723 * and the new value is larger than the minimal acceptable mount.
1724 */
1725extern
1726ARM_NONNULL(1)
1728 float fAngle,
1729 float fScale);
1730
1731/*!
1732 * \brief update the dirty region after a transform operation
1733 * \note Deprecated.
1734 * \param[in] ptThis the target helper
1735 * \param[in] ptCanvas the canvas
1736 * \param[in] bIsNewFrame whether this is a new frame
1737 */
1738extern
1739ARM_NONNULL(1)
1742 const arm_2d_region_t *ptCanvas,
1743 bool bIsNewFrame);
1744
1745
1746/*----------------------------------------------------------------------------*
1747 * The Dirty Region Transform Helper Service *
1748 *----------------------------------------------------------------------------*/
1749/*!
1750 * \brief initialize a given dirty region transform helper
1751 *
1752 * \param[in] ptThis the target helper
1753 * \param[in] ptHelper the host arm_2d_helper_dirty_region_t object.
1754 * \param[in] ptTransformOP the target transform OP, NULL is not accepted.
1755 * \param[in] fAngleStep the minimal acceptable angle change.
1756 * \param[in] fScaleStep the minimal acceptable scale ratio change.
1757 */
1758extern
1759ARM_NONNULL(1,2,3)
1763 arm_2d_op_t *ptTransformOP,
1764 float fAngleStep,
1765 float fScaleStep);
1766
1767/*!
1768 * \brief depose a given dirty region transform helper
1769 *
1770 * \param[in] ptThis the target helper
1771 */
1772extern
1773ARM_NONNULL(1)
1776
1777/*!
1778 * \brief the on-frame-begin event handler for a given dirty region transform
1779 * helper
1780 *
1781 * \param[in] ptThis the target helper
1782 * \note Usually this event handler should be insert the frame start event
1783 * handler of a target scene.
1784 */
1785extern
1786ARM_NONNULL(1)
1789
1790/*!
1791 * \brief force a dirty region transform helper to update its dirty region
1792 *
1793 * \note sometimes, we want to force transform helper to update dirty regions
1794 * even if both the angel and scale keep the same, for example, the pivots
1795 * are updated.
1796 * \param[in] ptThis the target helper
1797 */
1798extern
1799ARM_NONNULL(1)
1802
1803/*!
1804 * \brief force a dirty region transform helper to use the minimal enclosure
1805 * region as the dirty region.
1806 *
1807 * \param[in] ptThis the target helper
1808 * \param[in] bEnable whether enable this feature.
1809 * \return boolean the original setting
1810 */
1811extern
1812ARM_NONNULL(1)
1815 bool bEnable);
1816
1817/*!
1818 * \brief force a dirty region transform helper to suspend updating.
1819 *
1820 * \param[in] ptThis the target helper
1821 * \param[in] bEnable whether enable this feature.
1822 * \return boolean the original setting
1823 */
1824extern
1825ARM_NONNULL(1)
1828 bool bEnable);
1829
1830/*!
1831 * \brief update a given dirty region transform helper with new values
1832 *
1833 * \param[in] ptThis the target helper
1834 * \param[in] fAngle the new angle value
1835 * \param[in] fScale the new scale ratio
1836 * \note The new value is only accepted when the change between the old value
1837 * and the new value is larger than the minimal acceptable mount.
1838 */
1839extern
1840ARM_NONNULL(1)
1843 float fAngle,
1844 float fScale);
1845
1846/*!
1847 * \brief update the dirty region after a transform operation
1848 *
1849 * \param[in] ptThis the target helper
1850 * \param[in] ptCanvas the canvas
1851 * \param[in] bIsNewFrame whether this is a new frame
1852 */
1853extern
1854ARM_NONNULL(1)
1857 const arm_2d_region_t *ptCanvas,
1858 bool bIsNewFrame);
1859
1860
1861/*! @} */
1862
1863#if defined(__clang__)
1864# pragma clang diagnostic pop
1865#endif
1866
1867#ifdef __cplusplus
1868}
1869#endif
1870
1871
1872
1873#endif