Arm-2D  
2D Image Processing Library for Cortex-M Processors
arm_2d_helper_scene.h
1/*
2 * Copyright (C) 2022 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_scene.h"
22 * Description: Public header file for the scene service
23 *
24 * $Date: 16. May 2024
25 * $Revision: V.1.6.8
26 *
27 * Target Processor: Cortex-M cores
28 * -------------------------------------------------------------------- */
29
30#ifndef __ARM_2D_HELPER_SCENE_H__
31#define __ARM_2D_HELPER_SCENE_H__
32
33/*============================ INCLUDES ======================================*/
34#include "arm_2d_helper_pfb.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40#if defined(__clang__)
41# pragma clang diagnostic push
42# pragma clang diagnostic ignored "-Wunknown-warning-option"
43# pragma clang diagnostic ignored "-Wreserved-identifier"
44# pragma clang diagnostic ignored "-Wdeclaration-after-statement"
45# pragma clang diagnostic ignored "-Wpadded"
46# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
47#endif
48
49/*============================ MACROS ========================================*/
50
51/*!
52 * \addtogroup Deprecated
53 * @{
54 */
55#define arm_2d_scene_player_set_switching_period \
56 arm_2d_scene_player_set_auto_switching_period
57/*! @} */
58
59/*!
60 * \addtogroup gHelper 8 Helper Services
61 * @{
62 */
63/*============================ MACROFIED FUNCTIONS ===========================*/
64
65/*!
66 * \brief register / update the evtOnDrawNavigation event handler. You can use
67 * this event to draw an ALWAY-TOP navigation bar or title during switching
68 * period.
69 *
70 * \param[in] __DISP_ADAPTER_PTR the target scene player
71 * \param[in] __DRAW_HANDLER the event handler to draw the navigation bar and/or
72 * titles
73 * \param[in] __USER_TARGET_PTR the address of an user specified object. If it
74 * is NULL, ptThis will be used instead.
75 * \param[in] ... an optional dirty region list for the navigation layer. If
76 * ommited, NULL is used.
77 * \note if the optional dirty region list is omitted and the normal scene
78 * doesn't cover the region of the content in the navigation layer,
79 * you won't see the content.
80 * \return arm_2d_err_t the operation result
81 */
82#define arm_2d_scene_player_register_on_draw_navigation_event_handler( \
83 __SCENE_PLAYER_PTR, \
84 __DRAW_HANDLER, \
85 __USER_TARGET_PTR, \
86 ...) \
87 __arm_2d_scene_player_register_on_draw_navigation_event_handler( \
88 (__SCENE_PLAYER_PTR), \
89 (__DRAW_HANDLER), \
90 (__USER_TARGET_PTR), \
91 (NULL,##__VA_ARGS__))
92
93/*!
94 * \brief configure the scene switching mode
95 *
96 * \param[in] __DISP_ADAPTER_PTR the target scene player
97 * \param[in] __SWITCH_MODE a switching mode object
98 * \param[in] ... an optional configurations for the switching
99 */
100#define arm_2d_scene_player_set_switching_mode(__SCENE_PLAYER_PTR, \
101 __SWITCH_MODE, \
102 ...) \
103 __arm_2d_scene_player_set_switching_mode((__SCENE_PLAYER_PTR), \
104 &(__SWITCH_MODE), \
105 (0,##__VA_ARGS__))
106
107/*!
108 * \brief register / update the evtBeforeSwitching event handler. You can use
109 * this event to prepare next scenes.
110 *
111 * \param[in] ptThis the target scene player
112 * \param[in] fnHandler the event handler
113 * \param[in] ... optional, the address of an user specified object.
114 * \return arm_2d_err_t the operation result
115 */
116#define arm_2d_scene_player_register_before_switching_event_handler( \
117 __SCENE_PLAYER_PTR, \
118 __HANDLER, \
119 ...) \
120 __arm_2d_scene_player_register_before_switching_event_handler( \
121 (__SCENE_PLAYER_PTR), \
122 (__HANDLER), \
123 (NULL,##__VA_ARGS__))
124
125
126/*============================ TYPES =========================================*/
127
128/*!
129 * \brief scene switching mode
130 */
131typedef enum {
132
133 /* valid switching visual effects begin */
134 ARM_2D_SCENE_SWITCH_CFG_NONE = 0, //!< no switching visual effect
135 ARM_2D_SCENE_SWITCH_CFG_USER = 1, //!< user defined switching visual effect
136 ARM_2D_SCENE_SWITCH_CFG_FADE_WHITE = 2, //!< fade in fade out (white)
137 ARM_2D_SCENE_SWITCH_CFG_FADE_BLACK = 3, //!< fade in fade out (black)
142 ARM_2D_SCENE_SWITCH_CFG_ERASE_LEFT = 8, //!< erase to the right
144 ARM_2D_SCENE_SWITCH_CFG_ERASE_UP, //!< erase to the top
145 ARM_2D_SCENE_SWITCH_CFG_ERASE_DOWN, //!< erase to the bottom
146
147 /* valid switching visual effects end */
148 __ARM_2D_SCENE_SWITCH_CFG_VALID, //!< For internal user only
149
150 ARM_2D_SCENE_SWITCH_CFG_IGNORE_OLD_BG = _BV(8), //!< ignore the background of the old scene
151 ARM_2D_SCENE_SWITCH_CFG_IGNORE_OLD_SCEBE = _BV(9), //!< ignore the old scene
152 ARM_2D_SCENE_SWITCH_CFG_IGNORE_NEW_BG = _BV(10), //!< ignore the background of the new scene
153 ARM_2D_SCENE_SWITCH_CFG_IGNORE_NEW_SCEBE = _BV(11), //!< ignore the new scene
154
155 ARM_2D_SCENE_SWITCH_CFG_DEFAULT_BG_WHITE = 0 << 12, //!< use white as default background
156 ARM_2D_SCENE_SWITCH_CFG_DEFAULT_BG_BLACK = 1 << 12, //!< use black as default background
157 ARM_2D_SCENE_SWITCH_CFG_DEFAULT_BG_USER = 2 << 12, //!< use user defined default background
158
159 __ARM_2D_SCENE_SWTICH_CFG_IGNORE_msk = 0x0F << 8, //!< For internal user only
160 __ARM_2D_SCENE_SWTICH_CFG_IGNORE_pos = 8, //!< For internal user only
161 __ARM_2D_SCENE_SWTICH_CFG_DEFAULT_BG_msk = 3 << 12, //!< For internal user only
162 __ARM_2D_SCENE_SWTICH_CFG_DEFAULT_BG_pos = 12, //!< For internal user only
163
165
166/*!
167 * \brief the scene switching status
168 *
169 */
170typedef enum {
171 ARM_2D_SCENE_SWITCH_STATUS_AUTO, //!< time-based auto switching
172 ARM_2D_SCENE_SWITCH_STATUS_MANUAL, //!< offset-based manual switching
173 ARM_2D_SCENE_SWITCH_STATUS_MANUAL_CANCEL, //!< cancel existing manual switching
174 ARM_2D_SCENE_SWITCH_STATUS_MANUAL_AUTO_CPL, //!< automatically finish the rest part of switching.
176
177/*!
178 * \brief an internal data structure for scene switching
179 *
180 * \note Please do not use it.
181 */
183
184 struct {
185 uint8_t chMode; //!< the switch visual effect
186 uint8_t bIgnoreOldSceneBG : 1; //!< when set, ignore the background of the old scene
187 uint8_t bIgnoreOldScene : 1; //!< when set, ignore the old scene
188 uint8_t bIgnoreNewSceneBG : 1; //!< when set, ignore the background of the new scene
189 uint8_t bIgnoreNewScene : 1; //!< when set, ignore the new scene
190 uint8_t u2DefaultBG : 2; //!< the default background
191 uint8_t : 2;
192 } Feature;
193 uint16_t hwSetting; //!< the setting value
194
196
198
199/*!
200 * \brief scene switching mode descriptor
201 */
202typedef const struct {
203 uint8_t chEffects; //!< switching effects
204 arm_2d_helper_draw_handler_t *fnSwitchDrawer; //!< switching algorithm
205
206 void (*fnOnRequestChangeSwitchingStatus)(arm_2d_scene_player_t *ptThis); //!< on request change-switch-status event handler
208
209/*!
210 * \brief a class for describing scenes which are the combination of a
211 * background and a foreground with a dirty-region-list support
212 *
213 */
214typedef struct arm_2d_scene_t arm_2d_scene_t;
216ARM_PRIVATE(
217 arm_2d_scene_t *ptNext; //!< next scene
218
219 struct {
220 uint8_t bLoaded : 1;
221 uint8_t : 7;
222 };
224 arm_2d_scene_player_t *ptPlayer; //!< points to the host scene player
225
226 arm_2d_colour_t tCanvas; //!< the canvas colour
227
228 /*! \note Please do NOT use it unless it is necessary */
229 arm_2d_helper_draw_handler_t *fnBackground;
230
231 arm_2d_region_list_item_t *ptDirtyRegion; //!< dirty region list for the scene
232 arm_2d_helper_draw_handler_t *fnScene; //!< the function pointer for the scene
233
234 void (*fnOnLoad)(arm_2d_scene_t *ptThis); //!< on load event handler
235 void (*fnOnBGStart)(arm_2d_scene_t *ptThis); //!< on-start-drawing-background event handler
236 void (*fnOnBGComplete)(arm_2d_scene_t *ptThis); //!< on-complete-drawing-background event handler
237 void (*fnOnFrameStart)(arm_2d_scene_t *ptThis); //!< on-frame-start event handler
238 void (*fnOnFrameCPL)(arm_2d_scene_t *ptThis); //!< on-frame-complete event handler
239
240 /*!
241 * \note We can use this event to initialize/generate the new(next) scene
242 */
243 void (*fnBeforeSwitchOut)(arm_2d_scene_t *ptThis); //!< before-scene-switch-out event handler
244
245 /*!
246 * \note We use fnDepose to free the resources
247 */
248 void (*fnDepose)(arm_2d_scene_t *ptThis); //!< on-scene-depose event handler
249 struct {
250 uint8_t bOnSwitchingIgnoreBG : 1; //!< ignore background during switching period
251 uint8_t bOnSwitchingIgnoreScene : 1; //!< ignore forground during switching period
252 uint8_t : 2;
253 uint8_t : 3;
254 uint8_t bUseDirtyRegionHelper : 1; //!< indicate whether use the built-in dirty region helper.
255 };
256
257 arm_2d_helper_dirty_region_t tDirtyRegionHelper;
258};
259
260/*!
261 * \brief the scene player event handler
262 *
263 * \param[in] pTarget a user attached target address
264 * \param[in] ptPlayer the scene player
265 * \param[in] ptScene the old scene that is to be switched out
266 */
268 void *pTarget,
269 arm_2d_scene_player_t *ptPlayer,
270 arm_2d_scene_t *ptScene);
271
272/*!
273 * \brief on low level render event
274 */
277 void *pTarget; //!< user attached target
279
280/*!
281 * \brief a class to manage scenes
282 *
283 */
285 inherit(arm_2d_helper_pfb_t); //!< inherit from arm_2d_helper_pfb_t
286
287 struct {
288 uint32_t wMin;
289 uint32_t wMax;
290 uint64_t dwTotal;
291 uint64_t dwRenderTotal;
292 uint32_t wAverage;
293 float fCPUUsage;
294 uint16_t hwIterations;
295 uint16_t hwFrameCounter;
296 uint32_t wLCDLatency;
297 int64_t lTimestamp;
298 } Benchmark;
299
300 ARM_PRIVATE(
301 struct {
302 arm_2d_scene_t *ptHead; //!< points to the head of the FIFO
303 arm_2d_scene_t *ptTail; //!< points to the tail of the FIFO
304 } SceneFIFO; //!< Scene FIFO
305
306 struct {
307
308 uint8_t bNextSceneReq : 1; //!< a flag to request switching-to-the next-scene
309 uint8_t bManualSwitchReq : 1; //!< a flag to request using manual switching
310 uint8_t bCancelSwitchReq : 1; //!< a flag to request cancel a manual switching
311 uint8_t bFinishManualSwitchReq : 1; //!< a flag to request finishing a manual switching
312 uint8_t : 4;
313
314 uint8_t bManualSwitch : 1; //!< manual switching
315 uint8_t bCancelSwitch : 1; //!< cancel a manual switching
316 uint8_t bFinishManualSwitch : 1; //!< finish a manual switching
317 uint8_t : 5;
318
319 uint8_t bSwitchCPL : 1; //!< indication of scene switching completion
320 uint8_t bUpdateBG : 1; //!< update the background of the current scene
321 uint8_t : 2;
322 uint8_t bCallOldSceneFrameCPL : 1; //!< call the old scene frame complete event handler
323 uint8_t bCallNewSceneFrameCPL : 1; //!< call the new scene frame complete event handler
324 uint8_t bCallOldSceneBGCPL : 1; //!< call the old scene Background complete event handler
325 uint8_t bCallNewSceneBGCPL : 1; //!< call the new scene Background complete event handler
326
327 uint8_t chState; //!< the state of the FSM used by runtime.
328 } Runtime; //!< scene player runtime
329
330 struct {
331 arm_2d_scene_switch_mode_t *ptMode; //!< the switching mode
332 union {
333 uint8_t chState; //!< FSM state
334 struct {
335 uint8_t chState; //!< FSM state
336 uint8_t chOpacity; //!< opacity of the cover
337 bool bIsFadeBlack; //!< the colour of the cover
338 }Fade;
339 struct {
340 uint8_t chState; //!< FSM state
341 arm_2d_tile_t tSceneWindow; //!< scene window
342 arm_2d_tile_t tTemp; //!< a temp tile
343 int16_t iOffset; //!< erase offset
344 }Erase;
345 struct {
346 uint8_t chState; //!< FSM state
347 arm_2d_tile_t tSceneWindow; //!< scene window
348 int16_t iOffset; //!< slide offset
349 }Slide;
350 struct {
351 uint8_t chState; //!< FSM state
352 arm_2d_tile_t tSceneWindow; //!< scene window
353 int16_t iOffset; //!< slide offset
354 }Fly;
355 };
356 __arm_2d_helper_scene_switch_t tConfig; //!< the switching configuration
357
358 uint16_t hwPeriod; //!< the switching should finish in specified millisecond
359 int16_t iTouchOffset; //!< the coordinate offset for manual switching mode, used in erasing, sliding etc.
360 int16_t iFullLength;
361 int64_t lTimeStamp;
362 }Switch;
363
364 struct {
365 /*!
366 * \note We can use this event to initialize/generate the new(next) scene
367 */
368 arm_2d_scene_before_scene_switching_evt_t evtBeforeSwitching; //!< before-scene-switch-out event handler
369 } Events;
371};
372
373/*============================ GLOBAL VARIABLES ==============================*/
374
375extern
376arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_NONE;
377
378extern
379arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_USER;
380
381extern
382arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_FADE_WHITE;
383
384extern
385arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_FADE_BLACK;
386
387extern
388arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_SLIDE_LEFT;
389
390extern
391arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_SLIDE_RIGHT;
392
393extern
394arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_SLIDE_UP;
395
396extern
397arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_SLIDE_DOWN;
398
399extern
400arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_ERASE_LEFT;
401
402extern
403arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_ERASE_RIGHT;
404
405extern
406arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_ERASE_UP;
407
408extern
409arm_2d_scene_switch_mode_t ARM_2D_SCENE_SWITCH_MODE_ERASE_DOWN;
410
411/*============================ LOCAL VARIABLES ===============================*/
412/*============================ PROTOTYPES ====================================*/
413
414/*!
415 * \brief flush the scene FIFO
416 *
417 * \param[in] ptThis the target scene player
418 */
419extern
420ARM_NONNULL(1)
422
423/*!
424 * \brief append a set of scenes to a scene player
425 *
426 * \param[in] ptThis the target scene player
427 * \param[in] ptScenes a scene array
428 * \param[in] hwCount the number of scenes in the array
429 */
430extern
431ARM_NONNULL(1)
433 arm_2d_scene_t *ptScenes,
434 int_fast16_t hwCount);
435
436/*!
437 * \brief request updating the background of the current scene
438 * \param[in] ptThis the target scene player
439 */
440ARM_NONNULL(1)
442
443
444/*!
445 * \brief get the screen size of a specified display adapter.
446 *
447 * \param[in] ptThis the target scene player
448 * \return arm_2d_size_t the screen size
449 */
450extern
451ARM_NONNULL(1)
453
454/*!
455 * \brief request switching to the next scene safely
456 *
457 * \param[in] ptThis the target scene player
458 *
459 * \note Once received a request, the scene player will only switch to the
460 * next scene at the end of a frame.
461 */
462extern
463ARM_NONNULL(1)
465
466/*!
467 * \brief check whether scene player is switching scenes
468 *
469 * \param[in] ptThis the target scene player
470 * \return true the scene player is switching scenes
471 * \return false the scene player stays in tge current scene.
472 */
473extern
474ARM_NONNULL(1)
476
477/*!
478 * \brief get the scene player switching status
479 *
480 * \param[in] ptThis the target scene player
481 * \return arm_2d_scene_player_switch_status_t the switching status
482 */
483extern
484ARM_NONNULL(1)
487/*!
488 * \brief configure the scene switching mode
489 *
490 * \param[in] ptThis the target scene player
491 * \param[in] ptMode a switching mode object
492 * \param[in] hwSettings configurations for the switching
493 */
494extern
495ARM_NONNULL(1)
498 uint16_t hwSettings);
499
500/*!
501 * \brief read the current scene switching mode
502 *
503 * \param[in] ptThis the target scene player
504 * \return uint16_t the current setting value for the scene switching mode
505 */
506extern
507ARM_NONNULL(1)
509
510/*!
511 * \brief configure the scene switching period in auto-switching
512 *
513 * \param[in] ptThis the target scene player
514 * \param[in] iMS period in millisecond
515 */
516extern
517ARM_NONNULL(1)
519 int_fast16_t iMS);
520
521extern
522ARM_NONNULL(1)
523/*!
524 * \brief use manual switch mode and set the offset
525 *
526 * \param[in] ptThis the target scene player
527 * \param[in] iTouchOffset the touch offset
528 */
530 int16_t iTouchOffset);
531
532extern
533ARM_NONNULL(1)
534/*!
535 * \brief end the manual switching and finish the left part in a specific period (ms)
536 *
537 * \param[in] ptThis the target scene player
538 * \param[in] bMoveToPreviousScene a boolean value indicating whether move back to the
539 * previous scene, i.e. whether cancel the current switching
540 * \param iInMS the planned period as if the switching is done in auto-switching mode
541 * \return arm_2d_err_t configuration result
542 */
544 bool bMoveToPreviousScene,
545 int_fast16_t iInMS);
546
547/*!
548 * \brief register / update the evtOnDrawNavigation event handler. You can use
549 * this event to draw an ALWAY-TOP navigation bar or title during switching
550 * period.
551 *
552 * \param[in] ptThis the target scene player
553 * \param[in] fnHandler the event handler to draw the navigation bar and/or titles
554 * \param[in] pTarget the address of an user specified object. If it is NULL,
555 * ptThis will be used instead.
556 * \param[in] ptDirtyRegions a dirty region list for the navigation layer.
557 * \note if ptDirtyRegions is NULL and the normal scene doesn't cover the region
558 * of the content in the navigation layer, you won't see the content.
559 * \return arm_2d_err_t the operation result
560 */
561extern
562ARM_NONNULL(1)
564 arm_2d_scene_player_t *ptThis,
565 arm_2d_helper_draw_handler_t *fnHandler,
566 void *pTarget,
567 arm_2d_region_list_item_t *ptDirtyRegions);
568
569/*!
570 * \brief hide the navigation layer
571 * \param[in] ptThis an initialised scene player
572 */
573extern
574ARM_NONNULL(1)
576
577/*!
578 * \brief show the navigation layer if there is a valid one
579 * \param[in] ptThis an initialised scene player
580 */
581extern
582ARM_NONNULL(1)
584
585/*!
586 * \brief register / update the evtBeforeSwitching event handler. You can use
587 * this event to prepare next scenes.
588 *
589 * \param[in] ptThis the target scene player
590 * \param[in] fnHandler the event handler
591 * \param[in] pTarget the address of an user specified object.
592 * \return arm_2d_err_t the operation result
593 */
594extern
595ARM_NONNULL(1)
597 arm_2d_scene_player_t *ptThis,
599 void *pTarget
600 );
601
602/*!
603 * \brief the scene player task function
604 *
605 * \param[in] ptThis the target scene player
606 *
607 * \note the event sequence of a scene:
608 * 1. when fnBackground is valid
609 * - invoke fnOnBGStart when it is valid
610 * - invoke fnBackground
611 * - invoke fnOnBGComplete when it is valid
612 * 2. invoke fnOnFrameStart when it is valid
613 * 3. invoke fnScene
614 * 4. invoke fnOnFrameCPL when it is valid
615 * 5. Check bNextSceneReq
616 * - false (0), go back to step 2
617 * - true, invoke fnDepose when it is valid and switch to the next scene
618 *
619 */
620extern
621ARM_NONNULL(1)
623
624/*!
625 * \brief append dirty regions to the a specified scene
626 * \param[in] ptScene the target scene
627 * \param[in] ptItems the dirty regions
628 * \param[in] tCount the number of dirty regions
629 * \retval true operation is successful
630 * \retval false the operation is failed.
631 */
632extern
633ARM_NONNULL(1,2)
636 size_t tCount);
637
638/*!
639 * \brief remove dirty regions from the a specified scene
640 * \param[in] ptScene the target scene
641 * \param[in] ptItems the dirty regions
642 * \param[in] tCount the number of dirty regions
643 * \retval true operation is successful
644 * \retval false the operation is failed.
645 */
646extern
647ARM_NONNULL(1,2)
650 size_t tCount);
651
652/*!
653 * \brief get the current scene of a given scene player
654 * \param[in] ptThis the target scene player
655 * \return arm_2d_scene_t * the current scene
656 */
657extern
658ARM_NONNULL(1)
661
662
663/*-----------------------------------------------------------------------------*
664 * Dynamic Dirty Region Helper Service *
665 *-----------------------------------------------------------------------------*/
666
667/*!
668 * \brief initialize a user dynamic dirty region
669 *
670 * \param[in] ptThis the target region list item. If it is NULL, this function will
671 * allocate an object from the heap
672 * \param[in] ptScene the target scene.
673 * \return arm_2d_region_list_item_t* the target region list item
674 */
675extern
678 arm_2d_scene_t *ptScene);
679
680/*!
681 * \brief depose a given user dynamic dirty region
682 *
683 * \param[in] ptThis the target region list item.
684 * \param[in] ptScene the target scene.
685 */
686extern
687ARM_NONNULL(1)
690 arm_2d_scene_t *ptScene);
691
692/*! @} */
693
694#if defined(__clang__)
695# pragma clang diagnostic pop
696#endif
697
698#ifdef __cplusplus
699}
700#endif
701
702#endif