1 概述

本文档解释了 ARM-2D 的基本概念。在我们开始体验Arm-2D时,你可能会有很多问题,比如:

  1. Arm-2D 是什么?

  2. 它能解决什么问题?

  3. 目标受众是谁?

  4. Arm-2D 由什么组成?

  5. 发展环境如何?

接下来的内容,将一一作答。

1.1 什么是arm-2d

如果您想在 Linux 中设计 GUI 应用程序,则不必直接面对硬件。Linux 生态系统为您提供了所有必要的软件组件,包括 GPU 驱动程序、 GUI 栈和许多方便的参考设计。

不幸的是,如果您是使用 Cortex-M 设备的嵌入式开发人员,则必须直接面对各种显示硬件。更糟糕的是,您可能要面对来自不同硬件厂商的各种非标准2D 图形加速器。许多 GUI 栈可用于嵌入式应用程序,但是大多数 GUI 栈并不能立即用于目标设备。因此,您必须首先完成移植工作。总之,在 Cortex-M 系统中使用 GUI 是可行的,但是在此之前还有很多底层的工作要做。

图1-1 GUI 中富嵌入式系统与约束嵌入式系统的生态系统比较

Arm-2D 不是重新发明图形用户界面或与现有的图形用户界面堆栈竞争。ARM-2D 想要解决的问题是如何为所有的 GUI 栈提供一个统一的低级硬件加速接口,这样高级软件服务提供商就可以不用为不断涌现的非标准硬件编写驱动程序。一旦 ARM-2D 成为图形用户界面供应商和芯片制造商之间的桥梁,每个人都可以做到最好。

图1-2典型嵌入式 GUI 系统的层次结构

Arm-2D 侧重于低级别的2D 图像处理,并为各种2D 加速器提供统一的软件接口。

1.2 目标受众

Arm-2d 的参与者有三种类型: GUI 服务提供商、硬件供应商和嵌入式软件开发商。

GUI服务

GUI服务提供商可以受益于ARM-2D,为常用硬件加速提供标准接口。GUI 服务提供商可以默认使用 Arm-2D 来获得低级加速。因此,他们不再需要为硬件编写驱动程序,而是专注于改进软件并为 VIP 客户提供定制服务。

硬件厂商

半导体制造商可以从 ARM-2D 中受益。为了节省学习新体系结构的时间,程序员希望在相同的体系结构下使用微控制器,在大多数情况下,这意味着使用 Cortex-M 处理器。由于设备使用相同的处理器架构,半导体制造商有动力引入专有的外围设备以实现差异化。引入专用于二维图形的加速器已成为新的趋势。在硬件差异化给终端用户带来好处的同时,也不可避免地引入了软件碎片化的问题。引入一个硬件抽象层来缓解这个问题是软件工程中常见的做法。Arm-2D 是用于各种2D 图形加速的抽象层。

在理想的情况下,芯片制造商只需要为他们的硬件加速器实现 ARM-2d 兼容驱动程序,这足以从主流 GUI 栈获得支持。

嵌入式软件开发人员

大多数嵌入式软件开发人员使用资源有限的设备。一个典型的系统具有小于64KB 的 FLASH 和4 ~ 32K 的 SRAM。作为参考,一个标准的低成本串行液晶显示器(320 * 240分辨率和65K 彩色)需要150KB 内存的显示缓冲区,这是负担不起的。

此外,对于这样的微控制器,大多数现有的 GUI 栈太昂贵,以至于无法使用内存占用。另一方面,许多 GUI 应用程序非常简单,甚至一些自制的实现也足以满足需求。在这种情况下,大多数现有的 GUI 堆栈都太重了。

当一个人想用这种资源受限的微控制器从头开始构建一个基于 GUI 的应用程序时,你要么完全放弃 GUI 的想法,要么在以下选项中做出权衡:

  1. 实现图形用户界面只使用简单的形状,如点,线,颜色块等

  2. 操作带宽低的轴承: 从 LCD 内部显示缓冲区读取像素,修改并写回

  3. 只复制/发送预先存储在 ROM 中的图片到 LCD,不需要任何处理

  4. 使用一种称为部分帧缓冲区的技术来实现时空交换

