Skip to content

[MNT]: macOS backend likely double-draws renderer output #31875

Open

Description

@iccir

Summary

Right now, -[View drawRect:] does the following:

  1. Acquires the GIL.
  2. Calls get_renderer() to get the agg renderer
  3. Calls buffer_rgba() to get a memoryview of the buffer.
  4. Performs a malloc() and copies the contents to the new buffer.
  5. Wraps in CGDataProviderRef, then CGImageRef
  6. Draws into the View's buffer via CGContextDrawImage()
  7. View's buffer is then composited to the window's buffer.
  8. Releases the GIL.

We can probably merge Step 6 / Step 7 by using a layer-backed view and setting CALayer.contents directly. There may be more optimizations here as well, if we can directly "push" a buffer to the view rather than relying on the -drawRect: call during the render cycle.

In either case, the rubberband would need to be a separate layer or view (non-opaque).

Proposed fix

No response

Activity

  1. iccir commented on Jun 27, 2026

    @iccir
    ContributorAuthor

    Fixed in my macosx-rework branch but requires more testing.

    Moving away from -drawRect: and setting the CALayer.contents directly is a huge win - I'm no longer seeing flickering when updating figures or resizing the window. I was also able to remove an additional draw by changing the NSWindow's color space to match the layer-hosted view.

    Previously, 50% of the draw cycle was Agg and the other 50% was CoreGraphic DrawImages. This is now at 80% in Agg and only 20% in CG.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions