8000 Drop caching of drawn state (bad interaction with layout="constrained"). · matplotlib/mplcairo@8c63f65 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8c63f65

Browse files
committed
Drop caching of drawn state (bad interaction with layout="constrained").
1 parent 3280f39 commit 8c63f65

File tree

5 files changed

+27
-64
lines changed

5 files changed

+27
-64
lines changed

lib/mplcairo/base.py

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ class GraphicsContextRendererCairo(
5757
GraphicsContextBase,
5858
RendererBase):
5959

60-
_draw_previously_disabled = False
61-
6260
def __init__(self, width, height, dpi):
6361
# Hide the overloaded constructors used by from_pycairo_ctx and
6462
# _for_fmt_output.
@@ -131,20 +129,6 @@ def _finish():
131129
obj._finish = _finish
132130
return obj
133131

134-
@contextlib.contextmanager
135-
def _draw_disabled(self):
136-
# After a disabled draw, mark the renderer as such so that later
137-
# fetches in _get_cached_or_new_renderer force a redraw (otherwise,
138-
# we can get a blank canvas after interactively saving a CL figure).
139-
# But that redraw is not needed if the fetch is happening in a (later)
140-
# _draw_disabled context, so we clear the flag at entry.
141-
try:
142-
self._draw_previously_disabled = False
143-
with super()._draw_disabled():
144-
yield
145-
finally:
146-
self._draw_previously_disabled = True
147-
148132
def option_image_nocomposite(self):
149133
return (not mpl.rcParams["image.composite_image"]
150134
if self._has_vector_surface() else True)
@@ -226,50 +210,33 @@ def __init__(self, *args, **kwargs):
226210
device_pixel_ratio = property(
227211
lambda self: getattr(self, "_dpi_ratio", 1))
228212

229-
def _get_cached_or_new_renderer(
230-
self, func, *args,
231-
_ensure_cleared=False, _ensure_drawn=False,
232-
**kwargs):
213+
# NOTE: Needed for tight_layout() (and we use it too).
214+
def get_renderer(self, cleared=False):
215+
args = (*self.figure.bbox.size, self.figure.dpi)
233216
last_call, last_renderer = self._last_renderer_call
234-
if (func, args, kwargs) == last_call:
235-
if last_renderer._draw_previously_disabled:
236-
_ensure_cleared = _ensure_drawn = True
237-
if _ensure_cleared:
238-
# This API is present (rather than just throwing away the
239-
# renderer and creating a new one) so to avoid invalidating the
240-
# Text._get_layout cache.
241-
last_renderer.clear()
242-
if _ensure_drawn:
243-
with _LOCK:
244-
self.figure.draw(last_renderer)
245-
last_renderer._draw_previously_disabled = False
246-
return last_renderer
217+
if args == last_call:
218+
renderer = last_renderer
247219
else:
248-
renderer = func(*args, **kwargs)
249-
self._last_renderer_call = (func, args, kwargs), renderer
250-
if _ensure_drawn:
251-
with _LOCK:
252-
self.figure.draw(renderer)
253-
return renderer
254-
255-
# NOTE: Needed for tight_layout() (and we use it too).
256-
def get_renderer(self, cleared=False, *, _ensure_drawn=False):
257-
return self._get_cached_or_new_renderer(
258-
GraphicsContextRendererCairo,
259-
*self.figure.bbox.size, self.figure.dpi,
260-
_ensure_cleared=cleared, _ensure_drawn=_ensure_drawn)
220+
renderer = GraphicsContextRendererCairo(*args)
221+
self._last_renderer_call = args, renderer
222+
if cleared: # matplotlib#22245 (<3.6).
223+
renderer.clear()
224+
return renderer
261225

262226
renderer = property(get_renderer) # NOTE: Needed for FigureCanvasAgg.
263227

