render/software.go
Functions
func Capabilities
func (r *SoftwareRenderer) Capabilities() RendererCapabilities {
return RendererCapabilities{
IsGPU: false,
SupportsAntialiasing: true,
SupportsBlendModes: false, // TODO: implement
SupportsGradients: false, // TODO: implement
SupportsTextures: false, // TODO: implement
MaxTextureSize: 0, // No limit
}
}
func Flush
Flush ensures all rendering is complete.
For the software renderer, this is a no-op as operations are synchronous.
func (r *SoftwareRenderer) Flush() error {
return nil
}
func NewSoftwareRenderer
NewSoftwareRenderer creates a new CPU-based software renderer.
func NewSoftwareRenderer() *SoftwareRenderer {
return &SoftwareRenderer{
edgeBuilder: raster.NewEdgeBuilder(2), // 4x AA quality
}
}
func Render
Render draws the scene to the target.
This method processes each drawing command in the scene and renders
it to the target using CPU-based rasterization.
Returns an error if the target is GPU-only (no Pixels() support).
func (r *SoftwareRenderer) Render(target RenderTarget, scene *Scene) error {
if target == nil {
return errors.New("render: nil target")
}
pixels := target.Pixels()
if pixels == nil {
return errors.New("render: target does not support CPU rendering")
}
if scene == nil || scene.IsEmpty() {
return nil
}
width := target.Width()
height := target.Height()
stride := target.Stride()
// Ensure filler is sized correctly
r.ensureFiller(width, height)
// Process each command
for _, cmd := range scene.drawCommands() {
switch cmd.op {
case opClear:
r.renderClear(pixels, width, height, stride, cmd.color)
case opFill:
if cmd.path != nil && !cmd.path.IsEmpty() {
r.renderFill(pixels, width, height, stride, cmd.path, cmd.color, cmd.fillRule)
}
case opStroke:
if cmd.path != nil && !cmd.path.IsEmpty() {
r.renderStroke(pixels, width, height, stride, cmd.path, cmd.color, cmd.width)
}
}
}
return nil
}
Structs
type SoftwareRenderer struct
SoftwareRenderer is a CPU-based renderer using the core/ package algorithms.
This renderer provides anti-aliased 2D rendering without any GPU dependencies.
It uses AnalyticFiller for high-quality coverage-based anti-aliasing.
Performance characteristics:
- Single-threaded (future: parallel scanline processing)
- O(n) where n is the number of pixels covered
- Memory: O(width) for scanline buffers
Example:
renderer := render.NewSoftwareRenderer()
target := render.NewPixmapTarget(800, 600)
scene := render.NewScene()
scene.SetFillColor(color.RGBA{255, 0, 0, 255})
scene.Circle(400, 300, 100)
scene.Fill()
renderer.Render(target, scene)
img := target.Image()
type SoftwareRenderer struct {
// edgeBuilder is reused for path-to-edge conversion.
edgeBuilder *raster.EdgeBuilder
// filler is reused for analytic anti-aliasing.
filler *raster.AnalyticFiller
// lastWidth and lastHeight track the filler dimensions.
lastWidth, lastHeight int
}
Capabilities returns the renderer's capabilities.