Skip to content

Commit 3239307

Browse files
Add WebGPU shader effects and native API refactor
Introduces a full WebGPU shader-effect pipeline (custom WGSL programs, uniforms/layouts, pass sequencing, diagnostics, compilation errors, precompile support, and CPU fallbacks) plus new built-in WebGPU layer/backdrop effects (blur, color matrix, drop shadow, glow, inner shadow, acrylic). Refactors backend/runtime internals to explicit WGPU native types, adds native library resolution, error-scope callbacks, effect pipeline caching, pooled textures/buffers, and ordered-scene shader-effect execution support. Updates WebGPU samples to a shared surface session architecture with scene-owned views, adds a new custom shader demo scene, refreshes window demo rich text rendering, and expands tests/reference outputs including shader source validation coverage.
1 parent 2b361b7 commit 3239307

155 files changed

Lines changed: 9238 additions & 2708 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# GitHub Copilot Instructions
2+
3+
Read and follow [AGENTS.md](../AGENTS.md) as the repository-wide source of coding, performance, and verification requirements. Prefer existing local patterns and repository configuration whenever generated code or suggestions are accepted.

AGENTS.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Six Labors AI Coding Guidelines
2+
3+
These instructions apply to the entire repository. More-specific `AGENTS.md` files may add to or override them for their directory tree.
4+
5+
## Working Practices
6+
7+
- Inspect the relevant implementation, tests, benchmarks, project files, and nearby code before proposing or making changes. Do not infer current behavior when the source is available.
8+
- Make the smallest complete change that solves the requested problem. Avoid unrelated cleanup, speculative abstractions, and formatting churn.
9+
- Match established architecture, naming, formatting, documentation, and test patterns. Treat `.editorconfig`, analyzers, and repository build settings as authoritative.
10+
- Preserve public API and observable behavior unless the task explicitly requires a change. Public API documentation must describe observable behavior, not implementation details.
11+
- Do not use reflection against built assemblies, ad hoc assembly loading, or temporary probe projects unless explicitly requested.
12+
- Build .NET projects in Release configuration unless explicitly instructed otherwise.
13+
14+
## Performance
15+
16+
- Treat throughput, latency, memory use, and binary size as design constraints, especially in pixel-processing, drawing, parsing, encoding, and other hot paths.
17+
- Avoid unnecessary allocations, copies, boxing, closures, interface dispatch, repeated enumeration, and extra passes over data.
18+
- Reuse the repository's existing memory ownership, pooling, span, vectorization, and parallelization patterns. Do not introduce a new mechanism when an established one fits.
19+
- Keep hot loops simple and bounds-check-friendly. Hoist invariant work, preserve locality, and use the narrowest suitable data types without sacrificing correctness.
20+
- Do not trade correctness or maintainability for assumed speed. Support non-obvious optimizations with measurements or clear evidence, and add or update benchmarks when performance is the purpose of the change.
21+
- Consider all supported target frameworks and runtime capabilities. Do not regress fallback paths while optimizing newer runtimes.
22+
23+
## C# Conventions
24+
25+
- Follow the existing code around the change; local patterns take precedence over generic preferences.
26+
- Do not use `record` or `record struct` types.
27+
- Prefer established invariants over redundant guards. Validate at real external boundaries and do not add defensive checks for internally controlled states.
28+
- Do not extract single-use helpers merely to name a block. Extract only for genuine reuse, an established local pattern, or meaningful complexity reduction.
29+
- Add vertical whitespace after multi-line statements and declarations and between distinct logical stages. Never add trailing whitespace.
30+
- Document every method, constructor, and property, regardless of whether it is public, internal, protected, or private. Keep public API documentation limited to observable behavior; use private and internal documentation to capture the contract and intent needed to maintain the code.
31+
- Add inline comments throughout complex code. Explain algorithms, formulas, invariants, ownership, compatibility behavior, and performance tradeoffs at the operations and decisions they govern. Explain why the code is shaped that way rather than narrating the syntax.
32+
- Document SIMD code especially thoroughly. Explain the vector layout, lane meaning, widening or narrowing, masks, shuffles, constants, alignment or remainder handling, supported instruction paths, scalar equivalence, and the reason each non-obvious operation is correct.
33+
- Write algorithm and SIMD comments for a maintainer who is unfamiliar with the implementation. The reader should not need to reconstruct intent from external documentation, issue history, or benchmark results.
34+
35+
## Verification
36+
37+
- Add or update focused tests when behavior changes, following the test framework and conventions already used by the project.
38+
- Never hack, weaken, skip, conditionally bypass, or otherwise manipulate a test to make it pass. Fix the production defect or the genuine test defect while preserving the test's intended coverage and sensitivity.
39+
- Do not update golden files, reference images, snapshots, baselines, or expected-output artifacts to resolve a test failure. Treat a mismatch as evidence to investigate and correct the implementation.
40+
- Run the narrowest relevant formatting, test, and Release build commands, then expand verification in proportion to the risk and scope of the change.
41+
- Report what changed, the verification performed, and any remaining risks or unverified assumptions.

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Claude Code Instructions
2+
3+
Read and follow [AGENTS.md](AGENTS.md) as the repository-wide source of coding, performance, and verification requirements. Apply any more-specific `AGENTS.md` or `CLAUDE.md` found below the files being changed.

