-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Speed up Tkagg blit with Tk_PhotoPutBlock #20840
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
Speed up Tkagg blit with Tk_PhotoPutBlock #20840
Conversation
Also release GIL Currently, drawing an equivalence between blank and TK_PHOTO_COMPOSITE_SET which may not be entirely accurate
Based on tcltk/tk@8abf694 this seems backcompatible to as far back as tk 8.4.0 (2002)? Or did I miss something? It's not clear why this was changed in #6442.
8.4.0 seems certainly old enough that we can require it, although a doc note may be good (I can't find any mention in the cpython docs stating that it cannot be built against tk 8.3, although that may be a bit academic).
At least you'll need to simimarly adjust the call to |
I based 8.5 on a fuzzy reading of the docs, if it's there in 8.4, then it's even less of an issue
If you can point me to roughly the right file in the docs, I'm happy to make a change. Probably a
The call signature of |
There's a list in doc/devel/dependencies.rst; an api_changes entry seems safe too.
Yes, that's a bit confusing. It's all private anyways, so they can be changed at will. Looks like tkcairo works fine with this (well, possibly modulo some preexisting compositing issues, but they are not introduced by the changes here). |
I don't really know, but it does seem that successfully always predicting |
Looking at repology, I don't see anything that ships <8.4, so it's probably quite fine to bump to it. |
Suggest squash merge |
PR Summary
This PR releases the GIL while blitting, and chooses a slightly different but sometimes faster function to actually perform the blit.
In my usage, blitting can often be over 100 ms, which is a long time to hold the GIL... especially while not using the Python C API. I verified the safety of releasing the GIL back in 2ad422a but for some reason I took it back out when thread-based parallelism didn't work out. (#18565)
_tkagg.blit
has been backed byTk_PhotoPutBlock_NoComposite
since #6442. This interface is deprecated, and on Tk 8.5 and laterTk_PhotoPutBlock
gives the option to composite or not as a function argument, avoiding the need for an extra blanking step and permitting a fast path when the data are properly aligned, which seems to be the case on TkAgg. My profiling shows that the time spent specifically in_tkagg.blit
drops by a factor of 2 to 10 (!?) in the naive use case of callingfig.canvas.draw()
. However,FigureCanvasAgg.draw
is the main time sink in either case, so the FPS gains are limited, and for large canvases blitting still takes enough time to make dropping the GIL worthwhile. Nevertheless, I get a practical responsivity boost in a downstream application (100 ms -> 10 ms blit latency) so I think it is worth sharing.If anyone can tell me why this speedup is only visible when
Figure.get_frameon()==True
, I will sleep much better at night. It would seem to have to do with the abundance or paucity of transparent pixels in thePhotoImage
, but the Tk source doesn't inspect that directly. Could it boil down to CPU branch prediction?This change is backwards-incompatible with Tk < 8.5. I don't think that affects Python 3 or Matplotlib 3 users, but I would like confirmation. Also I would like someone to check if this change is problematic in the TkCairo backend
PR Checklist
Has pytest style unit tests(andpytest
passes).flake8
on changed files to check).[ ] New features are documented, with examples if plot related.[x] Documentation is sphinx and numpydoc compliant (the docs should build without error).[ ] Conforms to Matplotlib style conventions (installflake8-docstrings
and runflake8 --docstring-convention=all
).[ ] New features have an entry indoc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).