pikapython/package/Arm2D/arm_2d_tile.h
2021-11-09 22:19:51 +08:00

504 lines
27 KiB
C

/*
* Copyright (C) 2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ----------------------------------------------------------------------
* Project: Arm-2D Library
* Title: arm_2d_tile.h
* Description: Public header file to contain the basic tile operations
*
* $Date: 01. December 2020
* $Revision: V.0.9.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
#ifndef __ARM_2D_TILE_H__
#define __ARM_2D_TILE_H__
/*============================ INCLUDES ======================================*/
#include "arm_2d_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*============================ MACROS ========================================*/
/*============================ MACROFIED FUNCTIONS ===========================*/
#define arm_2d_c8bit_tile_copy( __SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MODE) /*!< mode */ \
arm_2dp_c8bit_tile_copy(NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MODE))
#define arm_2d_rgb16_tile_copy( __SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MODE) /*!< mode */ \
arm_2dp_rgb16_tile_copy(NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MODE))
#define arm_2d_rgb32_tile_copy( __SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MODE) /*!< mode */ \
arm_2dp_rgb32_tile_copy(NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MODE))
#define arm_2d_c8bit_tile_copy_with_colour_masking( \
__SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MSK_COLOUR, /*!< mask(key) colour */ \
__MODE) /*!< mode */ \
arm_2dp_c8bit_tile_copy_with_colour_keying( \
NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MSK_COLOUR), \
(__MODE))
#define arm_2d_c8bit_tile_copy_with_colour_keying( \
__SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MSK_COLOUR, /*!< mask(key) colour */ \
__MODE) /*!< mode */ \
arm_2dp_c8bit_tile_copy_with_colour_keying( \
NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MSK_COLOUR), \
(__MODE))
#define arm_2d_rgb16_tile_copy_with_colour_masking( \
__SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MSK_COLOUR, /*!< mask(key) colour */ \
__MODE) /*!< mode */ \
arm_2dp_rgb16_tile_copy_with_colour_keying( \
NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MSK_COLOUR), \
(__MODE))
#define arm_2d_rgb16_tile_copy_with_colour_keying( \
__SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MSK_COLOUR, /*!< mask(key) colour */ \
__MODE) /*!< mode */ \
arm_2dp_rgb16_tile_copy_with_colour_keying( \
NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MSK_COLOUR), \
(__MODE))
#define arm_2d_rgb32_tile_copy_with_colour_masking( \
__SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MSK_COLOUR, /*!< mask(key) colour */ \
__MODE) /*!< mode */ \
arm_2dp_rgb32_tile_copy_with_colour_keying( \
NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MSK_COLOUR), \
(__MODE))
#define arm_2d_rgb32_tile_copy_with_colour_keying( \
__SRC_ADDR, /*!< source tile address */ \
__DES_ADDR, /*!< target tile address */ \
__DES_REGION_ADDR, /*!< target region address*/\
__MSK_COLOUR, /*!< mask(key) colour */ \
__MODE) /*!< mode */ \
arm_2dp_rgb32_tile_copy_with_colour_keying( \
NULL, \
(__SRC_ADDR), \
(__DES_ADDR), \
(__DES_REGION_ADDR), \
(__MSK_COLOUR), \
(__MODE))
/*
calculate the start address
HOW IT WORKS:
Base Address
+------------------------------------------------------------------------+
| |
|<------------------------------- iWidth ------------------------------->|
| |
| |
| Start Address = Base Address + iX + iY * iWidth |
| (iX,iY) |
|<-------- iX --------->+------------------------------+ |
| | | |
| | Valid Region | |
| | | |
| +------------------------------+ |
... ...
| |
+------------------------------------------------------------------------+
*/
#define __arm_2d_get_address_and_region_from_tile( __TILE_PTR, \
__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR, \
__TYPE, \
__BUF_PTR_NAME) \
arm_2d_region_t __VALID_REGION_NAME; \
assert(NULL != (__TILE_PTR)); \
__TYPE *(__BUF_PTR_NAME) = NULL; \
\
(__TILE_PTR) = arm_2d_tile_get_root((__TILE_PTR), \
&__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR); \
\
if (NULL != (__TILE_PTR)) { \
(__BUF_PTR_NAME) = ((__TYPE *)((__TILE_PTR)->pchBuffer)) \
+ (__TILE_PTR)->tRegion.tSize.iWidth * \
__VALID_REGION_NAME.tLocation.iY \
+ __VALID_REGION_NAME.tLocation.iX; \
}
#define arm_2d_get_address_and_region_from_tile(__TILE_PTR, \
__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR, \
__TYPE, \
__BUF_PTR_NAME) \
__arm_2d_get_address_and_region_from_tile( __TILE_PTR, \
__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR, \
__TYPE, \
__BUF_PTR_NAME)
#define __arm_2d_get_address_and_region_from_tile_with_mirroring( \
__TILE_PTR, \
__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR, \
__TYPE, \
__BUF_PTR_NAME, \
__MODE) \
arm_2d_region_t __VALID_REGION_NAME; \
assert(NULL != (__TILE_PTR)); \
__TYPE *(__BUF_PTR_NAME) = NULL; \
\
(__TILE_PTR) = arm_2d_tile_get_root((__TILE_PTR), \
&__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR); \
\
if (NULL != (__TILE_PTR)) { \
arm_2d_location_t tOffset = __VALID_REGION_NAME.tLocation; \
if ((__MODE) & ARM_2D_CP_MODE_X_MIRROR) { \
tOffset.iX = 0; \
} \
if ((__MODE) & ARM_2D_CP_MODE_Y_MIRROR) { \
tOffset.iY = 0; \
} \
(__BUF_PTR_NAME) = ((__TYPE *)((__TILE_PTR)->pchBuffer)) \
+ (__TILE_PTR)->tRegion.tSize.iWidth * tOffset.iY \
+ tOffset.iX; \
}
#define arm_2d_get_address_and_region_from_tile_with_mirroring( \
__TILE_PTR, \
__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR, \
__TYPE, \
__BUF_PTR_NAME, \
__MODE) \
__arm_2d_get_address_and_region_from_tile_with_mirroring( \
__TILE_PTR, \
__VALID_REGION_NAME, \
__LOCATION_OFFSET_PTR, \
__TYPE, \
__BUF_PTR_NAME, \
(__MODE))
/*============================ TYPES =========================================*/
typedef arm_2d_op_src_t arm_2d_op_cp_t;
/*! \note arm_2d_op_cp_cl_key_t inherits from arm_2d_op_src_t explicitly
*/
typedef struct arm_2d_op_cp_cl_key_t {
inherit(arm_2d_op_core_t);
struct {
const arm_2d_tile_t *ptTile; //!< target tile
const arm_2d_region_t *ptRegion; //!< target region
} Target;
struct {
const arm_2d_tile_t *ptTile; //!< source tile
}Source;
uint32_t wMode;
union {
uint8_t chColour;
uint16_t hwColour;
uint32_t wColour;
};
} arm_2d_op_cp_cl_key_t;
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ PROTOTYPES ====================================*/
/*----------------------------------------------------------------------------*
* Tile Operations *
*----------------------------------------------------------------------------*/
ARM_NONNULL(1)
__STATIC_INLINE bool arm_2d_is_root_tile(const arm_2d_tile_t *ptTile)
{
return ptTile->tInfo.bIsRoot;
}
/*
HOW IT WORKS:
Input Region 0
+------------------------------------------------------+
| |
| |
| |
| +------------------------------+---------+
| | |/////////|
| | Output Region |/////////|
| | |/////////|
+-----------------------+------------------------------+/////////|
|////////////////////////////////////////|
|////////////////////////////////////////|
+----------------------------------------+
Input Region 1
*/
extern
ARM_NONNULL(1,2)
bool arm_2d_region_intersect( const arm_2d_region_t *ptRegionIn0,
const arm_2d_region_t *ptRegionIn1,
arm_2d_region_t *ptRegionOut);
extern
ARM_NONNULL(1,2)
bool arm_2d_is_point_inside_region( const arm_2d_region_t *ptRegion,
const arm_2d_location_t *ptPoint);
/*
HOW IT WORKS:
Root Tile (Output Tile)
+------------------------------------------------------------------------+
| ... ... |
| |
| Parent Tile' (Child Tile of Parent Tile'') |
| +------------------------------------+ |
| | Child Tile of Parent Tile' | |
| | +------------------------------+---------+ |
| | | |/////////| |
| | | Valid Region |/////////| |
| | | |/////////| |
| +-----+------------------------------+/////////| |
| |////////////////////////////////////////| |
| |////////////////////////////////////////| |
| +----------------------------------------+ |
| |
+------------------------------------------------------------------------+
*/
extern
ARM_NONNULL(1,2)
const arm_2d_tile_t *arm_2d_tile_get_root( const arm_2d_tile_t *ptTile,
arm_2d_region_t *ptValidRegion,
arm_2d_location_t *ptOffset);
/*
HOW IT WORKS:
Parent Tile (Are NOT necessarily a ROOT tile )
+------------------------------------------------------+
| |
| |
| Target Region |
| +------------------------------+---------+
| | |/////////|
| | New Child Tile (Output) |/////////|
| | |/////////|
+-----------------------+------------------------------+/////////|
|////////////////////////////////////////|
|////////////////////////////////////////|
+----------------------------------------+
*/
extern
ARM_NONNULL(1,2,3)
arm_2d_tile_t *arm_2d_tile_generate_child(
const arm_2d_tile_t *ptTargetTile,
const arm_2d_region_t *ptRegion,
arm_2d_tile_t *ptOutput,
bool bClipRegion);
extern
ARM_NONNULL(1,2)
arm_2d_cmp_t arm_2d_tile_width_compare( const arm_2d_tile_t *ptTarget,
const arm_2d_tile_t *ptReference);
extern
ARM_NONNULL(1,2)
arm_2d_cmp_t arm_2d_tile_height_compare(const arm_2d_tile_t *ptTarget,
const arm_2d_tile_t *ptReference);
extern
ARM_NONNULL(1,2)
arm_2d_cmp_t arm_2d_tile_shape_compare( const arm_2d_tile_t *ptTarget,
const arm_2d_tile_t *ptReference);
extern
ARM_NONNULL(1,2)
const arm_2d_tile_t * arm_2d_get_absolute_location(
const arm_2d_tile_t *ptTile,
arm_2d_location_t *ptLocation);
extern
ARM_NONNULL(1,2,3)
arm_2d_region_t *arm_2d_tile_region_diff( const arm_2d_tile_t *ptTarget,
const arm_2d_tile_t *ptReference,
arm_2d_region_t *ptBuffer);
/*----------------------------------------------------------------------------*
* Copy tile to destination directly *
*----------------------------------------------------------------------------*/
enum {
ARM_2D_CP_MODE_COPY = 0,
ARM_2D_CP_MODE_FILL = _BV(0),
ARM_2D_CP_MODE_Y_MIRROR = _BV(2),
ARM_2D_CP_MODE_X_MIRROR = _BV(3),
};
extern
ARM_NONNULL(2,3)
arm_fsm_rt_t arm_2dp_c8bit_tile_copy(arm_2d_op_cp_t *ptOP,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint32_t wMode);
extern
ARM_NONNULL(2,3)
arm_fsm_rt_t arm_2dp_rgb16_tile_copy(arm_2d_op_cp_t *ptOP,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint32_t wMode);
extern
ARM_NONNULL(2,3)
arm_fsm_rt_t arm_2dp_rgb32_tile_copy(arm_2d_op_cp_t *ptOP,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint32_t wMode);
/*----------------------------------------------------------------------------*
* Copy tile to destination with specified transparency color mask *
*----------------------------------------------------------------------------*/
/*! \brief copy source tile to destination tile and use destination tile as
*! background. When encountering specified mask colour, the background
*! pixel should be used, otherwise the foreground pixel from source tile
*! is used.
*!
*! \note All color formats which using 8bits per pixel are treated equally.
*!
*/
extern
ARM_NONNULL(2,3)
arm_fsm_rt_t arm_2dp_c8bit_tile_copy_with_colour_keying(
arm_2d_op_cp_cl_key_t *ptOP,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint8_t chMaskColour,
uint32_t wMode);
/*! \brief copy source tile to destination tile and use destination tile as
*! background. When encountering specified mask colour, the background
*! pixel should be used, otherwise the foreground pixel from source tile
*! is used.
*!
*! \note All color formats which using 16bits per pixel are treated equally.
*!
*! \note alpha channel is not handled, i.e. rgba5551
*/
extern
ARM_NONNULL(2,3)
arm_fsm_rt_t arm_2dp_rgb16_tile_copy_with_colour_keying(
arm_2d_op_cp_cl_key_t *ptOP,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint16_t hwMaskColour,
uint32_t wMode);
/*! \brief copy source tile to destination tile and use destination tile as
*! background. When encountering specified mask colour, the background
*! pixel should be used, otherwise the foreground pixel from source tile
*! is used.
*!
*! \note All color formats which using 32bits per pixel are treated equally.
*!
*! \note alpha channel is not handled.
*/
extern
ARM_NONNULL(2,3)
arm_fsm_rt_t arm_2dp_rgb32_tile_copy_with_colour_keying(
arm_2d_op_cp_cl_key_t *ptOP,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint32_t wMaskColour,
uint32_t wMode);
#ifdef __cplusplus
}
#endif
#endif