Skip to content

Let QPaintEvent tell us what region to repaint. #8951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 20, 2018

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Jul 28, 2017

(instead of just updating the blitboxes.)

Alternate approach for #8948.
attn @tacaswell

As for the performance questions, my work on mpl_cairo suggests to me that a big cost actually comes from the fact that we are copying the whole buffer into a string (https://github.com/matplotlib/matplotlib/blob/master/src/_backend_agg_wrapper.cpp#L586 before my recent changes, https://github.com/matplotlib/matplotlib/blob/master/src/_backend_agg_wrapper.cpp#L79 now that we always rely on Regions). Note that the old Py2 version used to create a buffer object, which would avoid the need for copying.
In mpl_cairo, I instead return a numpy array which is a view on the internal buffer (https://github.com/anntzer/mpl_cairo/blob/master/src/_mpl_cairo.cpp#L260) and pass the address of the pointer (which can be retrieve via numpy) into QImage (https://github.com/anntzer/mpl_cairo/blob/master/mpl_cairo/qt.py#L15). (To be clear, I haven't tried with agg, but on mpl_cairo this is much faster than copying the string around.)
This approach also removes the need for a refcount hack on PySide, as there is no buffer object for PySide to hold on anymore.

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code is PEP 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/whats_new.rst if major new feature
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

bbox_queue = [
Bbox([[0, 0], [self.renderer.width, self.renderer.height]])]
self._bbox_queue = []

self._bbox_queue = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need this any more

self._bbox_queue = []
for bbox in bbox_queue:
if bbox is None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any of them are None can short circuit the whole thing and just copy once.

@tacaswell tacaswell added this to the 2.1 (next point release) milestone Jul 28, 2017
@anntzer anntzer changed the title Qt: On draw(), request a full repaint. Let QPaintEvent tell us what region to repaint. Jul 28, 2017
@anntzer
Copy link
Contributor Author

anntzer commented Jul 28, 2017

Actually I just rewrote the entire thing to use QPaintEvent.rect() (the idea you mentioned in #7366), which is much simpler.

@anntzer anntzer force-pushed the qtagg-blitting branch 2 times, most recently from 7290244 to 98d5753 Compare July 28, 2017 18:58
@tacaswell
Copy link
Member

Does update eventually produce a paint event with the full canvas as the event?

@@ -134,7 +136,7 @@ def blit(self, bbox=None):
"""
# If bbox is None, blit the entire canvas. Otherwise
# blit only the area defined by the bbox.
if bbox is None and self.figure:
if bbox is None:
bbox = self.figure.bbox

self._bbox_queue.append(bbox)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might as well drop this line too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would technically be backwards incompatible (and the behavior is "mandated" by the docstring of FigureCanvasBase), but a quick grep suggests that we never rely on it (always explicitly passing in the figure bbox when needed) so I'm fine with getting rid of the behavior. You get to decide on the deprecation policy :-)

@anntzer
Copy link
Contributor Author

anntzer commented Jul 28, 2017

bbox_queue = [
Bbox([[0, 0], [self.renderer.width, self.renderer.height]])]
self._bbox_queue = []
for bbox in bbox_queue:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One concern is that Qt drops some paint events, but that would be surprising.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Qt pulls the rug under us, we're cooked anyways, no?

@anntzer
Copy link
Contributor Author

anntzer commented Aug 24, 2017

rebased

@tacaswell tacaswell modified the milestones: 2.1 (next point release), 2.2 (next next feature release) Sep 24, 2017
@anntzer anntzer modified the milestones: needs sorting, v3.0 Feb 15, 2018
@tacaswell tacaswell merged commit 4b1f956 into matplotlib:master Jul 20, 2018
@anntzer anntzer deleted the qtagg-blitting branch July 20, 2018 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants