所以我正在研究一个涉及每秒更新 60 次的 LCD 屏幕的项目。它使用 BitmapFrame,我需要将这些像素复制到更新屏幕的库。目前我的帧速率约为 30-35 FPS,这太低了。所以我尝试使用多线程,但这会产生很多问题。
DisplayController 已经创建了一个标题来完成所有工作,如下所示:
public void Start()
{
_looper = new Thread(Loop);
_looper.IsBackground = true;
_looper.Start();
}
private void Loop()
{
while (_IsRunning)
{
renderScreen();
}
}
它调用renderScreen
方法来绘制所有元素并将像素复制到BitmapFrame
。但这个过程花费的时间太长,所以我的 FPS 下降了。我尝试解决这个问题的方法是创建一个绘制、复制和写入像素的任务。但此解决方案会占用大量 CPU,并会导致屏幕出现故障。
public void renderScreen()
{
Task.Run(() =>
{
Monitor.Enter(_object);
// Push screen to LCD
BitmapFrame bf = BitmapFrame.Create(screen);
RenderOptions.SetBitmapScalingMode(bf, BitmapScalingMode.LowQuality);
bf.CopyPixels(new Int32Rect(0, 0, width, height), pixels, width * 4, 0);
DisplayWrapper.USBD480_DrawFullScreenBGRA32(ref disp, pixels);
Monitor.Exit(_object);
});
}
我已经阅读了很多有关 C# 并发队列的内容,但这不是我需要的。使用两个线程会导致编译器说该变量由另一个线程拥有的问题。
如何同时渲染新位图并将该位图每秒 60 次写入 LCD?
最佳答案
我假设USBD480_DrawFullScreenBGRA32
是实际写入LCD的内容,其余代码只是准备图像。我认为提高性能的关键是在写入上一个图像的同时准备下一个图像。
我认为最好的解决方案是使用两个线程并使用 ConcurrentQueue
作为需要写入内容的缓冲区。一个线程准备图像和 puts them into the ConcurrentQueue
,另一个线程 pulls them off the queue并将它们写入 LCD。这样您就不需要每次调用 Task.Run
的开销。
限制写入队列的帧数也可能是明智的,这样它就不会超前太多并占用不必要的内存。
关于C#异步LCD写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58402150/