264228
def draw(self):
265-
self.get_renderer(cleared=True, _ensure_drawn=True)
229+
renderer = self.get_renderer()
230+
renderer.clear()
231+
with _LOCK:
232+
self.figure.draw(renderer)
266233
super().draw()
267234

268235
def buffer_rgba(self): # NOTE: Needed for tests.
269-
return self.get_renderer(_ensure_drawn=True).buffer_rgba()
236+
return self.get_renderer().buffer_rgba()
270237

271238
def copy_from_bbox(self, bbox):
272-
return self.get_renderer(_ensure_drawn=True).copy_from_bbox(bbox)
239+
return self.get_renderer().copy_from_bbox(bbox)
273240

274241
def restore_region(self, region):
275242
with _LOCK:
@@ -369,13 +336,10 @@ def _print_ps_impl(self, is_eps, path_or_stream, *,
369336
print_eps = partialmethod(_print_ps_impl, True)
370337

371338
def _get_fresh_straight_rgba8888(self):
372-
# Swap out the cache, as savefig may be playing with the background
373-
# color.
374-
last_renderer_call = self._last_renderer_call
375-
self._last_renderer_call = (None, None)
339+
renderer = self.get_renderer()
340+
renderer.clear()
376341
with _LOCK:
377-
renderer = self.get_renderer(_ensure_drawn=True)
378-
self._last_renderer_call = last_renderer_call
342+
self.figure.draw(renderer)
379343
return _util.cairo_to_straight_rgba8888(renderer._get_buffer())
380344

381345
def print_rgba(self, path_or_stream, *,

lib/mplcairo/gtk.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ def on_draw_event(self, widget, ctx):
1717
_mpl_gtk.Gtk.render_background(
1818
self.get_style_context(), ctx,
1919
allocation.x, allocation.y, allocation.width, allocation.height)
20-
surface = \
21-
self.get_renderer(_ensure_drawn=True)._get_context().get_target()
20+
surface = self.get_renderer()._get_context().get_target()
2221
surface.flush()
2322
scale = self.device_pixel_ratio
2423
prev_scale = surface.get_device_scale()

lib/mplcairo/gtk_native.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ def on_draw_event(self, widget, ctx):
2727
# The context surface size may not match the figure size (it can
2828
# include e.g. toolbars) or may not even be known (on Gtk4, which uses
2929
# a RecordingSurface).
30-
renderer = self._get_cached_or_new_renderer(
31-
GraphicsContextRendererCairo.from_pycairo_ctx,
30+
renderer = GraphicsContextRendererCairo.from_pycairo_ctx(
3231
ctx, figure.bbox.width, figure.bbox.height, figure.dpi, prev_scale)
3332
figure.draw(renderer)
3433
surface.set_device_scale(*prev_scale)

lib/mplcairo/macosx.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66

77
class FigureCanvasMacCairo(FigureCanvasCairo, FigureCanvasMac):
88

9-
# A bit hackish, but that's what _macosx.FigureCanvas wants...
109
def _draw(self):
11-
if self.figure.stale:
12-
self._last_renderer_call = None, None
10+
renderer = self.get_renderer()
11+
renderer.clear()
12+
self.figure.draw(renderer)
13+
# A bit hackish, but that's what _macosx.FigureCanvas wants...
1314
self._renderer = _util.cairo_to_straight_rgba8888(
14-
self.get_renderer(_ensure_drawn=True)._get_buffer())
15+
renderer._get_buffer())
1516
return self
1617

1718

lib/mplcairo/qt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def paintEvent(self, event):
2020
# additional copy of the buffer into a contiguous block, so it's not
2121
# clear it would be faster).
2222
buf = _util.cairo_to_premultiplied_argb32(
23-
self.get_renderer(_ensure_drawn=True)._get_buffer())
23+
self.get_renderer()._get_buffer())
2424
height, width, _ = buf.shape
2525
# The image buffer is not necessarily contiguous, but the padding
2626
# in the ARGB32 case (each scanline is 32-bit aligned) happens to

0 commit comments

Comments
 (0)
0