总而言之,在过去,很难在裸机环境中实现外观现代的 GUI。现在,Arm-2D 提供了一系列易于使用的 API,帮助用户使用所谓的部分帧缓冲区辅助服务实现所需的图形效果。值得一提的是,由 Arm-2D 引入的 PFB 支持的设计范例对于上层软件是透明的,这极大地简化了在裸金属环境中的应用程序开发,即用户可以设计应用程序,就好像有一个完整的帧缓冲区。

总之,Arm-2D 使许多设备(传统上不适合现代外观的 GUI)能够实现一个内存占用很小的现代外观的 GUI。

1.3 arm-2d库

作为一个起点,Arm-2D 为所有算法提供了默认的软件实现。这些软件实现主要是用 C 语言编写的,有时还包括一些本地汇编加速。这确保了 Arm-2D 可以直接在所有 Cortex-M 处理器上使用而不需要修改。

Helium加速

如果您使用的是 Armv8.1-M 处理器,比如 Cortex-M55,只要您启用编译选项的 Helium 支持,ARM-2D 库将自动使用 Helium 技术进行加速。

第三方执行

Arm-2D 已经提供了标准的方法来添加对各种第三方硬件加速器的支持。虽然现在不包括在内,在未来,我们将介绍模板,示例和文档,以显示如何添加对第三方硬件加速器的支持。

arm定制指令支持

Arm-2D 已经提供了标准的方法来添加对定制指令加速的2D 图像处理算法的支持。虽然不包括现在,在未来,我们将介绍模板,例子和文档,以显示如何。

1.4 范围和限制

ARM-2D 应该满足智能手表应用的要求:

  • 最多640 * 640分辨率,32位颜色

  • 60FPS刷新率

  • 提供缩放,旋转的支持

ARM-2D 应满足硬件受限环境下深度嵌入式应用的要求:

  • 一种典型的小于64K 闪存和4 ~ 32K SRAM 的单片机

  • 系统频率约为48MHZ或以上

  • 用于容忍低帧速范围从1 FPS 到30 FPS 的应用程序

  • 使用部分帧缓冲交付现代外观的 GUI (小至8 * 8 PFB,128字节,16位颜色),不限制支持的分辨率大小(用低帧速率交换 RAM)

相关限制如下:

该库原则上专注于 Cortex-M 处理器

该库应由以下编译器编译:

  • Arm Compiler 5
  • Arm Compiler 6
  • GCC
  • LLVM
  • IAR

该库聚焦于低级像素处理加速

  • 原则上,该库不提供为内容创建提供 API,例如绘图形状、文本显示等,但是提供简单的绘图点 API

  • 原则上,该库不提供创建 GUI 所必需的数据结构或相关算法,例如,元素树、 GUI 消息处理和树遍历算法

1.6 文件夹结构

文件夹和文件 类型 描述
Library 文件夹 此文件夹包含arm-2d库的源文件和头文件
Helper 文件夹 此文件夹包含 helper 函数/服务的源文件和头文件
documentation 文件夹 此文件夹包含所有文档
examples 文件夹 此文件夹包含所有示例代码/项目
README md文档 说明文档
how_to_deploy_the_arm_2d_library md文档 一步一步的指导,帮助您将 Arm-2D 库部署到项目中
LICENSE 许可证 Apache 2.0许可证
tools 文件夹 此文件夹包含一些使用库的有用实用程序。例如img2c.py是一个python脚本,用于将指定图片转换为平铺数据结构。

2 基础知识

Arm-2D 定义了一些易于使用的基本数据结构,为各种图形资源提供了统一的描述方法,并简化了需要传递给2D 处理 API 的参数。本章将介绍一些使用 Arm-2D 库必须知道的基本概念和相应的数据结构。Arm-2D 系统地介绍了一个Boxing模型,以提供更复杂和易于使用的2D 图形操作。

2.1 region区域

Region是由 Location (左上角的坐标)和 Size 信息描述的矩形区域。

