跳转到主要内容

Flash受限的GUI开发

本文介绍了如何利用TouchGFX开发低Flash存储器使用率的图形用户界面。

在使用TouchGFX生成代码时,像图像、文本和字体这样的资源会被转换成C++文件,然后在编程过程中与TouchGFX应用程序代码、用户代码和TouchGFX库一起存储在Flash存储中。 这意味着具有许多资源的大型或复杂项目会导致高Flash使用率。

由于大多数应用程序中的存储器资源都是有限的,因此有几种方法可以减少Flash存储器的使用率。 TouchGFX提供四项内置功能,可以帮助您显著减少应用程序的Flash存储器使用率。 这四项功能分别是L8图像格式、图像压缩、可缩放矢量图形(SVG)和矢量字体。

本文中,我们将了解如何利用这四项功能来限制应用程序占用的Flash存储器空间。 这些测量使用的是STM32U5G9J-DK2,但节约Flash空间的功能也可以应用于其他硬件平台。

Further reading

Read the Memory Usage article for more information on memory management.

节省Flash的电动自行车演示

在TouchGFX Designer中可以找到节省Flash使用率的电动自行车演示,其中说明了如何使用TouchGFX的四项功能来节省Flash空间。 该演示是STM32U5G9J-DK2板专用演示。 具有NeoChromVG GPU是STM32U5G9J-DK2的一大优势,该硬件可以加速矢量渲染。 然而,L8图像格式和图像压缩可在所有STM32 MCU中使用。

如果演示都使用未压缩的位图(无L8、压缩、SVG和矢量字体)实现,它将占用大约10.5MB的Flash存储器。 而在采用了四项节省Flash空间的功能时,演示仅占用大约800KB的Flash存储器。 由此可以看到,大量的Flash空间被节省下来。 在演示中,四项措施总共可节约92%的Flash空间。

各项功能的使用场合

有关如何使用TouchGFX四项Flash功能的技术信息和指南,请点击此处:

上述四项功能均可帮助减少应用程序所需的Flash存储器空间。 各项功能的使用具体取决于应用场景,但也可运用一些通用规则来判断。 现在我们将对此进行讨论。

L8和压缩

如果要在位图上使用L8图像格式,位图最多为256色。 L8格式的素材渲染会采用Chrom ART硬件加速,这意味着L8位图的渲染时间几乎与常规位图相同。 有时,与常规位图相比,以L8格式渲染位图甚至更快,这是因为从Flash存储器读取的数据更少。 与32位色深的普通位图相比,L8可以节约70%以上的Flash空间。

与L8相比,图像压缩能帮助您节约更多的Flash空间。 Image compression comes in two formats: L8 compression and RGB compression. To use L8 compression on a bitmap, the bitmap needs to be in L8 format first, since the L8 compression algorithms use the color look-up table. As a result of this, L8 compressed bitmaps are still limited to a maximum of 256 colors. Some of the L8 compression algorithms have further limitations on the maximum number of colors. L4 is limited to a maximum of 16 colors and L8 RLE is limited to a maximum of 64 colors. RGB compression doesn't require the bitmap to be in L8 format and can hence be used on all bitmaps. Opposed to rendering of L8 bitmaps, which are hardware accelerated with Chrom-ART, compressed bitmaps (both L8- and RGB compressed) are software rendered and are hence more expensive to render. 压缩位图的另一个限制,是其无法用于可缩放或旋转的控件。

如果您已经拥有PNG格式的素材,则可轻松使用L8图像格式和图像压缩。 通常,您可以在最多256色的位图上使用L8图像格式,而不会有任何显著的性能损失。 If you need to save even more flash and have available render time to achieve the required performance, you could use L8 image compression as well. If you want to compress bitmaps that are not compatible with L8 format, you can use RGB compression instead. If you need to use your bitmap in scalable or rotatable widgets, you can't use compressed bitmaps natively. 当然,有一些方法可以解决这一问题,我们稍后将进行简要介绍。

SVG

