linebender / linebender/druid

druid::PaintCtx::capture_image_area fails in macOS

Open
#2,245 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug piet
Dominant language
Rust
Stars
9.7k
Forks
565
PR merge metrics
No merged PRs in 30d

Description

TLDR: The surface type of the graphics context you end up with inside druid is different from what's used in piet's test cases, so functions that work fine in standalone piet do not work in druid when you're using the provided `PaintCtx`. This is the case for `capture_image_area` under `piet-coregraphics`.

There is a very similar issue with Windows under `piet-direct2d` (#2216), but the fix is simple enough (linebender/piet#526). With macOS it's considerably trickier: In `piet-coregraphics`, `capture_image_area` passes the active `CGContextRef` pointer to `CGBitmapContextCreateImage`. This works fine in the test case where the graphics context is a `CGBitmapContext`, but it does not work when `CGContextRef` points to a screen-type context. As far as I can tell there is no universal or appropriate alternate method to cache a region of a context -- the closest you get is this one for bitmap contexts. Even attempting to identify context types and respond accordingly is tricky, you can call `CGContextGetTypeID` on it to get a type id but unless I'm missing something major there's not a supported approach to mapping the returned id to any particular type of `CGContext`.

Unless there's a simple fix I'm completely missing (some sort of `NS*` magic, perhaps), the way forward could be a macOS-specific `ext` trait or `env` flag to give the option of caching all drawing in a `CGBitmapContext` rather than drawing directly to the `CGContextRef` we get from `NSGraphicsContext::currentContext`. Barring a better fix I'll submit a PR with this approach once I get the bugs worked out, but it'd be nice to have a cleaner solution than having to take a performance hit just to get this one function working.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in piet-coregraphics with capture_image_area and compare its CGBitmapContextCreateImage assumptions against the CGContextRef obtained through NSGraphicsContext::currentContext in druid. Investigate the available context types and platform APIs, then define and validate a macOS approach that captures an area reliably without leaving the existing drawing path unusable.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
computer-graphics, desktop
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.