The pool was previously used by both NewImage and SubImage, but only
the sub-image churn case benefits from pooling. Any image could be
recycled, including originals — a documented footgun.
Add RecyclableSubImage that explicitly creates pooled sub-images, and
restrict Recycle to only work on images created by RecyclableSubImage.
Closes#3423
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a global sync.Pool (theImagePool) for *Image structs so that both
NewImage and SubImage can reuse allocations instead of always calling new.
Add Image.Recycle to return a struct to the pool when the caller is done
with it. After Recycle is called the image must not be used; the behavior
is undefined.
Closes#3418
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add a global sync.Pool (theImagePool) for *Image structs so that both
NewImage and SubImage can reuse allocations instead of always calling new.
Add Image.Recycle to return a struct to the pool when the caller is done
with it. After Recycle is called the image must not be used; the behavior
is undefined.
Closes#3418
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Create a new internal/colormshader package that owns the color matrix
shader generation, fully independent of internal/builtinshader. It has
its own shader template with ColorM logic baked in, its own
Filter/Address types, and a go:generate pipeline producing defs.go.
This removes the useColorM dimension from internal/builtinshader,
reducing it from 18 shader variants to 9. The colorm package now
imports only colormshader (not builtinshader) for shader sources,
preparing for the v2/v3 split where v2's colorm cannot access v3's
builtinshader.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create a new internal/colormshader package that owns the color matrix
shader generation, fully independent of internal/builtinshader. It has
its own shader template with ColorM logic baked in, its own
Filter/Address types, and a go:generate pipeline producing defs.go.
This removes the useColorM dimension from internal/builtinshader,
reducing it from 18 shader variants to 9. The colorm package now
imports only colormshader (not builtinshader) for shader sources,
preparing for the v2/v3 split where v2's colorm cannot access v3's
builtinshader.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The new implementation uses Evan's method [1] using texture representing
a stencil buffer instead of the graphics library's stencil buffer.
This simplifies the implementaiton of the graphics drivers, and enables
better anti-alias without changing the rendering cost.
Also, this fixes an issue of line rendering quality
This change deprecates some existing APIs like DrawImageOptions.AntiAlias
and FillRule. Users should always use DrawFilledPath or StrokePath.
[1] https://medium.com/@evanwallace/easy-scalable-text-rendering-on-the-gpu-c3f4d782c5acCloses#3124Closes#3153
The race condition could happen even if you follow the rule that
one image is touched from one goroutine. This change fixed the issue
by a mutex.
Closes#3267
Mipmaps could be unexpectedly expensive even when we don't need mipmaps.
In order to improve performance, let's add an option to disable mipmaps.
Closes#3095