typedef struct arm_2d_region_t {implement_ex(arm_2d_location_t, tLocation);implement_ex(arm_2d_size_t, tSize);
} arm_2d_region_t;

图2-1有位置和面积的区域region

location位置

“区域region”的坐标由位矩形左上角的顶点定义。其数据结构如下:

typedef struct arm_2d_location_t {int16_t iX;int16_t iY;
} arm_2d_location_t;

与一般的笛卡儿坐标系不同,在图形中,Y 轴通常反射在相反的方向,这意味着 Y 坐标越低,Y 坐标越大。在后面将要介绍的 Boxing 模型中,我们将理解区域的坐标可以是负的,表示当前区域相对于其父区域起点的位置。

图2-2当位置为负坐标时。

如图2-2所示,当一个 region的 x 和 y 坐标都为负值时,它实际上在其父 Area 的外部(左上角)有相当大的面积。当我们尝试找到当前 region及其父 region的交集时,我们将发现只有部分区域是有效的。

size大小

区域region的大小信息由“高度”和“宽度”一起描述。数据结构的定义如下:

typedef struct arm_2d_size_t {int16_t iWidth;int16_t iHeight;
} arm_2d_size_t;

虽然有符号类型 int16_t 用于描述宽度和高度,但是负数是没有意义的,应该避免使用

2.2 boxing模型

所谓的boxing模型描述了区域之间的联系,这通常用于描述容器和可视元素之间的关系。

在 GUI 栈中,Boxing 模型通常涉及更复杂的内容,比如边框的宽度、容器边框内的边距、容器内元素之间的填充/距离等等。Arm-2D 并不关心这些细节,而只是描述容器和内部元素之间的简单关系。

绝对位置和相对位置

在 Arm-2d 中,我们将面板或窗口视为容器,面板和窗口的位置是它们在显示缓冲区中的坐标。我们称这种位置信息为绝对位置,它直接将显示缓冲区中的坐标描述为绝对位置。在图2-3中,面板(顶部容器)的坐标是绝对坐标。

容器内元素的坐标被描述为相对于父容器左上角的坐标。我们称这种位置为相对位置。除此之外,由于容器只是一个特殊的元素,因此容器嵌套成为可能。在图2-3中,最里面的两个区域region有相对位置。

图2-3绝对位置和相对位置的典型例子

如果一个区域region有绝对位置,它就是绝对区域; 类似地,如果一个区域region有相对位置,它就是相对区域。

图2-4绝对区域和相对区域的典型例子

当我们使用这些相对和绝对信息来执行视觉区域计算时,很容易从各种图形操作中排除那些实际上对用户不可见的区域,从而提高整体2D 处理性能(如图2-4所示)。

2.3 tile贴图

tile瓷砖是 Arm-2D 中各种2D 操作的最小单元。瓷砖数据结构由三部分组成:

  1. 瓷砖的特点

  2. 瓷砖的区域

  3. 瓷砖的指针

Tile 数据结构的 C 定义如下:

typedef struct arm_2d_tile_t arm_2d_tile_t;
struct arm_2d_tile_t {implement_ex(struct {uint8_t    bIsRoot              : 1;uint8_t    bHasEnforcedColour   : 1;uint8_t    bDerivedResource     : 1;uint8_t                         : 5;uint8_t                         : 8;uint8_t                         : 8;arm_2d_color_info_t    tColourInfo;}, tInfo);implement_ex(arm_2d_region_t, tRegion);union {/*! when bIsRoot is true, phwBuffer is available,*! otherwise ptParent is available*/arm_2d_tile_t       *ptParent;uint8_t             *pchBuffer;uint16_t            *phwBuffer;uint32_t            *pwBuffer;intptr_t            nAddress;};
};

表2-1 arm_2d_tiles_t 中每个成员的功能

