Skip to content

WIP. Expand DrawingBackend API and Canvas.#377

Draft
JimBobSquarePants wants to merge 80 commits intomainfrom
js/canvas-api
Draft

WIP. Expand DrawingBackend API and Canvas.#377
JimBobSquarePants wants to merge 80 commits intomainfrom
js/canvas-api

Conversation

@JimBobSquarePants
Copy link
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following matches the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

WIP - Still lots of normalization and testing to do!

This PR expand on the backend drawing API and drawing canvas to normalize usage throughout the library and to better allow custom backends both CPU and GPU.

There's an experimental WebGPU backend in the repo but it's nowhere near production ready so serves simply as a dogfooding tool for the API design. Our new CPU backend is more than fast enough for most usage.

@JimBobSquarePants
Copy link
Member Author

I want to take a look at this, but it looks massive so the earliest time I can really get to it is around next weekend.

Before jumping into the code there is an important general question however: how would describe typical use-cases for this feature?

There are two that come into my mind; if you are envisioning the same ones, how do you weight their importance? (1) Is it more about GPU accelerated offscreen rendering for services? (2) Or is this new API more for desktop (and maybe mobile and WASM) apps to be used for drawing?

Thanks, mate.

I see these as a complete re-envisioning of the library and how it should work with both those targets in mind. There are MAJOR breaking changes*.

The new API can support both scenarios but the WebGPU IDrawingBackend implementation is purely experimental and currently only exists to validate my design (as you recommended) - it works but would take someone who really knows what they are doing in that space to make it perform as well as I'm sure it could. (That said it's not slow!!)

So, in short: Target 2, then 1.

I'm changing the entire shape of the library to focus around the new DrawingCanvas<TPixel> type which can operate separately from Image<TPixel> and with it via a new extension method ProcessWithCanvas.

The canvas is designed based on the best features of both System.Drawing Graphics and Skia SkGraphics implementations and provides all the methods and state management that users should require. It's IMO a joy to use and far less confusing than the current API. It's also really fast!

*I'm confident that these changes are both necessary and beneficial. This moves the library square into the expectations bracket for users.

@codecov
Copy link

codecov bot commented Mar 4, 2026

Codecov Report

❌ Patch coverage is 17.76600% with 5897 lines in your changes missing coverage. Please review.
✅ Project coverage is 39%. Comparing base (e7aa1b6) to head (2ec6284).

Files with missing lines Patch % Lines
.../ImageSharp.Drawing.WebGPU/WebGPUDrawingBackend.cs 0% 1448 Missing ⚠️
....WebGPU/WebGPUDrawingBackend.CoverageRasterizer.cs 0% 1108 Missing ⚠️
...rc/ImageSharp.Drawing.WebGPU/WebGPUFlushContext.cs 0% 970 Missing ⚠️
...bGPU/Shaders/PreparedCompositeFineComputeShader.cs 0% 393 Missing ⚠️
...p.Drawing.WebGPU/Shaders/PathCountComputeShader.cs 0% 244 Missing ⚠️
...Drawing.WebGPU/WebGPUTestNativeSurfaceAllocator.cs 0% 206 Missing ⚠️
....Drawing.WebGPU/Shaders/PathTilingComputeShader.cs 0% 201 Missing ⚠️
...U/Shaders/PreparedCompositeBinningComputeShader.cs 0% 159 Missing ⚠️
...rawing.WebGPU/Shaders/CoverageFineComputeShader.cs 0% 141 Missing ⚠️
...rp.Drawing.WebGPU/WebGPUDrawingBackend.Readback.cs 0% 116 Missing ⚠️
... and 26 more
Additional details and impacted files
@@          Coverage Diff           @@
##           main    #377     +/-   ##
======================================
- Coverage    84%     39%    -46%     
======================================
  Files       101     112     +11     
  Lines      4529   10793   +6264     
  Branches    654    1095    +441     
======================================
+ Hits       3849    4285    +436     
- Misses      540    6337   +5797     
- Partials    140     171     +31     
Flag Coverage Δ
unittests 39% <17%> (-46%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@antonfirsov
Copy link
Member

antonfirsov commented Mar 4, 2026

Target 2, then 1.

This means that it would be of key importance to validate the API with a simple GUI app that truly challenges the rendering engine! I just made this thing with Claude*. We need an equivalent C# app. It can of course do something else (as long as it does mass text rendering!), but we need to make sure we have an HTML5 reference app, and that its' functionality is kept in sync with our C# app's, so we can compare them.

the WebGPU IDrawingBackend implementation is purely experimental

We don't need it to be production ready, but if we find performance bottlenecks, we should identify where is the root cause: suboptimal backend implementation VS the API shape VS our library code.

I can chime in into this work later, but not right now.

*disclaimer: didn't spend time on deslopification

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.

2 participants