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

1514 lines
57 KiB
C

/*
* Copyright (C) 2010-2021 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_core.c
* Description: Basic Tile operations
*
* $Date: 02. Oct 2021
* $Revision: V.0.9.0
*
* Target Processor: Cortex-M cores
*
* -------------------------------------------------------------------- */
/*============================ INCLUDES ======================================*/
#if defined(__clang__)
# pragma clang diagnostic ignored "-Wempty-translation-unit"
#endif
#ifdef __ARM_2D_COMPILATION_UNIT
#define __ARM_2D_IMPL__
#include "arm_2d.h"
#include "__arm_2d_impl.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-warning-option"
# pragma clang diagnostic ignored "-Wreserved-identifier"
# pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
# pragma clang diagnostic ignored "-Wcast-qual"
# pragma clang diagnostic ignored "-Wcast-align"
# pragma clang diagnostic ignored "-Wextra-semi-stmt"
# pragma clang diagnostic ignored "-Wsign-conversion"
# pragma clang diagnostic ignored "-Wunused-function"
# pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
# pragma clang diagnostic ignored "-Wdouble-promotion"
# pragma clang diagnostic ignored "-Wunused-parameter"
# pragma clang diagnostic ignored "-Wimplicit-float-conversion"
# pragma clang diagnostic ignored "-Wimplicit-int-conversion"
# pragma clang diagnostic ignored "-Wtautological-pointer-compare"
# pragma clang diagnostic ignored "-Wsign-compare"
# pragma clang diagnostic ignored "-Wmissing-prototypes"
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
# pragma clang diagnostic ignored "-Wgnu-statement-expression"
# pragma clang diagnostic ignored "-Wswitch-enum"
# pragma clang diagnostic ignored "-Wswitch"
#elif defined(__IS_COMPILER_ARM_COMPILER_5__)
# pragma diag_suppress 174,177,188,68,513
#elif defined(__IS_COMPILER_GCC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wenum-compare"
# pragma GCC diagnostic ignored "-Wpedantic"
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
/*============================ MACROS ========================================*/
#ifndef __ARM_2D_DEFAULT_SUB_TASK_POOL_SIZE
# define __ARM_2D_DEFAULT_SUB_TASK_POOL_SIZE 3
#endif
/*============================ MACROFIED FUNCTIONS ===========================*/
/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/
__WEAK
arm_2d_runtime_feature_t ARM_2D_RUNTIME_FEATURE = {
.TREAT_OUT_OF_RANGE_AS_COMPLETE = 1,
.HAS_DEDICATED_THREAD_FOR_2D_TASK = 0,
};
/*============================ PROTOTYPES ====================================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ IMPLEMENTATION ================================*/
ARM_NOINIT
struct __arm_2d_op_control ARM_2D_CTRL;
#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; \
}
/*----------------------------------------------------------------------------*
* Region Calculation *
*----------------------------------------------------------------------------*/
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_tile_process(
arm_2d_op_t *ptThis,
__arm_2d_tile_param_t *ptParam)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tTileProcess = *ptParam,
};
/* todo: update the tile process interface */
/* call default software implementation */
ARM_2D_RUN_DEFAULT( 0, __arm_2d_io_func_t);
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_fill(
arm_2d_op_cp_t *ptThis,
__arm_2d_tile_param_t *ptSource,
__arm_2d_tile_param_t *ptTarget)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tFill = {
.tSource = *ptSource,
.tTarget = *ptTarget,
},
};
/* call default software implementation */
ARM_2D_RUN_DEFAULT( 1,__arm_2d_io_func_t );
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_fill_with_mask(
arm_2d_op_cp_t *ptThis,
__arm_2d_tile_param_t *ptSource,
__arm_2d_tile_param_t *ptSourceMask,
__arm_2d_tile_param_t *ptTarget,
__arm_2d_tile_param_t *ptTargetMask)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tFillMask = {
.use_as____arm_2d_param_fill_t = {
.tSource = *ptSource,
.tTarget = *ptTarget,
},
},
};
if (NULL == ptSourceMask){
ptTask->Param.tFillMask.tSrcMask.bInvalid = true;
} else {
ptTask->Param.tFillMask.tSrcMask = *ptSourceMask;
}
if (NULL == ptTargetMask){
ptTask->Param.tFillMask.tDesMask.bInvalid = true;
} else {
ptTask->Param.tFillMask.tDesMask = *ptTargetMask;
}
/* call default software implementation */
ARM_2D_RUN_DEFAULT( 1,__arm_2d_io_func_t );
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_copy(arm_2d_op_cp_t *ptThis,
__arm_2d_tile_param_t *ptSource,
__arm_2d_tile_param_t *ptTarget,
arm_2d_size_t * __RESTRICT ptCopySize)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tCopy = {
.tSource = *ptSource,
.tTarget = *ptTarget,
.tCopySize = *ptCopySize,
},
};
/* call default software implementation */
ARM_2D_RUN_DEFAULT(0,__arm_2d_io_func_t );
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_copy_with_mask(
arm_2d_op_cp_t *ptThis,
__arm_2d_tile_param_t *ptSource,
__arm_2d_tile_param_t *ptSourceMask,
__arm_2d_tile_param_t *ptTarget,
__arm_2d_tile_param_t *ptTargetMask,
arm_2d_size_t * __RESTRICT ptCopySize)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tCopyMask = {
.use_as____arm_2d_param_copy_t = {
.tSource = *ptSource,
.tTarget = *ptTarget,
.tCopySize = *ptCopySize,
},
},
};
if (NULL == ptSourceMask){
ptTask->Param.tCopyMask.tSrcMask.bInvalid = true;
} else {
ptTask->Param.tCopyMask.tSrcMask = *ptSourceMask;
}
if (NULL == ptTargetMask){
ptTask->Param.tCopyMask.tDesMask.bInvalid = true;
} else {
ptTask->Param.tCopyMask.tDesMask = *ptTargetMask;
}
/* call default software implementation */
ARM_2D_RUN_DEFAULT(0,__arm_2d_io_func_t );
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_fill_origin(
arm_2d_op_cp_t *ptThis,
__arm_2d_tile_param_t *ptSource,
__arm_2d_tile_param_t *ptOrigin,
__arm_2d_tile_param_t *ptTarget)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tFillOrig = {
.use_as____arm_2d_param_fill_t = {
.tSource = *ptSource,
.tTarget = *ptTarget,
},
.tOrigin = *ptOrigin,
},
};
/* call default software implementation */
ARM_2D_RUN_DEFAULT( 1,__arm_2d_io_func_t );
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_issue_sub_task_copy_origin(
arm_2d_op_cp_t *ptThis,
__arm_2d_tile_param_t *ptSource,
__arm_2d_tile_param_t *ptOrigin,
__arm_2d_tile_param_t *ptTarget,
arm_2d_size_t * __RESTRICT ptCopySize)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
__arm_2d_sub_task_t *ptTask = &(__arm_2d_sub_task_t){
.ptOP = (arm_2d_op_core_t *)ptThis,
.Param.tCopyOrig = {
.use_as____arm_2d_param_copy_t = {
.tSource = *ptSource,
.tTarget = *ptTarget,
.tCopySize = *ptCopySize,
},
.tOrigin = *ptOrigin,
},
};
/* call default software implementation */
ARM_2D_RUN_DEFAULT(0,__arm_2d_io_func_t );
return tResult;
}
ARM_NONNULL(1,2)
static const arm_2d_tile_t * __arm_2d_tile_region_caculator(
const arm_2d_tile_t *ptTile,
__arm_2d_tile_param_t *ptOut,
uint_fast8_t *pchPixelLenInBit,
bool bAllowEnforcedColour,
uint32_t wMode)
{
arm_2d_region_t tValidRegion;
int32_t nOffset = 0;
uint8_t *pchBuffer = NULL;
assert(NULL != ptTile);
assert(NULL != ptOut);
bool bDerivedResource = ptTile->tInfo.bDerivedResource
& !ptTile->tInfo.bIsRoot;
//memset(ptOut, 0, sizeof(__arm_2d_tile_param_t));
ptTile = arm_2d_tile_get_root( ptTile,
&tValidRegion,
NULL);
if (NULL != ptTile) {
//! check if enforced colour is allowed
if (bAllowEnforcedColour) {
if (ptTile->tInfo.bHasEnforcedColour) {
*pchPixelLenInBit = _BV(ptTile->tInfo.tColourInfo.u3ColourSZ);
}
}
uint_fast8_t chPixelLenInBit = *pchPixelLenInBit;
arm_2d_location_t tOffset = tValidRegion.tLocation;
if ((wMode) & ARM_2D_CP_MODE_X_MIRROR) {
tOffset.iX = 0;
}
if ((wMode) & ARM_2D_CP_MODE_Y_MIRROR) {
tOffset.iY = 0;
}
if (chPixelLenInBit >= 8) {
nOffset = ptTile->tRegion.tSize.iWidth * tOffset.iY + tOffset.iX;
pchBuffer = ptTile->pchBuffer
+ (nOffset * chPixelLenInBit >> 3);
} else {
nOffset = tOffset.iX;
pchBuffer = ptTile->pchBuffer
+ ((ptTile->tRegion.tSize.iWidth
* chPixelLenInBit + 7) >> 3) * tOffset.iY
+ ((tOffset.iX * chPixelLenInBit) >> 3);
}
ptOut->iStride = ptTile->tRegion.tSize.iWidth;
ptOut->nOffset = nOffset;
ptOut->pBuffer = pchBuffer;
ptOut->tValidRegion = tValidRegion;
ptOut->tColour.chScheme = ptTile->tColourInfo.chScheme;
ptOut->bDerivedResource = bDerivedResource;
ptOut->bInvalid = false;
}
return ptTile;
}
ARM_NONNULL(1,2)
static
arm_fsm_rt_t __arm_2d_tile_process( arm_2d_op_t *ptThis,
const arm_2d_tile_t *ptTarget)
{
assert(NULL != ptTarget);
assert(OP_CORE.ptOp->Info.Colour.u3ColourSZ >= ARM_2D_COLOUR_SZ_8BIT);
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
uint_fast8_t chPixelLenInBit = _BV(OP_CORE.ptOp->Info.Colour.u3ColourSZ);
__arm_2d_tile_param_t tTileParam;
__arm_2d_tile_region_caculator(
ptTarget,
&tTileParam,
&chPixelLenInBit,
OP_CORE.ptOp->Info.Param.bAllowEnforcedColour,
0);
tResult = __arm_2d_issue_sub_task_tile_process( ptThis, &tTileParam);
return tResult;
}
static void __arm_2d_source_side_tile_mirror_preprocess(
const arm_2d_tile_t *ptTile,
__arm_2d_tile_param_t *ptTileParam,
uint_fast8_t chPixelLenInBit,
const arm_2d_size_t *ptActualSize,
uint32_t wMode)
{
//! right and/or bottom alignment
arm_2d_size_t tOffset = {0};
if (ptTileParam->bDerivedResource) {
//!< treat the content inside the valid region as the one to be mirrored
//! right alignment
if (wMode & ARM_2D_CP_MODE_X_MIRROR) {
tOffset.iWidth = ptTileParam->tValidRegion.tLocation.iX;
tOffset.iWidth += ptTileParam->tValidRegion.tSize.iWidth
- ptActualSize->iWidth;
}
//! bottom alignment
if (wMode & ARM_2D_CP_MODE_Y_MIRROR) {
tOffset.iHeight = ptTileParam->tValidRegion.tLocation.iY;
tOffset.iHeight += ptTileParam->tValidRegion.tSize.iHeight
- ptActualSize->iHeight;
}
} else {
//!< treat valid region as a logic region to indicate the area for mirroring.
//! right alignment
if (wMode & ARM_2D_CP_MODE_X_MIRROR) {
tOffset.iWidth = ptTile->tRegion.tSize.iWidth
- ( ptTileParam->tValidRegion.tLocation.iX
+ ptActualSize->iWidth);
}
//! bottom alignment
if (wMode & ARM_2D_CP_MODE_Y_MIRROR) {
tOffset.iHeight = ptTile->tRegion.tSize.iHeight
- ( ptTileParam->tValidRegion.tLocation.iY
+ ptActualSize->iHeight);
}
}
if (chPixelLenInBit >= 8) {
ptTileParam->nOffset += ( tOffset.iHeight * ptTile->tRegion.tSize.iWidth
+ tOffset.iWidth);
ptTileParam->pBuffer = ptTile->pchBuffer
+ (ptTileParam->nOffset * chPixelLenInBit >> 3);
} else {
ptTileParam->nOffset += tOffset.iWidth;
(*(uintptr_t *)&(ptTileParam->pBuffer)) +=
+ ((ptTile->tRegion.tSize.iWidth
* chPixelLenInBit + 7) >> 3) * tOffset.iHeight
+ ((tOffset.iWidth * chPixelLenInBit) >> 3);
}
}
ARM_NONNULL(1,2)
static
arm_fsm_rt_t __arm_2d_big_pixel_tile_pave( arm_2d_op_cp_t *ptThis,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptSourceMask,
const arm_2d_tile_t *ptTarget,
const arm_2d_tile_t *ptTargetMask,
uint32_t wMode)
{
assert(NULL != ptSource);
assert(NULL != ptTarget);
//assert(OP_CORE.ptOp->Info.Colour.u3ColourSZ >= ARM_2D_COLOUR_SZ_8BIT);
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
uint_fast8_t chTargetPixelLenInBit = _BV(OP_CORE.ptOp->Info.Colour.u3ColourSZ);
uint_fast8_t chSourcePixelLenInBit = chTargetPixelLenInBit;
uint_fast8_t chSourceMaskPixelLenInBit = 8;
__arm_2d_tile_param_t tSourceTileParam;
__arm_2d_tile_param_t tSourceMaskParam;
__arm_2d_tile_param_t tTargetTileParam;
__arm_2d_tile_param_t tTargetMaskParam;
__arm_2d_tile_param_t tOriginTileParam;
arm_2d_tile_t tSourceMask;
arm_2d_tile_t tTargetMask;
//const arm_2d_tile_t *ptTargetMask = NULL;
//const arm_2d_tile_t *ptSourceMask = NULL;
const arm_2d_tile_t *ptOrigin = NULL;
if (OP_CORE.ptOp->Info.Param.bHasOrigin) {
arm_2d_op_src_orig_t *ptOP = (arm_2d_op_src_orig_t *)ptThis;
uint_fast8_t chOriginPixelLenInBit = chSourcePixelLenInBit;
ptOrigin = __arm_2d_tile_region_caculator(
ptOP->Origin.ptTile,
&tOriginTileParam,
&chOriginPixelLenInBit,
OP_CORE.ptOp->Info.Param.bAllowEnforcedColour,
wMode);
if (NULL == ptOrigin) {
return (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
}
}
ptSource = __arm_2d_tile_region_caculator(
ptSource,
&tSourceTileParam,
&chSourcePixelLenInBit,
OP_CORE.ptOp->Info.Param.bAllowEnforcedColour,
wMode);
ptTarget = __arm_2d_tile_region_caculator(
ptTarget,
&tTargetTileParam,
&chTargetPixelLenInBit,
false,
0);
if (NULL == ptSource || NULL == ptTarget) {
return (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
}
if (!OP_CORE.ptOp->Info.Param.bHasOrigin) {
if (OP_CORE.ptOp->Info.Param.bHasSrcMask) {
arm_2d_op_src_msk_t *ptOP = (arm_2d_op_src_msk_t *)ptThis;
ptSourceMask = ptOP->Mask.ptSourceSide;
if (NULL != ptSourceMask) {
ptSourceMask = arm_2d_tile_generate_child( ptSourceMask,
&tSourceTileParam.tValidRegion,
&tSourceMask,
false);
ptSourceMask = __arm_2d_tile_region_caculator(
ptSourceMask,
&tSourceMaskParam,
&chSourceMaskPixelLenInBit,
true,
wMode);
}
}
if (OP_CORE.ptOp->Info.Param.bHasDesMask) {
arm_2d_op_src_msk_t *ptOP = (arm_2d_op_src_msk_t *)ptThis;
ptTargetMask = ptOP->Mask.ptTargetSide;
if (NULL != ptTargetMask) {
uint_fast8_t chTargetMaskPixelLenInBit = 8;
do {
arm_2d_region_t tTempRegion= {
.tSize = ptThis->Target.ptTile->tRegion.tSize,
};
arm_2d_get_absolute_location(ptThis->Target.ptTile,
&tTempRegion.tLocation);
tTempRegion.tLocation.iX
= tTargetTileParam.tValidRegion.tLocation.iX
- tTempRegion.tLocation.iX;
tTempRegion.tSize.iWidth
= tTargetTileParam.tValidRegion.tSize.iWidth
- tTempRegion.tSize.iWidth;
#if 0 //! no use for now
tTempRegion.tLocation.iY
= tTargetTileParam.tValidRegion.tLocation.iY
- tTempRegion.tLocation.iY;
tTempRegion.tSize.iHeight
= tTargetTileParam.tValidRegion.tSize.iHeight
- tTempRegion.tSize.iHeight;
#endif
arm_2d_region_t tNewTargetMaskRegion = ptTargetMask->tRegion;
tNewTargetMaskRegion.tLocation.iX += tTempRegion.tLocation.iX;
tNewTargetMaskRegion.tSize.iWidth += tTempRegion.tSize.iWidth;
ptTargetMask = arm_2d_tile_generate_child(
ptTargetMask,
&tNewTargetMaskRegion,
&tTargetMask,
false);
} while(0);
ptTargetMask = __arm_2d_tile_region_caculator(
ptTargetMask,
&tTargetMaskParam,
&chTargetMaskPixelLenInBit,
true,
0);
}
}
} //!else { //! todo }
if (wMode & ARM_2D_CP_MODE_FILL) {
//! handle mirroring
do {
__arm_2d_source_side_tile_mirror_preprocess(
ptSource,
&tSourceTileParam,
chSourcePixelLenInBit,
&tSourceTileParam.tValidRegion.tSize,
wMode);
if ( OP_CORE.ptOp->Info.Param.bHasSrcMask
&& (NULL != ptSourceMask)) {
__arm_2d_source_side_tile_mirror_preprocess(
ptSourceMask,
&tSourceMaskParam,
chSourceMaskPixelLenInBit,
&tSourceMaskParam.tValidRegion.tSize,
wMode);
}
} while(0);
if (OP_CORE.ptOp->Info.Param.bHasOrigin) {
tResult = __arm_2d_issue_sub_task_fill_origin(
ptThis,
&tSourceTileParam,
&tOriginTileParam,
&tTargetTileParam);
} else {
if ( (OP_CORE.ptOp->Info.Param.bHasSrcMask)
|| (OP_CORE.ptOp->Info.Param.bHasDesMask)){
tResult = __arm_2d_issue_sub_task_fill_with_mask(
ptThis,
&tSourceTileParam,
((NULL != ptSourceMask) ? &tSourceMaskParam : NULL),
&tTargetTileParam,
((NULL != ptTargetMask) ? &tTargetMaskParam : NULL)
);
} else {
tResult = __arm_2d_issue_sub_task_fill( ptThis,
&tSourceTileParam,
&tTargetTileParam);
}
}
} else {
arm_2d_size_t tActualSize = {
.iWidth = MIN( tSourceTileParam.tValidRegion.tSize.iWidth,
tTargetTileParam.tValidRegion.tSize.iWidth),
.iHeight = MIN( tSourceTileParam.tValidRegion.tSize.iHeight,
tTargetTileParam.tValidRegion.tSize.iHeight),
};
//! handle mirroring
do {
__arm_2d_source_side_tile_mirror_preprocess(
ptSource,
&tSourceTileParam,
chSourcePixelLenInBit,
&tActualSize,
wMode);
if ( OP_CORE.ptOp->Info.Param.bHasSrcMask
&& (NULL != ptSourceMask)) {
arm_2d_size_t tMaskActualSize = {
.iWidth = MIN(tActualSize.iWidth,
tSourceMaskParam.tValidRegion.tSize.iWidth),
.iHeight = MIN(tActualSize.iHeight,
tSourceMaskParam.tValidRegion.tSize.iHeight),
};
__arm_2d_source_side_tile_mirror_preprocess(
ptSourceMask,
&tSourceMaskParam,
chSourceMaskPixelLenInBit,
&tMaskActualSize,
wMode);
}
} while(0);
if (OP_CORE.ptOp->Info.Param.bHasOrigin) {
tResult = __arm_2d_issue_sub_task_copy_origin( ptThis,
&tSourceTileParam,
&tOriginTileParam,
&tTargetTileParam,
&tActualSize);
} else {
if ( (OP_CORE.ptOp->Info.Param.bHasSrcMask)
|| (OP_CORE.ptOp->Info.Param.bHasDesMask)){
tResult = __arm_2d_issue_sub_task_copy_with_mask(
ptThis,
&tSourceTileParam,
((NULL != ptSourceMask) ? &tSourceMaskParam : NULL),
&tTargetTileParam,
((NULL != ptTargetMask) ? &tTargetMaskParam : NULL),
&tActualSize);
} else {
tResult = __arm_2d_issue_sub_task_copy( ptThis,
&tSourceTileParam,
&tTargetTileParam,
&tActualSize);
}
}
}
return tResult;
}
static
arm_fsm_rt_t __tile_clipped_pave(
arm_2d_op_cp_t *ptThis,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
arm_2d_region_t *ptClippedRegion,
uint32_t wMode)
{
arm_2d_tile_t tTempSourceTile = {0};
arm_2d_tile_t tTargetTile = {0};
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
do {
arm_2d_region_t tempRegion = {
.tLocation = this.Source.ptTile->tRegion.tLocation,
.tSize = ptRegion->tSize,
};
tempRegion.tLocation.iX = -ptRegion->tLocation.iX;
tempRegion.tLocation.iY = -ptRegion->tLocation.iY;
tempRegion.tSize.iWidth += ptRegion->tLocation.iX;
tempRegion.tSize.iHeight += ptRegion->tLocation.iY;
if (NULL == arm_2d_tile_generate_child( this.Source.ptTile,
&tempRegion,
&tTempSourceTile,
true)) {
break;
};
if (NULL != ptClippedRegion) {
*ptClippedRegion = tTempSourceTile.tRegion;
}
//! [Modify][Target.ptTile]
//if (NULL == arm_2d_tile_generate_child( this.Target.ptTile,
if (NULL == arm_2d_tile_generate_child( //this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile,
ptTarget,
ptRegion,
&tTargetTile,
true)) {
break;
}
#if 0
switch (OP_CORE.ptOp->Info.Colour.u3ColourSZ) {
case ARM_2D_COLOUR_SZ_8BIT:
case ARM_2D_COLOUR_SZ_16BIT:
case ARM_2D_COLOUR_SZ_32BIT:
tResult = __arm_2d_big_pixel_tile_pave( ptThis,
&tTempSourceTile,
&tTargetTile,
wMode);
break;
default:
tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
break;
}
#else
if (OP_CORE.ptOp->Info.Colour.u3ColourSZ >= ARM_2D_COLOUR_SZ_8BIT) {
tResult = __arm_2d_big_pixel_tile_pave( ptThis,
&tTempSourceTile,
NULL, //!< source mask
&tTargetTile,
NULL, //!< target mask
wMode);
} else {
tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
}
#endif
} while(0);
return tResult;
}
static arm_fsm_rt_t __tile_non_negtive_location_pave(
arm_2d_op_cp_t *ptThis,
const arm_2d_tile_t *ptSource,
const arm_2d_tile_t *ptTarget,
const arm_2d_region_t *ptRegion,
uint32_t wMode)
{
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
do {
arm_2d_tile_t tTile = {0};
if (NULL == arm_2d_tile_generate_child(ptTarget, ptRegion, &tTile, true)) {
break;
}
#if 0
switch (OP_CORE.ptOp->Info.Colour.u3ColourSZ) {
case ARM_2D_COLOUR_SZ_8BIT:
case ARM_2D_COLOUR_SZ_16BIT:
case ARM_2D_COLOUR_SZ_32BIT:
tResult = __arm_2d_big_pixel_tile_pave(ptThis, ptSource, &tTile, wMode);
break;
default:
tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
break;
}
#else
if (OP_CORE.ptOp->Info.Colour.u3ColourSZ >= ARM_2D_COLOUR_SZ_8BIT) {
tResult = __arm_2d_big_pixel_tile_pave( ptThis,
ptSource,
NULL, //!< source mask
&tTile,
NULL, //!< target mask
wMode);
} else {
tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
}
#endif
} while(0);
return tResult;
}
__WEAK
bool __arm_2d_op_ensure_resource( arm_2d_op_core_t *ptOP,
uint_fast16_t hwRequired)
{
ARM_2D_UNUSED(hwRequired);
ARM_2D_UNUSED(ptOP);
return true;
}
static
arm_fsm_rt_t __arm_2d_op_frontend_region_process( arm_2d_op_core_t *ptOP)
{
ARM_2D_IMPL(arm_2d_op_t, ptOP)
arm_fsm_rt_t tResult = (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;;
arm_2d_tile_t tTile = {0};
arm_2d_region_t tDrawRegion = {0};
arm_2d_region_t tTargetRegion = {0};
arm_2d_tile_t *ptTarget = NULL;
if (!__arm_2d_op_ensure_resource(ptOP, 1)) {
//! insufficient resources, ask users to try again
return arm_fsm_rt_wait_for_res;
}
if (NULL == this.Target.ptRegion) {
//! use target region instead
this.Target.ptRegion = &(this.Target.ptTile->tRegion);
tTargetRegion.tSize = (*this.Target.ptRegion).tSize;
} else {
tTargetRegion = *this.Target.ptRegion;
}
//! handle the offset of the target tile
do {
//arm_2d_tile_t tValidTargetTile;
arm_2d_region_t tValidRegion;
arm_2d_location_t tOffset;
if (NULL == arm_2d_tile_get_root(this.Target.ptTile, &tValidRegion, &tOffset)) {
//! nothing to draw, actually
return (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
}
//! calculate the valid region in the view of the target tile
tValidRegion.tLocation = tOffset;
//! [Modify][Target.ptTile]
//this.Target.ptTile = arm_2d_tile_generate_child( this.Target.ptTile,
//this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile
ptTarget = arm_2d_tile_generate_child( this.Target.ptTile,
&tValidRegion,
&tTile,
true);
//! [Modify][Target.ptTile]
//assert(NULL != this.Target.ptTile);
//assert(NULL != this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile);
assert(NULL != ptTarget);
tTargetRegion.tLocation.iX -= tOffset.iX;
tTargetRegion.tLocation.iY -= tOffset.iY;
} while(0);
//! [Modify][Target.ptTile]
//tDrawRegion.tSize = this.Target.ptTile->tRegion.tSize;
//tDrawRegion.tSize
// = this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile->tRegion.tSize;
tDrawRegion.tSize = ptTarget->tRegion.tSize;
if (!arm_2d_region_intersect( &tDrawRegion,
&tTargetRegion,
&tDrawRegion)) {
return (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
}
//! drawing
do {
arm_2d_tile_t tTempTile = {0};
//! [Modify][Target.ptTile]
//if (NULL == arm_2d_tile_generate_child( this.Target.ptTile,
if (NULL == arm_2d_tile_generate_child(
//this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile,
ptTarget,
&tTargetRegion,
&tTempTile, true)) {
break;
}
#if 0
switch (OP_CORE.ptOp->Info.Colour.u3ColourSZ) {
case ARM_2D_COLOUR_SZ_8BIT:
case ARM_2D_COLOUR_SZ_16BIT:
case ARM_2D_COLOUR_SZ_32BIT:
tResult = __arm_2d_big_pixel_tile_pave(ptThis, ptSource, &tTile, wMode);
break;
default:
tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
break;
}
#else
if (OP_CORE.ptOp->Info.Colour.u3ColourSZ >= ARM_2D_COLOUR_SZ_8BIT) {
tResult = __arm_2d_tile_process( ptThis,
&tTempTile);
} else {
tResult = (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
}
#endif
} while(0);
return tResult;
}
static
arm_fsm_rt_t __arm_2d_op_frontend_control( arm_2d_op_core_t *ptOP)
{
/*TODO: add support for control operations*/
return (arm_fsm_rt_t)ARM_2D_ERR_NOT_SUPPORT;
}
static
arm_fsm_rt_t __arm_2d_op_frontend_region_process_with_src( arm_2d_op_core_t *ptOP)
{
ARM_2D_IMPL(arm_2d_op_src_t, ptOP)
arm_fsm_rt_t tResult;
arm_2d_tile_t tTile = {0};
arm_2d_region_t tDrawRegion = {0};
arm_2d_region_t tTargetRegion = {0};
const arm_2d_tile_t *ptTarget = NULL;
if (!__arm_2d_op_ensure_resource(ptOP, 4)) {
//! insufficient resources, ask users to try again
return arm_fsm_rt_wait_for_res;
}
if (NULL == this.Target.ptRegion) {
//! use target region instead
this.Target.ptRegion = &(this.Target.ptTile->tRegion);
tTargetRegion.tSize = (*this.Target.ptRegion).tSize;
} else {
tTargetRegion = *this.Target.ptRegion;
}
//! handle the offset of the target tile
do {
//arm_2d_tile_t tValidTargetTile;
arm_2d_region_t tValidRegion;
arm_2d_location_t tOffset;
if (NULL == arm_2d_tile_get_root(this.Target.ptTile, &tValidRegion, &tOffset)) {
//! nothing to draw, actually
return (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
}
//! calculate the valid region in the view of the target tile
tValidRegion.tLocation = tOffset;
//if (tOffset.iX != 0 || tOffset.iY != 0) {
//!! [Modify][Target.ptTile]
//this.Target.ptTile = arm_2d_tile_generate_child( this.Target.ptTile,
//this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile
ptTarget = arm_2d_tile_generate_child( this.Target.ptTile,
&tValidRegion,
&tTile,
true);
//!! [Modify][Target.ptTile]
//assert(NULL != this.Target.ptTile);
//assert(NULL != this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile);
assert(NULL != ptTarget);
tTargetRegion.tLocation.iX -= tOffset.iX;
tTargetRegion.tLocation.iY -= tOffset.iY;
//}
} while(false);
if ( this.wMode & ARM_2D_CP_MODE_FILL) {
/* quickly ignore non visiable area, only for FILL mode */
if (tTargetRegion.tLocation.iX < 0) {
int_fast16_t iX = tTargetRegion.tLocation.iX;
tTargetRegion.tLocation.iX %= this.Source.ptTile->tRegion.tSize.iWidth;
//! calculate the delta
iX = tTargetRegion.tLocation.iX - iX;
//! update the width to make sure the range won't be expanded mistakenly
tTargetRegion.tSize.iWidth -= iX;
}
if (tTargetRegion.tLocation.iY < 0) {
int_fast16_t iY = tTargetRegion.tLocation.iY;
tTargetRegion.tLocation.iY %= this.Source.ptTile->tRegion.tSize.iHeight;
//! calculate the delta
iY = tTargetRegion.tLocation.iY - iY;
//! update the width to make sure the range won't be expanded mistakenly
tTargetRegion.tSize.iHeight -= iY;
}
}
//!! [Modify][Target.ptTile]
//tDrawRegion.tSize = this.Target.ptTile->tRegion.tSize;
//tDrawRegion.tSize = this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile->tRegion.tSize;
tDrawRegion.tSize = ptTarget->tRegion.tSize;
if (!arm_2d_region_intersect( &tDrawRegion,
&tTargetRegion,
&tDrawRegion)) {
//! no overlapping
return (arm_fsm_rt_t)ARM_2D_ERR_OUT_OF_REGION;
}
if ( (tTargetRegion.tLocation.iX < 0)
|| (tTargetRegion.tLocation.iY < 0)) {
/*! draw the top left corner */
/*
HOW IT WORKS:
source tile (with negative relative location)
+------------------------------------+
| |
| +------------------------------+-- ... --+
| |//////////////////////////////| |
| |//ACTUAL DRAWING PART/////////| |
| |//////////////////////////////| |
+-----+------------------------------+-- ... --|
| | |
... ... ...
| | |
+------------------------------+-- ... --+
*/
arm_2d_region_t tClippdRegion;
tResult = __tile_clipped_pave( &this,
ptTarget,
&tTargetRegion,
&tClippdRegion,
this.wMode & ~ARM_2D_CP_MODE_FILL);
if (tResult < 0) {
return tResult;
}
if (this.wMode & ARM_2D_CP_MODE_FILL) { /*!< fill mode */
/*! draw the partial header */
/*
HOW IT WORKS:
source tile (with negative relative location)
+------------------+------------------------------------+-- ... --+
| | IGNORED HEADER PART | repeat |
| +---------------+------------------------------------+-- ... --+
| | |////////////////////////////////////|/////////|
| |Clipped Region |////ACTUAL DRAWING PART/////////////|/repeat//|
| | |////////////////////////////////////|/////////|
+--+---------------+------------------------------------+-- ... --+
| |
| |
+---------------------------------------------------------- ... --+
*/
if (tClippdRegion.tSize.iWidth < tDrawRegion.tSize.iWidth) {
//! something left to draw
arm_2d_region_t tHeaderRegion = tDrawRegion;
tHeaderRegion.tSize.iWidth = tDrawRegion.tSize.iWidth
- tClippdRegion.tSize.iWidth;
tHeaderRegion.tLocation.iX += tClippdRegion.tSize.iWidth;
tHeaderRegion.tSize.iHeight = tClippdRegion.tSize.iHeight
- tTargetRegion.tLocation.iY;
tHeaderRegion.tLocation.iY = tTargetRegion.tLocation.iY;
tResult = __tile_clipped_pave( &this,
ptTarget,
&tHeaderRegion,
NULL,
this.wMode);
//arm_2d_region_t tClippedRegion;
if (tResult < 0) {
return tResult;
}
}
/*! draw the partial column */
/*
HOW IT WORKS:
source tile (with negative relative location)
+------------------------------------+
| |
| +------------------------------+-- ... --+
| | | |
| | | |
| | | |
+-----+------------------------------+ |
| |//////////////////////////////| |
| |//////////////////////////////| |
| |////ACTUAL DRAWING COLUMN/////| |
| |//////////////////////////////| |
| |//////////////////////////////| |
+-----+------------------------------+ |
| |//////////////////////////////| |
... ...///repeat////////////////////| |
| |//////////////////////////////| |
+-----+------------------------------+-- ... --+
*/
if (tClippdRegion.tSize.iHeight < tDrawRegion.tSize.iHeight) {
//! something left to draw
arm_2d_region_t tFirstColumnRegion = tDrawRegion;
tFirstColumnRegion.tSize.iHeight = tDrawRegion.tSize.iHeight - tClippdRegion.tSize.iHeight;
tFirstColumnRegion.tLocation.iY += tClippdRegion.tSize.iHeight;
tFirstColumnRegion.tSize.iWidth = tClippdRegion.tSize.iWidth
- tTargetRegion.tLocation.iX;
tFirstColumnRegion.tLocation.iX = tTargetRegion.tLocation.iX;
tResult = __tile_clipped_pave( &this,
ptTarget,
&tFirstColumnRegion,
NULL,
this.wMode);
if (tResult < 0) {
return tResult;
}
}
/*! draw the normal non-negitive part */
/*
HOW IT WORKS:
source tile (with negative relative location)
+------------------------------------+
| |
| +------------------------------+-- ... --+
| | | |
| | | |
| | | |
+-----+------------------------------+-- ... --|
| |/////////|
| |/////////|
... ...///////...
| |/////////|
| |/////////|
+------------------------------+-- ... --+
*/
if ( (tClippdRegion.tSize.iWidth < tDrawRegion.tSize.iWidth)
&& (tClippdRegion.tSize.iHeight < tDrawRegion.tSize.iHeight)) {
arm_2d_region_t tNonNegRegion = tDrawRegion;
tNonNegRegion.tSize.iWidth = tDrawRegion.tSize.iWidth - tClippdRegion.tSize.iWidth;
tNonNegRegion.tSize.iHeight = tDrawRegion.tSize.iHeight - tClippdRegion.tSize.iHeight;
tNonNegRegion.tLocation.iX += tClippdRegion.tSize.iWidth;
tNonNegRegion.tLocation.iY += tClippdRegion.tSize.iHeight;
tResult = __tile_non_negtive_location_pave( &this,
this.Source.ptTile,
//! [Modify][Target.ptTile]
//this.Target.ptTile,
//this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile,
ptTarget,
&tNonNegRegion,
this.wMode);
if (tResult < 0) {
return tResult;
}
}
}
} else {
tResult = __tile_non_negtive_location_pave( &this,
this.Source.ptTile,
//! [Modify][Target.ptTile]
//this.Target.ptTile,
//this.use_as__arm_2d_op_core_t.Runtime.ptTargetTile,
ptTarget,
&tTargetRegion,
this.wMode);
}
return tResult;
}
/*----------------------------------------------------------------------------*
* Frontend *
*----------------------------------------------------------------------------*/
arm_fsm_rt_t __arm_2d_op_depose(arm_2d_op_core_t *ptThis,
arm_fsm_rt_t tResult)
{
//arm_irq_safe
{
this.tResult = tResult;
this.Status.tValue =
((tResult < 0) ? __ARM_2D_OP_STATUS_IO_ERROR_msk : 0) |
__ARM_2D_OP_STATUS_CPL_msk ;
}
return tResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_op_frontend_on_leave( arm_2d_op_core_t *ptThis,
arm_fsm_rt_t tResult)
{
return __arm_2d_op_depose(ptThis, tResult);
}
static void __arm_2d_op_use_default_frame_buffer(arm_2d_op_core_t *ptOP)
{
ARM_2D_IMPL(arm_2d_op_t, ptOP);
if ((intptr_t)-1 == (intptr_t)this.Target.ptTile) {
this.Target.ptTile = ARM_2D_CTRL.ptDefaultFrameBuffer;
}
}
arm_fsm_rt_t __arm_2d_op_frontend_op_decoder(arm_2d_op_core_t *ptThis)
{
arm_fsm_rt_t tResult;
//! decode operation
switch (this.ptOp->Info.Param.chValue &
( ARM_2D_OP_INFO_PARAM_HAS_SOURCE
//| ARM_2D_OP_INFO_PARAM_HAS_ORIGIN
| ARM_2D_OP_INFO_PARAM_HAS_TARGET
//| ARM_2D_OP_INFO_PARAM_HAS_SOURCE_MASK
//| ARM_2D_OP_INFO_PARAM_HAS_TARGET_MASK
)) {
case ( ARM_2D_OP_INFO_PARAM_HAS_SOURCE
| ARM_2D_OP_INFO_PARAM_HAS_TARGET):
__arm_2d_op_use_default_frame_buffer(ptThis);
/* operaion process target tile based on source tile */
tResult = __arm_2d_op_frontend_region_process_with_src(ptThis);
break;
case ARM_2D_OP_INFO_PARAM_HAS_TARGET:
__arm_2d_op_use_default_frame_buffer(ptThis);
/* operation which only processes target tile */
tResult = __arm_2d_op_frontend_region_process(ptThis);
break;
default:
/* control operation */
tResult = __arm_2d_op_frontend_control(ptThis);
}
if (ARM_2D_ERR_OUT_OF_REGION == tResult) {
if (ARM_2D_RUNTIME_FEATURE.TREAT_OUT_OF_RANGE_AS_COMPLETE) {
//! nothing to draw
tResult = arm_fsm_rt_cpl;
}
}
return tResult;
}
__WEAK
/*! \brief sync up with operation
*! \retval true sync up with operation
*! \retval false operation is busy
*/
bool arm_2d_op_wait_async(arm_2d_op_core_t *ptOP)
{
return true;
}
__WEAK
/*! \brief sync up with operation
*! \retval true operation is busy
*! \retval false operation isn't busy
*/
bool __arm_2d_op_acquire(arm_2d_op_core_t *ptOP)
{
ARM_2D_IMPL(arm_2d_op_core_t, ptOP)
bool bResult = !this.Status.bIsBusy;
arm_irq_safe {
if (bResult) {
//! initialize operation
do {
this.tResult = arm_fsm_rt_async;
this.Status.tValue = 0; //! reset status
this.Status.bIsBusy = true; //! set busy flag
} while(0);
}
}
return bResult;
}
__WEAK
arm_fsm_rt_t __arm_2d_op_frontend(arm_2d_op_core_t *ptThis)
{
arm_fsm_rt_t tResult;
tResult = __arm_2d_op_frontend_op_decoder(ptThis);
return __arm_2d_op_frontend_on_leave(ptThis, tResult);
}
arm_fsm_rt_t __arm_2d_op_invoke(arm_2d_op_core_t *ptOP)
{
ARM_2D_IMPL(arm_2d_op_core_t, ptOP)
#if 0
if (this.Status.bIsBusy) {
return arm_fsm_rt_on_going;
}
//! initialize operation
do {
this.tResult = arm_fsm_rt_async;
this.Status.tValue = 0; //! reset status
this.Status.bIsBusy = true; //! set busy flag
} while(0);
#endif
return __arm_2d_op_frontend(ptThis);
}
/*! \brief initialise the whole arm-2d service
*! \param none
*! \return none
*/
void __arm_2d_init(void)
{
/*! initialise arm-2d control block */
memset(&ARM_2D_CTRL, 0, sizeof(struct __arm_2d_op_control));
}
/*! \brief set the default frame buffer
*! \param ptFramebuffer the new frame buffer, if NULL is given, no default
*! frame buffer will be used
*! \return the address of the old frame buffer
*/
arm_2d_tile_t *arm_2d_set_default_frame_buffer(const arm_2d_tile_t *ptFrameBuffer)
{
arm_2d_tile_t *ptOldBuffer = NULL;
arm_irq_safe {
ptOldBuffer = ARM_2D_CTRL.ptDefaultFrameBuffer;
ARM_2D_CTRL.ptDefaultFrameBuffer = (arm_2d_tile_t *)ptFrameBuffer;
}
return ptOldBuffer;
}
/*! \brief get the default frame buffer
*! \return the address of the default frame buffer
*/
arm_2d_tile_t *arm_2d_get_default_frame_buffer(void)
{
return ARM_2D_CTRL.ptDefaultFrameBuffer;
}
/*! \brief attach a user param (which could be a pointer) to specified OP
*! \param ptOP the address of the target OP (NULL means using the default OP)
*! \param pUserParam a user param (it can be used as a pointer)
*/
void arm_2d_set_user_param(arm_2d_op_core_t *ptOP, uintptr_t pUserParam)
{
ARM_2D_IMPL(arm_2d_op_core_t, ptOP);
this.pUserParam = pUserParam;
}
/*! \brief get the status of a specified OP
*! \param ptOP the address of the target OP (NULL means using the default OP)
*! \return the status
*/
arm_2d_op_status_t arm_2d_get_op_status(arm_2d_op_core_t *ptOP)
{
ARM_2D_IMPL(arm_2d_op_core_t, ptOP)
volatile arm_2d_op_status_t *ptStatus
= (volatile arm_2d_op_status_t *)&(this.Status);
return *ptStatus;
}
__WEAK
/*! \brief arm-2d pixel pipeline task entery
*! \note This function is *TRHEAD-SAFE*
*! \param none
*! \retval arm_fsm_rt_cpl The sub-task FIFO is empty, the caller, i.e. the host
*! RTOS thread can block itself by waiting for a semaphore which is
*! set by arm_2d_notif_sub_task_fifo_task_arrive()
*! \retval arm_fsm_rt_on_going The arm_2d_task issued one sub-task without
*! problem and it yields.
*! \retval arm_fsm_rt_async You shouldn't see this value
*! \retval arm_fsm_rt_wait_for_obj some algorithm or hardware accelerator wants
*! to sync-up with applications.
*! \retval (<0) Serious error is detected.
*/
arm_fsm_rt_t arm_2d_task(arm_2d_task_t *ptTask)
{
ARM_2D_UNUSED(ptTask);
return arm_fsm_rt_cpl;
}
/*----------------------------------------------------------------------------*
* Low Level IO Interfaces *
*----------------------------------------------------------------------------*/
const __arm_2d_op_info_t ARM_2D_OP_BARRIER = {
.Info = {
//! control operation
.Param = {
.bHasSource = false,
.bHasTarget = false,
},
.chOpIndex = __ARM_2D_OP_IDX_BARRIER,
.LowLevelIO = {
.ptCopyLike = NULL,
.ptFillLike = NULL,
},
},
};
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__IS_COMPILER_ARM_COMPILER_5__)
# pragma diag_warning 174,177,188,68,513,144
#elif defined(__IS_COMPILER_GCC__)
# pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
}
#endif
#endif