成员 分类 类型 描述
bIsRoot 特征信息 bit-field 这个位表示一个贴图是否是根贴图。如果目标贴图是根贴图,那么将包含一个指向显示缓冲区的指针的,且该位为1。如果目标贴图是子贴图,其中必须包含一个指向父节点的指针。
bHasEnforcedColour 特征信息 bit-field 此位指示平铺是否显式包含像素颜色的描述符。当值为1,tColourInfo是有效的,否则视为包含无效信息。如果贴图被用作颜色转换操作的源贴图,这个位必须置为1,且tColourInfo必须包含有效的描述。对于大多数 Arm-2d 操作,当这个位为0时,Arm-2d API 将使用它自己对瓷砖颜色的隐式声明。比如说,arm_2d_rgb16_tile_copy()就有描述色彩的隐式声明即RGB16。因此,即使该值为1,操作上仍然使用隐式的RGB16。
bDerivedResource 特征信息 bit-field 此位指示子贴图是否被用作资源当从现有的贴片创建资源时,必须将此位设置为“1”。该位只有在bIsRoot为0时才有效。
tColourInfo 特征信息 arm_2d_color_info_t 当bHasEnforcedColour被置为1,tColourInfo则包含关于目标tile中使用颜色的有效描述符
tRegion region区域 arm_2d_region_t 取决于给定tile的类型,tregion区域有不同的含义。
ptParent 指针 arm_2d_tile_t * 当bIsRoot=0时,该指针用于父tile
pchBuffer 指针 uint8_t * bIsRoot=1时,此指针用于指向一个显示缓冲区,该缓冲区包含少于或等于8位的像素
phwBuffer 指针 int16_t * 当bIsRoot=1时,此指针用于指向包含16位像素的显示缓冲区。
pwBuffer 指针 uint32_t* 当bIsRoot=1时,此指针用于指向包含32位像素的显示缓冲区

2.3.1 根tile

根tile是一种直接包含显示缓冲区的tile,她的特征位bIsRoot是根据显示缓冲区中使用的像素类型设置的,对应的指针应该被使用。

值得强调的是,对于根 Tile,其 Location 坐标必须为(0,0) ; 否则,将认为它是非法的。

在 C99标准的帮助下,tile结构可以清晰、容易地初始化。下面的示例显示根tile:c_tPictureCMSISLogo

,表明一个存储在称为c_bmpCMSISLogo[]的常量数组中的RGBA8888位图。请注意,由于位图和tile结构类型被指定为常量,编译器很可能使用 ROM 而不是 RAM 来存储它们,并保持较小的 RAM 占用量。

/*! picture cmsis_logo */
extern const uint8_t c_bmpCMSISLogo[163 * 65 * sizeof(uint32_t)];
const static arm_2d_tile_t c_tPictureCMSISLogo = {.tRegion = {.tSize = {.iWidth = 163,.iHeight = 65},},.tInfo = {.bIsRoot = true,.bHasEnforcedColour = true,.tColourInfo = {.chScheme = ARM_2D_COLOUR_RGBA8888,},},.pwBuffer = (uint32_t *)c_bmpCMSISLogo,
};

事实上,在一些宏的帮助下,我们可以使用 Tile 来实现所谓的可视化层的概念:

#define __declare_tile(__NAME)                                      \extern const arm_2d_tile_t __NAME;
#define declare_tile(__NAME)            __declare_tile(__NAME)#define __implement_tile(__NAME, __WIDTH, __HEIGHT, __TYPE)         \ARM_NOINIT static __TYPE                                \__NAME##Buffer[(__WIDTH) * (__HEIGHT)];             \const arm_2d_tile_t __NAME = {                          \.tRegion = {                                        \.tSize = {(__WIDTH), (__HEIGHT)},               \},                                                  \.tInfo.bIsRoot = true,                              \.pchBuffer = (uint8_t *)__NAME##Buffer,             \}#define implement_tile(__NAME, __WIDTH, __HEIGHT, __TYPE)           \__implement_tile(__NAME, __WIDTH, __HEIGHT, __TYPE)

例如,我们可以创建两个可视化图层,大小分别为100 * 100和200 * 50,并使用颜色arm_ 2d_color_rgb565_t 作为像素:

declare_tile(c_tLayerA)
implement_tile(c_tLayerA, 100, 100, arm_2d_color_rgb565_t);declare_tile(c_tLayerB)
implement_tile(c_tLayerB, 200, 50, arm_2d_color_rgb565_t);

