Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Audit the D2D paint pipeline for per-frame waste — allocations, recomputation, redundant API calls at 120-240fps
user-invocable
true
disable-model-invocation
true
Enter planning mode. Deep-audit the D2D paint pipeline for anything that wastes cycles per frame — from per-frame allocations to redundant D2D API calls. Use maximum parallelism — spawn explore agents for independent subsystems.
Context
The overlay renders at 120-240fps via Direct2D 1.1. At these frame rates, per-frame waste compounds fast: a 5μs allocation ×30/frame ×240fps = 36ms/s of pure garbage. The AHK runtime allocates objects on the heap — every Buffer(), Array(), Object(), and Map() lookup is a real cost.
This review covers the D2D rendering pipeline — from pre-render through BeginDraw to EndDraw, including the 8-layer compositor stack, effect chains, and resource management. It does NOT cover:
Shader compilation or D3D11 interop (use review-d3d for that)
Window data / store operations (use review-latency Path 1)
Post-#177 architecture note: The compositor is an 8-layer stack: DWM backdrop → background image → shader layers 1-N → background image (configurable order) → mouse effect → selection effect → hover effect → window list + text. Shader layers render to independent D3D11 intermediate textures, composited via with premultiplied alpha srcOver blending. PushLayer/PopLayer is eliminated for shader opacity (baked into HLSL via ). However, / is still used for BG-shader-as-selection clipping (rounded rect clip to selection row). The pre-render phase (, , ) runs D3D11 dispatches BEFORE — this is part of the paint-path cost even though it's outside the D2D draw calls.
DrawImage
AT_PostProcess
PushAxisAlignedClip
PopLayer
FX_PreRenderShaderLayers
FX_PreRenderMouseEffect
FX_PreRenderSelectionEffect
BeginDraw
What to Look For
1. Per-Frame Allocations (Highest Priority)
Any Buffer(), [] array literal, {} object literal, or Map() creation inside a function called every frame.
The fix pattern is established (from ahk-patterns.md):
; WRONG — allocates every call
MyHotFunc() {
buf := Buffer(72)
NumPut("float", x, buf, 0)
DllCall(..., "Ptr", buf, ...)
}
; CORRECT — static buffer, repopulated (ONLY if not reachable during STA pump)
MyHotFunc() {
static buf := Buffer(72)
NumPut("float", x, buf, 0)
DllCall(..., "Ptr", buf, ...)
}
Scan for: Buffer(, Array(, literal [, literal { inside any function reachable from the paint path.
Exceptions:
Buffers whose size varies per call cannot be made static. Flag them but note the constraint.
Buffers in functions reachable during STA pump reentrancy MUST NOT be static — COM calls (DrawText, DrawBitmap, FillRoundedRectangle, EndDraw, DwmFlush) pump the STA message loop and can re-enter the same function through timer/callback dispatch, corrupting the shared buffer. Critical "On" does NOT prevent this. See ahk-patterns.md Hot Path Resource Rules.
2. Redundant D2D API Calls
D2D operations that produce the same result every frame:
Setting the same effect property to the same value (e.g., blur radius that hasn't changed)
Creating/releasing resources that could be cached (brushes, geometries, layers)
SetTransform / GetTransform pairs that could be avoided
Effect chain SetInput / GetOutput calls that don't change between frames
3. Cacheable Computation
Values computed every frame that only change on config change, resize, or state transition:
Layout math (positions, rects) recomputed on every paint when overlay size hasn't changed
Color conversions (hex → ARGB) done per-frame instead of on config load
Gradient stop arrays rebuilt identically every frame
Shadow/glow parameters recomputed from config values that haven't changed
4. Map Lookup Overhead
gFX_GPU["effectName"] string-keyed Map lookups on the hot path. Each lookup hashes the string and walks the bucket. When the same key is accessed multiple times per frame, cache it in a local variable.
5. Unnecessary DrawImage / DrawBitmap Calls
Drawing layers with zero opacity (should early-exit)
Phase 5b eliminated PushLayer/PopLayer for shader opacity (now baked into HLSL premultiplied alpha). However, PushAxisAlignedClip + PopLayer is still used for BG-shader-as-selection and BG-shader-as-hover (clipping background shaders to the selection/hover row rounded rect). Check:
Can the clip be avoided when the shader already respects selRect bounds via cbuffer?
Are clips applied when the selection shader isn't using BG-as-selection mode (wasted clip/pop)?
Is clip setup per-frame even when selection hasn't moved?
7. Any other detected optimizations.
Files to Audit
Primary (called every frame):
src/gui/gui_paint.ahk — main paint orchestrator (_GUI_PaintOverlay)
src/shared/config_registry.ahk — which values feed into paint-path computations
Explore Strategy
Split by subsystem (run in parallel):
Paint orchestrator agent: gui_paint.ahk — trace _GUI_PaintOverlay from pre-render through BeginDraw to EndDraw. Map every function call, every Buffer allocation, every D2D API call. Include the pre-render phase (shader/mouse/selection pre-render calls happen before BeginDraw but are per-frame cost). Count per-frame frequency.
Effects agent: gui_effects.ahk — the 8-layer compositor. For each layer: pre-render cost, draw cost, allocations, recomputed invariants. Key functions: FX_PreRenderShaderLayers (loops N shader layers, calls Shader_PreRender each), FX_DrawShaderLayers (loops N layers, DrawImage each), FX_PreRenderMouseEffect (compute dispatch + adaptive FPS skip), FX_PreRenderSelectionEffect/FX_PreRenderHoverEffect (selection/hover shader dispatch), FX_DrawSelectionEffect/FX_DrawHoverEffect (clip + DrawImage), FX_DrawSoftRect (inner shadow chains). Note: mouse effect has QPC-based adaptive framerate skip — check if similar skip logic would benefit background shader layers.
query_function.ps1 <func> — extract function bodies without loading full files
query_interface.ps1 <file> — public API surface of paint path files
query_timers.ps1 — find animation/repaint timers and their frequencies
query_global_ownership.ps1 <global> — trace who writes paint-path globals
Assessment Format
Surface everything — do not auto-exclude findings based on estimated size. At 240fps, a 2μs saving ×240 = 480μs/s. That matters.
For each finding:
Finding
File:Lines
Per-Call Cost
Calls/Frame
Per-Frame Cost
Complexity
Fix
FX_LayerParams allocates 72B Buffer
gui_effects.ahk:123
~3μs
4
~12μs
One-line static
static buf := Buffer(72)
Columns:
Per-Call Cost: Estimated cost of one invocation (allocation + computation)
Calls/Frame: How many times this runs per frame (trace the paint path, don't guess)
Per-Frame Cost: Per-Call × Calls/Frame — the actual per-frame waste
Complexity: One-line, small refactor, medium refactor, architectural
Fix: Concrete fix description
Do not filter. A 1μs saving ×30/frame is 30μs/frame = 7.2ms/s at 240fps. List everything, ordered by per-frame cost (highest first).
Validation
After explore agents report back, validate every finding yourself:
Trace the call path: Confirm the function is actually called per-frame by tracing from _GUI_PaintOverlay → ... → the function. Don't flag init-time code as per-frame.
Check for existing optimization: This codebase has been through optimization passes. Some functions already use static buffers, cached brushes, or early-exits. Verify the waste still exists.
Verify mutability: Before suggesting static, confirm the buffer content actually changes between calls (otherwise it could be a one-time init). If content is frame-invariant, the fix might be "compute once, cache" rather than "static buffer."
Check AHK semantics: static in AHK v2 persists across calls to the same function. Critical "On" prevents timer/hotkey interruption but does NOT prevent STA pump reentrancy — any D2D/COM draw call can dispatch callbacks that re-enter the same function, corrupting the static buffer. Only use static when the buffer is fully consumed before any COM/D2D call, or when the function is provably unreachable from STA pump paths.
Preserve Float() on GPU buffers: Never remove Float() wrappers from NumPut("float", ...) calls that feed D2D/D3D geometry buffers (rects, points, ellipses, viewports). These ensure IEEE 754 bit patterns — AHK v2 integer-to-float coercion in NumPut is not guaranteed safe. Removing them is not an optimization.
Distinguish from shader path: If a finding is in d2d_shader.ahk and relates to D3D11 operations (texture creation, SRV binding, shader dispatch), it's out of scope. Only flag the D2D-side draw call.
Plan Format
Section 1 — Per-Frame Allocations:
Finding
File:Lines
Per-Call Cost
Calls/Frame
Per-Frame Cost
Complexity
Fix
Section 2 — Redundant D2D API Calls:
Finding
File:Lines
Per-Call Cost
Calls/Frame
Per-Frame Cost
Complexity
Fix
Section 3 — Cacheable Computation:
Finding
File:Lines
Per-Call Cost
Calls/Frame
Per-Frame Cost
Complexity
Fix
Section 4 — Map Lookups & Misc:
Finding
File:Lines
Per-Call Cost
Calls/Frame
Per-Frame Cost
Complexity
Fix
Order within each section by per-frame cost (highest first).