另一个节约Flash空间的方法是将其保存为SVG格式,而非PNG格式。 SVG对颜色的数量无限制。 然而,与L8和压缩相比,SVG的渲染成本通常更高。 因此,建议限制同时使用的SVG数量,并将包含SVG的动画保持在最少。 SVG素材越简单,占用的Flash空间就越小,并且可以获得更好的性能。 为此,建议使用单层SVG。

要在SVG控件中使用它,需要以SVG格式导入该素材。 TouchGFX无法转换此类素材。

矢量字体

对于SVG格式的非字体资产,矢量字体的渲染成本也很高,因其渲染方式与SVG相同。 矢量字体通常适用于大字体或同一种字体有多种不同尺寸的情况。 如果您有不同尺寸的矢量字体和矢量表示,只需要存储一次字体。 然后,只需要一个缩放因子便可用不同的尺寸来表示。 对于位图字体,每个字体大小都需要单独存储。 矢量字体节约的Flash空间通常不亚于图像压缩和SVG。 因此,如有必要将Flash存储器占用空间限制在绝对最小值,则应使用矢量字体。

示例

To provide specific examples of the characteristics of the different concepts, measurements are performed on two assets from the E-bike demo in regular bitmap, L8, L8 RLE compressed, RGB compressed and SVG-format. 测量在STM32U5G9J-DK2上进行,素材位于内部Flash。 对于没有NeoChrom GPU的MCU,SVG的渲染时间将更长。 然而,更快的CPU可弥补这一点。

以下资产的色深为32位,是一个顶部有图标的按钮。 按钮为122 x 112像素,图标为72 x 72像素。

电动自行车演示中带图标的按钮

对素材执行以下测量:

格式大小百分比渲染时间CPU负荷
位图:75.4 KB100%0.414 ms2.4%
L8:19.3 KB25.6%0.448 ms2.3%
L8 RLE:2.55 KB3.4%1.51 ms9.6%
RGB:4.53 KB12.0%1.65 ms10.5%
SVG:3.01 KB4.0%1.43 ms4.1%

As seen from this, L8 RLE has the lowest flash footprint, but takes approximately 1 ms longer to render compared to regular bitmap format.

以下素材的色深为32位,是演示中仪表板页面中仪表的一部分。 150 x 436像素。

电动自行车演示中仪表的一部分

对素材执行以下测量:

格式大小百分比渲染时间CPU负荷
位图:261.6 KB100%1.15 ms1.5%
L8:65.6 KB25.1%1.24 ms1.4%
L8 RLE:4.66 KB1.78%2.75 ms15.0%
RGB:10.5 KB4.01%3.08 ms17.6%
SVG:0.686 KB0.27%3.40 ms2.0%

SVG格式的资源占用的Flash空间最少,但渲染成本也最高。

结论

如上所述,没有一种格式适合所有资产。 However, for flash saving alone, L8 image compression generally has the smallest flash footprint when the asset is relatively small, and SVG has the smallest flash footprint when the asset is larger. 尽管SVG资产的颜色可以超过256色,但出于Flash存储器使用和性能方面的考虑,仍然建议SVG资产保持相对简单。 在L8、图像压缩和SVG中,L8图像格式占用的Flash空间最大,但L8的渲染时间最短。

因此,在开发Flash资源有限的应用程序时,您需要确定瓶颈并确定什么对您的应用程序最重要。 性能还是Flash存储器空间节约量? 如果是性能,L8将是最有效的方法。 如果性能允许,L8甚至可以与某些素材的压缩相结合。 如果需要尽可能小的Flash占用空间,那么建议使用图像压缩和SVG。

使用“智能”素材

使用“智能”素材可提高Flash空间节约量和性能。 在这里,智能素材指的是素材本身及其用途。

简单素材

首先,素材越简单,可压缩的素材就越多,SVG定义也就越简单, 最终占用的Flash空间会更小。

As a reference, in the E-bike demo all bitmap assets have a maximum of 64 colors and since the assets are also well-suited for L8 RLE, all the bitmap assets are L8 RLE compressed. Since L8 RLE is faster to render compared to L8 LZW9, this also gives the best performance.

此外,如果设计本身较为简单,那么在某些情况下也可使用平铺图像。 然后,您只需要存储图像的一部分,便可重复存储。

使用boxes