这些层存储在 RAM 中,作为2D 操作的源和目标。

注意,在上面提到的宏模板中,我们使用 ARM_NOINIT 来装饰显示缓冲区,其定义如下:

#ifndef ARM_NOINIT
#if     defined(__IS_COMPILER_ARM_COMPILER_5__)
#   define ARM_NOINIT           __attribute__( ( section( ".bss.noinit"),zero_init) )
#elif   defined(__IS_COMPILER_ARM_COMPILER_6__)
#   define ARM_NOINIT           __attribute__( ( section( ".bss.noinit")) )
#elif   defined(__IS_COMPILER_IAR__)
#   define ARM_NOINIT           __no_init
#elif   defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)
#   define ARM_NOINIT           __attribute__(( __section__( ".bss.noinit")))
#else
#   define ARM_NOINIT
#endif
#endif

很明显,对于 ARM Compiler 5和 ARM Compiler 6,ARM_NOINIT把目标变量放入名为.bss.noinit的ZI节信息里面去,在脚本文件中,该节将被放置在具有UNINIT特性的执行区域里面。

LR_ROM __ROM_BASE __ROM_SIZE  {                           ...; Reserve empty region for stackARM_LIB_STACK __RAM1_BASE ALIGN 8 EMPTY __STACK_SIZE { }RW_RAM1 +0 __RAM1_RW_SIZE {* (+RO-DATA)* (+RW +ZI)}RM_RAM_NOINIT +0 UNINIT {* (.bss.noinit)}; Reserve empty region for heapARM_LIB_HEAP  __HEAP_BASE ALIGN 8 EMPTY __HEAP_SIZE  { }...
}

2.3.2 子tile

给定任意一个tile,我们可以基于它推导出理论上无限数量的子tile,这些子tile被称为 Arm-2D 中的子tile。值得强调的是,可用于派生的tile不需要是根tile。子tile的bIsRoot 标志为0,这意味着指针 ptParent 指向其父 Tile。

子tile的位置信息用于指示它在父tile中的位置。这里的坐标是允许负数的。子tile的区域可以大于父tile的大小。这通常用于实现部分帧缓冲区。有关详情,请参阅第2.3.3节。

图2-3显示了一系列的子tile,以及它们在区域视图中的派生关系。

引入子tile可以大大简化 GUI 资源的存储和表示。聪明的设计师甚至可以将许多图像元素放在同一张图片中,并通过从不同位置创建不同大小的子tile来检索它们。在实践中,一个多级子tile在2D 操作中几乎没有性能损失。

2.3.3 部分帧缓冲区PFB

所谓的部分帧缓冲区是 Tile Child 方案的一种特殊用法。它为一个小的矩形显示缓冲区建立一个根 Tile,并派生一个与实际屏幕大小相同的子 Tile。实际上,上层的 GUI 软件使用 Child Tile (全屏大小)来绘制图形和混合视觉层。完成一个帧后,实际上保存像素信息的 PFB 被发送到 LCD 驱动程序进行刷新。由于 FPB 只覆盖了一个很小的区域,在大多数情况下,上述绘图过程将被判定为“不需要实际绘图”而跳过。为了显示整个屏幕,我们需要不断重复这个过程,并在每次迭代开始时调整 FPB 和 Child Tile 之间的相对位置。对于我们来说,它看起来像在屏幕上一行一行移动 FPB,如图2-4所示。

图2-4部分帧缓冲区的工作原理

更多细节显示在examples/benchmark目录中的专用示例项目中。

2.4 色彩

Arm-2D 为支持更多的颜色格式保留了足够的空间。引入了一种数据结构来描述给定瓷砖中使用的颜色格式。C 的定义如下:

