piker icon indicating copy to clipboard operation
piker copied to clipboard

Graphics caching for fast render: `QPixMap`, `QPainterPath`, `QBackingStore` or OpenGL?

Open goodboy opened this issue 5 years ago • 2 comments

In trying to squeeze performance for #109 I stumbled upon many resources for toying with avoidance of graphics re-drawing/rendering and have now a slew of place to get started if we decide to dig further on this optimization front in the Qt types and apis.

This also pertains to ongoing work discussed in #109 which has since moved to rendering OHLC bars using QPainterPath much like pyqtgraph's internal usage for line plots which are very performant even for moderately sized data sets.

As some preface please note the following:

QPainterPath (what we're using)

  • pyqtgraph uses this internally with a fancy binary-format array generation routine, pg.functions.arrayToQPath(), which streams to the path magically and is quite fast
  • we've adopted this as the implementation for our internal BarsItems graphics and it seems to be scaling well (at least way better then any other easily testable platform) with renders of 15-20k bars with ~ 3 - 10ms latency depending on how far zoomed out the view is.
  • we've numba-ized the binary format array generation which can likely be extended if arrayToQPath() can be split up into it's numpy only and Qt only parts.
  • appends are supported out of the box using .addPath() (which we're also using) which avoids having to regenerate path segments previously drawn to screen
  • use of QPicture and QPainter.drawPicture() seems to slow this down oddly
  • the painter paths example is likely relevant reading for newcomers to this api

QBackingStore (what we should probably look into for further speedups)

OpenGL options in Qt (the distant goals of 3d UX)

QPixMap for painting images to screen (likely not what we want at all)

  • api docs for creation and passing to QPainter.drawPixmap() and redraws with QPainter.play()
  • originally looked into this due to discussion on forums regarding ways to speed up QPicture draws:
    • ironically, in practice QPicture.play() seems to be slowing everything down
    • forum discussion on using pixmaps to do fast drawing for a music app
    • SO question regarding QPainter "keeping" previous drawings to avoid re-draws
    • SO answer on using QPainterPath over QLineF (this is actually the eventual solution we came to for bars drawing)
    • SO question on how to use the QPixMap api
    • a slew of example code on using the pixmap api
    • SO question on how to update a QPixmap inside a QGraphicsScene
    • a tutorial on QPainter and bitmap graphics
    • example C++ code on how to use a QPixmap for rendering a magnifying glass thinger
  • further resources:

goodboy avatar Nov 24 '20 19:11 goodboy

Oh boy.. and now we have vulkan contenders from the vispy authors.. So I guess on the GL front we have some other stuff to look at.

  • datoviz a vulkan rewrite of vispy which apparently bases most of it's 2D code from,
  • glumpy which apparently does have fast GL based 2d stuff and seems to be the original source of most of the showcased vispy examples.

goodboy avatar Feb 16 '21 19:02 goodboy