另一种以智能方式节约Flash存储器空间的方法是使用Box控件。 使用boexes有两大优势:

  1. 首先,box将直接绘制在帧缓冲器中。 因此,无需Flash存储器来储存box。 对Flash的唯一影响来自定义box所需的少量代码。
  2. 其次,box可调整且可在运行时改变颜色和大小。 在Flash有限的电动自行车演示中,box用于纯色背景等,通过改变方框颜色即可支持亮/暗模式。

可重复使用的素材

另一种节约Flash存储器空间的方法是限制素材总数。 当然,这可以通过非常简单的设计来实现,但有时也可以通过多次重复使用同一素材来限制现有的素材数量。

例如,在Flash使用率有限的电动自行车演示中,该方法可用于天气页面。 天气图标是经过缩放可适应所有3种尺寸的相同资源。 由于它是一种缩放资产,因此SVG格式优于压缩格式,即使RLE的Flash占用空间较小。 然而,如果素材以RLE格式存储在所有3种大小中,则Flash空间的总占用量将更大。

此外,这些按钮还能作为可重复使用的素材来实现。 例如,将按钮与其图标分开,以便重复使用。

在演示中可重复使用的另一个例子是背景。 演示中总共有5种不同的背景设计,但通过使用可调整的素材(Box和可重复使用的素材),所有背景仅需一项素材和一Box即可创建。

提高性能

开发Flash使用率有限的应用程序时,存在降低性能的风险。 但是,如有可用的备用RAM,则有办法提高应用程序的性能。 通过使用动态位图可缓存容器,将素材或容器的静态快照绘制到RAM中。 之后,无论何时使用资产或容器,均可用缓存版本。 缓存版本只是RAM中的一个位图,这意味着渲染时间与渲染常规位图相同。

在限制Flash使用率受限的电动自行车演示中,可缓存容器用于滚动SVG资产和矢量字体,同时保持良好的性能。

天气元素作为可缓存容器

通常,矢量字体在运行时移动或可移动时都会被缓存。 由此确保了在滚动矢量字体的情况下至少有30 FPS。

演示中使用的另一个技巧是将压缩位图解压缩到位图缓存中。 通过将位图解压缩到RAM,就可以在缩放或旋转的控件中使用此位图了。 当位图被解压缩时,TouchGFX引用位图ID时将始终使用解压缩的缓存版本。 下面是电动自行车演示的一个例子。 压缩的位图被简单地解压缩之后,便可以像常规位图那样使用。

StartView.cpp
StartView::StartView()
{
Bitmap::decompress(BITMAP_MAIN_RIPPLE_LEFT_ID); // Decompress compressed image to bitmap cache
Bitmap::decompress(BITMAP_MAIN_RIPPLE_RIGHT_ID); // Decompress compressed image to bitmap cache
}

void StartView::setupScreen()
{
leftMainRippleScale.setBitmap(BITMAP_MAIN_RIPPLE_LEFT_ID); // Set bitmap for Scalable Image
rightMainRippleScale.setBitmap(BITMAP_MAIN_RIPPLE_RIGHT_ID); // Set bitmap for Scalable Image
leftMainRippleScale.setWidthHeight(0, 0); // Set scale of image
rightMainRippleScale.setWidthHeight(0, 0); // Set scale of image
}

由于广泛使用动态位图,Flash使用率受限的电动自行车演示需要922KB的位图缓存。 这意味着需要大量的备用RAM。 然而,该演示也将Flash空间节约到了一个相当极端的程度。 在更简单的应用程序或性能要求不那么重要的应用程序中,可以使用更小的位图缓存。

结论

在本文中,我们了解了如何节省TouchGFX应用程序的Flash用量。

4项Flash节约功能可在所有STM32硬件平台上使用,但请记住,SVG和矢量字体的渲染成本很高。 所以,如果没有矢量渲染的硬件加速或额外的计算能力,性能可能会因此降低。

限制Flash使用率GUI开发的功能可能会导致性能损失,但可以通过使用动态位图和可缓存容器来提高性能。

Flash空间节约功能使节约Flash空间拥有巨大的潜力。 这些功能可节约的实际Flash量取决于具体的应用,而对于Flash使用率受限的电动自行车演示,可节约92%的使用率。