GEMINI.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Gemini CLI Instructions
2+
3+
Read and follow [AGENTS.md](AGENTS.md) as the repository-wide source of coding, performance, and verification requirements. Apply any more-specific `AGENTS.md` or `GEMINI.md` found below the files being changed.

samples/WebGPUExternalSurfaceDemo/Controls/WebGPURenderControl.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ public sealed partial class WebGPURenderControl : Control
1717
{
1818
private const int WM_MOVING = 0x0216;
1919
private const int WM_EXITSIZEMOVE = 0x0232;
20+
private static readonly nint ProcessModuleHandle = GetModuleHandle(null);
2021

22+
private readonly WebGPUSurfaceSession surfaceSession;
2123
private WebGPUExternalSurface? surface;
2224
private Size framebufferSize;
2325
private bool idleHooked;
@@ -29,8 +31,11 @@ public sealed partial class WebGPURenderControl : Control
2931
/// <summary>
3032
/// Initializes a new instance of the <see cref="WebGPURenderControl"/> class.
3133
/// </summary>
32-
public WebGPURenderControl()
34+
/// <param name="surfaceSession">The session shared by the application's related presentation surfaces.</param>
35+
public WebGPURenderControl(WebGPUSurfaceSession surfaceSession)
3336
{
37+
this.surfaceSession = surfaceSession;
38+
3439
// WebGPU presents directly to the native surface. Normal WinForms buffering and background
3540
// painting would add flicker or unnecessary work, so the control opts into direct user painting.
3641
this.SetStyle(
@@ -81,12 +86,12 @@ protected override void OnHandleCreated(EventArgs e)
8186
Math.Max(this.framebufferSize.Width, 1),
8287
Math.Max(this.framebufferSize.Height, 1));
8388

84-
// The module handle is required by the Win32 surface descriptor. It identifies the process module
85-
// that owns the window class backing this control.
86-
this.surface = new WebGPUExternalSurface(
89+
// WinForms registers its window classes against the process executable module. Use that same
90+
// HINSTANCE in the WebGPU descriptor instead of the managed assembly's module handle.
91+
this.surface = this.surfaceSession.CreateSurface(
8792
WebGPUSurfaceHost.Win32(
8893
this.Handle,
89-
Marshal.GetHINSTANCE(typeof(WebGPURenderControl).Module)),
94+
ProcessModuleHandle),
9095
initialFramebufferSize,
9196
new WebGPUExternalSurfaceOptions
9297
{
@@ -322,5 +327,8 @@ private struct NativeMessage
322327
[LibraryImport("user32.dll", EntryPoint = "PeekMessageW")]
323328
private static partial int PeekMessage(out NativeMessage msg, nint hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);
324329

330+
[LibraryImport("kernel32.dll", EntryPoint = "GetModuleHandleW", StringMarshalling = StringMarshalling.Utf16)]
331+
private static partial nint GetModuleHandle(string? moduleName);
332+
325333
private static bool IsApplicationIdle() => PeekMessage(out _, 0, 0, 0, 0) == 0;
326334
}

0 commit comments

Comments
 (0)