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