Skip to content

anyrender_skia: add opt-in Skia Graphite backend for Metal (macOS/iOS) - #103

Open
nicoburns wants to merge 2 commits into
mainfrom
devin/1790696745-skia-graphite-metal
Open

nicoburns wants to merge 2 commits into
mainfrom
devin/1790696745-skia-graphite-metal

Conversation

@nicoburns

@nicoburns nicoburns commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds an opt-in Skia Graphite backend to SkiaWindowRenderer on macOS/iOS (Metal). Ganesh stays the default everywhere, and Linux/Windows are unchanged (Ganesh via OpenGL).

# Graphite on Apple; Ganesh + GL elsewhere. Uses prebuilt Skia binaries on all platforms.
anyrender_skia = { version = "0.11", default-features = false, features = ["graphite"] }

Cargo features

  • New ganesh (default) and graphite features.
  • gl is now only enabled on non-Apple targets. The Metal backend never used it, and dropping it lets Apple builds match the published ganesh-…-metal-pdf / graphite-…-metal-pdf prebuilt binaries.
  • graphite = ["dep:skia-safe"] activates an optional, Apple-only skia-safe entry that has the graphite feature. So on Linux/Windows (including CI's --all-features) graphite doesn't touch the Skia build.
  • ganesh/vulkan use the weak skia-safe?/… syntax. Without it, skia-safe/ganesh would also activate that optional Graphite entry.
  • rust-skia has no prebuilt binary with both Ganesh and Graphite. Enabling both still works, but Skia builds from source; in that case Graphite is used.

Resolved skia-bindings features, from cargo tree -e features:

target default --no-default-features --features graphite --all-features
linux ganesh gl pdf ganesh gl pdf ganesh gl pdf vulkan
windows ganesh gl pdf textlayout ganesh gl pdf textlayout + vulkan
macos/ios ganesh metal pdf graphite metal pdf ganesh graphite metal pdf vulkan (source build)

Code

  • metal.rs → metal/{ganesh,graphite}.rs. The CAMetalLayer setup is shared in metal::create_metal_layer.
  • MetalGraphiteBackend on each frame:
    • prepare: wraps the drawable's texture via graphite::mtl::backend_textures::make_metal and graphite::surfaces::wrap_backend_texture.
    • flush: recorder.snap() → context.insert_recording → context.submit, then presents on the same MTLCommandQueue.
  • Graphite's default ImageProvider drops raster images: they aren't drawn, and Skia logs Couldn't convert SkImage to a Graphite-backed representation. skia-safe doesn't expose custom image providers, so:
    • SkiaScenePainter gets an optional &mut graphite::Recorder. The window renderer gets it from the new SkiaBackend::recorder().
    • Image brushes are uploaded with graphite::images::texture_from_image before the image shader is built. The result goes into the existing image_shader cache.
    • shader_from_image_brush is split into image_from_image_data + shader_from_image for this.
  • New public SkiaScenePainter::new_graphite(canvas, cache, recorder) for painting into your own Graphite surfaces, e.g. offscreen. It's used by the Blitz benchmark in [Testing] anyrender_skia Graphite backend (anyrender#103) + skia_paint_bench blitz#983.

Known gaps

  • Uploaded textures have no mipmaps: skia-safe's texture_from_image doesn't take RequiredProperties. With ImageQuality::Medium/High, Skia falls back to linear, non-mipmapped sampling for these images.
  • Vulkan Graphite (Linux/Windows) isn't included. skia-safe has no binding to wrap a VkImage as a Graphite BackendTexture.

Performance

Testing (macOS arm64)

  • bunnymark release builds with each engine; both render correctly. Blitz rdme also renders correctly on Graphite (see blitz#983). Graphite logged no warnings.
  • cargo clippy -D warnings for the workspace (default features) and for anyrender_skia with --no-default-features --features graphite (with and without pixels_window_renderer). cargo doc with Graphite.

Graphite (1000 bunnies):
bunnymark on Graphite

Ganesh (default, 500 bunnies), for comparison:
bunnymark on Ganesh

Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/7b8d8492640e46d08ea6cd8b5ab63dbb
Open in Devin Desktop: https://dioxus.staging.devinenterprise.com/desktop/session/7b8d8492640e46d08ea6cd8b5ab63dbb?variant=devin-insiders
Requested by: @nicoburns

@staging-devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access that start with 'Devin'.

  • Disable automatic comment, CI, and merge conflict monitoring

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant