ST意法半导体
登录
直播中
李晶
8年用户
1012经验值
私信
关注
[问答]
你怎么看有一个选项可以在调用swapFrameBuffers之前旋转帧缓冲区呢
开启该帖子的消息推送
LCD显示
SPI接口
TFT
控制器
我们使用的 LCD 没有 SPI 接口,只有通过 LCD-TFT 控制器外围设备的并行 RGB 接口,因此无法按照您对上述链接的回答中的描述控制 LCD。
由于我们的客户对显示器方向(扁平电缆位置)存在机械问题,我们正在尝试使用 SW 解决方案来解决它。
如我所见,有一个选项可以在调用 swapFrameBuffers 之前旋转帧缓冲区,您怎么看?可以做到吗?性能问题?我们可以自己做吗?如何?
回帖
(2)
秦伙茂
2022-12-19 16:06:35
多么的不幸!您可以手动进行旋转,但性能损失会非常大,以至于只能实现非常简单的 UI。
这是由于两件事:
如果屏幕上
有任何
变化,那么您必须使
整个
屏幕无效()。否则它不会正确地“撤消”上次的旋转,导致小部件同时出现在正常位置和旋转位置。
旋转算法必须反转 X 轴和 Y 轴。这意味着您必须非顺序地读取或写入屏幕的每个像素到 SDRAM,这是非常昂贵的。
我认为进行这种轮换的正确位置是重写 HAL::endFrame。是这样的:
void MyHAL::endFrame()
{
dma.flush(); //wait for all dma operations to have completed
rotateFb(getClientFrameBuffer()); //apply rotation on the fb
HAL::endFrame(); //call base impl when rotation is done.}
除此之外,您还需要反转触摸控制器驱动程序中的坐标。
你可以试一试,但老实说我不太乐观。希望您能说服您的客户切换到另一个可以正常安装或支持扫描方向交换的显示器。
多么的不幸!您可以手动进行旋转,但性能损失会非常大,以至于只能实现非常简单的 UI。
这是由于两件事:
如果屏幕上
有任何
变化,那么您必须使
整个
屏幕无效()。否则它不会正确地“撤消”上次的旋转,导致小部件同时出现在正常位置和旋转位置。
旋转算法必须反转 X 轴和 Y 轴。这意味着您必须非顺序地读取或写入屏幕的每个像素到 SDRAM,这是非常昂贵的。
我认为进行这种轮换的正确位置是重写 HAL::endFrame。是这样的:
void MyHAL::endFrame()
{
dma.flush(); //wait for all dma operations to have completed
rotateFb(getClientFrameBuffer()); //apply rotation on the fb
HAL::endFrame(); //call base impl when rotation is done.}
除此之外,您还需要反转触摸控制器驱动程序中的坐标。
你可以试一试,但老实说我不太乐观。希望您能说服您的客户切换到另一个可以正常安装或支持扫描方向交换的显示器。
举报
马秀英
2022-12-19 16:06:50
它只支持 180 度旋转,但如果你愿意,你可以移植它来轻松地进行所有旋转——你应该能够从代码中分辨出来。
所以总结一下——这种轮换是以显着的性能成本完成的。这是一项昂贵的操作,因为必须在 X 轴和 Y 轴上交换像素。它会导致非常低效的 RAM 访问。
Mirror.hpp 是一个自定义小部件,它只会反转 X 轴和 Y 轴上的像素。要使用它,您必须:
-
#include
它在您的视图中,并将 Mirror 类型的成员添加到您的 View 类中。
- 将其放置在 (0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT) 处,使其覆盖整个屏幕区域
-
确保
它在顶部(使其成为您添加()到视图的最后一个小部件)
此外,您需要将以下函数添加到您的 FrontendApplication.hpp 中:
// Force redrawing entire screen
virtual void draw(Rect& rect)
{
if (drawCacheEnabled)
{
// Invalidate entire screen instead of requested rect.
Rect r(0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT);
Application::draw(r);
}
else
{
// Use original rect if we are *actually* drawing and not just invalidating.
Application::draw(rect);
}
}
最后,您需要在触摸控制器 sampleTouch() 函数中恢复 X 和 Y 坐标。像这样的东西(假设是 480x272 显示器):
x = 479-x;
y = 271-y;
如果您使用不同的分辨率,您还需要更改 Mirror.hpp 文件底部的常量!
Mirror 类假设 16bpp 帧缓冲区。如果您使用 24bpp 帧缓冲区,您可能会想出如何修改它。
它只支持 180 度旋转,但如果你愿意,你可以移植它来轻松地进行所有旋转——你应该能够从代码中分辨出来。
所以总结一下——这种轮换是以显着的性能成本完成的。这是一项昂贵的操作,因为必须在 X 轴和 Y 轴上交换像素。它会导致非常低效的 RAM 访问。
Mirror.hpp 是一个自定义小部件,它只会反转 X 轴和 Y 轴上的像素。要使用它,您必须:
-
#include
它在您的视图中,并将 Mirror 类型的成员添加到您的 View 类中。
- 将其放置在 (0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT) 处,使其覆盖整个屏幕区域
-
确保
它在顶部(使其成为您添加()到视图的最后一个小部件)
此外,您需要将以下函数添加到您的 FrontendApplication.hpp 中:
// Force redrawing entire screen
virtual void draw(Rect& rect)
{
if (drawCacheEnabled)
{
// Invalidate entire screen instead of requested rect.
Rect r(0, 0, HAL::DISPLAY_WIDTH, HAL::DISPLAY_HEIGHT);
Application::draw(r);
}
else
{
// Use original rect if we are *actually* drawing and not just invalidating.
Application::draw(rect);
}
}
最后,您需要在触摸控制器 sampleTouch() 函数中恢复 X 和 Y 坐标。像这样的东西(假设是 480x272 显示器):
x = 479-x;
y = 271-y;
如果您使用不同的分辨率,您还需要更改 Mirror.hpp 文件底部的常量!
Mirror 类假设 16bpp 帧缓冲区。如果您使用 24bpp 帧缓冲区,您可能会想出如何修改它。
举报
更多回帖
rotate(-90deg);
回复
相关问答
LCD显示
SPI接口
TFT
控制器
STM32H735IG Discovery
可以
使用OctoSPI作为
帧
缓冲区
吗?
2022-12-08
483
为什么无法将
帧
缓冲区
放在靠近每个的外部RAM中?
2023-01-04
508
为什么Touchgfx 4.18
帧
缓冲区
像素格式与层像素格式不匹配
呢
2022-12-23
473
如何将stm32f767和LTDC与双
帧
缓冲区
一
起使用?
2023-01-10
577
从TouchGFX Designer生成
一
个
Demo Project时,如何检查默认使用了多少
帧
缓冲区
?
2023-02-07
416
请问串口的DMA接收
缓冲区
是不是环形
缓冲区
2022-08-30
1642
从外部RAM分配所有发件箱
缓冲区
是否有可能
呢
?
2023-03-02
384
可变大小
缓冲区
的内存分配技术
2020-04-09
2086
imx8不支持双
帧
缓冲区
和IPU吗?
2023-04-17
790
阻止GUI任务或
帧
缓冲区
访问的正确方法是什么
呢
2022-12-19
716
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分