ST意法半导体
直播中

李晶

8年用户 1012经验值
私信 关注
[问答]

你怎么看有一个选项可以在调用swapFrameBuffers之前旋转帧缓冲区呢

我们使用的 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.}

除此之外,您还需要反转触摸控制器驱动程序中的坐标。
你可以试一试,但老实说我不太乐观。希望您能说服您的客户切换到另一个可以正常安装或支持扫描方向交换的显示器。
举报

马秀英

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 帧缓冲区,您可能会想出如何修改它。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分