Add our own `FastAppendCurve.clear()`, try mem reso

In an effort to try and make `QPainterPath.reserve()` work, add internal
logic to use the same object without de-allocating memory from
a previous path write/creation.

Note this required the addition of a `._redraw` flag (to be used in
`.clear()` and a small patch to `pyqtgraph.functions.arrayToQPath` to
allow passing in an existing path (thus reusing the same underlying mem
alloc) which will likely be first pushed to our fork.
big_data_lines
Tyler Goodlet 2022-03-23 12:32:55 -04:00
parent 44f3a08ef1
commit 1abe513ecb
1 changed files with 40 additions and 2 deletions

View File

@ -124,6 +124,7 @@ class FastAppendCurve(pg.PlotCurveItem):
) -> None: ) -> None:
self._name = name self._name = name
self.path: Optional[QtGui.QPainterPath] = None
# TODO: we can probably just dispense with the parent since # TODO: we can probably just dispense with the parent since
# we're basically only using the pen setting now... # we're basically only using the pen setting now...
@ -133,6 +134,7 @@ class FastAppendCurve(pg.PlotCurveItem):
# self._last_draw = time.time() # self._last_draw = time.time()
self._use_poly = use_polyline self._use_poly = use_polyline
self.poly = None self.poly = None
self._redraw: bool = False
# all history of curve is drawn in single px thickness # all history of curve is drawn in single px thickness
pen = pg.mkPen(hcolor(color)) pen = pg.mkPen(hcolor(color))
@ -203,8 +205,11 @@ class FastAppendCurve(pg.PlotCurveItem):
# by default we only pull data up to the last (current) index # by default we only pull data up to the last (current) index
x_out, y_out = x[:-1], y[:-1] x_out, y_out = x[:-1], y[:-1]
if self.path is None or prepend_length > 0: if (
self.path is None
or prepend_length > 0
or self._redraw
):
if self._use_poly: if self._use_poly:
self.poly = pg.functions.arrayToQPolygonF( self.poly = pg.functions.arrayToQPolygonF(
x_out, x_out,
@ -217,8 +222,19 @@ class FastAppendCurve(pg.PlotCurveItem):
y_out, y_out,
connect='all', connect='all',
finiteCheck=False, finiteCheck=False,
path=self.path,
) )
# reserve mem allocs see:
# - https://doc.qt.io/qt-5/qpainterpath.html#reserve
# - https://doc.qt.io/qt-5/qpainterpath.html#capacity
# - https://doc.qt.io/qt-5/qpainterpath.html#clear
# XXX: right now this is based on had hoc checks on a
# hidpi 3840x2160 4k monitor but we should optimize for
# the target display(s) on the sys.
self.path.reserve(int(500e3))
profiler('generate fresh path') profiler('generate fresh path')
self._redraw = False
# if self._step_mode: # if self._step_mode:
# self.path.closeSubpath() # self.path.closeSubpath()
@ -351,6 +367,28 @@ class FastAppendCurve(pg.PlotCurveItem):
# XXX: seems to be needed to avoid artifacts (see above). # XXX: seems to be needed to avoid artifacts (see above).
self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
def clear(self):
'''
Clear internal graphics making object ready for full re-draw.
'''
# NOTE: original code from ``pg.PlotCurveItem``
self.xData = None ## raw values
self.yData = None
self._renderSegmentList = None
# self.path = None
self.fillPath = None
self._fillPathList = None
self._mouseShape = None
self._mouseBounds = None
self._boundsCache = [None, None]
#del self.xData, self.yData, self.xDisp, self.yDisp, self.path
# path reservation aware non-mem de-alloc cleaning
if self.path:
self.path.clear()
self._redraw = True
def disable_cache(self) -> None: def disable_cache(self) -> None:
''' '''
Disable the use of the pixel coordinate cache and trigger a geo event. Disable the use of the pixel coordinate cache and trigger a geo event.