在将线条渲染到屏幕外缓冲区方面,Direct 2D 会比 Qt 更好吗?

本文关键字:2D Direct 会比 Qt 更好 方面 缓冲区 屏幕 | 更新日期: 2023-09-27 17:55:45

我有一个数据可视化应用程序(平行坐标)。这涉及在屏幕上绘制大量线条。该应用程序适用于大型数据集。测试数据集涉及~2.5M线(精确为2527700)。屏幕会很混乱,但它会显示一些模式。该应用程序具有沿 X 和 Y 缩放的功能。在典型的缩放级别下,它绘制大约 300K 线。该应用程序是用Qt编写的,渲染所花费的时间是可观的。典型数字为(以毫秒为单位的时间)

所需时间:496画了1003226线

所用时间:603画了1210032线

所需时间:112画了344582线

所需时间:182绘制了 387960 行

所需时间:178画了361424线

所需时间:222画了676470行

所需时间:171画了475652线

所需时间:251画了318709线

所需时间:5画了14160行

所需时间:16绘制了 27233 行

以下代码段用于对绘制的线段进行计时和计数。渲染发生在屏幕外图像(格式为 Format_ARGB32_Premultiplied的 QImage)。QImage 的最大尺寸为 1366 x 768。段类型为 QVector。

QTime m_timer;
m_timer.start();
painter.drawLines(segments);
qDebug() << "Time taken: " << m_timer.elapsed();
painter.end();
qDebug() << "Drew " << segments.size();

此 QImage 被缓存以保存将来的抽奖。我从未使用过DirectX。直接 2D 渲染是否会提供比我已经拥有的更多的性能优势。有什么办法可以改善这些数字吗?

如果直接 2D 渲染可以提高这些数字,那么使用什么技术堆栈?使用 C#/SharpDX 会更好吗?我问这个是因为Qt只能通过翻译来做DirectX(不确定成本是多少),而且由于该应用程序主要是Windows C#可能会简化开发过程。

在将线条渲染到屏幕外缓冲区方面,Direct 2D 会比 Qt 更好吗?

最好

创建自己的线条绘制函数,直接在 QImage 内存缓冲区上运行。在那里,您可以做出一些Qt的画家可能无法做到的假设,并实现更好的性能。然后使用 QGLWidget 将图像块化以屏幕抗锯齿(并可能缩放?

良好的线条绘制代码:http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Simplification。虽然对于C++和内存缓冲区实现,可以通过用单指针替换x0y0坐标来进一步优化。

最重要的是,您可以在线条循环中内联线条绘制,并且在迭代超过一百万条线时具有零函数调用。

如果让块传输部分进行抗锯齿,则只需设置每个像素的记忆字,而无需检查它是哪种笔等。

还可以将硬件放大到任何所需的目标分辨率,您可以自由优化 QImage 大小以获得您想要的图案,而不是在屏幕上显示它。

如果可以让线条主要按 Y 坐标排序,这将有助于缓存,因为设置连续行的像素将在 QImage 缓冲区的内存中更接近。

不管你怎么做,都要加快优化(gcc 的 -O3 标志,不确定 MS 编译器),默认值至少不是 gcc 的最大值。

您可以做的另一件事是在每个图像级别并行化绘图,这甚至可以使用 QPainter。允许在主线程以外的 QImage 上绘制,Qt 可以轻松地将 QImage 作为信号参数从绘图线程发送到 GUI 线程。您所做的是严重限制 CPU 和内存,因此最好让绘制线程计数与实际内核计数相同,而不是计算超线程。

不知道Qt,但对于Direct2D,在Windows 7上绘制数百万条抗锯齿线(如果没有最新的IE10/SP更新),您将无法获得良好的性能。在Windows 8上,Direct2D略有改进,但我不确定它是否可以处理这样的速率。如果要获得更好的性能,则必须直接将 Direct3D 与 MSAA 图面或可能的一些碎石空间后期效果(如 FXAA)一起使用,或者使用几何感知抗锯齿技术(如 GPAA/GBAA)。查看"实时抗锯齿的过滤方法"最新实时抗锯齿技术的综合列表。

也许我不会直接回答你的问题,但是:

  • 我猜,Qt使用标准的系统例程来执行图形操作,所以这里的意思是GDI和/或GDI+。如果速度快,两者都不会在 CPU 上进行所有计算。另一方面,如果可能,来自 DirectX11+ 的 Direct2D 会尝试使用 GPU 功能加速绘图,因此它可以更快地工作。

  • 我不太了解Qt,但我想,您应该能够检索要以某种方式绘制的窗口(=控件)的句柄(即使这意味着使用WinAPI - 总有一种方法)。如果是这样,您可以绕过所有Qt机制,并使用DirectX直接在该窗口上绘制,而无需额外的开销。

  • 至于 SharpDX - 我不知道,存在这样的库,感谢您提供的信息。他们发表了一篇关于操作性能的论文,你可能想看看:http://code4k.blogspot.com/2011/03/benchmarking-cnet-direct3d-11-apis-vs.html。无论如何,它似乎是围绕 DirectX 标头的或多或少简单的包装器,因此它不会给您的应用程序增加太多开销(除非性能真的很关键)。