diff --git a/src/Makefile b/src/Makefile index 5b2d11082..19dcc2134 100755 --- a/src/Makefile +++ b/src/Makefile @@ -69,6 +69,7 @@ VL53L5CX_DIR=drivers/vl53l5cx PIXART_DIR=drivers/pixart DISPLAY_DIR=drivers/display DAVE2D_DIR=drivers/dave2d +NEMA_DIR=drivers/nema LIBPDM_DIR=lib/libpdm TENSORFLOW_DIR=lib/tflm CYW4343_FW_DIR=drivers/cyw4343/firmware/ diff --git a/src/drivers/nema/LICENSE.pdf b/src/drivers/nema/LICENSE.pdf new file mode 100644 index 000000000..72f275608 Binary files /dev/null and b/src/drivers/nema/LICENSE.pdf differ diff --git a/src/drivers/nema/include/build_version.h b/src/drivers/nema/include/build_version.h new file mode 100644 index 000000000..8c235c31d --- /dev/null +++ b/src/drivers/nema/include/build_version.h @@ -0,0 +1 @@ +// Build Hash: 41847c80308e08cc83474b118b1bd53ab622cd7e diff --git a/src/drivers/nema/include/nema_blender.h b/src/drivers/nema/include/nema_blender.h new file mode 100644 index 000000000..fdfed21b0 --- /dev/null +++ b/src/drivers/nema/include/nema_blender.h @@ -0,0 +1,188 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_BLENDER_H__ +#define NEMA_BLENDER_H__ + +#include "nema_sys_defs.h" +#include "nema_graphics.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Blending Factor Selector +//----------------------------------------------------------------------------------------------------------------------- +#define NEMA_BF_ZERO (0x0U) /**< 0 */ +#define NEMA_BF_ONE (0x1U) /**< 1 */ +#define NEMA_BF_SRCCOLOR (0x2U) /**< Sc */ +#define NEMA_BF_INVSRCCOLOR (0x3U) /**< (1-Sc) */ +#define NEMA_BF_SRCALPHA (0x4U) /**< Sa */ +#define NEMA_BF_INVSRCALPHA (0x5U) /**< (1-Sa) */ +#define NEMA_BF_DESTALPHA (0x6U) /**< Da */ +#define NEMA_BF_INVDESTALPHA (0x7U) /**< (1-Da) */ +#define NEMA_BF_DESTCOLOR (0x8U) /**< Dc */ +#define NEMA_BF_INVDESTCOLOR (0x9U) /**< (1-Dc) */ +#define NEMA_BF_CONSTCOLOR (0xaU) /**< Cc */ +#define NEMA_BF_CONSTALPHA (0xbU) /**< Ca */ + + /* source factor destination factor */ +#define NEMA_BL_SIMPLE ( (uint32_t)NEMA_BF_SRCALPHA | ((uint32_t)NEMA_BF_INVSRCALPHA <<8) ) /**< Sa * Sa + Da * (1 - Sa) */ +#define NEMA_BL_CLEAR ( (uint32_t)NEMA_BF_ZERO /*| ((uint32_t)NEMA_BF_ZERO <<8)*/) /**< 0 */ +#define NEMA_BL_SRC ( (uint32_t)NEMA_BF_ONE /*| ((uint32_t)NEMA_BF_ZERO <<8)*/) /**< Sa */ +#define NEMA_BL_SRC_OVER ( (uint32_t)NEMA_BF_ONE | ((uint32_t)NEMA_BF_INVSRCALPHA <<8) ) /**< Sa + Da * (1 - Sa) */ +#define NEMA_BL_DST_OVER ( (uint32_t)NEMA_BF_INVDESTALPHA | ((uint32_t)NEMA_BF_ONE <<8) ) /**< Sa * (1 - Da) + Da */ +#define NEMA_BL_SRC_IN ( (uint32_t)NEMA_BF_DESTALPHA /*| ((uint32_t)NEMA_BF_ZERO <<8)*/) /**< Sa * Da */ +#define NEMA_BL_DST_IN (/*(uint32_t)NEMA_BF_ZERO |*/ ((uint32_t)NEMA_BF_SRCALPHA <<8) ) /**< Da * Sa */ +#define NEMA_BL_SRC_OUT ( (uint32_t)NEMA_BF_INVDESTALPHA/*| ((uint32_t)NEMA_BF_ZERO <<8)*/ ) /**< Sa * (1 - Da) */ +#define NEMA_BL_DST_OUT (/*(uint32_t)NEMA_BF_ZERO |*/ ((uint32_t)NEMA_BF_INVSRCALPHA <<8) ) /**< Da * (1 - Sa) */ +#define NEMA_BL_SRC_ATOP ( (uint32_t)NEMA_BF_DESTALPHA | ((uint32_t)NEMA_BF_INVSRCALPHA <<8) ) /**< Sa * Da + Da * (1 - Sa) */ +#define NEMA_BL_DST_ATOP ( (uint32_t)NEMA_BF_INVDESTALPHA | ((uint32_t)NEMA_BF_SRCALPHA <<8) ) /**< Sa * (1 - Da) + Da * Sa */ +#define NEMA_BL_ADD ( (uint32_t)NEMA_BF_ONE | ((uint32_t)NEMA_BF_ONE <<8) ) /**< Sa + Da */ +#define NEMA_BL_XOR ( (uint32_t)NEMA_BF_INVDESTALPHA | ((uint32_t)NEMA_BF_INVSRCALPHA <<8) ) /**< Sa * (1 - Da) + Da * (1 - Sa) */ + + +#define NEMA_BLOP_NONE (0U) /**< No extra blending operation */ +#define NEMA_BLOP_RECOLOR (0x00100000U) /**< Cconst*Aconst + Csrc*(1-Aconst). Overrides MODULATE_RGB. On NemaP GPU, recolor is available only when HW Rop Blender is enabled */ +#define NEMA_BLOP_LUT (0x00200000U) /**< src_tex as index, src2_tex as palette */ +#define NEMA_BLOP_STENCIL_XY (0x00400000U) /**< Use TEX3 as mask */ +#define NEMA_BLOP_STENCIL_TXTY (0x00800000U) /**< Use TEX3 as mask */ +#define NEMA_BLOP_NO_USE_ROPBL (0x01000000U) /**< Don't use Rop Blender even if present */ +#define NEMA_BLOP_DST_CKEY_NEG (0x02000000U) /**< Apply Inverse Destination Color Keying - draw only when dst color doesn't match colorkey*/ +#define NEMA_BLOP_SRC_PREMULT (0x04000000U) /**< Premultiply Source Color with Source Alpha (cannot be used with NEMA_BLOP_MODULATE_RGB) */ +#define NEMA_BLOP_MODULATE_A (0x08000000U) /**< Modulate by Constant Alpha value*/ +#define NEMA_BLOP_FORCE_A (0x10000000U) /**< Force Constant Alpha value */ +#define NEMA_BLOP_MODULATE_RGB (0x20000000U) /**< Modulate by Constant Color (RGB) values */ +#define NEMA_BLOP_SRC_CKEY (0x40000000U) /**< Apply Source Color Keying - draw only when src color doesn't match colorkey */ +#define NEMA_BLOP_DST_CKEY (0x80000000U) /**< Apply Destination Color Keying - draw only when dst color matches colorkey */ +#define NEMA_BLOP_MASK (0xfff00000U) + +/** \brief Return blending mode given source and destination blending factors and additional blending operations + * + * \param src Source Blending Factor + * \param dst Destination Blending Factor + * \param ops Additional Blending Operations + * \return Final Blending Mode + * + */ +static inline uint32_t nema_blending_mode(uint32_t src_bf, uint32_t dst_bf, uint32_t blops) { + return ( (src_bf) | (dst_bf << 8) | (blops&NEMA_BLOP_MASK) ); +} + +/** \brief Set blending mode + * + * \param blending_mode Blending mode to be set + * \param dst_tex Destination Texture + * \param fg_tex Foreground (source) Texture + * \param bg_tex Background (source2) Texture + * + */ +void nema_set_blend(uint32_t blending_mode, nema_tex_t dst_tex, nema_tex_t fg_tex, nema_tex_t bg_tex); + +/** \brief Set blending mode for filling + * + * \param blending_mode Blending mode to be set + * + */ +static inline void nema_set_blend_fill(uint32_t blending_mode) { + nema_set_blend(blending_mode, NEMA_TEX0, NEMA_NOTEX, NEMA_NOTEX); +} + +/** \brief Set blending mode for filling with composing + * + * \param blending_mode Blending mode to be set + * + */ +static inline void nema_set_blend_fill_compose(uint32_t blending_mode) { + nema_set_blend(blending_mode, NEMA_TEX0, NEMA_NOTEX, NEMA_TEX2); +} + +/** \brief Set blending mode for blitting + * + * \param blending_mode Blending mode to be set + * + */ +static inline void nema_set_blend_blit(uint32_t blending_mode) { + nema_set_blend(blending_mode, NEMA_TEX0, NEMA_TEX1, NEMA_NOTEX); +} + +/** \brief Set blending mode for blitting with composing + * + * \param blending_mode Blending mode to be set + * + */ +static inline void nema_set_blend_blit_compose(uint32_t blending_mode) { + nema_set_blend(blending_mode, NEMA_TEX0, NEMA_TEX1, NEMA_TEX2); +} + +/** \brief Set constant color + * + * \param rgba RGBA color + * \see nema_rgba() + * + */ +void nema_set_const_color(uint32_t rgba); + + +/** \brief Set recolor color. Overrides constant color + * + * \param rgba RGBA color + * \see nema_rgba(), nema_set_const_color() + * + */ +void nema_set_recolor_color(uint32_t rgba); + +/** \brief Set source color key + * + * \param rgba RGBA color key + * \see nema_rgba() + * + */ +void nema_set_src_color_key(uint32_t rgba); + +/** \brief Set destination color key + * + * \param rgba RGBA color key + * \see nema_rgba() + * + */ +void nema_set_dst_color_key(uint32_t rgba); + + +/** \brief Enable/disable ovedraw debugging. Disables gradient and texture, forces blending mode to NEMA_BL_ADD + * + * \param enable Enables overdraw debugging if non-zero + * + */ +void nema_debug_overdraws(uint32_t enable); + +#ifdef __cplusplus +} +#endif + +#endif // NEMA_BLENDER_H__ diff --git a/src/drivers/nema/include/nema_cmdlist.h b/src/drivers/nema/include/nema_cmdlist.h new file mode 100644 index 000000000..2f2de1aaf --- /dev/null +++ b/src/drivers/nema/include/nema_cmdlist.h @@ -0,0 +1,208 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_CMDLIST_H__ +#define NEMA_CMDLIST_H__ + +#include "nema_sys_defs.h" +#include "nema_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CL_NOP 0x010000U +#define CL_PUSH 0x020000U +#define CL_RETURN 0x040000U +#define CL_ABORT 0x080000U + +#define CL_BATCH_SHIFT 12 +#define CL_BATCH_LOOP 0x8000 + +#define SUBMISSION_ID_MASK 0xffffff + +#define CL_ALIGNMENT_MASK (0x00000007U) // CL buffer must be 8 byte aligned + +//--------------------------------------------------------------------------- +typedef struct nema_cmdlist_t_ { + nema_buffer_t bo; + int size; /**< Number of entries in the command list */ + int offset; /**< Points to the next address to write */ + uint32_t flags; /**< Flags */ + int32_t submission_id; + struct nema_cmdlist_t_ *next; /**< Points to next command list */ + struct nema_cmdlist_t_ *root; /**< Points to the head of the list */ +} nema_cmdlist_t; + +/** \brief Create a new Command List into a preallocated space + * + * \param addr_virt Command List's address (preallocated) + * \param size_bytes Command List's size in bytes + * \return The instance of the new Command List + * + */ +nema_cmdlist_t nema_cl_create_prealloc(nema_buffer_t *bo); + +/** \brief Create a new, non expandable Command List of specific size + * + * \param size_bytes Command List's size in bytes + * \return The instance of the new Command List + * + */ +nema_cmdlist_t nema_cl_create_sized(int size_bytes); + +/** \brief Create a new expandable Command List + * + * \return The instance of the new Command List + * + */ +nema_cmdlist_t nema_cl_create(void); + +/** \brief Destroy/Free a Command List + * + * \param cl Pointer to the Command List + * + */ +void nema_cl_destroy(nema_cmdlist_t *cl); + +/** \brief Reset position of next command to be written to the beginning. Doesn't clear the List's contents. + * + * \param cl Pointer to the Command List + * + */ +void nema_cl_rewind(nema_cmdlist_t *cl); + +/** \brief Define in which Command List each subsequent commands are going to be inserted. + * + * \param cl Pointer to the Command List + * + */ +void nema_cl_bind(nema_cmdlist_t *cl); + +/** \brief Define in which Command List each subsequent commands are going to be inserted. + * Bind this command list as Circular. It never gets full, it never expands, + * it may get implicitly submitted, it cannot be reused. No other CL should be submitted + * while a circular CL is bound + * + * \param cl Pointer to the Command List + * + */ +void nema_cl_bind_circular(nema_cmdlist_t *cl); + +/** \brief Unbind current bound Command List, if any. + * + * + */ +void nema_cl_unbind(void); + + +/** \brief Get bound Command List + * + * \return Pointer to the bound Command List + * + */ +nema_cmdlist_t *nema_cl_get_bound(void); + +/** \private */ +void nema_cl_submit_no_irq(nema_cmdlist_t *cl); + +/** \brief Enqueue Command List to the Ring Buffer for execution + * + * \param cl Pointer to the Command List + * + */ +void nema_cl_submit(nema_cmdlist_t *cl); + +/** \brief Wait for Command List to finish + * + * \param cl Pointer to the Command List + * \return 0 if no error has occurred + * + */ +int nema_cl_wait(nema_cmdlist_t *cl); + +/** \brief Add a command to the bound Command List + * + * \param reg Hardware register to be written + * \param data Data to be written + * + */ +void nema_cl_add_cmd(uint32_t reg, uint32_t data); + +/** \brief Add multiple commands to the bound Command List + * + * \param cmd_no Numbers of commands to add + * \param cmd Pointer to the commands to be added + * \return 0 if no error has occurred + * + */ +int nema_cl_add_multiple_cmds(int cmd_no, uint32_t *cmd); + +/** private */ +uint32_t * nema_cl_get_space(int cmd_no); + +/** \brief Branch from the bound Command List to a different one. Return is implied. + * + * \param cl Pointer to the Command List to branch to + * + */ +void nema_cl_branch(nema_cmdlist_t *cl); + +/** \brief Jump from the bound Command List to a different one. No return is implied. + * + * \param cl Pointer to the Command List to jump to + * + */ +void nema_cl_jump(nema_cmdlist_t *cl); + +/** \brief Add an explicit return command to the bound Command List + * + * + */ +void nema_cl_return(void); + +/** \brief Returns positive number if the Command List is almost full, otherwise returns 0. + * + * \param cl Pointer to the Command List + * + */ +int nema_cl_almost_full(nema_cmdlist_t *cl); + +/** \brief Check if there is enough space or expansion can be performed for + * required commands. + * + * \param cmd_no Numbers of commands to be checked if they fit + * \reurn zero is commands fit or expansion xan be performed else return negative + */ +int nema_cl_enough_space(int cmd_no); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_core.h b/src/drivers/nema/include/nema_core.h new file mode 100644 index 000000000..2cb73a17b --- /dev/null +++ b/src/drivers/nema/include/nema_core.h @@ -0,0 +1,42 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_CORE_H__ +#define NEMA_CORE_H__ + +#include "nema_hal.h" +#include "nema_cmdlist.h" +#include "nema_graphics.h" +#include "nema_interpolators.h" +#include "nema_blender.h" +#include "nema_math.h" +#include "nema_matrix3x3.h" +#include "nema_matrix4x4.h" +#include "nema_version.h" + +#endif diff --git a/src/drivers/nema/include/nema_easing.h b/src/drivers/nema/include/nema_easing.h new file mode 100644 index 000000000..bf289383c --- /dev/null +++ b/src/drivers/nema/include/nema_easing.h @@ -0,0 +1,369 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_EASING_H__ +#define NEMA_EASING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//Linear + +// Modeled after the line y = x +/** \brief Linear easing, no acceleration + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_linear(float p); + +//Quadratic + +// Modeled after the parabola y = x^2 +/** \brief Quadratic easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quad_in(float p); + +// Modeled after the parabola y = -x^2 + 2x +/** \brief Quadratic easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quad_out(float p); + +// Modeled after the piecewise quadratic +// y = (1/2)((2x)^2) ; [0, 0.5) +// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1] +/** \brief Quadratic easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quad_in_out(float p); + +//Cubic + +// Modeled after the cubic y = x^3 +/** \brief Cubic easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_cub_in(float p); + +// Modeled after the cubic y = (x - 1)^3 + 1 +/** \brief Cubic easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_cub_out(float p); + +// Modeled after the piecewise cubic +// y = (1/2)((2x)^3) ; [0, 0.5) +// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1] +/** \brief Cubic easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_cub_in_out(float p); + +//Quartic + +// Modeled after the quartic x^4 +/** \brief Quartic easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quar_in(float p); + +// Modeled after the quartic y = 1 - (x - 1)^4 +/** \brief Quartic easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quar_out(float p); + +// Modeled after the piecewise quartic +// y = (1/2)((2x)^4) ; [0, 0.5) +// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1] +/** \brief Quartic easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quar_in_out(float p); + +//Quintic + +// Modeled after the quintic y = x^5 +/** \brief Quintic easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quin_in(float p); + +// Modeled after the quintic y = (x - 1)^5 + 1 +/** \brief Quintic easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quin_out(float p); + +// Modeled after the piecewise quintic +// y = (1/2)((2x)^5) ; [0, 0.5) +// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1] +/** \brief Quintic easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_quin_in_out(float p); + +//Sin + +// Modeled after quarter-cycle of sine wave +/** \brief Sinusoidal easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_sin_in(float p); + +// Modeled after quarter-cycle of sine wave (different phase) +/** \brief Sinusoidal easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_sin_out(float p); + +// Modeled after half sine wave +/** \brief Sinusoidal easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_sin_in_out(float p); + +//Circular + +// Modeled after shifted quadrant IV of unit circle +/** \brief Circular easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_circ_in(float p); + +// Modeled after shifted quadrant II of unit circle +/** \brief Circular easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_circ_out(float p); + +// Modeled after the piecewise circular function +// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5) +// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1] +/** \brief Circular easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_circ_in_out(float p); + +//Exponential + +// Modeled after the exponential function y = 2^(10(x - 1)) +/** \brief Exponential easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_exp_in(float p); + +// Modeled after the exponential function y = -2^(-10x) + 1 +/** \brief Exponential easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_exp_out(float p); + +// Modeled after the piecewise exponential +// y = (1/2)2^(10(2x - 1)) ; [0,0.5) +// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1] +/** \brief Exponential easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_exp_in_out(float p); + +//Elastic +// Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1)) + +/** \brief Elastic easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_elast_in(float p); + +// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1 +/** \brief Elastic easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_elast_out(float p); + +// Modeled after the piecewise exponentially-damped sine wave: +// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5) +// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1] +/** \brief Elastic easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_elast_in_out(float p); + +//Back + +// Modeled after the overshooting cubic y = x^3-x*sin(x*pi) +/** \brief Overshooting easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_back_in(float p); + +// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi)) +/** \brief Overshooting easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_back_out(float p); + +// Modeled after the piecewise overshooting cubic function: +// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5) +// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1] +/** \brief Overshooting easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_back_in_out(float p); + +//Bounce + +/** \brief Bouncing easing in, accelerate from zero + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_bounce_out(float p); + +/** \brief Bouncing easing out, decelerate to zero velocity + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_bounce_in(float p); + +/** \brief Bouncing easing in and out, accelerate to halfway, then decelerate + * + * \param p Input value, typically within the [0, 1] range + * \return Eased value + * + */ +float nema_ez_bounce_in_out(float p); + + +/** \brief Convenience function to perform easing between two values given number of steps, current step and easing function + * + * \param A Initial value within range [0, 1] + * \param B Finale value within range [0, 1] + * \param steps Total number of steps + * \param cur_step Current Step + * \param ez_func pointer to the desired easing function + * \return Eased value + * + */ + + +float nema_ez(float A, float B, float steps, float cur_step, float (*ez_func)(float p)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_error.h b/src/drivers/nema/include/nema_error.h new file mode 100644 index 000000000..58ff5b11b --- /dev/null +++ b/src/drivers/nema/include/nema_error.h @@ -0,0 +1,69 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +#ifndef NEMA_ERROR_H__ +#define NEMA_ERROR_H__ + +#include "nema_sys_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Error Handling + +#define NEMA_ERR_NO_ERROR (0x00000000U) /**< No error has occured */ +#define NEMA_ERR_SYS_INIT_FAILURE (0x00000001U) /**< System initialization failure */ +#define NEMA_ERR_GPU_ABSENT (0x00000002U) /**< Nema GPU is absent */ +#define NEMA_ERR_RB_INIT_FAILURE (0x00000004U) /**< Ring buffer initialization failure */ +#define NEMA_ERR_NON_EXPANDABLE_CL_FULL (0x00000008U) /**< Non expandable command list is full*/ +#define NEMA_ERR_CL_EXPANSION (0x00000010U) /**< Command list expansion error */ +#define NEMA_ERR_OUT_OF_GFX_MEMORY (0x00000020U) /**< Graphics memory is full */ +#define NEMA_ERR_OUT_OF_HOST_MEMORY (0x00000040U) /**< Host memory is full */ +#define NEMA_ERR_NO_BOUND_CL (0x00000080U) /**< There is no bound command list */ +#define NEMA_ERR_NO_BOUND_FONT (0x00000100U) /**< There is no bound font */ +#define NEMA_ERR_GFX_MEMORY_INIT (0x00000200U) /**< Graphics memory initialization failure */ +#define NEMA_ERR_DRIVER_FAILURE (0x00000400U) /**< Nema GPU Kernel Driver failure*/ +#define NEMA_ERR_MUTEX_INIT (0x00000800U) /**< Mutex initialization failure*/ +#define NEMA_ERR_INVALID_BO (0x00001000U) /**< Invalid buffer provided*/ +#define NEMA_ERR_INVALID_CL (0x00002000U) /**< Invalid CL provided*/ +#define NEMA_ERR_INVALID_CL_ALIGMENT (0x00004000U) /**< Invalid CL buffer alignment*/ +#define NEMA_ERR_NO_INIT (0x00008000U) /**< GFX uninitialised*/ + +/** \brief Return Error Id + * + * \return 0 if no error exists + * + */ +uint32_t nema_get_error(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NEMA_ERROR_H__ diff --git a/src/drivers/nema/include/nema_font.h b/src/drivers/nema/include/nema_font.h new file mode 100644 index 000000000..bb5ab1adf --- /dev/null +++ b/src/drivers/nema/include/nema_font.h @@ -0,0 +1,184 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_FONT_H__ +#define NEMA_FONT_H__ + +#include "nema_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEMA_ALIGNX_LEFT (0x00U) /**< Align horizontally to the left */ +#define NEMA_ALIGNX_RIGHT (0x01U) /**< Align horizontally to the right */ +#define NEMA_ALIGNX_CENTER (0x02U) /**< Align horizontally centered */ +#define NEMA_ALIGNX_JUSTIFY (0x03U) /**< Justify horizontally */ +#define NEMA_ALIGNX_MASK (0x03U) /**< Horizontal alignment mask */ +#define NEMA_ALIGNY_TOP (0x00U) /**< Align vertically to the top */ +#define NEMA_ALIGNY_BOTTOM (0x04U) /**< Align vertically to the bottom */ +#define NEMA_ALIGNY_CENTER (0x08U) /**< Align vertically centered */ +#define NEMA_ALIGNY_JUSTIFY (0x0cU) /**< Justify vertically */ +#define NEMA_ALIGNY_MASK (0x0cU) /**< Vertical alignment mask */ +#define NEMA_TEXT_WRAP (0x10U) /**< Use text wrapping */ + +typedef struct { + uint32_t left; /**< Neighbor character to the left of the current one (Unicode value) */ + int8_t x_offset; /**< Kerning offset (horizontally) */ +} nema_kern_pair_t; + +typedef struct { + uint32_t bitmapOffset; + uint8_t width; + uint8_t xAdvance; + int8_t xOffset; + int8_t yOffset; + uint32_t kern_offset; + uint8_t kern_length; +} nema_glyph_t; + +typedef struct { + int bitmapOffset; + uint8_t width; + uint8_t xAdvance; + int8_t xOffset; + int8_t yOffset; + int id; +} nema_glyph_indexed_t; + +typedef struct { + uint32_t first, last; + const nema_glyph_t *glyphs; +} nema_font_range_t; + +typedef struct { + nema_buffer_t bo; + const nema_font_range_t *ranges; + const int bitmap_size; + const uint8_t *bitmap; + uint32_t flags; + uint8_t xAdvance; //default xAdvance + uint8_t yAdvance; + uint8_t max_ascender; + uint8_t bpp; + const nema_kern_pair_t *kern_pairs; + const nema_glyph_indexed_t *indexed_glyphs; +} nema_font_t; + +/** \brief Bind the font to use in future nema_print() calls + * + * \param font Pointer to font + * + */ +void nema_bind_font(nema_font_t *font); + +/** \brief Get the bounding box's width and height of a string. + * + * \param str Pointer to string + * \param w Pointer to variable where width should be written + * \param h Pointer to variable where height should be written + * \param max_w Max allowed width + * \return Number of carriage returns + * + */ +int nema_string_get_bbox(const char *str, int *w, int *h, int max_w, uint32_t wrap); + +/** \brief Print pre-formatted text + * + * \param str Pointer to string + * \param x X coordinate of text-area's top-left corner + * \param y Y coordinate of text-area's top-left corner + * \param w Width of the text area + * \param h Height of the text area + * \param fg_col Foreground color of text + * \param align Alignment and wrapping mode + * + */ +void nema_print(const char *str, int x, int y, int w, int h, uint32_t fg_col, uint32_t align); + +/** \brief Print pre-formatted text + * + * \param *str Pointer to string + * \param *cursor_x X position of next character to be drawn. Usually initialized to 0 by the user and then updated internally by the library + * \param *cursor_y Y position of next character to be drawn. Usually initialized to 0 by the user and then updated internally by the library + * \param x X coordinate of text-area's top-left corner + * \param y Y coordinate of text-area's top-left corner + * \param w Width of the text area + * \param h Height of the text area + * \param fg_col Foreground color of text + * \param align Alignment and wrapping mode + * + */ +void nema_print_to_position(const char *str, int *pos_x, int *pos_y, int x, int y, int w, int h, uint32_t fg_col, uint32_t align); + + +/** \brief Print text (not formated) with indexed glyphs. Text is printed in a single line, from left to right + * + * \param ids Array with the glyphs indices + * \param id_count Count of the characters to be drawn + * \param x X coordinate of the text-area's top-left corner + * \param y Y coordinate of the text-area's top-left corner + * \param fg_col Foreground color of text + * + */ +void nema_print_indexed(const int *ids, int id_count, int x, int y, uint32_t fg_col); + +/** \brief Print a single character with indexed glyph + * + * \param id Array with the glyphs indices + * \param x X coordinate of the character's top-left corner + * \param y Y coordinate of the character's top-left corner + * \param fg_col Character's color + * + */ +void nema_print_char_indexed(const int id, int x, int y, uint32_t fg_col); + +/** \brief Returns the bounding box's width and height of a string with indexed glyphs + * + * \details The string must be specified as a single line text, due to the restriction + * that the characters are described by respective glyph indices. The height of the + * bounding box will be equal to the height of the bound font. + * + * \param ids Array with the glyphs indices + * \param id_count Count of the characters contained in the array with the glyphs indices + * \param w Pointer to variable where width should be written + * \param h Pointer to variable where height should be written + * \param max_w Maximum allowed width (if w is greater than this value, it will saturate to this) + */ +void nema_string_indexed_get_bbox(const int *ids, int id_count, int *w, int *h, int max_w); + +/** \brief Returns the horizontal advance (in pixels) of the bound font + * + */ +int nema_font_get_x_advance(void); + +#ifdef __cplusplus +} +#endif + +#endif // NEMA_FONT_H__ diff --git a/src/drivers/nema/include/nema_graphics.h b/src/drivers/nema/include/nema_graphics.h new file mode 100644 index 000000000..5685cfe6e --- /dev/null +++ b/src/drivers/nema/include/nema_graphics.h @@ -0,0 +1,1019 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_GRAPHICS_H__ +#define NEMA_GRAPHICS_H__ + +#include "nema_sys_defs.h" +#include "nema_hal.h" +#include "nema_matrix3x3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _img_obj_ { + nema_buffer_t bo; + uint16_t w; + uint16_t h; + int stride; + uint32_t color; + uint8_t format; + uint8_t sampling_mode; // NEMA_FILTER* +} img_obj_t; + +typedef img_obj_t nema_img_obj_t; + +typedef enum { + NEMA_NOTEX = -1, /**< No Texture */ + NEMA_TEX0 = 0, /**< Texture 0 */ + NEMA_TEX1 = 1, /**< Texture 1 */ + NEMA_TEX2 = 2, /**< Texture 2 */ + NEMA_TEX3 = 3, /**< Texture 3 */ + NEMA_TEXMAX = 4 /**< Enum max value */ +} nema_tex_t; + +#define NEMA_RGBX8888 0x00U /**< RGBX8888 */ +#define NEMA_RGBA8888 0x01U /**< RGBA8888 */ +#define NEMA_XRGB8888 0x02U /**< XRGB8888 */ +#define NEMA_ARGB8888 0x03U /**< ARGB8888 */ +#define NEMA_RGB565 0x04U /**< RGBA5650 */ +#define NEMA_RGBA5650 0x04U /**< RGBA5650 */ +#define NEMA_RGBA5551 0x05U /**< RGBA5551 */ +#define NEMA_RGBA4444 0x06U /**< RGBA4444 */ +#define NEMA_RGBA0800 0x07U /**< RGBA0800 */ +#define NEMA_A8 0x08U /**< RGBA0008 */ +#define NEMA_RGBA0008 0x08U /**< RGBA0008 */ +#define NEMA_L8 0x09U /**< L8 */ +#define NEMA_RGBA3320 0x38U /**< RGBA3320 (source only) */ +#define NEMA_RGB332 0x38U /**< RGBA3320 (source only) */ +#define NEMA_BW1 0x0CU /**< A1 (source only) */ +#define NEMA_A1 0x0CU /**< A1 (source only) */ +#define NEMA_L1 0x0BU /**< L1 (source only) */ +#define NEMA_UYVY 0x0DU /**< UYVY */ +#define NEMA_ABGR8888 0x0EU /**< ABGR8888 */ +#define NEMA_XBGR8888 0x0FU /**< XBGR8888 */ +#define NEMA_BGRA8888 0x10U /**< BGRA */ +#define NEMA_BGRX8888 0x11U /**< BGRX */ +#define NEMA_TSC4 0x12U /**< TSC4 */ +#define NEMA_TSC6 0x16U /**< TSC6 */ +#define NEMA_TSC6A 0x17U /**< TSC6A */ +#define NEMA_RV 0x18U /**< RV */ +#define NEMA_GU 0x19U /**< GU */ +#define NEMA_BY 0x1AU /**< BY */ +#define NEMA_YUV 0x1BU /**< YUV */ +#define NEMA_Z24_8 0x1cU /**< Z24_8 */ +#define NEMA_Z16 0x1dU /**< Z16 */ +#define NEMA_UV 0x1eU /**< UV */ +#define NEMA_A1LE 0x27U /**< A1LE (source only) */ +#define NEMA_A2LE 0x28U /**< A2LE (source only) */ +#define NEMA_A4LE 0x29U /**< A4LE (source only) */ +#define NEMA_L1LE 0x2AU /**< L1LE (source only) */ +#define NEMA_L2LE 0x2BU /**< L2LE (source only) */ +#define NEMA_L4LE 0x2CU /**< L4LE (source only) */ +#define NEMA_A2 0x30U /**< A2 (source only) */ +#define NEMA_A4 0x34U /**< A4 (source only) */ +#define NEMA_L2 0x31U /**< L2 (source only) */ +#define NEMA_L4 0x35U /**< L4 (source only) */ +#define NEMA_BGR24 0x39U /**< BGR24 */ +#define NEMA_RGB24 0x3CU /**< RGB24 */ +#define NEMA_RV10 0x3DU /**< RV-10bit */ +#define NEMA_GU10 0x3EU /**< GU-10bit */ +#define NEMA_BY10 0x3FU /**< BY-10bit */ +#define NEMA_RGBA2222 0x40U /**< RGBA2222 (Available if HW enabled - check HW manual) */ +#define NEMA_ABGR2222 0x41U /**< ABGR2222 (Available if HW enabled - check HW manual) */ +#define NEMA_BGRA2222 0x42U /**< BGRA2222 (Available if HW enabled - check HW manual) */ +#define NEMA_ARGB2222 0x43U /**< ARGB2222 (Available if HW enabled - check HW manual) */ +#define NEMA_AL88 0x44U /**< AL88 (Available if HW enabled - check HW manual) */ +#define NEMA_AL44 0x45U /**< AL44 (Available if HW enabled - check HW manual) */ +#define NEMA_ARGB1555 0x46U /**< ARGB1555 (Available if HW enabled - check HW manual) */ +#define NEMA_ARGB4444 0x47U /**< ARGB4444 (Available if HW enabled - check HW manual) */ +#define NEMA_BGRA5650 0x13U /**< BGRA5650 (Available if HW enabled - check HW manual) */ +#define NEMA_BGR565 0x13U /**< BGRA5650 (Available if HW enabled - check HW manual) */ +#define NEMA_BGRA5551 0x48U /**< BGRA5551 (Available if HW enabled - check HW manual) */ +#define NEMA_ABGR1555 0x49U /**< ABGR1555 (Available if HW enabled - check HW manual) */ +#define NEMA_BGRA4444 0x4aU /**< BGRA4444 (Available if HW enabled - check HW manual) */ +#define NEMA_ABGR4444 0x4bU /**< ABGR4444 (Available if HW enabled - check HW manual) */ +#define NEMA_TSC12 0x4cU /**< TSC12 (Available if HW enabled - check HW manual) */ +#define NEMA_TSC12A 0x4dU /**< TSC12A (Available if HW enabled - check HW manual) */ +#define NEMA_TSC6AP 0x4eU /**< TSC6AP (Available if HW enabled - check HW manual) */ + +#define NEMA_DITHER 0x80U /**< Nema Dithering */ +#define NEMA_FORMAT_MASK 0x7FU /**< Format Mask */ + +typedef uint32_t nema_tex_format_t; + +//----------------------------------------------------------------------------------------------------------------------- + +// Texture Unit Parameters +//----------------------------------------------------------------------------------------- + // Filtering - 0:0 + //---------------------- +#define NEMA_FILTER_PS 0x00U /**< Point Sampling. */ +#define NEMA_FILTER_BL 0x01U /**< Bilinear filtering. */ + + // Wrapping Mode 3:2 + //---------------------- +#define NEMA_TEX_CLAMP (0x00U) /**< Clamp */ +#define NEMA_TEX_REPEAT (0x01U<<2) /**< Repeat */ +#define NEMA_TEX_BORDER (0x02U<<2) /**< Border */ +#define NEMA_TEX_MIRROR (0x03U<<2) /**< Mirror */ + + // Texture Coordinates Ordering 4:4 + //---------------------- +#define NEMA_TEX_MORTON_ORDER (0x10U) + + // Texture Coordinates Format 6:5 + //---------------------- +#define NEMA_TEX_RANGE_0_1 (0x1U<<5) /**< Interpolated Coordinates range: 0-1 */ +#define NEMA_TEX_LEFT_HANDED (0x1U<<6) /**< (0,0) is bottom left corner */ + +typedef uint8_t nema_tex_mode_t; + +// Triangle Culling +//----------------------------------------------------------------------------------------- +typedef enum { + NEMA_CULL_NONE = 0 , /**< Disable Triangle/Quadrilateral Culling */ + NEMA_CULL_CW = (1U<<28), /**< Cull clockwise Triangles/Quadrilaterals */ + NEMA_CULL_CCW = (1U<<29), /**< Cull anti-clockwise Triangles/Quadrilaterals */ + NEMA_CULL_ALL = NEMA_CULL_CW | NEMA_CULL_CCW /**< Cull all */ +} nema_tri_cull_t; + +// Rotation Modes +//----------------------------------------------------------------------------------------------------------------------- + +#define NEMA_ROT_000_CCW (0x0U) /**< No rotation */ +#define NEMA_ROT_090_CCW (0x1U) /**< Rotate 90 degrees counter-clockwise */ +#define NEMA_ROT_180_CCW (0x2U) /**< Rotate 180 degrees counter-clockwise */ +#define NEMA_ROT_270_CCW (0x3U) /**< Rotate 270 degrees counter-clockwise */ +#define NEMA_ROT_000_CW (0x0U) /**< No rotation */ +#define NEMA_ROT_270_CW (0x1U) /**< Rotate 270 degrees clockwise */ +#define NEMA_ROT_180_CW (0x2U) /**< Rotate 180 degrees clockwise */ +#define NEMA_ROT_090_CW (0x3U) /**< Rotate 90 degrees clockwise */ +#define NEMA_MIR_VERT (0x4U) /**< Mirror Vertically */ +#define NEMA_MIR_HOR (0x8U) /**< Mirror Horizontally */ + + +/** \brief Check if a known GPU is present + * + * \return -1 if no known GPU is present + * + */ +int nema_checkGPUPresence(void); + +// ------------------------------ TEXTURES ------------------------------------- + +/** \brief Program a Texture Unit + * + * \param texid Texture unit to be programmed + * \param addr_gpu Texture's address as seen by the GPU + * \param width Texture's width + * \param height Texture's height + * \param format Texture's format + * \param stride Texture's stride. If stride < 0, it's left to be calculated + * \param wrap_mode Wrap/Repeat mode to be used. When using 'repeat' or 'mirror', texture dimensions must be a power of two. Otherwise the behavior is undefined. + * + */ +void nema_bind_tex(nema_tex_t texid, uintptr_t addr_gpu, + uint32_t width, uint32_t height, + nema_tex_format_t format, int32_t stride, nema_tex_mode_t wrap_mode); + +/** \brief Set Texture Mapping default color + * + * \param color default color in 32-bit RGBA format + * \see nema_rgba() + * + */ +void nema_set_tex_color(uint32_t color); + +// ------------------------------ CONSTREGS ------------------------------------ + +/** \brief Write a value to a Constant Register of the GPU + * + * \param reg Constant Register to be written + * \param value Value to be written + * + */ +void nema_set_const_reg(int reg, uint32_t value); + +// --------------------------------- CLIP -------------------------------------- + +/** \brief Sets the drawing area's Clipping Rectangle + * + * \param x Clip Window top-left x coordinate + * \param y Clip Window minimum y + * \param w Clip Window width + * \param h Clip Window height + * + */ +void nema_set_clip(int32_t x, int32_t y, uint32_t w, uint32_t h); + +void nema_enable_gradient(int enable); + +void nema_enable_depth(int enable); + +/** \brief Enables MSAA per edge + * + * \param e0 Enable MSAA for edge 0 (vertices 0-1) + * \param e1 Enable MSAA for edge 1 (vertices 1-2) + * \param e2 Enable MSAA for edge 2 (vertices 2-3) + * \param e3 Enable MSAA for edge 3 (vertices 3-0) + * \return previous AA flags (may be ignored) + * + */ +uint32_t nema_enable_aa(uint8_t e0, uint8_t e1, uint8_t e2, uint8_t e3); + +// ------------------------------- DIRTY REGIONS ------------------------------------ + +/** \brief Returns the bounding rectangle of all the pixels that have been modified since its previous call. + * Available only on Nema|P and Nema|PVG GPUs. + * + * \param minx x coordinate of the upper left corner of the dirty region + * \param miny y coordinate of the upper left corner of the dirty region + * \param maxx x coordinate of the lower right corner of the dirty region + * \param maxy y coordinate of the lower right corner of the dirty region + * + */ +void nema_get_dirty_region(int *minx, int *miny, int *maxx, int *maxy); + +/** \brief Clear dirty region information - runs via the bound command-list + * Available only on Nema|P and Nema|PVG GPUs. + * + * \see nema_get_dirty_region() + * \see nema_clear_dirty_region_imm() + * + */ +void nema_clear_dirty_region(void); + +/** \brief Clear dirty region information immediately, no command-list involved + * Available only on Nema|P and Nema|PVG GPUs. + * + * \see nema_get_dirty_region() + * \see nema_clear_dirty_region() + * + */ +void nema_clear_dirty_region_imm(void); + +// -------------------------------- UTILS -------------------------------------- + +/** \brief Set triangle/quadrilateral culling mode + * + * \param cull Culling mode + * + */ +void nema_tri_cull(nema_tri_cull_t cull); + +/** \brief Return pixel size in bytes + * + * \param format Color format + * \return Pixel size in bytes + * + */ +int nema_format_size (nema_tex_format_t format); + +/** \brief Return stride in bytes + * + * \param format Color format + * \param wrap_mode Wrap/Repeat mode to be used. When using 'repeat' or 'mirror', texture dimensions must be a power of two. Otherwise the behavior is undefined. + * \param width Texture color format + * \return Stride in bytes + * + */ +int nema_stride_size(nema_tex_format_t format, nema_tex_mode_t wrap_mode, int width); + + +/** \brief Return texture size in bytes + * + * \param format Texture color format + * \param wrap_mode Wrap/Repeat mode to be used. When using 'repeat' or 'mirror', texture dimensions must be a power of two. Otherwise the behavior is undefined. + * \param width Texture width + * \param height Texture height + * \return Texture size in bytes + * + */ +int nema_texture_size(nema_tex_format_t format, nema_tex_mode_t wrap_mode, int width, int height); + +/** \brief Return Nema internal RGBA color + * + * \param R Red component + * \param G Green component + * \param B Blue component + * \param A Alpha component + * \return RGBA value + * + */ +uint32_t nema_rgba(unsigned char R, + unsigned char G, + unsigned char B, + unsigned char A); + +/** \brief Premultiply RGB channels with Alpha channel + * + * \param rgba RGBA color + * \return Premultiplied RGBA color + * + */ +uint32_t nema_premultiply_rgba(uint32_t rgba); + +/** \brief Initialize NemaGFX library + * + * \return negative value on error + * + */ +int nema_init(void); + +/** \brief Reinitialize NemaGFX library + * + * \details This function reinitializes the NemaGFX library after a GPU poweroff + * No memory allocation for ringbuffer etc is performed. + * + * \return negative value on error + * + */ +int nema_reinit(void); + +// ------------------------------- CONTEXT ------------------------------------- + +/** \brief Program Texture Unit with a foreground (source) texture (NEMA_TEX1) + * + * \param baseaddr_phys Address of the source texture, as seen by the GPU + * \param width Texture width + * \param height Texture hight + * \param format Texture format + * \param stride Texture stride. If negative, it's calculated internally. + * \param wrap_mode Wrap/Repeat mode to be used. When using 'repeat' or 'mirror', texture dimensions must be a power of two. Otherwise the behavior is undefined. + * + */ +void nema_bind_src_tex(uintptr_t baseaddr_phys, + uint32_t width, uint32_t height, + nema_tex_format_t format, int32_t stride, nema_tex_mode_t mode); + +/** \brief Program Texture Unit with a background texture ((NEMA_TEX2) + * + * \param baseaddr_phys Address of the source2 texture, as seen by the GPU + * \param width Texture width + * \param height Texture hight + * \param format Texture format + * \param stride Texture stride. If negative, it's calculated internally. + * \param wrap_mode Wrap/Repeat mode to be used. When using 'repeat' or 'mirror', texture dimensions must be a power of two. Otherwise the behavior is undefined. + * + */ +void nema_bind_src2_tex(uintptr_t baseaddr_phys, + uint32_t width, uint32_t height, + nema_tex_format_t format, int32_t stride, nema_tex_mode_t mode); + +/** \brief Program Texture Unit with a destination texture (NEMA_TEX0) + * + * \param baseaddr_phys Address of the destination texture, as seen by the GPU + * \param width Texture width + * \param height Texture hight + * \param format Texture format + * \param stride Texture stride. If negative, it's calculated internally. + * + */ +void nema_bind_dst_tex(uintptr_t baseaddr_phys, + uint32_t width, uint32_t height, + nema_tex_format_t format, int32_t stride); + +/** \brief Program Texture Unit with a lut/palette texture (NEMA_TEX2) and index texture (NEMA_TEX1_) + * + * \param baseaddr_phys Address of the index texture + * \param width Index texture width + * \param height Index texture hight + * \param format Index texture format + * \param stride Index texture stride. If negative, it's calculated internally. + * \param mode Index texture sampling mode. When using 'NEMA_TEX_REPEAT' or 'NEMA_TEX_MIRROR' wrapping mode, + * texture dimensions must be a power of two, otherwise the behavior is undefined. NEMA_FILTER_BL is not supported. + * \param palette_baseaddr_phys Address of the lut/palette texture + * \param palette_format lut/palette texture format + * + */ +void nema_bind_lut_tex( uintptr_t baseaddr_phys, + uint32_t width, uint32_t height, + nema_tex_format_t format, int32_t stride, nema_tex_mode_t mode, + uintptr_t palette_baseaddr_phys, + nema_tex_format_t palette_format); + +/** \brief Bind Depth Buffer + * + * \param baseaddr_phys Address of the depth buffer, as seen by the GPU + * \param width Buffer width + * \param height Buffer hight + * + */ +void nema_bind_depth_buffer(uintptr_t baseaddr_phys, + uint32_t width, uint32_t height); + +/** \private */ +// -------------------------------- DEPTH -------------------------------------- +void nema_set_depth(float start, float dx, float dy); + +// ------------------------------ GRADIENT ------------------------------------- +/** \private */ +void nema_set_gradient(float r_init, float g_init, float b_init, float a_init, + float r_dx, float r_dy, + float g_dx, float g_dy, + float b_dx, float b_dy, + float a_dx, float a_dy); + +// ------------------------------- DRAWING ------------------------------------- +/** \brief Clear destination texture with color + * + * \param rgba8888 32-bit RGBA color + * \see nema_rgba() + * + */ +void nema_clear(uint32_t rgba8888); + +/** \brief Clear depth buffer with specified value + * + * \param val Clear value + * + */ +void nema_clear_depth(uint32_t val); + +/** \brief Draw a colored line + * + * \param x0 x coordinate at the beginning of the line + * \param y0 y coordinate at the beginning of the line + * \param x1 x coordinate at the end of the line + * \param y1 y coordinate at the end of the line + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_draw_line(int x0, int y0, int x1, int y1, uint32_t rgba8888); + + +/** \brief Draw a line with width. Apply AA if available + * + * \param x0 x coordinate at the beginning of the line + * \param y0 y coordinate at the beginning of the line + * \param x1 x coordinate at the end of the line + * \param y1 y coordinate at the end of the line + * \param w line width + * \param rgba8888 Color to be used + * \see nema_draw_line() + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void +nema_draw_line_aa(float x0, float y0, float x1, float y1, float w, + uint32_t rgba8888); + +/** \brief Draw a colored circle with 1 pixel width + * + * \param x x coordinate of the circle's center + * \param y y coordinate of the circle's center + * \param r circle's radius + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_draw_circle(int x, int y, int r, uint32_t rgba8888); + +/** \brief Draw a colored circle with Anti-Aliasing (if available) and specified width + * + * \param x x coordinate of the circle's center + * \param y y coordinate of the circle's center + * \param r circle's radius + * \param w pencil width + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_draw_circle_aa(float x, float y, float r, float w, uint32_t rgba8888); + +/** \brief Draw a colored rectangle with rounded edges + * + * \param x0 x coordinate of the upper left vertex of the rectangle + * \param y0 y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param r corner radius + * \param rgba8888 + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_draw_rounded_rect(int x0, int y0, int w, int h, int r, uint32_t rgba8888); + +/** \brief Draw a colored rectangle + * + * \param x x coordinate of the upper left vertex of the rectangle + * \param y y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_draw_rect(int x, int y, int w, int h, uint32_t rgba8888); + +/** \brief Fill a circle with color + * + * \param x x coordinate of the circle's center + * \param y y coordinate of the circle's center + * \param r circle's radius + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_circle(int x, int y, int r, uint32_t rgba8888); + +/** \brief Fill a circle with color, use Anti-Aliasing if available + * + * \param x x coordinate of the circle's center + * \param y y coordinate of the circle's center + * \param r circle's radius + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_circle_aa(float x, float y, float r, uint32_t rgba8888); + +/** \brief Fill a triangle with color + * + * \param x0 x coordinate at the first vertex of the triangle + * \param y0 y coordinate at the first vertex of the triangle + * \param x1 x coordinate at the second vertex of the triangle + * \param y1 y coordinate at the second vertex of the triangle + * \param x2 x coordinate at the third vertex of the triangle + * \param y2 y coordinate at the third vertex of the triangle + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * + */ +void nema_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t rgba8888); + +/** \brief Fill a rectangle with rounded edges with color + * + * \param x0 x coordinate of the upper left vertex of the rectangle + * \param y0 y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param r corner radius + * \param rgba8888 + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_rounded_rect(int x0, int y0, int w, int h, int r, uint32_t rgba8888); + +/** \brief Fill a rectangle with color + * + * \param x x coordinate of the upper left vertex of the rectangle + * \param y y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_rect(int x, int y, int w, int h, uint32_t rgba8888); + +/** \brief Fill a quadrilateral with color + * + * \param x0 x coordinate at the first vertex of the quadrilateral + * \param y0 y coordinate at the first vertex of the quadrilateral + * \param x1 x coordinate at the second vertex of the quadrilateral + * \param y1 y coordinate at the second vertex of the quadrilateral + * \param x2 x coordinate at the third vertex of the quadrilateral + * \param y2 y coordinate at the third vertex of the quadrilateral + * \param x3 x coordinate at the fourth vertex of the quadrilateral + * \param y3 y coordinate at the fourth vertex of the quadrilateral + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_quad(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, uint32_t rgba8888); + + +/** \brief Fill a rectangle with color (float coordinates) + * + * \param x x coordinate of the upper left vertex of the rectangle + * \param y y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_rect_f(float x, float y, float w, float h, uint32_t rgba8888); + + +/** \brief Fill a quadrilateral with color (float coordinates) + * + * \param x0 x coordinate at the first vertex of the quadrilateral + * \param y0 y coordinate at the first vertex of the quadrilateral + * \param x1 x coordinate at the second vertex of the quadrilateral + * \param y1 y coordinate at the second vertex of the quadrilateral + * \param x2 x coordinate at the third vertex of the quadrilateral + * \param y2 y coordinate at the third vertex of the quadrilateral + * \param x3 x coordinate at the fourth vertex of the quadrilateral + * \param y3 y coordinate at the fourth vertex of the quadrilateral + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * \see nema_rgba() + * + */ +void nema_fill_quad_f(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, uint32_t rgba8888); + + +/** \brief Fill a triangle with color (float coordinates) + * + * \param x0 x coordinate at the first vertex of the triangle + * \param y0 y coordinate at the first vertex of the triangle + * \param x1 x coordinate at the second vertex of the triangle + * \param y1 y coordinate at the second vertex of the triangle + * \param x2 x coordinate at the third vertex of the triangle + * \param y2 y coordinate at the third vertex of the triangle + * \param rgba8888 Color to be used + * \see nema_set_blend_fill() + * + */ +void nema_fill_triangle_f(float x0, float y0, float x1, float y1, float x2, float y2, uint32_t rgba8888); + + +// ------------------------------- BLITTING ------------------------------------ + +/** \brief Blit source texture to destination texture + * + * \param x destination x coordinate + * \param y destination y coordinate + * \see nema_set_blend_fill() + * + */ +void nema_blit (int x, int y); + + +/** \brief Blit source texture to destination texture with rounded corners + * + * \param x destination x coordinate + * \param y destination y coordinate + * \param r destination corner radius + * \see nema_set_blend_fill() + * + */ +void nema_blit_rounded (int x, int y, int r); + +/** \brief Blit source texture to destination's specified rectangle (crop or wrap when needed) + * + * \param x destination x coordinate + * \param y destination y coordinate + * \param w destination width + * \param h destination height + * \see nema_set_blend_blit() + * + */ +void nema_blit_rect (int x, int y, int w, int h); + +/** \brief Blit part of a source texture to destination's specified rectangle (crop or wrap when needed) + * + * \param x destination x coordinate + * \param y destination y coordinate + * \param w destination width + * \param h destination height + * \param x source x coordinate + * \param y source y coordinate + * \see nema_blit_subrect() + * \see nema_set_blend_blit() + * + */ +void nema_blit_subrect(int dst_x, int dst_y, int w, int h, int src_x, int src_y); + +/** \brief Blit source texture to destination. Fit (scale) texture to specified rectangle. + * + * \param x destination x coordinate + * \param y destination y coordinate + * \param w destination width + * \param h destination height + * \see nema_set_blend_blit() + * + */ +void nema_blit_rect_fit(int x, int y, int w, int h); + + +/** \brief Blit part of source texture to destination. Fit (scale) texture to specified rectangle. + * + * \param x destination x coordinate + * \param y destination y coordinate + * \param w destination width + * \param h destination height + * \param x source x coordinate + * \param y source y coordinate + * \param w source width + * \param h source height + * \see nema_blit_rect_fit() + * \see nema_set_blend_blit() + * + */ +void nema_blit_subrect_fit( int dst_x, int dst_y, int dst_w, int dst_h, + int src_x, int src_y, int src_w, int src_h); + +/** \brief Rotate around pivot point and Blit source texture. + * + * \param cx destination rotation center x coordinate + * \param cy destination rotation center y coordinate + * \param px source pivot point x coordinate + * \param py source pivot point y coordinate + * \param degrees_cw degrees of clockwise rotation in range [0, 360] + * \see nema_set_blend_blit() + * + */ +void nema_blit_rotate_pivot( float cx, float cy, + float px, float py, float degrees_cw ); + +/** \brief Rotate and Blit source texture to destination. + * + * \param x destination x coordinate + * \param y destination y coordinate + * \param rotation Rotation to be done + * \see nema_set_blend_blit() + * + */ +void nema_blit_rotate(int x, int y, uint32_t rotation); + +/** \brief Rotate and Blit partial source texture to destination. + * + * \param sx source upper left x coordinate + * \param sy source upper left y coordinate + * \param sw source width of partial region + * \param sh source height of partial region + * \param x destination x coordinate + * \param y destination y coordinate + * \param rotation Rotation to be done + * \see nema_set_blend_blit() + * + */ +void nema_blit_rotate_partial(int sx, int sy, + int sw, int sh, + int x, int y, + uint32_t rotation); + + +/** \brief Blit source texture to destination. Fit texture to specified triangle. + * + * \param dx0 x coordinate at the first vertex of the triangle + * \param dy0 y coordinate at the first vertex of the triangle + * \param v0 in [0, 3] indicates the corner of the texture that fits to the first vertex of the triangle + * 0 _ _ 1 + * |_ _| + * 3 2 + * \param dx1 x coordinate at the second vertex of the triangle + * \param dy1 y coordinate at the second vertex of the triangle + * \param v1 in [0, 3] indicates the corner of the texture that fits to the second vertex of the triangle + * \param dx2 x coordinate at the third vertex of the triangle + * \param dy2 y coordinate at the third vertex of the triangle + * \param v2 in [0, 3] indicates the corner of the texture that fits to the third vertex of the triangle + * \see nema_set_blend_blit() + * + */ +void nema_blit_tri_fit (float dx0, float dy0, int v0, + float dx1, float dy1, int v1, + float dx2, float dy2, int v2); + +/** \brief Blit a triangular part of the source tecture to a triangular destination area + * + * \param dx0 x coordinate at the first vertex of the destination triangle + * \param dy0 y coordinate at the first vertex of the destination triangle + * \param dw0 w coordinate at the first vertex of the destination triangle + * \param dx1 x coordinate at the second vertex of the destination triangle + * \param dy1 y coordinate at the second vertex of the destination triangle + * \param dw1 w coordinate at the second vertex of the destination triangle + * \param dx2 x coordinate at the third vertex of the destination triangle + * \param dy2 y coordinate at the third vertex of the destination triangle + * \param dw2 w coordinate at the third vertex of the destination triangle + * \param sx0 x coordinate at the first vertex of the source triangle + * \param sy0 y coordinate at the first vertex of the source triangle + * \param sx1 x coordinate at the second vertex of the source triangle + * \param sy1 y coordinate at the second vertex of the source triangle + * \param sx2 x coordinate at the third vertex of the source triangle + * \param sy2 y coordinate at the third vertex of the source triangle + * \see nema_set_blend_blit() + * + */ +void nema_blit_tri_uv (float dx0, float dy0, float dw0, + float dx1, float dy1, float dw1, + float dx2, float dy2, float dw2, + float sx0, float sy0, + float sx1, float sy1, + float sx2, float sy2 + ); + +/** \brief Blit source texture to destination. Fit texture to specified quadrilateral. + * + * \param dx0 x coordinate at the first vertex of the quadrilateral + * \param dy0 y coordinate at the first vertex of the quadrilateral + * \param dx1 x coordinate at the second vertex of the quadrilateral + * \param dy1 y coordinate at the second vertex of the quadrilateral + * \param dx2 x coordinate at the third vertex of the quadrilateral + * \param dy2 y coordinate at the third vertex of the quadrilateral + * \param dx3 x coordinate at the fourth vertex of the quadrilateral + * \param dy3 y coordinate at the fourth vertex of the quadrilateral + * \see nema_set_blend_blit() + * \see nema_blit_subrect_quad_fit() + * + */ +void nema_blit_quad_fit (float dx0, float dy0, + float dx1, float dy1, + float dx2, float dy2, + float dx3, float dy3); + +/** \brief Blit source texture to destination. Fit rectangulare area of texture to specified quadrilateral. + * + * \param dx0 x coordinate at the first vertex of the quadrilateral + * \param dy0 y coordinate at the first vertex of the quadrilateral + * \param dx1 x coordinate at the second vertex of the quadrilateral + * \param dy1 y coordinate at the second vertex of the quadrilateral + * \param dx2 x coordinate at the third vertex of the quadrilateral + * \param dy2 y coordinate at the third vertex of the quadrilateral + * \param dx3 x coordinate at the fourth vertex of the quadrilateral + * \param dy3 y coordinate at the fourth vertex of the quadrilateral + * \param sx x coordinate of the top left corner of the texture's rectangular area to be blitted + * \param sy y coordinate of the top left corner of the texture's rectangular area to be blitted + * \param sw width of the texture's rectangular area to be blitted + * \param sh height of the texture's rectangular area to be blitted + * \see nema_set_blend_blit() + * \see nema_blit_quad_fit() + * + */ +void nema_blit_subrect_quad_fit(float dx0, float dy0, + float dx1, float dy1, + float dx2, float dy2, + float dx3, float dy3, + int sx, int sy, + int sw, int sh); + +/** \brief Blit source texture to destination. Use the matrix provided by the user. + * + * \param dx0 x coordinate at the first vertex of the quadrilateral + * \param dy0 y coordinate at the first vertex of the quadrilateral + * \param dx1 x coordinate at the second vertex of the quadrilateral + * \param dy1 y coordinate at the second vertex of the quadrilateral + * \param dx2 x coordinate at the third vertex of the quadrilateral + * \param dy2 y coordinate at the third vertex of the quadrilateral + * \param dx3 x coordinate at the fourth vertex of the quadrilateral + * \param dy3 y coordinate at the fourth vertex of the quadrilateral + * \param m 3x3 matrix (screen coordinates to texture coordinates) + * \see nema_set_blend_blit() + * + */ +void nema_blit_quad_m(float dx0, float dy0, + float dx1, float dy1, + float dx2, float dy2, + float dx3, float dy3, nema_matrix3x3_t m); + + + + +/** \brief Enable breakpoints + * + * \see nema_brk_disable() + * + */ +void nema_brk_enable(void); + +/** \brief Disable breakpoints + * + * \see nema_brk_enable() + * + */ +void nema_brk_disable(void); + + +/** \brief Add a breakpoint to the current Command List + * + * \return Breakpoint ID + * + */ +int nema_brk_add(void); + +/** \brief Add a breakpoint to the current Command List + * + * \param brk_id Breakpoint ID to wait for. If zero (0), wait until next Breakpoint + * \return ID of reached Breakpoint + * + */ +int nema_brk_wait(int brk_id); + +/** \brief Instruct the GPU to resume execution + * + * + */ +void nema_brk_continue(void); + +/** \brief Enable external hold signals + * + * \param hold_id Hold signals to be enabled [0-3] + * \see nema_ext_hold_disable() + * + */ +void nema_ext_hold_enable(uint32_t hold_id); + +/** \brief Disable external hold signals + * + * \param hold_id Hold signals to be disabled [0-3] + * \see nema_ext_hold_enable() + * + */ +void nema_ext_hold_disable(uint32_t hold_id); + +/** \brief Enable Interrupt Request when GPU reaches hold point + * + * \param hold_id Hold signals' IRQ to be enabled [0-3] + * \see nema_ext_hold_disable() + * + */ +void nema_ext_hold_irq_enable(uint32_t hold_id); + +/** \brief Disable external hold signals + * + * \param hold_id Hold signals' IRQ to be disabled [0-3] + * \see nema_ext_hold_enable() + * + */ +void nema_ext_hold_irq_disable(uint32_t hold_id); + + +/** \brief Assert hold signals internally via a Command List + * + * \param hold_id Hold signal to be asserted + * \param stop If not zero, force Command List Processor to wait for FLAG to be deasserted + * \see nema_ext_hold_deassert() + * + */ +void nema_ext_hold_assert(uint32_t hold_id, int stop); + +/** \brief Dessert hold signals internally via a Command List + * + * \param hold_id Hold signal to be deasserted + * \see nema_ext_hold_assert() + * + */ +void nema_ext_hold_deassert(uint32_t hold_id); + +/** \brief Assert hold signals from the CPU (no Command List) + * + * \param hold_id Hold signal to be asserted + * \see nema_ext_hold_deassert() + * + */ +void nema_ext_hold_assert_imm(uint32_t hold_id); + +/** \brief Dessert hold signals from the CPU (no Command List) + * + * \param hold_id Hold signal to be deasserted + * \see nema_ext_hold_assert() + * + */ +void nema_ext_hold_deassert_imm(uint32_t hold_id); + +/** \brief Check for which architeture is the library compiled + * + * \return Returns string with the architecture name + * + */ +const char* nema_get_sw_device_name(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_hal.h b/src/drivers/nema/include/nema_hal.h new file mode 100644 index 000000000..c76ef0463 --- /dev/null +++ b/src/drivers/nema/include/nema_hal.h @@ -0,0 +1,218 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_HAL_H__ +#define NEMA_HAL_H__ + +#include "nema_sys_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct nema_buffer_t_ { + int size; /**< Size of buffer */ + int fd; /**< File Descriptor of buffer */ + void *base_virt; /**< Virtual address of buffer */ + uintptr_t base_phys; /**< Physical address of buffer */ +} nema_buffer_t; + +/** \brief Initialize system. Implementor defined. Called in nema_init() + * + * \param void + * \return 0 if no errors occurred + * \see nema_init() + * + */ +int32_t nema_sys_init(void); + + +/** \brief Wait for interrupt from the GPU + * + * \param void + * \return 0 on success + * + */ +int nema_wait_irq(void); + +/** \brief Wait for a Command List to finish + * + * \param cl_id Command List ID + * \return 0 on success + * + */ +int nema_wait_irq_cl(int cl_id); + +/** \brief Wait for a Breakpoint + * + * \param cl_id Breakpoint ID + * \return 0 on success + * + */ +int nema_wait_irq_brk(int brk_id); + +/** \brief Read Hardware register + * + * \param reg Register to read + * \return Value read from the register + * \see nema_reg_write + * + */ +uint32_t nema_reg_read(uint32_t reg); + +/** \brief Write Hardware Register + * + * \param reg Register to write + * \param value Value to be written + * \return void() + * \see nema_reg_read() + * + */ +void nema_reg_write(uint32_t reg, uint32_t value); + +/** \brief Create memory buffer + * + * \param size Size of buffer in bytes + * \return nema_buffer_t struct + * + */ +nema_buffer_t nema_buffer_create(int size); + +/** \brief Create memory buffer at a specific pool + * + * \param pool ID of the desired memory pool + * \param size Size of buffer in bytes + * \return nema_buffer_t struct + * + */ +nema_buffer_t nema_buffer_create_pool(int pool, int size); + +/** \brief Maps buffer + * + * \param bo Pointer to buffer struct + * \return Virtual pointer of the buffer (same as in bo->base_virt) + * + */ +void *nema_buffer_map(nema_buffer_t *bo); + +/** \brief Unmaps buffer + * + * \param bo Pointer to buffer struct + * \return void + * + */ +void nema_buffer_unmap(nema_buffer_t *bo); + +/** \brief Destroy/deallocate buffer + * + * \param bo Pointer to buffer struct + * \return void + * + */ +void nema_buffer_destroy(nema_buffer_t *bo); + +/** \brief Get physical (GPU) base address of a given buffer + * + * \param bo Pointer to buffer struct + * \return Physical base address of a given buffer + * + */ +uintptr_t nema_buffer_phys(nema_buffer_t *bo); + +/** \brief Write-back buffer from cache to main memory + * + * \param bo Pointer to buffer struct + * \return void + * + */ +void nema_buffer_flush(nema_buffer_t * bo); + +/** \brief Allocate memory for CPU to use (typically, standard malloc() is called) + * + * \param size Size in bytes + * \return Pointer to allocated memory (virtual) + * \see nema_host_free() + * + */ +void *nema_host_malloc(size_t size); + +/** \brief Free memory previously allocated with nema_host_malloc() + * + * \param ptr Pointer to allocated memory (virtual) + * \return void + * \see nema_host_malloc() + * + */ +void nema_host_free(void *ptr ); + +/** \private */ +typedef struct nema_ringbuffer_t_ { + nema_buffer_t bo; + int offset; //number of 32-bit entries + int last_submission_id; +} nema_ringbuffer_t; + + +/** \brief Initialize Ring Buffer. Should be called from inside nema_sys_init(). + * This is a private function, the user should never call it. + * + * \param *rb Pointer to nema_ring_buffer_t struct + * \param reset Resets the Ring Buffer if non-zero + * \return Negative number on error + * \see nema_sys_init() + * + */ +/** \private */ +int nema_rb_init(nema_ringbuffer_t *rb, int reset); + +#define MUTEX_RB 0 +#define MUTEX_MALLOC 1 +#define MUTEX_FLUSH 2 +#define MUTEX_MAX 2 + +/** \brief Mutex Lock for multiple processes/threads + * + * \param MUTEX_RB or MUTEX_MALLOC + * \return int + * + */ +int nema_mutex_lock(int mutex_id); + +/** \brief Mutex Unlock for multiple processes/threads + * + * \param MUTEX_RB or MUTEX_MALLOC + * \return int + * + */ +int nema_mutex_unlock(int mutex_id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_interpolators.h b/src/drivers/nema/include/nema_interpolators.h new file mode 100644 index 000000000..aa267cc38 --- /dev/null +++ b/src/drivers/nema/include/nema_interpolators.h @@ -0,0 +1,122 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef _NEMA_INTERPOLATORS_H_ +#define _NEMA_INTERPOLATORS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nema_sys_defs.h" + +typedef struct _color_var_t { + float r; /**< Red */ + float g; /**< Green */ + float b; /**< Blue */ + float a; /**< Alpha */ +} color_var_t; + +/** \brief Interpolate color gradient for rectangle + * + * \param x0 x coordinate of the upper left vertex of the rectangle + * \param y0 y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param col0 color for the first vertex + * \param col1 color for the second vertex + * \param col1 color for the third vertex + * + */ +void nema_interpolate_rect_colors(int x0, int y0, int w, int h, color_var_t* col0, color_var_t* col1, color_var_t* col2); + + +/** \brief Interpolate color gradient for triangle + * + * \details The upper left vertex of the triangle to be drawn + * must be in the vertex arguments as well. In addition, if + * clipping is applied for rendering a triangle with gradient, + * the upper left vertex must be within the clipping area. + * \param x0 x coordinate at the first vertex of the triangle + * \param y0 y coordinate at the first vertex of the triangle + * \param x1 x coordinate at the second vertex of the triangle + * \param y1 y coordinate at the second vertex of the triangle + * \param x2 x coordinate at the third vertex of the triangle + * \param y2 y coordinate at the third vertex of the triangle + * \param col0 color for the first vertex + * \param col1 color for the second vertex + * \param col1 color for the third vertex + * + */ +void nema_interpolate_tri_colors(float x0, float y0, float x1, float y1, float x2, float y2, color_var_t* col0, color_var_t* col1, color_var_t* col2); + +/** \brief Interpolate depth buffer values for triangle + * + * \param x0 x coordinate at the first vertex of the triangle + * \param y0 y coordinate at the first vertex of the triangle + * \param z0 z coordinate at the first vertex of the triangle + * \param x1 x coordinate at the second vertex of the triangle + * \param y1 y coordinate at the second vertex of the triangle + * \param z1 z coordinate at the second vertex of the triangle + * \param x2 x coordinate at the third vertex of the triangle + * \param y2 y coordinate at the third vertex of the triangle + * \param z2 z coordinate at the third vertex of the triangle + * + */ +void nema_interpolate_tri_depth(float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2); + +/** \brief Interpolate texture values for triangle + * + * \param x0 x coordinate at the first vertex of the triangle + * \param y0 y coordinate at the first vertex of the triangle + * \param w0 w coordinate at the first vertex of the triangle + * \param tx0 x texture coordinate at the first vertex of the triangle + * \param ty0 y texture coordinate at the first vertex of the triangle + * \param x1 x coordinate at the second vertex of the triangle + * \param y1 y coordinate at the second vertex of the triangle + * \param w1 w coordinate at the second vertex of the triangle + * \param tx1 x texture coordinate at the second vertex of the triangle + * \param ty1 y texture coordinate at the second vertex of the triangle + * \param x2 x coordinate at the third vertex of the triangle + * \param y2 y coordinate at the third vertex of the triangle + * \param w2 w coordinate at the third vertex of the triangle + * \param tx2 x texture coordinate at the third vertex of the triangle + * \param ty2 x texture coordinate at the third vertex of the triangle + * \param tex_width texture width + * \param tex_height texture height + * + */ +void nema_interpolate_tx_ty(float x0, float y0, float w0, float tx0, float ty0, + float x1, float y1, float w1, float tx1, float ty1, + float x2, float y2, float w2, float tx2, float ty2, + int tex_width, int tex_height ); +#ifdef __cplusplus +} +#endif + +#endif // _NEMA_INTERPOLATORS_H_ diff --git a/src/drivers/nema/include/nema_math.h b/src/drivers/nema/include/nema_math.h new file mode 100644 index 000000000..3bc3862a6 --- /dev/null +++ b/src/drivers/nema/include/nema_math.h @@ -0,0 +1,278 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_MATH_H__ +#define NEMA_MATH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEMA_E 2.71828182845904523536f /**< e */ +#define NEMA_LOG2E 1.44269504088896340736f /**< log2(e) */ +#define NEMA_LOG10E 0.434294481903251827651f /**< log10(e) */ +#define NEMA_LN2 0.693147180559945309417f /**< ln(2) */ +#define NEMA_LN10 2.30258509299404568402f /**< ln(10) */ +#define NEMA_PI 3.14159265358979323846f /**< pi */ +#define NEMA_PI_2 1.57079632679489661923f /**< pi/2 */ +#define NEMA_PI_4 0.785398163397448309616f /**< pi/4 */ +#define NEMA_1_PI 0.318309886183790671538f /**< 1/pi */ +#define NEMA_2_PI 0.636619772367581343076f /**< 2/pi */ +#define NEMA_2_SQRTPI 1.12837916709551257390f /**< 2/sqrt(pi) */ +#define NEMA_SQRT2 1.41421356237309504880f /**< sqrt(2) */ +#define NEMA_SQRT1_2 0.707106781186547524401f /**< 1/sqrt(2) */ + +/** \brief Fast sine approximation of a given angle + * + * \param angle_degrees Angle in degrees + * \return Sine of the given angle + * + */ +float nema_sin(float angle_degrees); + + +/** \brief Fast cosine approximation of a given angle + * + * \param angle_degrees Angle in degrees + * \return Cosine of the given angle + * + */ +float nema_cos(float angle_degrees); + +/** \brief Fast tangent approximation of a given angle + * + * \param angle_degrees Angle in degrees + * \return Tangent of the given angle + * + */ +float nema_tan(float angle_degrees); + + +/** \brief Fast sine approximation of a given angle + * + * \param angle_radians Angle in radians + * \return Sine of the given angle + * + */ +float nema_sin_r(float angle_radians); + + +/** \brief Fast cosine approximation of a given angle + * + * \param angle_radians Angle in radians + * \return Cosine of the given angle + * + */ +float nema_cos_r(float angle_radians); + +/** \brief Fast tangent approximation of a given angle + * + * \param angle_radians Angle in radians + * \return Tangent of the given angle + * + */ +float nema_tan_r(float angle_radians); + +/** \brief Fast arc tangent approximation of a y/x + * + * \param y value + * \param x value + * \return Arc tangent of the given y/x in degrees + * + */ +float nema_atan2(float y, float x); + +/** \brief Fast arc tangent approximation of a y/x + * + * \param y value + * \param x value + * \return Arc tangent of the given y/x in radians + * + */ +float nema_atan2_r(float y, float x); + +/** \brief A rough approximation of x raised to the power of y. USE WITH CAUTION! + * + * \param x base value. Must be non negative. + * \param y power value + * \return the result of raising x to the power y + * + */ +float nema_pow(float x, float y); + +/** \brief A rough approximation of the square root of x. USE WITH CAUTION! + * + * \param x X value. Must be non negative + * \param + * \return The square root of x + * + */ +float nema_sqrt(float x); + + +/** \brief A floating-point approximation of the inverse tangent of x + * + * \param x X value + * \return Inverse tangent (angle) of x in degrees + * + */ +float nema_atan(float x); + +/** \brief Find the minimum of two values + * + * \param a First value + * \param b Second value + * \return The minimum of a and b + * + */ +#define nema_min2(a,b) (((a)<(b))?( a):(b)) + +/** \brief Find the maximum of two values + * + * \param a First value + * \param b Second value + * \return The maximum of a and b + * + */ +#define nema_max2(a,b) (((a)>(b))?( a):(b)) + +/** \brief Clamp value + * + * \param val Value to clamp + * \param min Minimum value + * \param max Minimum value + * \return Clamped value + * + */ +#define nema_clamp(val, min, max) nema_min2((max), nema_max2((min), (val))) + +/** \brief Calculate the absolute value of int + * + * \param a Value + * \return The absolute value of a + * + */ +#define nema_abs(a) (((a)< 0 )?(-(a)):(a)) + +/** \brief Calculate the absolute value of float + * + * \param a Value + * \return The absolute value of a + * + */ +#define nema_absf(a) (((a)< 0.f )?(-(a)):(a)) + + +/** \brief Compare two floats + * + * \param x First float + * \param y Second float + * \return 1 if x == y, 0 if x != y + * + */ +#define nema_floats_equal(x, y) (nema_absf((x) - (y)) <= 0.00001f * nema_min2(nema_absf(x), nema_absf(y))) + +/** \brief Checks if value x is zero + * + * \param x X value + * \return 1 if x == 0, 0 if x != 0 + * + */ +#define nema_float_is_zero(x) (nema_absf(x) <= 0.00001f) + +/** \brief Convert degrees to radians + * + * \param d Angle in degrees + * \return Angle in radians + * + */ +#define nema_deg_to_rad(d) (0.0174532925199f * (d)) //rad = deg * pi / 180 + +/** \brief Convert radians to degries + * + * \param r Angle in radians + * \return Angle in degrees + * + */ +#define nema_rad_to_deg(r) (57.295779513f * (r)) //deg = rad * 180 / pi + +/** \brief Convert integer to 16.16 fixed point + * + * \param a Value to be converted + * \return 16.16 fixed point value + * + */ +#define nema_i2fx(a) ((a)*0x10000) + +/** \brief Convert float to 16.16 fixed point + * + * \param a Value to be converted + * \return 16.16 fixed point value + * + */ +// #define nema_f2fx(a) ((int)(((a)*((float)0x10000)+0.5f))) +int nema_f2fx(float f); // ((int)(((a)*((float)0x10000)+0.5f))) + +/** \brief Floor function + * + * \param a Value to be floored + * \return floored value + * + */ +#define nema_floor(f) ((int)(f) - ( (int)(f) > (f) )) + +/** \brief Ceiling function + * + * \param a Value to be ceiled + * \return ceiled value + * + */ +#define nema_ceil(f) ((int)(f) + ( (int)(f) < (f) )) + +/** \brief Truncate function + * + * \param x Value to be truncated + * \return truncated value + * + */ +#define nema_truncf(x) (x < 0.0f ? nema_ceil(x) : nema_floor(x)) + +/** \brief Float Modulo function + * + * \param x Dividend + * \param y Divisor + * \return Remainder + * + */ +#define nema_fmod(x, y) ( (x) - nema_truncf( ( (x) / (y) ) ) * (y) ) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_matrix3x3.h b/src/drivers/nema/include/nema_matrix3x3.h new file mode 100644 index 000000000..ba6d4d6b6 --- /dev/null +++ b/src/drivers/nema/include/nema_matrix3x3.h @@ -0,0 +1,230 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_MATRIX3X3_H__ +#define NEMA_MATRIX3X3_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float nema_matrix3x3_t[3][3]; + + +/** \brief Load Identity Matrix + * + * \param m Matrix to be loaded + * + */ +void nema_mat3x3_load_identity(nema_matrix3x3_t m); + + +/** \brief Copy matrix _m to matrix m + * + * \param m Destination matrix + * \param m Source matrix + * + */ +void +nema_mat3x3_copy(nema_matrix3x3_t m, nema_matrix3x3_t _m); + +/** \brief Apply translate transformation + * + * \param m Matrix to apply transformation + * \param tx X translation factor + * \param ty Y translation factor + * + */ +void nema_mat3x3_translate (nema_matrix3x3_t m, float tx, float ty); + +/** \brief Apply scale transformation + * + * \param m Matrix to apply transformation + * \param sx X scaling factor + * \param sy Y scaling factor + * + */ +void nema_mat3x3_scale (nema_matrix3x3_t m, float sx, float sy); + +/** \brief Apply shear transformation + * + * \param m Matrix to apply transformation + * \param shx X shearing factor + * \param shy Y shearing factor + * + */ +void nema_mat3x3_shear (nema_matrix3x3_t m, float shx, float shy); + +/** \brief Apply mirror transformation + * + * \param m Matrix to apply transformation + * \param mx if non-zero, mirror horizontally + * \param my if non-zero, mirror vertically + * + */ +void nema_mat3x3_mirror (nema_matrix3x3_t m, int mx, int my); + +/** \brief Apply rotation transformation + * + * \param m Matrix to apply transformation + * \param angle_degrees Angle to rotate in degrees + * + */ +void nema_mat3x3_rotate (nema_matrix3x3_t m, float angle_degrees); + +/** \brief Apply rotation transformation + * + * \param m Matrix to apply transformation + * \param cosa Cos of angle to rotate + * \param sina Sin of angle to rotate + * + */ +void +nema_mat3x3_rotate2(nema_matrix3x3_t m, float cosa, float sina); + + +/** \brief Multiply two 3x3 matrices ( m = m*_m) + * + * \param m left matrix, will be overwritten by the result + * \param _m right matrix + * + */ +void nema_mat3x3_mul(nema_matrix3x3_t m, nema_matrix3x3_t _m); + +/** \brief Multiply vector with matrix + * + * \param m Matrix to multiply with + * \param x Vector x coefficient + * \param y Vector y coefficient + * + */ +void nema_mat3x3_mul_vec(nema_matrix3x3_t m, float *x, float *y); + +/** \brief Multiply vector with affine matrix + * + * \param m Matrix to multiply with + * \param x Vector x coefficient + * \param y Vector y coefficient + * + */ +void nema_mat3x3_mul_vec_affine(nema_matrix3x3_t m, float *x, float *y); + +/** \brief Calculate adjoint + * + * \param m Matrix + * + */ +void nema_mat3x3_adj(nema_matrix3x3_t m); + + +/** \brief Divide matrix with scalar value + * + * \param m Matrix to divide + * \param s scalar value + * + */ +void nema_mat3x3_div_scalar(nema_matrix3x3_t m, float s); + +/** \brief Invert matrix + * + * \param m Matrix to invert + * + */ +int nema_mat3x3_invert(nema_matrix3x3_t m); + +/** \private */ +int nema_mat3x3_square_to_quad(float dx0, float dy0, + float dx1, float dy1, + float dx2, float dy2, + float dx3, float dy3, + nema_matrix3x3_t m); + +/** \brief Map rectangle to quadrilateral + * + * \param width Rectangle width + * \param height Rectangle height + * \param sx0 x coordinate at the first vertex of the quadrilateral + * \param sy0 y coordinate at the first vertex of the quadrilateral + * \param sx1 x coordinate at the second vertex of the quadrilateral + * \param sy1 y coordinate at the second vertex of the quadrilateral + * \param sx2 x coordinate at the third vertex of the quadrilateral + * \param sy2 y coordinate at the third vertex of the quadrilateral + * \param sx3 x coordinate at the fourth vertex of the quadrilateral + * \param sy3 y coordinate at the fourth vertex of the quadrilateral + * \param m Mapping matrix + * + */ +int nema_mat3x3_quad_to_rect(int width, int height, + float sx0, float sy0, + float sx1, float sy1, + float sx2, float sy2, + float sx3, float sy3, + nema_matrix3x3_t m); + +/** \brief Apply rotation around a pivot point + * + * \param m Matrix to apply transformation + * \param angle_degrees Angle to rotate in degrees + * \param x X coordinate of the pivot point + * \param y Y coordinate of the pivot point + * + */ +void nema_mat3x3_rotate_pivot(nema_matrix3x3_t m, float angle_degrees, + float x, float y); + +/** \brief Apply scale and then rotation around a pivot point + * + * \param m Matrix to apply transformation +* \param sx X scaling factor + * \param sy Y scaling factor + * \param angle_degrees Angle to rotate in degrees + * \param x X coordinate of the pivot point + * \param y Y coordinate of the pivot point + * + */ +void nema_mat3x3_scale_rotate_pivot(nema_matrix3x3_t m, + float sx, float sy, + float angle_degrees, float x, float y); + + +/** \brief Copy matrix _m to matrix m + * + * \param m Destination matrix + * \param m Source matrix + * + */ + +void +nema_mat3x3_copy(nema_matrix3x3_t m, nema_matrix3x3_t _m); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_matrix4x4.h b/src/drivers/nema/include/nema_matrix4x4.h new file mode 100644 index 000000000..2a03b0510 --- /dev/null +++ b/src/drivers/nema/include/nema_matrix4x4.h @@ -0,0 +1,232 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_MATRIX4X4_H__ +#define NEMA_MATRIX4X4_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float nema_matrix4x4_t[4][4]; + + +/** \brief Load a 4x4 Identity Matrix + * + * \param m Matrix to be loaded + * + */ +void nema_mat4x4_load_identity(nema_matrix4x4_t m); + +/** \brief Multiply two 4x4 matrices + * + * \param m Result Matrix + * \param m_l Left operand + * \param m_r Right operand + * + */ +void nema_mat4x4_mul(nema_matrix4x4_t m, + nema_matrix4x4_t m_l, + nema_matrix4x4_t m_r); + + +void nema_mat4x4_copy(nema_matrix4x4_t m_l, + nema_matrix4x4_t m_r); + +/** \brief Multiply a 4x1 vector with a 4x4 matrix + * + * \param m Matrix to be multiplied + * \param x Vector first element + * \param y Vector second element + * \param z Vector third element + * \param w Vector forth element + * + */ +void nema_mat4x4_mul_vec(nema_matrix4x4_t m, float *x, float *y, float *z, float *w); + +// ------------------------------------------------------------------------------------ +// Object Transformation - ModelView Matrix +// Object Coordinates to Eye Coordinates +// ------------------------------------------------------------------------------------ + +/** \brief Apply translate transformation + * + * \param m Matrix to apply transformation + * \param tx X translation factor + * \param ty Y translation factor + * \param tz Z translation factor + * + */ +void nema_mat4x4_translate(nema_matrix4x4_t m, float tx, float ty, float tz); + +/** \brief Apply scale transformation + * + * \param m Matrix to apply transformation + * \param sx X scaling factor + * \param sy Y scaling factor + * \param sz Z scaling factor + * + */ +void nema_mat4x4_scale(nema_matrix4x4_t m, float sx, float sy, float sz); + +/** \brief Apply rotate transformation around X axis + * + * \param m Matrix to apply transformation + * \param angle_degrees Angle to rotate in degrees + * + */ +void nema_mat4x4_rotate_X (nema_matrix4x4_t m, float angle_degrees); + +/** \brief Apply rotate transformation around Y axis + * + * \param m Matrix to apply transformation + * \param angle_degrees Angle to rotate in degrees + * + */ +void nema_mat4x4_rotate_Y (nema_matrix4x4_t m, float angle_degrees); + +/** \brief Apply rotate transformation around Z axis + * + * \param m Matrix to apply transformation + * \param angle_degrees Angle to rotate in degrees + * + */ +void nema_mat4x4_rotate_Z (nema_matrix4x4_t m, float angle_degrees); + +// ------------------------------------------------------------------------------------ +// Scene Transformation/Frustum - Projection Matrix +// Eye Coordinates to Clip Coordinates +// ------------------------------------------------------------------------------------ + +/** \brief Set up a perspective projection matrix + * + * \param m A 4x4 Matrix + * \param fovy_degrees Field of View in degrees + * \param aspect Aspect ratio that determines the field of view in the x direction. + * \param nearVal Distance from the viewer to the near clipping plane (always positive) + * \param farVal Distance from the viewer to the far clipping plane (always positive) + * + */ +void nema_mat4x4_load_perspective(nema_matrix4x4_t m, float fovy_degrees, float aspect, + float nearVal, float farVal); + + +/** \brief Set up a Right Hand perspective projection matrix + * + * \param m A 4x4 Matrix + * \param fovy_degrees Field of View in degrees + * \param aspect Aspect ratio that determines the field of view in the x direction. + * \param nearVal Distance from the viewer to the near clipping plane (always positive) + * \param farVal Distance from the viewer to the far clipping plane (always positive) + * + */ +void nema_mat4x4_load_perspective_rh(nema_matrix4x4_t m, float fovy_degrees, float aspect, + float nearVal, float farVal); + +/** \brief Set up an orthographic projection matrix + * + * \param m A 4x4 Matrix + * \param left Left vertical clipping plane + * \param right Right vertical clipping plane + * \param bottom bottom horizontal clipping plane + * \param top Top horizontal clipping plane + * \param nearVal Distance from the viewer to the near clipping plane (always positive) + * \param farVal Distance from the viewer to the far clipping plane (always positive) + * + */ +void nema_mat4x4_load_ortho(nema_matrix4x4_t m, + float left, float right, + float bottom, float top, + float nearVal, float farVal); + +/** \brief Set up a 2D orthographic projection matrix + * + * \param m A 4x4 Matrix + * \param left Left vertical clipping plane + * \param right Right vertical clipping plane + * \param bottom bottom horizontal clipping plane + * \param top Top horizontal clipping plane + * + */ +void nema_mat4x4_load_ortho_2d(nema_matrix4x4_t m, + float left, float right, + float bottom, float top); + +/** \brief Set up a Right Hand view matrix. + * + * \param m A 4x4 Matrix + * \param eye_x Eye position x. + * \param eye_y Eye position y. + * \param eye_z Eye position z. + * \param center_x Center x to look at + * \param center_y Center y to look at + * \param center_z Center z to look at + * \param up_x Up vector x. (Usually 0) + * \param up_y Up vector y. (Usually 1) + * \param up_z Up vector z. (Usually 0) + * + */ +void nema_mat4x4_look_at_rh(nema_matrix4x4_t m, + float eye_x, float eye_y, float eye_z, + float center_x, float center_y, float center_z, + float up_x, float up_y, float up_z); + +// ------------------------------------------------------------------------------------ +// Clip Coordinates to Window Coordinates +// ------------------------------------------------------------------------------------ + +/** \brief Convenience Function to calculate window coordinates from object coordinates + * + * \param mvp Model, View and Projection Matrix + * \param x_orig Window top left X coordinate + * \param y_orig Window top left Y coordinate + * \param width Window width + * \param height Window height + * \param nearVal Distance from the viewer to the near clipping plane (always positive) + * \param farVal Distance from the viewer to the far clipping plane (always positive) + * \param x X object coordinate + * \param y Y object coordinate + * \param z Z object coordinate + * \param w W object coordinate + * \return 1 if vertex is outside frustum (should be clipped) + * + */ +int nema_mat4x4_obj_to_win_coords(nema_matrix4x4_t mvp, + float x_orig, float y_orig, + int width, int height, + float nearVal, float farVal, + float *x, + float *y, + float *z, + float *w); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_provisional.h b/src/drivers/nema/include/nema_provisional.h new file mode 100644 index 000000000..44a56588e --- /dev/null +++ b/src/drivers/nema/include/nema_provisional.h @@ -0,0 +1,124 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_PROVISIONAL_H__ +#define NEMA_PROVISIONAL_H__ + +#include "nema_sys_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Fill a triangle strip with color (float coordinates) + * + * \param vertices pointer to vertices coordinated (first x coordinate of vertex, + * then y coordinate of vertex) + * \param num_vertices number of vertices + * \param stride Distance between two vertices + * \param rgba8888 Color to be used + * + */ +void nema_fill_triangle_strip_f(float* vertices, int num_vertices, int stride, uint32_t rgba8888); + +/** \brief Fill a traingle fan with color (float coordinates) + * + * \param vertices pointer to vertices coordinated (first x coordinate of vertex, + * then y coordinate of vertex) + * \param num_vertices number of vertices + * \param stride Distance between two vertices + * \param rgba8888 Color to be used + * + */ +void nema_fill_triangle_fan_f(float* vertices, int num_vertices, int stride, uint32_t rgba8888); + +/** \brief Draws a triangle with specific border width. Apply AA if available. + * Degenerated triangles have undefined behavior. + * + * \param x0 x coordinate at the first vertex of the triangle + * \param y0 y coordinate at the first vertex of the triangle + * \param x1 x coordinate at the second vertex of the triangle + * \param y1 y coordinate at the second vertex of the triangle + * \param x2 x coordinate at the third vertex of the triangle + * \param y2 y coordinate at the third vertex of the triangle + * \param border_width triangle's border width + * \param color color of the triangle + * + */ +void nema_draw_triangle_aa(float x0, float y0, float x1, float y1, float x2, float y2, + float border_width, uint32_t color); + + +/** \brief Draw a colored rectangle with rounded edges and specific border width. Apply AA if available. + * + * \param x x coordinate of the upper left vertex of the rectangle + * \param y y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param r corner radius + * \param border_width border width + * \param rgba8888 rgba color of the rounded rectangle + * + */ +void nema_draw_rounded_rect_aa(float x, float y, float w, float h, float r, float border_width, uint32_t rgba8888); + + +/** \brief Draw a filled colored rectangle with rounded edges and specific border width. Apply AA if available. + * + * \param x x coordinate of the upper left vertex of the rectangle + * \param y y coordinate at the upper left vertex of the rectangle + * \param w width of the rectangle + * \param h height of the rectangle + * \param r corner radius + * \param rgba8888 rgba color of the rounded rectangle + * + */ +void nema_fill_rounded_rect_aa(float x, float y, float w, float h, float r, uint32_t rgba8888); + +/** \brief Draws a quadrilateral with specific border width. Apply AA if available. + * Only Convex quadrilaterals are supported. + * + * \param x0 x coordinate at the first vertex of the quadrilateral + * \param y0 y coordinate at the first vertex of the quadrilateral + * \param x1 x coordinate at the second vertex of the quadrilateral + * \param y1 y coordinate at the second vertex of the quadrilateral + * \param x2 x coordinate at the third vertex of the quadrilateral + * \param y2 y coordinate at the third vertex of the quadrilateral + * \param x3 x coordinate at the fourth vertex of the quadrilateral + * \param y3 y coordinate at the fourth vertex of the quadrilateral + * \param border_width trianquadrilateralgle's border width + * \param color color of the quadrilateral + * + */ +void nema_draw_quad_aa(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, + float border_width, uint32_t color); +#ifdef __cplusplus +} +#endif + +#endif // NEMA_PROVISIONAL_H__ diff --git a/src/drivers/nema/include/nema_raster.h b/src/drivers/nema/include/nema_raster.h new file mode 100644 index 000000000..770fbcd32 --- /dev/null +++ b/src/drivers/nema/include/nema_raster.h @@ -0,0 +1,117 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_RASTER_H__ +#define NEMA_RASTER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \private */ +void nema_set_raster_color(uint32_t rgba8888); + +/** \private */ +void nema_raster_pixel(int x, int y); + +/** \private */ +void nema_raster_line(int x0, int y0, int x1, int y1); + +/** \private */ +void nema_raster_triangle_fx(int x0fx, int y0fx, int x1fx, int y1fx, int x2fx, int y2fx); + + +/** \private */ +void nema_raster_rect(int x, int y, int w, int h); + +/** \private */ +void nema_raster_rounded_rect(int x0, int y0, int w, int h, int r); + + +/** \private */ +void nema_raster_quad_fx(int x0fx, int y0fx, + int x1fx, int y1fx, int x2fx, int y2fx, int x3fx, int y3fx); + +/** \private */ +void nema_raster_triangle (int x0, int y0, int x1, int y1, int x2, int y2); + +/** \private */ +void nema_raster_quad (int x0,int y0,int x1,int y1,int x2,int y2,int x3,int y3); + +/** \private */ +void nema_raster_circle(float x, float y, float r); + +/** \private */ +void nema_raster_circle_aa(float x, float y, float r); + +/** \private */ +void nema_raster_stroked_circle_aa(float x, float y, float r, float w); + +/** \private */ +void nema_raster_rect_fx(int xfx, int yfx, int wfx, int hfx); + +/** \private */ +void nema_raster_rect_f(float x, float y, float w, float h); + +/** \private */ +void +nema_raster_triangle_f(float x0, float y0, float x1, float y1, float x2, float y2); + +/** \private */ +void +nema_raster_triangle_p0_f(float x0, float y0); + +/** \private */ +void +nema_raster_triangle_p1_f(float x1, float y1); + +/** \private */ +void +nema_raster_triangle_p2_f(float x2, float y2); + +/** \private */ +void +nema_raster_quad_f(float x0, float y0, float x1, float y1, + float x2, float y2, float x3, float y3); + +/** \private */ +void +nema_raster_stroked_arc_aa( float x0, float y0, float r, float w, float start_angle, float end_angle); + +/** \private */ +// aa_mask: +// RAST_AA_E0: AA on first ending +// RAST_AA_E2: AA on last ending +void +nema_raster_stroked_arc_aa_mask( float x0, float y0, float r, float w, float start_angle, float end_angle, uint32_t aa_mask); + +#ifdef __cplusplus +} +#endif + +#endif //NEMA_RASTER_H__ diff --git a/src/drivers/nema/include/nema_sys_defs.h b/src/drivers/nema/include/nema_sys_defs.h new file mode 100644 index 000000000..0e48e528a --- /dev/null +++ b/src/drivers/nema/include/nema_sys_defs.h @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * @file nema_sys_defs.h + * @author MCD Application Team + * @brief Header file of NemaGFX System Definitions for STM32 Platforms. + * This file provides definition of types being used by the NemaGFX + * library. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef NEMA_SYS_DEFS_H__ +#define NEMA_SYS_DEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include + +/* Temporarily added by ST */ +#ifdef __ICCARM__ +#define FORCE_INLINE _Pragma("inline = forced") +#else +#define FORCE_INLINE +#endif + +/* No Multi-Thread support */ +#define TLS_VAR + +#ifdef NEMA_VG_INVALIDATE_CACHE +void platform_disable_cache(void); +void platform_invalidate_cache(void); + +#define NEMA_VG_DISABLE_CACHE platform_disable_cache() +#define NEMA_VG_ENABLE_INVALIDATE_CACHE platform_invalidate_cache() +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NEMA_SYS_DEFS_H__ */ diff --git a/src/drivers/nema/include/nema_transitions.h b/src/drivers/nema/include/nema_transitions.h new file mode 100644 index 000000000..3a92646a5 --- /dev/null +++ b/src/drivers/nema/include/nema_transitions.h @@ -0,0 +1,210 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_TRANSITIONS_H__ +#define NEMA_TRANSITIONS_H__ + +#include "nema_blender.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + NEMA_TRANS_LINEAR_H, + NEMA_TRANS_CUBE_H, + NEMA_TRANS_INNERCUBE_H, + NEMA_TRANS_STACK_H, + NEMA_TRANS_LINEAR_V, + NEMA_TRANS_CUBE_V, + NEMA_TRANS_INNERCUBE_V, + NEMA_TRANS_STACK_V, + NEMA_TRANS_FADE, + NEMA_TRANS_FADE_ZOOM, + NEMA_TRANS_MAX, + NEMA_TRANS_NONE, +} nema_transition_t; + +/** \brief Transition from 'initial' texture to 'final' texture. The transition is complete when 'step' is 0 or 1 + * + * \param effect Transition effect + * \param initial Initial texture + * \param final Final texture + * \param blending_mode Blending mode + * \param step Transition step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition(nema_transition_t effect, nema_tex_t initial, nema_tex_t final, + uint32_t blending_mode, float step, int width, int height); + + +/** \brief Linear transition horizontally. When 'step' changes from zero to one, textures move from right to left, +otherwise textures move from left to right. The transition is complete when 'step' is 0 or 1. + * + * \param left Texture on the left side + * \param right Texture on the right side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * + */ +void nema_transition_linear_hor(nema_tex_t left, nema_tex_t right, + uint32_t blending_mode, float step, int width); + +/** \brief Linear transition vertically. When 'step' changes from zero to one, textures move from top to bottom, +otherwise textures move from bottom to top. The transition is complete when 'step' is 0 or 1. + * + * \param up Texture on the top side + * \param down Texture on the bottom side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param height Texture height + * + */ +void nema_transition_linear_ver(nema_tex_t up, nema_tex_t down, + uint32_t blending_mode, float step, int height); + +/** \brief Cubic (textures are mapped on the external faces of a cube) transition horizontally. When 'step' changes from zero to one, textures move from left to right, +otherwise textures move from right to left. The transition is complete when 'step' is 0 or 1. + * + * \param left Texture on the left side + * \param right Texture on the right side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_cube_hor(nema_tex_t left, nema_tex_t right, + uint32_t blending_mode, float step, int width, int height); + +/** \brief Cube (textures are mapped on the external faces of a cube) transition vertically. When 'step' changes from zero to one, textures move from top to bottom, +otherwise textures move from bottom to top. The transition is complete when 'step' is 0 or 1. + * + * \param up Texture on the top side + * \param down Texture on the bottom side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_cube_ver(nema_tex_t up, nema_tex_t down, + uint32_t blending_mode, float step, int width, int height); + +/** \brief Inner Cube (textures are mapped on the internal faces of a cube) transition horizontally. When 'step' changes from zero to one, textures move from left to right, +otherwise textures move from right to left. The transition is complete when 'step' is 0 or 1. + * + * \param left Texture on the left side + * \param right Texture on the right side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_innercube_hor(nema_tex_t left, nema_tex_t right, + uint32_t blending_mode, float step, int width, int height); + +/** \brief Inner Cube (textures are mapped on the internal faces of a cube) transition vertically. When 'step' changes from zero to one, textures move from top to bottom, +otherwise textures move from bottom to top. The transition The transition is complete when 'step' is 0 or 1. + * + * \param up Texture on the top side + * \param down Texture on the bottom side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_innercube_ver(nema_tex_t up, nema_tex_t down, + uint32_t blending_mode, float step, int width, int height); + +/** \brief Stack transition horizontally. When 'step' changes from zero to one, textures move from left to right, +otherwise textures move from right to left. The transition is complete when 'step' is 0 or 1. + * + * \param up Texture on the top side + * \param down Texture on the bottom side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_stack_hor(nema_tex_t left, nema_tex_t right, float step, + int width, int height); + +/** \brief Stack transition vertically. When 'step' moves from zero to one, textures move from top to bottom, +otherwise textures move from bottom to top. The transition is complete when 'step' is 0 or 1. + * + * \param up Texture on the top side + * \param down Texture on the bottom side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_stack_ver(nema_tex_t up, nema_tex_t down, float step, + int width, int height); + +/** \brief Fade transition. Initial texture is being faded out, while final texture is being faded in. +The transition is complete when 'step' is 0 or 1. + * + * \param left Texture on the left side + * \param right Texture on the right side + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_fade(nema_tex_t initial, nema_tex_t final, + uint32_t blending_mode, float step, int width, int height); + +/** \brief Fade-zoom transition. Initial texture is being zoomed and faded out, while final texture is being zoomed and faded in. +The transition is complete when 'step' is 0 or 1. + * + * \param initial Initial texture + * \param final Final texture + * \param blending_mode Blending mode + * \param step Current step within [0.f , 1.f] range + * \param width Texture width + * \param height Texture height + * + */ +void nema_transition_fade_zoom(nema_tex_t initial, nema_tex_t final, + uint32_t blending_mode, float step, int width, int height); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_utils.h b/src/drivers/nema/include/nema_utils.h new file mode 100644 index 000000000..03caff051 --- /dev/null +++ b/src/drivers/nema/include/nema_utils.h @@ -0,0 +1,50 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + + +#ifndef NEMA_UTILS_H_ +#define NEMA_UTILS_H_ + +#include "nema_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +float nema_get_time(void); +float nema_get_wall_time(void); +nema_buffer_t nema_load_file(const char *filename, int length, void *buffer); +int nema_save_file(const char *filename, int length, void *buffer); +unsigned int nema_rand(void); +void nema_calculate_fps(void); +void * nema_memcpy ( void * destination, const void * source, size_t num ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/include/nema_version.h b/src/drivers/nema/include/nema_version.h new file mode 100644 index 000000000..8bd7af1b1 --- /dev/null +++ b/src/drivers/nema/include/nema_version.h @@ -0,0 +1,55 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief Contains version numbers for NemaGFX API and the currently supported font version. + * + */ + +#ifndef NEMA_VERSION_H__ +#define NEMA_VERSION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEMA_MAJOR_VERSION 0x01U /**< NemaGFX API version, major number */ +#define NEMA_MINOR_VERSION 0x04U /**< NemaGFX API version, minor number */ +#define NEMA_REVISION_VERSION 0x0BU /**< NemaGFX API version, revision number */ +#define NEMA_IMP_VERSION 0x00240600U /**< NemaGFX API version, implementation in format 0x00YYMM00 (Y: year, M: month) */ + +#define NEMA_API_VERSION ((NEMA_MAJOR_VERSION << 16) + (NEMA_MINOR_VERSION << 8) + (NEMA_REVISION_VERSION)) /**< NemaGFX API version in format 0x00MMmmrr (M:major, m:minor, r:revision if any) */ + +#define NEMA_FONT_VERSION 0x01U /**< Current font version */ + + +#ifdef __cplusplus +} +#endif + +#endif //NEMA_VERSION_H__ diff --git a/src/drivers/nema/include/nema_vg.h b/src/drivers/nema/include/nema_vg.h new file mode 100644 index 000000000..af5f95522 --- /dev/null +++ b/src/drivers/nema/include/nema_vg.h @@ -0,0 +1,254 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief Core NemaVG API drawing and initialization functions. + * + */ + +#ifndef __NEMA_VG_H__ +#define __NEMA_VG_H__ + +#include "nema_core.h" +#include "nema_sys_defs.h" +#include "nema_vg_path.h" +#include "nema_vg_paint.h" +#include "nema_vg_context.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------------------------------------------------------------------- +// SETUP +// ------------------------------------------------------------------------------- + +/** \brief Initializes NemaVG library and allocates the stencil buffer to the default memory pool (NEMA_MEM_POOL_FB) + * Call either this or nema_vg_init_stencil_pool to allocate the stencil buffer to a different memory pool + * or nema_vg_init_stencil_prealloc to provide the stencil buffer + * \param width Framebuffer width + * \param height Framebuffer height + */ +void nema_vg_init(int width, int height); + +/** \brief Initializes NemaVG library and allocate the stencil buffer in a specific memory pool. + * Call either this or nema_vg_init to allocate the stencil buffer to the default memory pool (NEMA_MEM_POOL_FB) + * or nema_vg_init_stencil_prealloc to provide the stencil buffer + * \param width Stencil buffer width - Must be the first multiple of 4 of the framebuffer width + * \param height Stencil buffer height - Must be the first multiple of 4 of the framebuffer height + * \param pool Memory pool for allocating the stencil buffer (memory pools are platform specific and defined in nema_sys_defs.h file) + */ +void nema_vg_init_stencil_pool(int width, int height, int pool); + +/** \brief Initializes NemaVG library without allocating the stencil buffer which is provided by the user. + * Call either this or nema_vg_init to allocate the stencil buffer to the default memory pool (NEMA_MEM_POOL_FB) + * or nema_vg_init_stencil_pool to allocate the stencil buffer to a different memory pool + * \param width Stencil buffer width - Must be the first multiple of 4 of the framebuffer width + * \param height Stencil buffer height - Must be the first multiple of 4 of the framebuffer height + * \param stencil_bo stencil buffer + */ +void nema_vg_init_stencil_prealloc(int width, int height, nema_buffer_t stencil_bo); + + +/** \brief Reinitialize NemaVG library after a gpu powerofff + * + */ +void nema_vg_reinit(void); + +/** \brief Deinitialize NemaVG library. Free memory from implicitly allocated objects (stencil buffer + * if created inside the library, lut buffer and tsvgs' path, paint and gradient buffers) + * + * + */ +void nema_vg_deinit(void); + +/** \brief Initialize NemaVG library for a new thread. + * Must be called for every new thread that is used. + * + * + */ +void nema_vg_thread_init(void); + + +// ------------------------------------------------------------------------------- +// PATH DRAW +// ------------------------------------------------------------------------------- + +/** \brief Draw a path using a specified paint object + * + * \param path Pointer (handle) to the path that will be drawn + * \param paint Pointer (handle) to the paint object that wil be used for drawing + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_path(NEMA_VG_PATH_HANDLE path, NEMA_VG_PAINT_HANDLE paint); + +/** \brief Draw a line shape + * + * \param x1 Upper left x coordinate + * \param y1 Upper left y coordinate + * \param x2 The width + * \param y2 The height + * \param m 3x3 affine transformation matrix + * \param paint The paint to draw + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_line(float x1, float y1, float x2, float y2, + nema_matrix3x3_t m, + NEMA_VG_PAINT_HANDLE paint); + +/** \brief Draw a rectangle shape + * + * \param x Upper left x coordinate + * \param y Upper left y coordinate + * \param width The width + * \param height The height + * \param m 3x3 affine transformation matrix + * \param paint The paint to draw + + * \return Error code + * + */ +uint32_t nema_vg_draw_rect(float x, float y, float width, float height, + nema_matrix3x3_t m, + NEMA_VG_PAINT_HANDLE paint); + +/** \brief Draw a rounded rectangle shape + * + * \param x Upper left x coordinate + * \param y Upper left y coordinate + * \param width The width + * \param height The height + * \param rx Horizontal cornel radius + * \param ry Vertical cornel radius + * \param m 3x3 affine transformation matrix + * \param paint The paint to draw + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_rounded_rect(float x, float y, float width, float height, + float rx, float ry, + nema_matrix3x3_t m, + NEMA_VG_PAINT_HANDLE paint); + +/** \brief Draw a ellipse shape + * + * \param cx The x position of the ellipse + * \param cy The y position of the ellipse + * \param rx Radius on the x axis + * \param ry Radius on the y axis + * \param m 3x3 affine transformation matrix + * \param paint The paint to draw + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_ellipse(float cx, float cy, float rx, float ry, + nema_matrix3x3_t m, + NEMA_VG_PAINT_HANDLE paint); + +/** \brief Draw a circle shape + * + * \param cx The x center of the circle + * \param cy The y center of the circle + * \param r Radius of the circle + * \param m 3x3 affine transformation matrix + * \param paint The paint to draw + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_circle(float cx, float cy, float r, + nema_matrix3x3_t m, + NEMA_VG_PAINT_HANDLE paint); + + +/** \brief Draw a filled ring with rounded caps shape. In case of a conical gradient paint type, + * the conical gradient center should be at the center of the ring(cx, cy). In other case, where the two centers do not match, + * the ring should be drawn with NEMA_VG_QUALITY_MAXIMUM. The ring width can be set with the paint's stroke_width. + * + * \param cx The center x coordinate of the ring + * \param cy The center y coordinate of the ring + * \param ring_radius The radius of the ring + * \param angle_start The angle in degrees of the ring + * \param angle_end The angle in degrees that ends this ring + * \param paint The paint to draw + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_ring(float cx, float cy, float ring_radius, float angle_start, float angle_end, + NEMA_VG_PAINT_HANDLE paint); + +/** \private + * \brief Draw a filled ring with flat ending or rounded ending caps. In case of a conical gradient paint type, + * the conical gradient center should be at the center of the ring(cx, cy). In other case, where the two centers do not match, + * the ring should be drawn with NEMA_VG_QUALITY_MAXIMUM. The ring width can be set with the paint's stroke_width. + * + * \param cx The center x coordinate of the ring + * \param cy The center y coordinate of the ring + * \param ring_radius The radius of the ring + * \param angle_start The angle in degrees of the ring + * \param angle_end The angle in degrees that ends this ring + * \param paint The paint to draw + * \param has_caps 1 For caps 0 for flat ending + + * \return Error code. See NEMA_VG_ERR_* defines in "nema_vg_context.h" header file for the error codes. + * + */ +uint32_t nema_vg_draw_ring_generic(float cx, float cy, float ring_radius, float angle_start, float angle_end, + NEMA_VG_PAINT_HANDLE paint, uint8_t has_caps); + + +/** \brief Returns the minimum and maximum values for the coordinates that + * can be handled by the underlying hardware + * + * \param min_coord Minimum coordinate (x or y) value (pointer) + * \param max_coord Maximum coordinate (x or y) value (pointer) + * + */ +void nema_vg_get_coord_limits(float *min_coord, float *max_coord); + + +/** \brief Disables tsvg features from rendering. Should be set before + * nema_vg_draw_tsvg() + * + * \param feature feature to be disabled + * + */ +void nema_vg_tsvg_disable_feature(uint32_t feature); + +#ifdef __cplusplus +} +#endif + +#endif //__NEMA_VG_H__ diff --git a/src/drivers/nema/include/nema_vg_context.h b/src/drivers/nema/include/nema_vg_context.h new file mode 100644 index 000000000..5cc237610 --- /dev/null +++ b/src/drivers/nema/include/nema_vg_context.h @@ -0,0 +1,233 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief NemaVG Context interface. + * + * Contains NemaVG error codes, fill rules, rendering quality defines and functions for updating various rendering parameters. + * The functions defined here can be used to access the context parameters. The Context is an internal (opaque) struct of NemaVG. + */ + +#ifndef __NEMA_VG_CONTEXT_H__ +#define __NEMA_VG_CONTEXT_H__ + +#include "nema_graphics.h" +#include "nema_matrix3x3.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef NEMA_VG_HANDLE +#define NEMA_VG_HANDLE void* /**< NemaVG handle object (void pointer)*/ +#endif + +#define NEMA_VG_PATH_HANDLE NEMA_VG_HANDLE /**< NemaVG path handle (pointer to path object)*/ +#define NEMA_VG_PAINT_HANDLE NEMA_VG_HANDLE /**< NemaVG paint handle (pointer to paint object)*/ +#define NEMA_VG_GRAD_HANDLE NEMA_VG_HANDLE /**< NemaVG gradient handle (pointer to gradient object)*/ + +typedef float nema_vg_float_t; /**< Floating point data type (default is 'float') */ + +#define NEMA_VG_ERR_NO_ERROR (0x00000000U) /**< No Error */ +#define NEMA_VG_ERR_BAD_HANDLE (0x00000001U) /**< Bad handle */ +#define NEMA_VG_ERR_BAD_BUFFER (0x00000002U) /**< Bad buffer */ +#define NEMA_VG_ERR_INVALID_FILL_RULE (0x00000004U) /**< Invalid fill rule*/ +#define NEMA_VG_ERR_INVALID_PAINT_TYPE (0x00000008U) /**< Invalid paint type*/ +#define NEMA_VG_ERR_INVALID_VERTEX_DATA (0x00000010U) /**< Invalid vertex data*/ +#define NEMA_VG_ERR_NO_RADIAL_ENABLED (0x00000020U) /**< Radial not present in HW*/ +#define NEMA_VG_ERR_NO_BOUND_CL (0x00000040U) /**< No bound CL*/ +#define NEMA_VG_ERR_INVALID_ARGUMENTS (0x00000080U) /**< Invalid arguments*/ +#define NEMA_VG_ERR_INVALID_ARC_DATA (0x00000100U) /**< reserved */ +#define NEMA_VG_ERR_CL_FULL (0x00000200U) /**< reserved */ +#define NEMA_VG_ERR_DRAW_OUT_OF_BOUNDS (0x00000400U) /**< Path is out of the drawing area */ +#define NEMA_VG_ERR_INVALID_MASKING_OBJ (0x00000800U) /**< Masking object was not set */ +#define NEMA_VG_ERR_INVALID_MASKING_FORMAT (0x00001000U) /**< Invalid Masking object Format */ +#define NEMA_VG_ERR_INVALID_LUT_IDX_FORMAT (0x00002000U) /**< Invalid LUT indices object Format */ +#define NEMA_VG_ERR_COORDS_OUT_OF_RANGE (0x00004000U) /**< Path coordinates out of supported range */ +#define NEMA_VG_ERR_EMPTY_TSVG (0x00008000U) /**< Tsvg has no geometries */ +#define NEMA_VG_ERR_NO_BOUND_FONT (0x00010000U) /**< There is no bound font */ +#define NEMA_VG_ERR_UNSUPPORTED_FONT (0x00020000U) /**< The font is not supported (eg. older version) by NemaVG API */ +#define NEMA_VG_ERR_NON_INVERTIBLE_MATRIX (0x00040000U) /**< A matrix that needs to be inverted, is not invertible */ +#define NEMA_VG_ERR_INVALID_GRAD_STOPS (0x00080000U) /**< Gradient stops exceed maximum available stops */ +#define NEMA_VG_ERR_NO_INIT (0x00100000U) /**< VG uninitialized */ +#define NEMA_VG_ERR_INVALID_STROKE_WIDTH (0x00200000U) /**< Invalid stroke width */ +#define NEMA_VG_ERR_INVALID_OPACITY (0x00400000U) /**< Invalid opacity */ +#define NEMA_VG_ERR_INVALID_CAP_STYLE (0x00800000U) /**< Invalid cap style */ +#define NEMA_VG_ERR_INVALID_JOIN_STYLE (0x01000000U) /**< Invalid join style */ +#define NEMA_VG_ERR_INVALID_STENCIL_SIZE (0x02000000U) /**< Invalid stencil buffer size */ + +#define NEMA_VG_FILL_DRAW (0x00U) /**< DEPRECATED Stroke fill rule */ +#define NEMA_VG_STROKE (0x00U) /**< Stroke fill rule */ +#define NEMA_VG_FILL_EVEN_ODD (0x01U) /**< Evenodd fill rule */ +#define NEMA_VG_FILL_NON_ZERO (0x02U) /**< Non zero fill rule */ + +#define NEMA_VG_QUALITY_BETTER (0x00U) /**< Better rendering quality (default option, balances rendering quality and performance)*/ +#define NEMA_VG_QUALITY_FASTER (0x01U) /**< Faster rendering quality (favors performance over rendering quality)*/ +#define NEMA_VG_QUALITY_MAXIMUM (0x02U) /**< Maximum rendering quality (favors rendering quality over performance)*/ +#define NEMA_VG_QUALITY_NON_AA (0x10U) /**< Rendering quality without AA*/ + +#define NEMA_VG_CAP_BUTT (0x00U) /**< Butt cap*/ +#define NEMA_VG_CAP_ROUND (0x01U) /**< Round cap*/ +#define NEMA_VG_CAP_SQUARE (0x02U) /**< Square cap*/ +#define NEMA_VG_CAP_MAX (0x03U) /**< Max value for cap*/ + +#define NEMA_VG_JOIN_BEVEL (0x00U) /**< Bevel join*/ +#define NEMA_VG_JOIN_MITER (0x01U) /**< Mitter join*/ +#define NEMA_VG_JOIN_ROUND (0x02U) /**< Round join*/ +#define NEMA_VG_JOIN_MAX (0x03U) /**< Max for join*/ + +#define NEMA_VG_TSVG_DISABLE_NONE (0x00000000U) /**< Disable none*/ +#define NEMA_VG_TSVG_DISABLE_CAPS (0x00000001U) /**< Disable caps*/ +#define NEMA_VG_TSVG_DISABLE_JOINS (0x00000002U) /**< Disable joins*/ + +/** \brief Set the global transformation matrix. Global matrix will be applied in all NemaVG rendering operations that will follow. + * + * \param m transformation matrix + * + * \return Error code + */ +uint32_t nema_vg_set_global_matrix(nema_matrix3x3_t m); + + +/** \brief Disable the global transformation matrix. + * + */ +void nema_vg_reset_global_matrix(void); + +/** \brief Set the fill rule that will be applied when rendering a path. + * + * \param fill_rule fill rule (NEMA_VG_STROKE, NEMA_VG_FILL_EVEN_ODD, NEMA_VG_FILL_NON_ZERO) + * + */ +void nema_vg_set_fill_rule(uint8_t fill_rule); + +/** \brief Set the stroke width that will be applied when stroking a path. + * + * \param width Stroke width to be set + * + */ +void nema_vg_stroke_set_width(float width); + + /** \brief Set stroke cap style + * + * \param cap_style Cap style (NEMA_VG_CAP_BUTT | NEMA_VG_CAP_SQUARE | NEMA_VG_CAP_ROUND) + * + */ +void nema_vg_stroke_set_cap_style(uint8_t start_cap_style, uint8_t end_cap_style); + + /** \brief Set stroke join style + * + * \param join_style Join style (NEMA_VG_JOIN_BEVEL | NEMA_VG_JOIN_MITER | NEMA_VG_JOIN_ROUND) + * + */ +void nema_vg_stroke_set_join_style(uint8_t join_style); + + /** \brief Set stroke miter limit + * If miter join is chosen and miter length is bigger than the product + * of miter limit and stroke width a bevel join will be added instead + * + * \param miter_limit miter join limit to be set + * + */ +void nema_vg_stroke_set_miter_limit(float miter_limit); + +/** \brief Enable/Disable Masking. + * + * \param masking 1 to enable, 0 to disable + * + */ +void nema_vg_masking(uint8_t masking); + +/** \brief Set the mask object (texture) + * + * \param mask_obj Texture to be used as mask. Its format must be NEMA_A1, NEMA_A2, NEMA_A4 or Nema_A8, otherwise it will return an error. + * \return Error code. If no error occurs, NEMA_VG_ERR_NO_ERROR otherwise NEMA_VG_ERR_INVALID_MASKING_FORMAT. + * + */ +uint32_t nema_vg_set_mask(nema_img_obj_t *mask_obj); + +/** \brief Translate the mask object (texture) with respect to origin point (0, 0). Sets the position of the mask object. + * + * \param x Horizontal position to place the mask object + * \param y Horizontal position to place the mask object + * + */ +void nema_vg_set_mask_translation(float x, float y); + +/** \brief Set the rendering quality + * + * \param quality level (NEMA_VG_QUALITY_BETTER, NEMA_VG_QUALITY_FASTER, NEMA_VG_QUALITY_MAXIMUM, NEMA_VG_QUALITY_NON_AA) + * + */ +void nema_vg_set_quality(uint8_t quality); + +/** \brief Set the blending mode for VG operations (see nema_blender.h documentation in NemaGFX API Manual) + * Additional Blending Operations: only NEMA_BLOP_SRC_PREMULT is supported + * + * \param blend Blending mode + * \see nema_blending_mode() + * + */ +void nema_vg_set_blend(uint32_t blend); + +/** \brief Get the current error code. Clears the error afterwards. + * + * \return Error code. See NEMA_VG_ERR_* defines for all the possible error codes. + */ +uint32_t nema_vg_get_error(void); + +/** \brief Enable/disable large coordinates handling when rendering a TSVG, a path or a predefined shape + * + * \param enable 0 to disable, 1 to enable + * \param allow_internal_alloc 0 to not allow internal allocation, 1 to allow + * + */ +void nema_vg_handle_large_coords(uint8_t enable, uint8_t allow_internal_alloc); + +/** \brief Bind segment and data buffers to be used for handling large coordinates + * + * \param segs Pointer to segment buffer for large coordinates + * \param segs_size_bytes Segment buffer size in bytes + * \param data Pointer to data buffer for large coordinates + * \param data_size_bytes Data buffer size in bytes + * + */ +uint32_t nema_vg_bind_clip_coords_buf(void *segs, uint32_t segs_size_bytes, void *data, uint32_t data_size_bytes); + +/** \brief Unbind segment and data buffers to be used for handling large coordinates + * + * + */ +void nema_vg_unbind_clip_coords_buf(void); + +#ifdef __cplusplus +} +#endif + +#endif //__NEMA_VG_CONTEXT_H__ diff --git a/src/drivers/nema/include/nema_vg_font.h b/src/drivers/nema/include/nema_vg_font.h new file mode 100644 index 000000000..01e01af50 --- /dev/null +++ b/src/drivers/nema/include/nema_vg_font.h @@ -0,0 +1,210 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief Vector font rendering + * + * This file includes the necessary structs and functions that are used for rendering text (strings and single characters), + * using vector fonts. The accompanying vector font converter utility, converts truetype fonts (ttf files) to instances + * of the structs defined here. A use case of this module is included in the respective examples (examples/NemaVG/render_vg_font). + */ + +#ifndef NEMA_VG_FONT_H_ +#define NEMA_VG_FONT_H_ + +#include "nema_matrix3x3.h" +#include "nema_vg.h" +#include "nema_vg_context.h" +#include "nema_font.h" //vector to raster conversion + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEMA_VG_ALIGNX_LEFT (0x00U) /**< Align horizontally to the left */ +#define NEMA_VG_ALIGNX_RIGHT (0x01U) /**< Align horizontally to the right */ +#define NEMA_VG_ALIGNX_CENTER (0x02U) /**< Align horizontally centered */ +#define NEMA_VG_ALIGNX_JUSTIFY (0x03U) /**< Justify horizontally */ +#define NEMA_VG_ALIGNX_MASK (0x03U) /**< Horizontal alignment mask */ +#define NEMA_VG_ALIGNY_TOP (0x00U) /**< Align vertically to the top */ +#define NEMA_VG_ALIGNY_BOTTOM (0x04U) /**< Align vertically to the bottom */ +#define NEMA_VG_ALIGNY_CENTER (0x08U) /**< Align vertically centered */ +#define NEMA_VG_ALIGNY_JUSTIFY (0x0cU) /**< Justify vertically */ +#define NEMA_VG_ALIGNY_MASK (0x0cU) /**< Vertical alignment mask */ +#define NEMA_VG_TEXT_WRAP (0x10U) /**< Use text wrapping */ + +#define NEMA_VG_CHAR_LTR (0x00U) /**< Character follows left to right orientation */ +#define NEMA_VG_CHAR_RTL (0x01U) /**< Character follows right to left orientation */ +#define NEMA_VG_CHAR_TTB (0x00U) /**< Character follows top to bottom orientation */ +#define NEMA_VG_CHAR_BTT (0x02U) /**< Character follows bottom to top orientation */ + + +/** NemaVG Kerning pair information data struct */ +typedef struct { + const uint32_t left; /**< Neighbor character to the left of the current one (Unicode value) */ + const float x_offset; /**< Kerning offset value (horizontally) */ +} nema_vg_kern_pair_t; + +/** NemaVG data struct of a glyph in vector format*/ +typedef struct { + const uint32_t data_offset; /**< Offset value for the data of the glyph in the respective data array */ + const size_t data_length; /**< Length of the data in the respective data array */ + const uint32_t segment_offset; /**< Offset value for the segments of the glyph in the respective segment array */ + const size_t segment_length; /**< Length of the segments in the respective segment array */ + const float xAdvance; /**< Advance width*/ + const uint32_t kern_offset; /**< Kerning offset of the glyph in the respective kerning array */ + const uint8_t kern_length; /**< Length of the kerning information of the glyph */ + const int16_t bbox_xmin; /**< Minimum x of the glyph's bounding box */ + const int16_t bbox_ymin; /**< Minimum y of the glyph's bounding box */ + const int16_t bbox_xmax; /**< Maximum x of the glyph's bounding box */ + const int16_t bbox_ymax; /**< Maximum y of the glyph's bounding box */ +} nema_vg_glyph_t; + +/** NemaVG vector font range data struct */ +typedef struct { + const uint32_t first; /**< Unicode value of the first value of the range */ + const uint32_t last; /**< Unicode value of the last value of the range */ + const nema_vg_glyph_t *glyphs; /**< Pointer to the array of glyphs */ +} nema_vg_font_range_t; + +/** NemaVG vector font data struct*/ +typedef struct { + const uint32_t version; /**< Font version */ + const nema_vg_font_range_t *ranges; /**< Pointer to the array of ranges */ + const nema_vg_float_t *data; /**< Pointer to the data of the vector font */ + const size_t data_length; /**< Length of the vector font data*/ + const uint8_t *segment; /**< Pointer to the segments of the vector font */ + const size_t segment_length; /**< Length of the vector font segments */ + const float size; /**< Default font size (height) */ + const float xAdvance; /**< Default advance width. If the space character is included in the ranges, then its advance width is set */ + const float ascender; /**< Vertical distance from the baseline to the highest point of the font */ + const float descender; /**< Vertical distance from the baseline to the lowest point of the font */ + const nema_vg_kern_pair_t *kern_pairs; /**< Pointer to the array of the font's kerning pairs */ + uint32_t flags; /**< Bit field, reserved for future use */ +} nema_vg_font_t; + +/** \brief Bind the font to use in future nema_vg_print() calls. Sets error code if font is not supported. + * + * \param font Pointer to the vector font + * + */ +void nema_vg_bind_font(nema_vg_font_t *font); + +/** \brief Sets the size of the bound font. Future nema_vg_print() and nema_vg_print_char() calls will print using the last set size. + * + * \param font Pointer to the vector font + * + */ +void nema_vg_set_font_size(float size); + + +/** \brief Print pre-formatted text + * + * \param paint Pointer to the current paint object (contains the text color) + * \param str Pointer to string + * \param x X coordinate of text-area's top-left corner + * \param y Y coordinate of text-area's top-left corner + * \param w Max allowed width + * \param h Max allowed height + * \param align Alignment and wrapping mode + * \param m Transformation matrix + * + */ +void nema_vg_print(NEMA_VG_PAINT_HANDLE paint, const char *str, float x, float y, float w, float h, uint32_t align, nema_matrix3x3_t m); + + +/** \brief Get the bounding box's width and height of a vector string. Prior to calling this function, "nema_vg_set_font_size" must be called first. + * + * \param str Pointer to string + * \param w Pointer to variable where width should be written + * \param h Pointer to variable where height should be written + * \param max_w Max allowed width + * \param size font size + * \param wrap enable text wraping + * \return Number of carriage returns + * + */ +int nema_vg_string_get_bbox(const char *str, float *w, float *h, float max_w, uint32_t wrap); + + +/** \brief Get the text ascender value in point units. Font size must be set pror to calling this function. + * + * \return Ascender pt + * + */ +int nema_vg_get_ascender_pt(void); + +/** \brief Print a single character + * + * \details The position of the character is determined by the 'orientation' argument. + * x and y arguments define a point on the baseline. If the orientation is left to right (LTR), + * the character will be placed to the right of the (x, y) point. Right to left (RTL) will place + * the character to the left of the (x, y) point. Top to bottom (TTB) will have the same effect as + * RTL and bottom to top (BTT) will place the character higher than the (x, y) point by an offset + * equal to the font height. + * + * \param paint Pointer to the current paint object (contains the text color) + * \param ch Character to be printed + * \param x X coordinate of character's top-left or top-right corner (controlled by the 'orientation' parameter) + * \param y Y coordinate of character's top-left or bottom-left corner (controlled by the 'orientation' parameter) + * \param m Transformation matrix + * \param orientation Character orientation (see NEMA_VG_CHAR_* defines) + * \return Character width in pixels + * + */ +float nema_vg_print_char(NEMA_VG_PAINT_HANDLE paint, char ch, float x, float y, nema_matrix3x3_t m, uint32_t orientation); + +/** \brief Generates a raster font from a vector font + * + * \details Creates an 8-bpp raster version of the bound vector font. Performs dynamic memory allocation in + * the graphics memory (for the font bitmaps) and in the heap (for the data structs accessed by the CPU). + * When the font is no longer needed, function "nema_vg_destroy_raster_font()" can be used to free the allocated + * memory. The font generation may fail when there is not enough memory to generate the font or when the font + * size is greater than the height of the framebuffer. + * + * \param size The size of the font that will be generated + * \param pool Memory pool to store the font bitmaps + * \return Pointer to the data struct of generated raster font. If the font was not generated (due to insufficient memory) it returns NULL. + * + */ +nema_font_t* nema_vg_generate_raster_font(int size, int pool); + +/** \brief Frees the memory that was allocated for a font data struct + * + * \details This function frees memory that was allocated at runtime. Input must be + * a font data struct that was generated by the "nema_vg_generate_raster_font" function. + * + * \param font Pointer to the raster font data struct that will be erased from the memory + * + */ +void nema_vg_destroy_raster_font(nema_font_t *font); + +#ifdef __cplusplus +} +#endif +#endif // NEMA_VG_FONT_H_ diff --git a/src/drivers/nema/include/nema_vg_paint.h b/src/drivers/nema/include/nema_vg_paint.h new file mode 100644 index 000000000..b6677ebf9 --- /dev/null +++ b/src/drivers/nema/include/nema_vg_paint.h @@ -0,0 +1,241 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief Paint operation related fuctions. Paint is an internal (opaque) struct of NemaVG. + * The functions defined here can be used access its parameters. + * + */ + +#ifndef __NEMA_VG_PAINT_H__ +#define __NEMA_VG_PAINT_H__ + +#include "nema_interpolators.h" +#include "nema_matrix3x3.h" +#include "nema_vg_context.h" +#include "nema_graphics.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEMA_VG_PAINT_COLOR (0x00U) /**< Fill with color */ +#define NEMA_VG_PAINT_FILL (0x00U) /**< Deprecated - Fill with color (same as NEMA_VG_PAINT_COLOR) */ +#define NEMA_VG_PAINT_GRAD_LINEAR (0x01U) /**< Fill with linear gradient */ +#define NEMA_VG_PAINT_TEXTURE (0x02U) /**< Fill with texture */ +#define NEMA_VG_PAINT_GRAD_RADIAL (0x03U) /**< Fill with radial gradient */ +#define NEMA_VG_PAINT_GRAD_CONICAL (0x04U) /**< Fill with conical gradient */ + +#define NEMA_VG_PAINT_MAX_GRAD_STOPS (32) /**< Maximum gradient stops*/ + +/** \brief Create a paint object. + * + * \return Handle to the created paint object + * + */ +NEMA_VG_PAINT_HANDLE nema_vg_paint_create(); + +/** \brief Destroy a paint object. + * + * \param paint Handle to paint object that should be destroyed + * + */ +void nema_vg_paint_destroy(NEMA_VG_PAINT_HANDLE paint); + +/** \brief Clear the parameters of a paint object. + * + * \param paint Pointer (handle) to paint object + * + */ +void nema_vg_paint_clear(NEMA_VG_PAINT_HANDLE paint); + +/** \brief Set the paint type + * + * \param paint Pointer (handle) to paint + * \param type Paint type (NEMA_VG_PAINT_COLOR, NEMA_VG_PAINT_GRAD_LINEAR, NEMA_VG_PAINT_TEXTURE, NEMA_VG_PAINT_GRAD_RADIAL, NEMA_VG_PAINT_GRAD_CONICAL) + * + */ +void nema_vg_paint_set_type(NEMA_VG_PAINT_HANDLE paint, uint8_t type); + + +/** \brief Lock paint transformation to path. If locked, path and paint + * transformation will be in sync. + * + * \param paint Pointer to paint object + * \param locked 1 if locked (default), 0 if not locked + * + */ +void nema_vg_paint_lock_tran_to_path(NEMA_VG_PAINT_HANDLE paint, int locked); + +/** \brief Set linear gradient to a paint object + * + * \param paint Pointer to paint object + * \param grad Pointer to gradient object + * \param x0 Linear gradient start point x coordinate + * \param y0 Linear gradient start point y coordinate + * \param x1 Linear gradient end point x coordinate + * \param y1 Linear gradient end point y coordinate + * \param sampling_mode Sampling mode. NEMA_TEX_BORDER defaults to NEMA_TEX_CLAMP + * + */ +void nema_vg_paint_set_grad_linear(NEMA_VG_PAINT_HANDLE paint, + NEMA_VG_GRAD_HANDLE grad, + float x0, float y0, + float x1, float y1, + nema_tex_mode_t sampling_mode); + + /** \brief Set the paint color + * + * \param paint Pointer (handle) to paint object + * \param rgba Color to be set, in rgba (hex 0xAABBGGRR) format + * + */ +void nema_vg_paint_set_paint_color(NEMA_VG_PAINT_HANDLE paint, uint32_t rgba); + + /** \brief Set the paint opacity + * + * \param paint Pointer (pointer) to paint object + * \param opacity Opacity to be set, 1 is fully opaque and 0 is fully transparent + * + */ +void nema_vg_paint_set_opacity(NEMA_VG_PAINT_HANDLE paint, float opacity); + + /** \brief Set stroke width - DEPRECATED USE nema_vg_stroke_set_width + * + * \param paint Pointer (handle) to paint object + * \param stroke_width Stroke width to be set + * + */ +void nema_vg_paint_set_stroke_width(NEMA_VG_PAINT_HANDLE paint, float stroke_width); + + /** \brief Set transformation matrix for texture + * + * \param paint Pointer (handle) to paint object + * \param m 3x3 transformation matrix + * + */ +void nema_vg_paint_set_tex_matrix(NEMA_VG_PAINT_HANDLE paint, nema_matrix3x3_t m); + + /** \brief Set texture to paint object + * + * \param paint Pointer (handle) to paint + * \param text Pointer to texture image object + * + */ +void nema_vg_paint_set_tex(NEMA_VG_PAINT_HANDLE paint, nema_img_obj_t* tex); + + /** \brief Set Lut-based (look-up-table) texture to paint object. See Nema Pixpresso User Manual regarding Lut formats + * + * \param paint Pointer (handle) to paint object + * \param lut_palette Pointer to the Palette of the Lut image object + * \param lut_indices Pointer to the indices of the Lut image object + * + */ +void nema_vg_paint_set_lut_tex(NEMA_VG_PAINT_HANDLE paint, nema_img_obj_t* lut_palette, nema_img_obj_t* lut_indices); + +/** \brief Set Conical gradient to paint object + * + * \param paint Pointer (handle) to paint + * \param grad Pointer (handle) to gradient + * \param cx Conical gradient center point x coordinate + * \param cy Conical gradient center point y coordinate + * \param sampling_mode Sampling mode + * + */ +void nema_vg_paint_set_grad_conical(NEMA_VG_PAINT_HANDLE paint, + NEMA_VG_GRAD_HANDLE grad, + float cx, float cy, + nema_tex_mode_t sampling_mode); + +/** \brief Set radial gradient to paint object + * + * \param paint Pointer (handle) to paint + * \param grad Pointer (handle) to gradient + * \param x0 Radial gradient center point x coordinate + * \param y0 Radial gradient center point y coordinate + * \param r Radial gradient radius + * \param sampling_mode Sampling mode + * + */ +void +nema_vg_paint_set_grad_radial(NEMA_VG_PAINT_HANDLE paint, + NEMA_VG_GRAD_HANDLE grad, + float x0, float y0, + float r, + nema_tex_mode_t sampling_mode); + + +/** \brief Set radial gradient to paint object, with different horizontal and vertical radius + * + * \param paint Pointer (handle) to paint + * \param grad Pointer (handle) to gradient + * \param x0 Radial gradient center point x coordinate + * \param y0 Radial gradient center point y coordinate + * \param rx Radial gradient radius on x axis + * \param ry Radial gradient radius on y axis + * \param sampling_mode Sampling mode + * + */ +void +nema_vg_paint_set_grad_radial2(NEMA_VG_PAINT_HANDLE paint, + NEMA_VG_GRAD_HANDLE grad, + float x0, float y0, + float rx, float ry, + nema_tex_mode_t sampling_mode); + +/** \brief Create gradient object + * + * \return Handle (pointer) to the created gradient object + */ +NEMA_VG_GRAD_HANDLE +nema_vg_grad_create(void); + +/** \brief Destroy gradient object + * + * \param grad Pointer to the gradient object + * + */ +void +nema_vg_grad_destroy(NEMA_VG_GRAD_HANDLE grad); + +/** \brief Set gradient parameters to a gradient object + * + * \param grad Pointer (handle) to gradient object + * \param stops_count Number of stop colors + * \param stops Pointer to stop colors coordinates + * \param colors Pointer to stop color values + * + */ +void +nema_vg_grad_set(NEMA_VG_GRAD_HANDLE grad, int stops_count, float *stops, color_var_t* colors); + +#ifdef __cplusplus +} +#endif + +#endif //__NEMA_VG_PAINT_H__ diff --git a/src/drivers/nema/include/nema_vg_path.h b/src/drivers/nema/include/nema_vg_path.h new file mode 100644 index 000000000..4280d4ed8 --- /dev/null +++ b/src/drivers/nema/include/nema_vg_path.h @@ -0,0 +1,143 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief Path operation related fuctions + * + */ + +#ifndef __NEMA_VG_PATH_H__ +#define __NEMA_VG_PATH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "nema_interpolators.h" +#include "nema_matrix3x3.h" +#include "nema_sys_defs.h" +#include "nema_vg_context.h" + +#define NEMA_VG_PRIM_CLOSE (0x00U) /**< Close segment */ +#define NEMA_VG_PRIM_MOVE (0x01U) /**< Move segment */ +#define NEMA_VG_PRIM_LINE (0x02U) /**< Line segment */ +#define NEMA_VG_PRIM_HLINE (0x03U) /**< Horizontal line segment */ +#define NEMA_VG_PRIM_VLINE (0x04U) /**< Vertical line segment */ +#define NEMA_VG_PRIM_BEZIER_QUAD (0x05U) /**< Quadratic bezier segment */ +#define NEMA_VG_PRIM_BEZIER_CUBIC (0x06U) /**< Cubic bezier segment */ +#define NEMA_VG_PRIM_BEZIER_SQUAD (0x07U) /**< Smooth quadratic bezier segment */ +#define NEMA_VG_PRIM_BEZIER_SCUBIC (0x08U) /**< Smooth cubic bezier segment */ +#define NEMA_VG_PRIM_ARC (0x09U) /**< Arc segment */ +#define NEMA_VG_PRIM_POLYGON (0x0AU) /**< Polygon segment */ +#define NEMA_VG_PRIM_POLYLINE (0x0BU) /**< Polyline segment */ +#define NEMA_VG_PRIM_MASK (0x0FU) /**< Mask for all segments */ +#define NEMA_VG_REL (0x10U) /**< Rel segment*/ +#define NEMA_VG_ARC_LARGE (0x20U) /**< Large arc segment */ +#define NEMA_VG_ARC_CW (0x40U) /**< Clockwise arc segment */ +#define NEMA_VG_PRIM_SCCWARC (NEMA_VG_PRIM_ARC ) /**< Small counterclockwise arc segment */ +#define NEMA_VG_PRIM_SCWARC (NEMA_VG_PRIM_ARC | NEMA_VG_ARC_CW ) /**< Small clockwise arc segment */ +#define NEMA_VG_PRIM_LCCWARC (NEMA_VG_PRIM_ARC | NEMA_VG_ARC_LARGE) /**< Large counterclockwise arc segment */ +#define NEMA_VG_PRIM_LCWARC (NEMA_VG_PRIM_ARC | NEMA_VG_ARC_CW |NEMA_VG_ARC_LARGE) /**< Large clockwise arc segment */ +#define NEMA_VG_PRIM_MOVE_REL (NEMA_VG_PRIM_MOVE | NEMA_VG_REL) /**< Relative move segment */ +#define NEMA_VG_PRIM_LINE_REL (NEMA_VG_PRIM_LINE | NEMA_VG_REL) /**< Relative line segment */ +#define NEMA_VG_PRIM_HLINE_REL (NEMA_VG_PRIM_HLINE | NEMA_VG_REL) /**< Relative horizontal line segment */ +#define NEMA_VG_PRIM_VLINE_REL (NEMA_VG_PRIM_VLINE | NEMA_VG_REL) /**< Relative vertical line segment */ +#define NEMA_VG_PRIM_BEZIER_QUAD_REL (NEMA_VG_PRIM_BEZIER_QUAD | NEMA_VG_REL) /**< Relative quadratic bezier segment */ +#define NEMA_VG_PRIM_BEZIER_CUBIC_REL (NEMA_VG_PRIM_BEZIER_CUBIC | NEMA_VG_REL) /**< Relative cubic bezier segment */ +#define NEMA_VG_PRIM_BEZIER_SQUAD_REL (NEMA_VG_PRIM_BEZIER_SQUAD | NEMA_VG_REL) /**< Relative smooth quadratic bezier segment */ +#define NEMA_VG_PRIM_BEZIER_SCUBIC_REL (NEMA_VG_PRIM_BEZIER_SCUBIC | NEMA_VG_REL) /**< Relative smooth cubic bezier segment */ +#define NEMA_VG_PRIM_SCCWARC_REL (NEMA_VG_PRIM_SCCWARC | NEMA_VG_REL) /**< Relative small counterclockwise arc segment */ +#define NEMA_VG_PRIM_SCWARC_REL (NEMA_VG_PRIM_SCWARC | NEMA_VG_REL) /**< Relative small clockwise arc segment */ +#define NEMA_VG_PRIM_LCCWARC_REL (NEMA_VG_PRIM_LCCWARC | NEMA_VG_REL) /**< Relative lareg counterclockwise arc segment */ +#define NEMA_VG_PRIM_LCWARC_REL (NEMA_VG_PRIM_LCWARC | NEMA_VG_REL) /**< Relative lareg rclockwise arc segment */ +#define NEMA_VG_PRIM_POLYGON_REL (NEMA_VG_PRIM_POLYGON | NEMA_VG_REL) /**< Relative polygon segment */ +#define NEMA_VG_PRIM_POLYLINE_REL (NEMA_VG_PRIM_POLYLINE | NEMA_VG_REL) /**< Relative polyline segment */ + + +/** \brief Create path + * + * \return Created path + * + */ +NEMA_VG_PATH_HANDLE nema_vg_path_create(); + +/** \brief Destroy path + * + * \param path Pointer to Path + * \return void + * + */ +void nema_vg_path_destroy(NEMA_VG_PATH_HANDLE path); + +/** \brief Clear path + * + * \param path Pointer to Path + * \return void + * + */ +void nema_vg_path_clear(NEMA_VG_PATH_HANDLE path); + +/** \brief Set path shape (vertex buffer) + * + * \param path Pointer to path + * \param seg_size Number of segments to be added + * \param seg Pointer to segments + * \param data_size Number of data to be added + * \param data Pointer to coordinates + * + */ +void nema_vg_path_set_shape(NEMA_VG_PATH_HANDLE path, const size_t seg_size , const uint8_t* seg, const size_t data_size, const nema_vg_float_t* data); + +/** \brief Set path shape (vertex buffer) and bounding box. Same functionality as nema_vg_path_set_shape() + * but bbox is given by user (reduces CPU utilization) + * + * \param path Pointer to path + * \param seg_size Number of segments to be added + * \param seg Pointer to segments + * \param data_size Number of data to be added + * \param data Pointer to coordinates + * \param bbox Pointer to shape bound box coordinates {min_x, min_y, max_x, max_y} + * + */ +void +nema_vg_path_set_shape_and_bbox(NEMA_VG_PATH_HANDLE path, const size_t seg_size, const uint8_t* seg, const size_t data_size, const nema_vg_float_t* data, const nema_vg_float_t *bbox); + +/** \brief Set affine transformation matrix + * + * \param path Pointer to path + * \param m 3x3 affine transformation matrix + * + */ +void nema_vg_path_set_matrix(NEMA_VG_PATH_HANDLE path, nema_matrix3x3_t m); + +#ifdef __cplusplus +} +#endif + +#endif //__NEMA_VG_PATH_H__ diff --git a/src/drivers/nema/include/nema_vg_tsvg.h b/src/drivers/nema/include/nema_vg_tsvg.h new file mode 100644 index 000000000..7c6eb9585 --- /dev/null +++ b/src/drivers/nema/include/nema_vg_tsvg.h @@ -0,0 +1,56 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief API for rendering .tsvg images + * + */ + +#ifndef NEMA_VG_TSVG_H_ +#define NEMA_VG_TSVG_H_ + +#include "nema_vg_context.h" + +/** \brief Draws a TSVG buffer + * + * \param buffer Pointer to the TSVG buffer that will be drawn + * + */ +void +nema_vg_draw_tsvg(const void* buffer); + +/** \brief Get the width and height of tsvg + * + * \param buffer Tsvg buffer + * \param width return Tsvg width + * \param height return Tsvg height + * + */ +void nema_vg_get_tsvg_resolution(const void *buffer, uint32_t *width, uint32_t *height); + +#endif // NEMA_VG_TSVG_H_ diff --git a/src/drivers/nema/include/nema_vg_version.h b/src/drivers/nema/include/nema_vg_version.h new file mode 100644 index 000000000..7e7581285 --- /dev/null +++ b/src/drivers/nema/include/nema_vg_version.h @@ -0,0 +1,55 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +/** + * @file + * @brief Contains version numbers for NemaVG API and the currently supported font version. + * + */ + +#ifndef NEMA_VG_VERSION_H__ +#define NEMA_VG_VERSION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NEMA_VG_MAJOR_VERSION 0x01U /**< NemaVG API version, major number */ +#define NEMA_VG_MINOR_VERSION 0x01U /**< NemaVG API version, minor number */ +#define NEMA_VG_REVISION_VERSION 0x07U /**< NemaVG API version, revision number */ +#define NEMA_VG_IMP_VERSION 0x00240600U /**< NemaVG API version, implementation in format 0x00YYMM00 (Y: year, M: month) */ + +#define NEMA_VG_API_VERSION ((NEMA_VG_MAJOR_VERSION << 16) + (NEMA_VG_MINOR_VERSION << 8) + (NEMA_VG_REVISION_VERSION)) /**< NemaVG API version in format 0x00MMmmrr (M:major, m:minor, r:revision if any) */ + +#define NEMA_VG_FONT_VERSION 0x01U /**< Current font version */ + + +#ifdef __cplusplus +} +#endif + +#endif //NEMA_VG_VERSION_H__ diff --git a/src/drivers/nema/include/tsi_malloc.h b/src/drivers/nema/include/tsi_malloc.h new file mode 100644 index 000000000..cf39538fe --- /dev/null +++ b/src/drivers/nema/include/tsi_malloc.h @@ -0,0 +1,64 @@ +/* TSI 2023.xmo */ +/******************************************************************************* + * Copyright (c) 2023 Think Silicon Single Member PC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this header file and/or associated documentation files to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Materials, and to permit persons to whom the Materials are furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: + * https://think-silicon.com/products/software/nemagfx-api + * + * The software is provided 'as is', without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall + * Think Silicon Single Member PC be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising + * from, out of or in connection with the software or the use or other dealings + * in the software. + ******************************************************************************/ + +#ifndef TSI_MALLOC_H__ +#define TSI_MALLOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define tsi_malloc_init(base_virt, base_phys, size, reset) \ + tsi_malloc_init_pool(0, base_virt, base_phys, size, reset) + +#define tsi_malloc(size) tsi_malloc_pool(0, size) + +int tsi_malloc_init_pool( int pool, + void *base_virt, + uintptr_t base_phys, + int size, + int reset); + +int tsi_malloc_init_pool_aligned( int pool, + void *base_virt, + uintptr_t base_phys, + int size, + int reset, + int alignment); /*alignment must be multiple of 4, otherwise it will be overwritten internaly to be multiple of 4*/ + +void *tsi_malloc_pool(int pool, int size); +void tsi_free(void *ptr); +uintptr_t tsi_virt2phys(void *addr); +void *tsi_phys2virt(uintptr_t addr); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/nema/lib/libnemagfx-cortex-m55+fp.a b/src/drivers/nema/lib/libnemagfx-cortex-m55+fp.a new file mode 100644 index 000000000..d755869d0 Binary files /dev/null and b/src/drivers/nema/lib/libnemagfx-cortex-m55+fp.a differ diff --git a/src/drivers/nema/lib/libnemagfx-cortex-m55.a b/src/drivers/nema/lib/libnemagfx-cortex-m55.a new file mode 100644 index 000000000..b664d6b6a Binary files /dev/null and b/src/drivers/nema/lib/libnemagfx-cortex-m55.a differ diff --git a/src/omv/ports/stm32/omv_gpu.c b/src/omv/ports/stm32/omv_gpu.c index ca0aa6af5..3729181c4 100644 --- a/src/omv/ports/stm32/omv_gpu.c +++ b/src/omv/ports/stm32/omv_gpu.c @@ -26,19 +26,114 @@ #include "omv_boardconfig.h" #if (OMV_GPU_ENABLE == 1) #include STM32_HAL_H + +#include "py/mphal.h" +#include "py/runtime.h" + #include "imlib.h" #include "dma.h" +#if OMV_GPU_NEMA +#include "nema_core.h" +#include "nema_vg.h" +#include "nema_error.h" +#endif + +#if OMV_GPU_NEMA_MM_STATIC +uint8_t OMV_ATTR_SECTION(OMV_ATTR_ALIGNED(NEMA_BUFFER[OMV_GPU_NEMA_BUFFER_SIZE], 32), ".dma_buffer"); +#endif + int omv_gpu_init() { - return 0; + int error = 0; + #if OMV_GPU_NEMA + nema_init(); + error = nema_get_error(); + #endif + return error; } void omv_gpu_deinit() { - DMA2D_HandleTypeDef dma2d = {}; - dma2d.Instance = DMA2D; - HAL_DMA2D_DeInit(&dma2d); + } +#if OMV_GPU_NEMA +static nema_tex_format_t omv_gpu_pixfmt(uint32_t omv_pixfmt) { + switch (omv_pixfmt) { + case PIXFORMAT_BINARY: + return NEMA_L1; // source only + case PIXFORMAT_BAYER_ANY: + case PIXFORMAT_GRAYSCALE: + return NEMA_L8; + case PIXFORMAT_RGB565: + return NEMA_RGB565; + } + mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Pixel format is not supported")); +} + +int omv_gpu_draw_image(image_t *src_img, + rectangle_t *src_rect, + image_t *dst_img, + rectangle_t *dst_rect, + int alpha, + const uint16_t *color_palette, + const uint8_t *alpha_palette, + image_hint_t hint) { + OMV_PROFILE_START(); + + if ((dst_rect->w != src_rect->w) || (dst_rect->h != src_rect->h)) { + // Create command list. + #if OMV_GPU_NEMA_MM_STATIC + nema_buffer_t bo = { + .size = sizeof(NEMA_BUFFER), + .base_virt = NEMA_BUFFER, + .base_phys = (uint32_t) NEMA_BUFFER, + }; + nema_cmdlist_t cl = nema_cl_create_prealloc(&bo); + #else + nema_cmdlist_t cl = nema_cl_create_sized(OMV_GPU_NEMA_BUFFER_SIZE); + #endif + // Bind command list. + nema_cl_bind_circular(&cl); + + nema_tex_mode_t blit_mode; + if (hint & IMAGE_HINT_BILINEAR) { + blit_mode = NEMA_FILTER_BL; + } else { + blit_mode = NEMA_FILTER_PS; + } + // Set up destination texture. + nema_tex_format_t dst_pixfmt = omv_gpu_pixfmt(dst_img->pixfmt); + nema_bind_dst_tex((uintptr_t) dst_img->data, dst_rect->w, dst_rect->h, dst_pixfmt, -1); + + // Set up source texture. + nema_tex_format_t src_pixfmt = omv_gpu_pixfmt(src_img->pixfmt); + nema_bind_src_tex((uintptr_t) src_img->data, src_rect->w, src_rect->h, src_pixfmt, -1, blit_mode); + + // Configure operations. + nema_set_blend_blit(NEMA_BL_SRC); + nema_set_clip(0, 0, dst_rect->w, dst_rect->h); + nema_blit_rect_fit(0, 0, dst_rect->w, dst_rect->h); + + // Flush source image + SCB_CleanDCache_by_Addr(src_img->data, image_size(src_img)); + + nema_cl_submit(&cl); + nema_cl_wait(&cl); + #if !OMV_GPU_NEMA_MM_STATIC + nema_cl_destroy(&cl); + #endif + + // Invalidate the destination image. + SCB_InvalidateDCache_by_Addr(dst_img->data, image_size(dst_img)); + + } else { + return -1; + } + + OMV_PROFILE_PRINT(); + return 0; +} +#else int omv_gpu_draw_image(image_t *src_img, rectangle_t *src_rect, image_t *dst_img, @@ -79,9 +174,11 @@ int omv_gpu_draw_image(image_t *src_img, } #endif - DMA2D_HandleTypeDef dma2d = {}; - - dma2d.Instance = DMA2D; + DMA2D_HandleTypeDef dma2d = { + .Instance = DMA2D, + .Init.ColorMode = DMA2D_OUTPUT_RGB565, + .Init.OutputOffset = dst_img->w - dst_rect->w, + }; if (dst_img->pixfmt != src_img->pixfmt) { dma2d.Init.Mode = DMA2D_M2M_PFC; @@ -97,9 +194,6 @@ int omv_gpu_draw_image(image_t *src_img, } #endif - dma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; - dma2d.Init.OutputOffset = dst_img->w - dst_rect->w; - HAL_DMA2D_Init(&dma2d); dma2d.LayerCfg[0].InputOffset = dst_img->w - dst_rect->w; @@ -245,4 +339,5 @@ int omv_gpu_draw_image(image_t *src_img, OMV_PROFILE_PRINT(); return 0; } -#endif // (OMV_GPU_ENABLE == 1) +#endif // OMV_GPU_NEMA +#endif // OMV_GPU_ENABLE diff --git a/src/omv/ports/stm32/omv_portconfig.mk b/src/omv/ports/stm32/omv_portconfig.mk index 8b4d7ce30..e19e5af15 100644 --- a/src/omv/ports/stm32/omv_portconfig.mk +++ b/src/omv/ports/stm32/omv_portconfig.mk @@ -58,6 +58,7 @@ CFLAGS += -D$(MCU) \ -DHSE_VALUE=$(OMV_HSE_VALUE)\ -DOMV_VTOR_BASE=$(OMV_FIRM_ADDR) \ -DCMSIS_MCU_H='<$(MCU_LOWER).h>' \ + -DOMV_NOSYS_STUBS_ENABLE=1 \ -DSTM32_HAL_H='' \ $(OMV_BOARD_CFLAGS) @@ -125,6 +126,7 @@ OMV_CFLAGS += -I$(TOP_DIR)/$(MLX90641_DIR)/include/ OMV_CFLAGS += -I$(TOP_DIR)/$(PIXART_DIR)/include/ OMV_CFLAGS += -I$(TOP_DIR)/$(DISPLAY_DIR)/include/ OMV_CFLAGS += -I$(TOP_DIR)/$(LIBPDM_DIR)/ +OMV_CFLAGS += -I$(TOP_DIR)/$(NEMA_DIR)/include ifeq ($(OMV_ENABLE_UVC), 1) UVC_CFLAGS := $(CFLAGS) $(HAL_CFLAGS) @@ -189,6 +191,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/common/, \ file_utils.o \ mp_utils.o \ omv_csi.o \ + nosys_stubs.o \ ) FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \ @@ -652,6 +655,10 @@ ifeq ($(MICROPY_PY_AUDIO), 1) LIBS += $(TOP_DIR)/$(LIBPDM_DIR)/libPDMFilter_CM7_GCC_wc32.a endif +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),n6)) +LIBS += $(TOP_DIR)/$(NEMA_DIR)/lib/libnemagfx-$(CPU)+fp.a +endif + #------------- ML libraries ----------------# ifeq ($(MICROPY_PY_ML_TFLM), 1) OMV_CFLAGS += -I$(BUILD)/$(TENSORFLOW_DIR)/ diff --git a/src/omv/ports/stm32/stm32_hal_msp.c b/src/omv/ports/stm32/stm32_hal_msp.c index ddd91fbf3..a1791d6cf 100644 --- a/src/omv/ports/stm32/stm32_hal_msp.c +++ b/src/omv/ports/stm32/stm32_hal_msp.c @@ -640,8 +640,36 @@ void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d) { __HAL_RCC_DMA2D_FORCE_RESET(); __HAL_RCC_DMA2D_RELEASE_RESET(); __HAL_RCC_DMA2D_CLK_DISABLE(); + __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE(); } +#if defined(GPU2D) +void HAL_GPU2D_MspInit(GPU2D_HandleTypeDef *hgpu2d) { + __HAL_RCC_GPU2D_FORCE_RESET(); + __HAL_RCC_GPU2D_RELEASE_RESET(); + + __HAL_RCC_GPU2D_CLK_ENABLE(); + __HAL_RCC_GPU2D_CLK_SLEEP_ENABLE(); +} + +void HAL_GPU2D_MspDeInit(GPU2D_HandleTypeDef *hgpu2d) { + __HAL_RCC_GPU2D_CLK_DISABLE(); + __HAL_RCC_GPU2D_CLK_SLEEP_DISABLE(); +} +#endif + +#if defined(GFXMMU) +void HAL_GFXMMU_MspInit(GFXMMU_HandleTypeDef *hgfxmmu) { + __HAL_RCC_GFXMMU_CLK_ENABLE(); + __HAL_RCC_GFXMMU_CLK_SLEEP_ENABLE(); +} + +void HAL_GFXMMU_MspDeInit(GFXMMU_HandleTypeDef *hgfxmmu) { + __HAL_RCC_GFXMMU_CLK_DISABLE(); + __HAL_RCC_GFXMMU_CLK_SLEEP_DISABLE(); +} +#endif + #if (OMV_JPEG_CODEC_ENABLE == 1) void HAL_JPEG_MspInit(JPEG_HandleTypeDef *hjpeg) { __HAL_RCC_JPEG_CLK_ENABLE(); diff --git a/src/omv/ports/stm32/stm32_nema.c b/src/omv/ports/stm32/stm32_nema.c new file mode 100644 index 000000000..0123a8c4e --- /dev/null +++ b/src/omv/ports/stm32/stm32_nema.c @@ -0,0 +1,167 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2024 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * STM32 Nema HAL layer. + */ +#include +#include STM32_HAL_H + +#include "omv_boardconfig.h" + +#if (OMV_GPU_NEMA == 1) +#include "omv_common.h" +#include "nema_core.h" +#include "nema_sys_defs.h" + +#ifndef OMV_GPU_NEMA_RING_SIZE +#define OMV_GPU_NEMA_RING_SIZE 1024 +#endif + +volatile static int last_cl_id; +static GPU2D_HandleTypeDef gpu2d = { 0 }; +static nema_ringbuffer_t ring_buf = {{0}}; +#if OMV_GPU_NEMA_MM_STATIC +uint8_t OMV_ATTR_SECTION(OMV_ATTR_ALIGNED(RING_BUFFER[OMV_GPU_NEMA_RING_SIZE], 32), ".dma_buffer"); +#endif + +int32_t nema_sys_init(void) { + // Initialize GPU2D + gpu2d.Instance = GPU2D; + HAL_GPU2D_Init(&gpu2d); + + // Configure and enable texture cache + HAL_ICACHE_DeInit(); + HAL_ICACHE_Disable(); + HAL_ICACHE_ConfigAssociativityMode(ICACHE_4WAYS); + HAL_ICACHE_Enable(); + + // Allocate ring buffer. + #if OMV_GPU_NEMA_MM_STATIC + ring_buf.bo.fd = 0; + ring_buf.bo.size = sizeof(RING_BUFFER); + ring_buf.bo.base_virt = RING_BUFFER; + ring_buf.bo.base_phys = (uint32_t) RING_BUFFER; + #else + ring_buf.bo = nema_buffer_create(OMV_GPU_NEMA_RING_SIZE); + #endif + + // Initialize ring buffer. + if (nema_rb_init(&ring_buf, 1) != 0) { + return -1; + } + + NVIC_SetPriority(GPU2D_IRQn, IRQ_PRI_GPU); + NVIC_EnableIRQ(GPU2D_IRQn); + + NVIC_SetPriority(GPU2D_ER_IRQn, IRQ_PRI_GPU); + NVIC_EnableIRQ(GPU2D_ER_IRQn); + return 0; +} + +int nema_wait_irq_cl(int cl_id) { + while (last_cl_id < cl_id) { + __WFI(); + } + return 0; +} + +int nema_wait_irq_brk(int brk_id) { + while (nema_reg_read(GPU2D_BREAKPOINT) == 0U) { + __WFI(); + } + return 0; +} + +uint32_t nema_reg_read(uint32_t reg) { + return HAL_GPU2D_ReadRegister(&gpu2d, reg); +} + +void nema_reg_write(uint32_t reg, uint32_t value) { + HAL_GPU2D_WriteRegister(&gpu2d, reg, value); +} + +nema_buffer_t nema_buffer_create(int size) { + nema_buffer_t bo = { + .base_virt = nema_host_malloc(size), + .base_phys = (uint32_t) bo.base_virt, + .size = size, + }; + return bo; +} + +nema_buffer_t nema_buffer_create_pool(int pool, int size) { + return nema_buffer_create(size); +} + +void *nema_buffer_map(nema_buffer_t *bo) { + return bo->base_virt; +} + +void nema_buffer_unmap(nema_buffer_t *bo) { + UNUSED(bo); +} + +void nema_buffer_destroy(nema_buffer_t *bo) { + nema_host_free(bo->base_virt); +} + +uintptr_t nema_buffer_phys(nema_buffer_t *bo) { + return bo->base_phys; +} + +void nema_buffer_flush(nema_buffer_t *bo) { + #if !OMV_GPU_NEMA_MM_STATIC + SCB_CleanInvalidateDCache_by_Addr((uint32_t *) bo->base_virt, bo->size); + #endif +} + +void nema_host_free(void *ptr) { + if (ptr) { + free(ptr); + } +} + +void *nema_host_malloc(unsigned size) { + return malloc(size); +} + +int nema_mutex_lock(int mutex_id) { + return 0; +} + +int nema_mutex_unlock(int mutex_id) { + return 0; +} + +void GPU2D_IRQHandler(void) { + HAL_GPU2D_IRQHandler(&gpu2d); +} + +void GPU2D_ER_IRQHandler(void) { + HAL_GPU2D_ER_IRQHandler(&gpu2d); +} + +void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef *gpu2d, uint32_t CmdListID) { + last_cl_id = CmdListID; +} +#endif // OMV_GPU_NEMA