需要有关 Qt Painting 的性能改进建议

Need performance improvement advice on Qt Painting

为简单起见,我的应用程序有两个滚动条。当任何滚动条发生变化时,QPainter 会重新绘制图像。

码片:

  // connect valueChanged to update
  connect(this->horizontalScrollBar(),
      SIGNAL(valueChanged(int)),
      this,
      SLOT(UpdateVisibleArea()));

  connect(this->verticalScrollBar(),
      SIGNAL(valueChanged(int)),
      this,
      SLOT(UpdateVisibleArea()));

在UpdateVisibleArea()中,调用了QWidget.update()方法。 QWidget.paintEvent() 方法的实现方式如下:

QPixmap q_pixmap;
if (!ImageCache::GetPixmap(cache_key, &q_pixmap)) {
    // there're up to thousands of images, we can not pre-load them all into the cache.
    // the following statement may take 80~250ms.
    loadImage(cache_key, &q_pixmap);    
    ImageCache::PutPixmap(cache_key, q_pixmap);
}

QPainter q_painter;
q_painter.drawPixmap(...);  // usually it takes less than 20ms.

问题:

当我快速拖动滚动条时,感觉很卡。

我的想法:

  1. 图像应该在后台线程中加载。但问题是,qpainter 实例正在等待 UI 线程。当图像未准备好时,它无法继续。
  2. 有什么方法可以防止滚动条快速变化时重绘发生得如此之快?

我的问题:

你能告诉我一些关于如何优化它的线索吗?

How can I optimize the complex drawing for many objects in scrolled content?

当我们在实际绘制到屏幕上之前填充图形缓冲区时,可以使用 "offscreen rendering" 来完成。在滚动的情况下,我们可以将整个滚动内容预填充为一个大的矩形区域,或者我们可以使用足够大的矩形 "window" 以便我们滚动更容易。我们是否应该使用较小的滚动 window 缓冲区而不是整个滚动矩形用于离屏渲染取决于滚动内容的大小。

使用 OpenGL 和帧缓冲区可以进一步改进此技术。这可以通过 or using QML QQuickPaintedItem 来完成(尽管这意味着整个 UI 是 QML)。不过,第二个示例并未详细说明离屏缓冲区技术,而只是展示了 QML 中帧缓冲区的使用。可以在第一个示例中应用相同的技术,只需稍作更改。