/*! * \brief enumerations for colour attributes*/
enum {ARM_2D_COLOUR_SZ_1BIT = 0,            //!< 1 bit:black and whiteARM_2D_COLOUR_SZ_2BIT = 1,            //!< 4 colours or 4 gray-levelsARM_2D_COLOUR_SZ_4BIT = 2,            //!< 16 colours or 16 gray-levelsARM_2D_COLOUR_SZ_8BIT = 3,            //!< 256 coloursARM_2D_COLOUR_SZ_16BIT = 4,           //!< 16bitsARM_2D_COLOUR_SZ_32BIT = 5,           //!< true colourARM_2D_COLOUR_SZ_1BIT_msk =   ARM_2D_COLOUR_SZ_1BIT << 1,ARM_2D_COLOUR_SZ_2BIT_msk =   ARM_2D_COLOUR_SZ_2BIT << 1,ARM_2D_COLOUR_SZ_4BIT_msk =   ARM_2D_COLOUR_SZ_4BIT << 1,ARM_2D_COLOUR_SZ_8BIT_msk =   ARM_2D_COLOUR_SZ_8BIT << 1,ARM_2D_COLOUR_SZ_16BIT_msk =  ARM_2D_COLOUR_SZ_16BIT<< 1,ARM_2D_COLOUR_SZ_32BIT_msk =  ARM_2D_COLOUR_SZ_32BIT<< 1,ARM_2D_COLOUR_SZ_msk      =   (0x07 << 1),ARM_2D_COLOUR_LITTLE_ENDIAN       = 0,ARM_2D_COLOUR_BIG_ENDIAN          = 1,ARM_2D_COLOUR_LITTLE_ENDIAN_msk   = ARM_2D_COLOUR_LITTLE_ENDIAN << 4,ARM_2D_COLOUR_BIG_ENDIAN_msk      = ARM_2D_COLOUR_BIG_ENDIAN    << 4,ARM_2D_COLOUR_NO_ALPHA = 0,ARM_2D_COLOUR_HAS_ALPHA = 1,ARM_2D_COLOUR_NO_ALPHA_msk        = ARM_2D_COLOUR_NO_ALPHA      << 0,ARM_2D_COLOUR_HAS_ALPHA_msk       = ARM_2D_COLOUR_HAS_ALPHA     << 0,ARM_2D_COLOUR_VARIANT_pos = 5,ARM_2D_COLOUR_VARIANT_msk         = 0x07 << ARM_2D_COLOUR_VARIANT_pos,
};/*!* \brief enumerations for colour types* */
enum {ARM_2D_COLOUR_BIN         =   ARM_2D_COLOUR_SZ_1BIT_msk,ARM_2D_COLOUR_1BIT        =   ARM_2D_COLOUR_SZ_1BIT_msk,ARM_2D_COLOUR_8BIT        =   ARM_2D_COLOUR_SZ_8BIT_msk,ARM_2D_COLOUR_GRAY8       =   ARM_2D_COLOUR_SZ_8BIT_msk,ARM_2D_COLOUR_16BIT       =   ARM_2D_COLOUR_SZ_16BIT_msk,ARM_2D_COLOUR_RGB16       =   ARM_2D_COLOUR_SZ_16BIT_msk,ARM_2D_COLOUR_RGB565      =   ARM_2D_COLOUR_RGB16,/*  won't supportARM_2D_COLOUR_RGB565_BE   =   ARM_2D_COLOUR_SZ_16BIT_msk        |ARM_2D_COLOUR_BIG_ENDIAN_msk      ,*/ARM_2D_COLOUR_32BIT       =   ARM_2D_COLOUR_SZ_32BIT_msk        ,ARM_2D_COLOUR_RGB32       =   ARM_2D_COLOUR_SZ_32BIT_msk        ,ARM_2D_COLOUR_CCCN888     =   ARM_2D_COLOUR_RGB32               ,ARM_2D_COLOUR_CCCA8888    =   ARM_2D_COLOUR_SZ_32BIT_msk        |ARM_2D_COLOUR_HAS_ALPHA_msk       ,ARM_2D_COLOUR_RGB888      =   ARM_2D_COLOUR_CCCN888             ,ARM_2D_COLOUR_BGRA8888    =   ARM_2D_COLOUR_CCCA8888            ,/* not supported yetARM_2D_COLOUR_NCCC888     =   ARM_2D_COLOUR_RGB32               |ARM_2D_COLOUR_BIG_ENDIAN_msk      ,ARM_2D_COLOUR_ACCC8888    =   ARM_2D_COLOUR_SZ_32BIT_msk        |ARM_2D_COLOUR_HAS_ALPHA_msk       |ARM_2D_COLOUR_BIG_ENDIAN_msk      ,
*/ARM_2D_CHANNEL_8in32      =   ARM_2D_COLOUR_SZ_32BIT_msk        |ARM_2D_COLOUR_HAS_ALPHA_msk       |ARM_2D_COLOUR_VARIANT_msk   ,
};/*!* \brief a type used as colour descriptor* */
typedef union {struct {uint8_t bHasAlpha  : 1;     //!< whether the target colour has alpha channeluint8_t u3ColourSZ : 3;     //!< the size of the colouruint8_t bBigEndian : 1;     //!< whether the colour is stored in big endianuint8_t u3Variant  : 3;};uint8_t chScheme;
} arm_2d_color_info_t;

表2.2 arm_2d_colour_info_t的成员

成员 类型 描述
bHasAlpha bit-field bHasAlpha是用来表明目标色彩格式是否包含alpha通道
u3ColourSZ bit-field u3ColourSZ是用来表明每个像素的数据长度,有效值表示为:" ARM_2D_COLOUR_SZ_ "
bBigEndian bit-field 用于指示像素是否存储在 Big-Endian 中
u3Variant bit-field 在极少数情况下,在上述位字段引用一种以上颜色格式最多可以用来编码8种不同的变体
chScheme uint8_t 上述位字段的8位表示。相比之下,它非常有效。以ARM_2D_COLOUR_开头的枚举,表示Arm-2D库中当前支持的颜色格式。例如:ARM_2D_COLOUR_RGB565。

除了颜色格式描述符之外,Arm-2D 库的当前版本还定义了受支持的颜色格式的数据结构:

typedef union arm_2d_color_rgb565_t {uint16_t tValue;struct {uint16_t u5B : 5;uint16_t u6G : 6;uint16_t u5R : 5;};
} arm_2d_color_rgb565_t;typedef union arm_2d_color_bgra8888_t {uint32_t tValue;struct {uint32_t u8B : 8;uint32_t u8G : 8;uint32_t u8R : 8;uint32_t u8A : 8;};
} arm_2d_color_bgra8888_t;typedef union arm_2d_color_rgb888_t {uint32_t tValue;struct {uint32_t u8B : 8;uint32_t u8G : 8;uint32_t u8R : 8;uint32_t     : 8;};
} arm_2d_color_rgb888_t;

如上所示,arm-2d 以小端方式描述颜色格式,例如,BGRA8888表示蓝色通道是第一个字节,Alpha 通道是第三个字节。颜色格式 CCCA8888意味着阿尔法通道是第三个字节,有三个颜色通道的名称和顺序,我们不关心。彩色格式 CCCN888意味着8个 MSB 是未使用的(保留给 alpha) ,较低的3个字节用于存储彩色通道。

2.4 API使用模式

Arm-2D API 可用于同步模式和异步模式。实际上,Arm-2D 库是为异步工作而设计的,并且封装后以支持同步模式。

2.4.1 同步模式

同步模式也称为经典模式,在这种模式下,直到服务完成或发生错误时,函数调用才会返回。在 Arm-2D 库的当前版本中,所有示例都是以同步模式编写的。

2.4.2 异步模式

异步模式有利于事件驱动的设计范式,适用于大多数基于实时操作系统的应用程序和裸机系统中用原型线程和/或有限状态机编写的应用程序。异步模式的示例和文档将很快添加进来。

arm-2d库详细介绍相关推荐

  1. STM32 HAL库详细介绍

    自从ST公司推出HAL库来替代原有的标准库,HAL库开始慢慢的被广大STM32开发者所接受,现在已经在实际的项目开发中大量使用,HAL库使得项目的移植变得简单容易,但是对于初学者而言,刚开始接触有些晦 ...

  2. Cadence每日一学_06 | OrCAD中自有默认元器件(原理图)库详细介绍

    文章目录 0.关于创建原理图库 1.如何添加/使用自有库 2.自有库详解 3.`Discrete.olb` 最近在学习小马哥的Cadence课程,该系列课程为学习笔记:使用Cadence Allegr ...

  3. Python中最常用十大图像处理库详细介绍

    本文主要介绍了一些简单易懂最常用的Python图像处理库 当今世界充满了各种数据,而图像是其中高的重要组成部分.然而,若想其有所应用,我们需要对这些图像进行处理.图像处理是分析和操纵数字图像的过程,旨 ...

  4. Simulink系列 - simulink模块库详细介绍

    (原创文章,转载请与作者联系,本文Matlab版本 R2019a) 往期回顾:SImulink仿真系列 - Simulink信号观察模块详解 上一篇:基于Matlab-Simulink 的 2FSK ...

  5. JSTL 标签库详细介绍资料 .

    http://blog.csdn.net/azheng270/article/details/2139528 前言 从JSP 1.1规范开始,JSP就支持在JSP中使用自定义标签了,自定义标签的广泛使 ...

  6. C++开源库详细介绍

    C++在"商业应用"方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又 ...

  7. JSTL标签库详细介绍

    目录 一JSTL标签库 二.核心(Core)标签库 通用标签 循环控制标签 导入文件和URL 总结 一JSTL标签库 JSTL是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta ...

  8. python基本使用-Python标准库详细介绍与基本使用方式,超详细!

    目录: Python 标准库概览概览 操作系统接口 os 模块提供了很多与操作系统交互的函数: 应该用 import os 风格而非 from os import *.这样可以保证随操作系统不同而有所 ...

  9. python标准库说明_Python标准库详细介绍与基本使用方式,超详细!

    目录: Python 标准库概览概览 操作系统接口 os 模块提供了很多与操作系统交互的函数: 应该用 import os 风格而非 from os import *.这样可以保证随操作系统不同而有所 ...

最新文章

  1. 发个IOCP的C++例子
  2. 最全中文leetcode解题攻略:思路知识点代码...搞定AI大厂笔试
  3. 重定向、别名、绝对路径、相对路径 详解
  4. python3+django写的个人笔记博客
  5. Mysql 乱码的解决
  6. DayDayUp:互联网江湖大佬那些事(互联网大佬学历一览)
  7. python基本数据类型的结构和使用方法
  8. java EE中JPA介绍
  9. WinPcap笔记(3):获取已安装设备的详细信息
  10. 密度聚类dbscan_DBSCAN —基于密度的聚类方法的演练
  11. python3安装cx oracle,[求助]python3安装cx_Oracle 报错
  12. Python:Python全球生态主站,pip安装方法、集成安装方法、文件安装方法、第三方库自动安装脚本
  13. Java中HashMap原理
  14. Property工具类,Properties文件工具类,PropertiesUtils工具类
  15. 怎么用matlab做系统辨识,MATLAB系统辨识仿真程序
  16. Java代理和动态代理机制分析和应用
  17. apache连接mysql配置_Apache+PHP配置及连接mysql数据库
  18. 四连测总结(WYL)
  19. 调用高德地图API接口,实现地铁站经纬度采集
  20. 从联邦学习角度聊人工智能隐私

热门文章

  1. Critical Reviews | 南农邹建文组综述全球农田土壤抗生素与耐药基因分布
  2. 考研政治——马克思三大定律之否定之否定
  3. application配置文件读取!
  4. body加背景图片没反应_css设置背景图片不显示问题
  5. 【大家说英语】Work Rob Gives a Speech
  6. [题解]CodeForces1208G Polygons
  7. echarts:基于上一篇我来给大家讲讲 如果你设置了自动播放但是鼠标放上去不生效 停留时间很短 应该怎么做呢???
  8. 学习英文-学以致用【场景:程序员英文-开发环境】
  9. 2022.4.9第十三届蓝桥杯web组省赛个人题解
  10. 靠2块钱月入4万:越朴素的方法,往往越挣钱