From 775a036579ec6b9ec36b7db76c03a21c8a947b60 Mon Sep 17 00:00:00 2001 From: Gabriel Wang Date: Thu, 19 Dec 2024 03:03:57 +0000 Subject: [PATCH] add example opcode: draw circle --- ARM.Arm-2D.pdsc | 12 +- .../opcodes/arm_2d_user_opcode_draw_circle.c | 65 +++++++++-- .../opcodes/arm_2d_user_opcode_draw_circle.h | 4 +- .../demos/arm_2d_scene_user_defined_opcode.c | 105 +++++------------- .../demos/arm_2d_scene_user_defined_opcode.h | 3 +- 5 files changed, 94 insertions(+), 95 deletions(-) diff --git a/ARM.Arm-2D.pdsc b/ARM.Arm-2D.pdsc index 24b6a1e3..effb16d4 100644 --- a/ARM.Arm-2D.pdsc +++ b/ARM.Arm-2D.pdsc @@ -756,13 +756,15 @@ - + An example for showing user define OPCODE(s) - - - - + + + + + + #define RTE_Acceleration_Arm_2D_Demos_User_Defined_OPCODE diff --git a/examples/common/opcodes/arm_2d_user_opcode_draw_circle.c b/examples/common/opcodes/arm_2d_user_opcode_draw_circle.c index f92e2a70..732d68db 100644 --- a/examples/common/opcodes/arm_2d_user_opcode_draw_circle.c +++ b/examples/common/opcodes/arm_2d_user_opcode_draw_circle.c @@ -112,6 +112,20 @@ arm_fsm_rt_t arm_2dp_rgb565_user_draw_circle( this.tParams = *ptParams; this.chOpacity = chOpacity; this.tForeground.hwColour = tColour.tValue; + + /* calculate the pivot */ + do { + if (this.tParams.ptPivot) { + this.tPivot = *this.tParams.ptPivot; + } else if (NULL != ptRegion) { + this.tPivot.iX = ptRegion->tLocation.iX + (ptRegion->tSize.iWidth >> 1); + this.tPivot.iY = ptRegion->tLocation.iY + (ptRegion->tSize.iHeight >> 1); + } else { + this.tPivot.iX = (ptTarget->tRegion.tSize.iWidth >> 1); + this.tPivot.iY = (ptTarget->tRegion.tSize.iHeight >> 1); + } + this.tPivot = arm_2d_get_absolute_location(ptTarget, this.tPivot, true ); + } while(0); return __arm_2d_op_invoke((arm_2d_op_core_t *)ptThis); } @@ -195,18 +209,51 @@ void __arm_2d_impl_rgb565_user_draw_circle( contains a valid buffer. */ - int_fast16_t iWidth = ptValidRegionOnVirtualScreen->tSize.iWidth; - int_fast16_t iHeight = ptValidRegionOnVirtualScreen->tSize.iHeight; - - for (int_fast16_t iY = 0; iY < iHeight; iY++) { + int_fast16_t iWidth = ptValidRegionOnVirtualScreen->tSize.iWidth + ptValidRegionOnVirtualScreen->tLocation.iX; + int_fast16_t iHeight = ptValidRegionOnVirtualScreen->tSize.iHeight + ptValidRegionOnVirtualScreen->tLocation.iY; - uint16_t *phwTargetLine = phwTarget; - - for (int_fast16_t iX = 0; iX < iWidth; iX++) { + uint32_t wRadius2 = (uint32_t)this.tParams.iRadius * (uint32_t)this.tParams.iRadius; + uint32_t wRadiusBorder2 = (uint32_t)(this.tParams.iRadius + 1) * (uint32_t)(this.tParams.iRadius + 1); + q16_t q16Radius = reinterpret_q16_s16(this.tParams.iRadius); - /* a simple example */ - __ARM_2D_PIXEL_BLENDING_OPA_RGB565(&hwColour, phwTargetLine++, chOpacity); + for (int_fast16_t iY = ptValidRegionOnVirtualScreen->tLocation.iY; iY < iHeight; iY++) { + uint16_t *phwTargetLine = phwTarget; + int16_t iYOffset = iY - this.tPivot.iY; + iYOffset = ABS(iYOffset); + + for (int_fast16_t iX = ptValidRegionOnVirtualScreen->tLocation.iX; iX < iWidth; iX++) { + + int16_t iXOffset = iX - this.tPivot.iX; + iXOffset = ABS(iXOffset); + + /* calculate the distance */ + uint32_t wDistance2 = (uint32_t)iXOffset * (uint32_t)iXOffset + (uint32_t)iYOffset * (uint32_t)iYOffset; + + if (wDistance2 >= wRadiusBorder2) { + phwTargetLine++; + continue; + } else if (wDistance2 <= wRadius2) { + /* fill colour with opacity */ + __ARM_2D_PIXEL_BLENDING_OPA_RGB565(&hwColour, phwTargetLine++, chOpacity); + continue; + } else if (!this.tParams.bAntiAlias) { + phwTargetLine++; + continue; + } + + /* anti alias */ + float fDistance; + arm_sqrt_f32((float)wDistance2, &fDistance); + q16_t q16Fraction = reinterpret_q16_f32(fDistance); + + /* get the residual */ + q16Fraction -= q16Radius; + + uint16_t hwOpacity = (q16Fraction & 0xFF00) >> 8; + uint8_t chPointOpacity = arm_2d_helper_alpha_mix(0xFF - hwOpacity, chOpacity); + + __ARM_2D_PIXEL_BLENDING_OPA_RGB565(&hwColour, phwTargetLine++, chPointOpacity); } phwTarget += iTargetStride; diff --git a/examples/common/opcodes/arm_2d_user_opcode_draw_circle.h b/examples/common/opcodes/arm_2d_user_opcode_draw_circle.h index c4216aa7..5efdf563 100644 --- a/examples/common/opcodes/arm_2d_user_opcode_draw_circle.h +++ b/examples/common/opcodes/arm_2d_user_opcode_draw_circle.h @@ -49,6 +49,7 @@ typedef struct arm_2d_user_draw_circle_api_params_t { arm_2d_location_t *ptPivot; int16_t iRadius; + bool bAntiAlias; } arm_2d_user_draw_circle_api_params_t; @@ -57,10 +58,9 @@ typedef struct arm_2d_user_draw_circle_descriptor_t { implement(arm_2d_op_t); /* inherit from base class arm_2d_op_t*/ arm_2d_user_draw_circle_api_params_t tParams; - //arm_2d_region_t tDrawRegion; + arm_2d_location_t tPivot; uint8_t chOpacity; - COLOUR_TYPE_T tForeground; }arm_2d_user_draw_circle_descriptor_t; diff --git a/examples/demos/arm_2d_scene_user_defined_opcode.c b/examples/demos/arm_2d_scene_user_defined_opcode.c index b836edff..d726a63f 100644 --- a/examples/demos/arm_2d_scene_user_defined_opcode.c +++ b/examples/demos/arm_2d_scene_user_defined_opcode.c @@ -79,11 +79,6 @@ /*============================ TYPES =========================================*/ /*============================ GLOBAL VARIABLES ==============================*/ - -extern const arm_2d_tile_t c_tileCMSISLogo; -extern const arm_2d_tile_t c_tileCMSISLogoMask; -extern const arm_2d_tile_t c_tileCMSISLogoA2Mask; -extern const arm_2d_tile_t c_tileCMSISLogoA4Mask; /*============================ PROTOTYPES ====================================*/ /*============================ LOCAL VARIABLES ===============================*/ @@ -127,8 +122,6 @@ static void __on_scene_user_defined_opcode_depose(arm_2d_scene_t *ptScene) *ptItem = 0; } - console_box_depose(&this.tConsole); - /* draw line */ do { arm_foreach(arm_2d_user_draw_line_descriptor_t, this.tDrawLineOP, ptLineOP) { @@ -169,10 +162,6 @@ static void __on_scene_user_defined_opcode_frame_start(arm_2d_scene_t *ptScene) this.iStartOffset = 100; } this.iStartOffset -= 4; - - console_box_printf(&this.tConsole, "%d\r\n",rand()); - - console_box_on_frame_start(&this.tConsole); } static void __on_scene_user_defined_opcode_frame_complete(arm_2d_scene_t *ptScene) @@ -283,54 +272,29 @@ IMPL_PFB_ON_DRAW(__pfb_draw_scene_user_defined_opcode_handler) } } - arm_2d_dock_top(__top_canvas, (tScreenSize.iHeight >> 1)) { - - arm_2d_align_centre(__top_region, c_tileCMSISLogoMask.tRegion.tSize) { - - arm_2d_fill_colour_with_vertical_alpha_gradient_mask_and_opacity( - ptTile, - &__centre_region, - &c_tileCMSISLogoMask, - (__arm_2d_color_t){GLCD_COLOR_GREEN}, - 255, - (arm_2d_alpha_samples_2pts_t){255, 0} - ); - } - } + arm_2d_align_centre(__top_canvas, 100, 100) { - arm_2d_align_centre(__top_canvas, 140, 128) { + /* draw circle */ + do { + arm_2d_user_draw_circle_api_params_t tParam = { + .iRadius = 25, + .bAntiAlias = true, + }; - arm_2d_dock(__centre_region, 10, 10, 32, 0) { - console_box_show( - &this.tConsole, + arm_2dp_rgb565_user_draw_circle( + NULL, ptTile, - &__dock_region, - bIsNewFrame, - 128); - + &__centre_region, + &tParam, + (arm_2d_color_rgb565_t){__RGB( 255, 200, 0)}, + 255); - } + ARM_2D_OP_WAIT_ASYNC(); + } while(0); - arm_2d_dock(__centre_region, 0, 0, 32, 10) { - draw_round_corner_border( ptTile, - &__dock_region, - GLCD_COLOR_GREEN, - (arm_2d_border_opacity_t) - {64, 64, 64, 64}, - (arm_2d_corner_opacity_t) - {64, 64, 64, 64}); - } } - /* draw text at the top-left corner */ - - arm_lcd_text_set_target_framebuffer((arm_2d_tile_t *)ptTile); - arm_lcd_text_set_font(&ARM_2D_FONT_6x8.use_as__arm_2d_font_t); - arm_lcd_text_set_draw_region(NULL); - arm_lcd_text_set_colour(GLCD_COLOR_RED, GLCD_COLOR_WHITE); - arm_lcd_text_location(0,0); - arm_lcd_puts("Scene user_defined_opcode"); /*-----------------------draw the foreground end -----------------------*/ } @@ -346,6 +310,19 @@ user_scene_user_defined_opcode_t *__arm_2d_scene_user_defined_opcode_init( arm bool bUserAllocated = false; assert(NULL != ptDispAdapter); +#if __GLCD_CFG_COLOUR_DEPTH__ != 16 + /* this demo only works for rgb565*/ + + ARM_2D_LOG_ERROR( + APP, + 0, + "Demo", + "The User Defined Opcode Demo currently only works for RGB565, i.e. __GLCD_CFG_COLOUR_DEPTH__ equals 16" + ); + + return NULL; +#endif + s_tDirtyRegions[dimof(s_tDirtyRegions)-1].ptNext = NULL; /* get the screen region */ @@ -415,32 +392,6 @@ user_scene_user_defined_opcode_t *__arm_2d_scene_user_defined_opcode_init( arm } } while(0); - do { - #if __DISP0_CFG_CONSOLE_INPUT_BUFFER__ - static uint8_t s_chInputBuffer[__DISP0_CFG_CONSOLE_INPUT_BUFFER__]; - #endif - static uint8_t s_chConsoleBuffer[(__DISP0_CFG_SCEEN_WIDTH__ / 6) * (__DISP0_CFG_SCEEN_HEIGHT__ / 8)]; - console_box_cfg_t tCFG = { - .tBoxSize = { - 120, 64 - }, - - .pchConsoleBuffer = s_chConsoleBuffer, - .hwConsoleBufferSize = sizeof(s_chConsoleBuffer), - - #if __DISP0_CFG_CONSOLE_INPUT_BUFFER__ - .pchInputBuffer = s_chInputBuffer, - .hwInputBufferSize = sizeof(s_chInputBuffer), - #endif - .tColor = GLCD_COLOR_GREEN, - .bUseDirtyRegion = true, - }; - - console_box_init( &this.tConsole, - &this.use_as__arm_2d_scene_t, - &tCFG); - } while(0); - /* ------------ initialize members of user_scene_user_defined_opcode_t end ---------------*/ arm_2d_scene_player_append_scenes( ptDispAdapter, diff --git a/examples/demos/arm_2d_scene_user_defined_opcode.h b/examples/demos/arm_2d_scene_user_defined_opcode.h index 42fe2dfd..980acddd 100644 --- a/examples/demos/arm_2d_scene_user_defined_opcode.h +++ b/examples/demos/arm_2d_scene_user_defined_opcode.h @@ -31,7 +31,7 @@ #include "arm_2d_helper.h" #include "arm_2d_user_opcode_draw_line.h" -#include "arm_2d_example_controls.h" +#include "arm_2d_user_opcode_draw_circle.h" #ifdef __cplusplus extern "C" { @@ -92,7 +92,6 @@ ARM_PRIVATE( int16_t iStartOffset; arm_2d_user_draw_line_descriptor_t tDrawLineOP[16]; - console_box_t tConsole; ) /* place your public member here */