显示

字体

为什么字体抗锯齿效果差或白色字体边缘有异常彩色?

在使用 2bit 以上的字库时,如果字体抗锯齿效果差,且字体边缘有异常彩色或者字体颜色显示异常,可能是字体渲染数据的大小端问题。

请通过显示 RGB 单通道色彩字体来判别,比如设置字体颜色为 gui_rgb(255,0,0,255) ,正常情况会显示红色,若颜色是蓝色则异常(彩色字体都能看出异常)。

图像

图片旋转后为什么会出现黑色条纹?

图片旋转后可能会出现黑色条纹,这是由于图片旋转时,像素点的位置发生了变化,旋转后的位置上的像素没有被填充,导致出现了黑色条纹。

可以使用 gui_img_set_quality 函数开启图像抗锯齿计算功能,通常可以解决这个问题。

如果问题仍然存在,可以联系技术支持团队获取帮助。

旋转屏幕

HoneyGUI 支持旋转屏幕功能吗?

HoneyGUI 支持屏幕旋转功能。

旋转屏幕是指将屏幕旋转 90、180、270 度,通常用来解决 UI 设计与显示屏幕宽高数值不匹配的问题。

例如, UI 设计使用 480*800 的分辨率,但显示屏幕是 800*480 分辨率。此时需要通过旋转屏幕进行像素宽高匹配。

HoneyGUI 不支持 UI 内部的实时旋转功能,例如手机的竖排锁定功能或者观看视频时的屏幕翻转功能。

旋转屏幕功能是如何实现的?

目前的旋转屏幕功能是一种渲染后处理,在渲染后,将生成的图像缓存区进行旋转。其渲染流程与普通模式完全一致。

旋转屏幕会对渲染帧率产生什么影响?

旋转屏幕会轻微降低帧率。

如何开启旋转屏幕功能?

由于屏幕旋转功能的实现方式有很多种,在不同的平台和不同的应用中,最高效的旋转实现可能不同,因此 SDK 中可能不包含旋转屏幕的功能实现。

用户可以参考技术文档,来进行对应的代码修改,此外可以联系技术团队获取帮助。

旋转屏幕有哪些旋转方式?

旋转屏幕的本质是将横向排列的像素数据调整为纵向排列的像素数据。根据硬件配置的不同,有多种实现方式可供选择。

快速决策流程

flowchart TD Start[选择旋转方案] --> Screen{屏幕支持旋转?} Screen -->|是| End1[使用屏幕旋转] Screen -->|否| GPU{有旋转 GPU?} GPU -->|是| RenderMode{绘制模式?} GPU -->|否| CPURenderMode{绘制模式?} RenderMode -->|整帧绘制| Plan1[方案 1:<br/>GPU 直接旋转] RenderMode -->|分块绘制| PushMode{推屏模式?} PushMode -->|分块推屏| Plan1 PushMode -->|整帧推屏| Compare1[推荐方案 1 或 2<br/>实测对比选择] CPURenderMode -->|分块绘制| CPUPushMode{推屏模式?} CPUPushMode -->|分块推屏| Plan3[方案 3:<br/>CPU 逐点旋转] CPUPushMode -->|整帧推屏| Plan4[方案 4:<br/>CPU 按列旋转] Plan1 --> End2[完成] Compare1 --> End2 Plan3 --> End2 Plan4 --> End2 End1 --> End2 style End1 fill:#90EE90 style Plan1 fill:#87CEEB style Compare1 fill:#FFD700 style Plan3 fill:#FFB6C1 style Plan4 fill:#FFB6C1

备注

重要提示:并非所有 GPU 都支持旋转功能。如果您的 GPU 不支持旋转,请按照 CPU 方案进行选择。

旋转方案详细说明

方案

执行单元

实现原理

适用条件与特点

方案 1:

GPU 直接旋转

GPU

GPU 直接从 SRC 读取像素,旋转后写入 DST

适用:SRC 和 DST 都是高速区,或无额外高速缓存

特点:实现简单,GPU 并行处理,适用于任意范围

方案 2:

GPU 缓存旋转

GPU + DMA

GPU 先旋转到高速缓存区,DMA 并行拷贝到 DST

