我正在尝试加快 Inkscape 矢量图像编辑器中的渲染(延迟和吞吐量方面),以便它对艺术家更友好。
我正在尝试决定是直接绘制到窗口还是绘制到中间的屏幕外表面,然后将其复制到窗口。
如果每次都必须重新绘制整个画布,那么通过节省内存带宽,直接绘制到窗口显然会更快。但不幸的是,Inkscape 不进行 GPU 渲染,因此它无法重绘整个窗口,只能重绘无效的矩形。
第一种方法是使用 gdk_window_begin_draw_frame(rect) 获取每个矩形的子表面,绘制并将其发送到屏幕。但缺点是您不能并行绘制 2,因为 GTK 一次只允许锁定 1 个矩形。
我想到的第二种方法是向窗口系统(GTK)询问两个矩形的边界框。然后并行绘制 2,并将结果发送到屏幕。但这里的问题是 GTK 不保留窗口的旧内容 - 它清除了整个更新区域,在 2 个矩形之间的间隙中创建空白区域。
因此,要使第二种方法起作用,我可以要求 GUI 工具包保留窗口的内容,或者渲染到保留整个窗口的中间缓冲区。但这需要额外的复制。我想知道绘图时是否习惯丢弃以前的内容?我知道丢弃具有不必等待先前渲染完成并且不必从 GPU 内存读回 CPU 内存的性能优势。该建议是针对 OpenGL 的 glMapBuffer() 和 DirectX 表面的 LockRect() 给出的。但是 glMapBuffer() 确实可以选择返回旧内容。那么GTK也应该有这样的选择吗?还是问的太多了?
由于 GUI 工具包的限制,我面临的很多问题似乎都是人为的。例如,如果 GUI 工具包允许您并行更新多个区域,那么第一种方法会更有效且更容易。OpenGL 允许您使用 glMapBufferRange() 来完成此操作。
我想为 GTK 提供一个好的解决方案,但同时我想知道您是否可以非常直接地访问 GPU 硬件,您将如何最有效地实现我描述的部分绘图?