适用:DST 是低速区且有额外高速缓存

特点:DMA 并行搬运,性能优于 CPU 拷贝,适用于分块场景

方案 3:

CPU 逐点旋转

CPU

CPU 逐点读取 SRC 像素,旋转写入 DST

适用:SRC 和 DST 都是高速区

特点:实现简单,适用于任意范围,但性能一般

方案 4:

CPU 按列旋转

CPU

CPU 从 SRC 按列读取完整行,旋转写入 DST

适用:DST 是低速区

特点:减少低速区写入次数,提高效率,适用于任意范围

关键概念

  • SRC(源缓存):旋转前的像素数据存储位置

  • DST(目标缓存):旋转后的像素数据存储位置

  • 高速区:SRAM 或速度接近 SRAM 的存储介质

  • 低速区:速度明显慢于 SRAM 的 PSRAM 或其他存储介质

  • 任意范围:方案可应用于整帧或分块,代码逻辑相同,只是处理范围不同

典型应用案例

案例 1::term:`GPU` + 分块绘制 + 整帧推屏

硬件配置:

  • 有 GPU 支持旋转

  • 分块绘制,分块区在高速 SRAM

  • 有另一个高速分块缓存区

  • 需要输出到低速 PSRAM 的完整帧区(无高速整帧缓存)

  • 整帧推屏

推荐方案:方案 2(GPU 缓存旋转),需与方案 1 对比测试

原因:分块区是高速区,GPU 旋转后先保存在另一个高速分块缓存区,然后用 DMA 并行拷贝到低速完整帧区。虽然 DMA 并行拷贝会占用总线影响其他低速区访问,但通常优于直接写入低速区。建议在实际平台上对比方案 1(GPU 直接旋转到低速区)和方案 2 的性能。

案例 2:GPU + 分块绘制 + 分块推屏

硬件配置:

  • 有 GPU 支持旋转

  • 分块绘制,分块区在高速 SRAM

  • 分块推屏,无需完整帧

推荐方案:方案 1(GPU 直接旋转)

原因:分块旋转后立刻推屏,源和目标都是高速区,GPU 直接旋转性能最优,无需额外缓存和拷贝,内存占用最小。

案例 3:GPU + 整帧绘制 + 整帧推屏

硬件配置:

  • 有 GPU 支持旋转

  • 整帧绘制,源和目标帧缓存都在高速 SRAM

  • 整帧推屏

推荐方案:方案 1(GPU 直接旋转)

原因:既然使用整帧绘制,说明内存充足且都是高速区,GPU 直接旋转性能最优。

案例 4:CPU + 分块绘制 + 整帧推屏

硬件配置:

  • 无 GPU,仅 CPU

  • 分块绘制,分块区在高速 SRAM

  • 有另一个高速分块缓存区

  • 需要输出到低速 PSRAM 的完整帧区

  • 整帧推屏

推荐方案:方案 4(CPU 按列旋转),需与方案 3 对比测试

原因:目标是低速区,按列读取完整行后再写入,减少低速区写入次数。可以在高速分块缓存区中进行按列读取操作,然后批量写入低速完整帧区,效率优于逐点旋转。

案例 5:CPU + 分块绘制 + 分块推屏

硬件配置:

  • 无 GPU,仅 CPU

  • 分块绘制,分块区在高速 SRAM

  • 分块推屏,无需完整帧

推荐方案:方案 3(CPU 逐点旋转)

原因:分块旋转后立刻推屏,源和目标都是高速区,使用方案 3 实现简单,性能可接受。

性能优化建议

  1. 优先使用硬件加速:如果屏幕或 GPU 支持旋转,优先使用硬件方案

  2. 减少低速区访问:当 DST 是低速区时,考虑使用高速缓存中转或按列读取算法

  3. 利用 DMA 并行:有 DMA 时,让 DMA 负责数据搬运,CPU/GPU 专注计算

  4. 实际测试验证:不同平台的存储介质速度差异较大,建议在目标平台上实测各算法性能

  5. 算法通用性:所有算法都支持任意范围(整帧或分块),根据实际绘制模式灵活应用