pixie/experiments/bench_cairo.nim

256 lines
5.9 KiB
Nim
Raw Normal View History

2022-06-21 00:19:32 +00:00
import benchy, cairo, pixie, pixie/fileformats/svg {.all.}, pixie/paths {.all.}
2021-11-26 05:30:05 +00:00
2022-06-21 00:19:32 +00:00
type
Fill = object
shapes: seq[Polygon]
transform: Mat3
paint: Paint
windingRule: WindingRule
2022-06-21 00:19:32 +00:00
Benchmark = object
name: string
fills: seq[Fill]
2020-12-13 08:35:02 +00:00
2022-06-21 00:19:32 +00:00
var benchmarks: seq[Benchmark]
2022-06-22 06:00:49 +00:00
let
opaque = newPaint(SolidPaint)
notOpaque = newPaint(SolidPaint)
opaque.color = color(0, 0, 0, 1)
notOpaque.color = color(0, 0, 0, 0.5)
2022-06-21 00:19:32 +00:00
block: # Basic rect
2021-11-26 05:30:05 +00:00
let path = newPath()
2022-06-22 06:00:49 +00:00
path.rect(rect(50, 50, 800, 800))
2021-11-26 05:30:05 +00:00
2022-06-22 06:00:49 +00:00
let shapes = path.commandsToShapes(true, 1)
2022-06-21 00:19:32 +00:00
benchmarks.add(Benchmark(
2022-06-22 06:00:49 +00:00
name: "rect opaque",
2022-06-21 00:19:32 +00:00
fills: @[Fill(
shapes: shapes,
transform: mat3(),
2022-06-22 06:00:49 +00:00
paint: opaque,
windingRule: NonZero
)]))
benchmarks.add(Benchmark(
name: "rect not opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: notOpaque,
2022-06-21 00:19:32 +00:00
windingRule: NonZero
)]))
block: # Rounded rect
2021-11-26 05:30:05 +00:00
let path = newPath()
2022-06-25 06:58:04 +00:00
path.roundedRect(rect(0, 0, 900, 900), 100, 100, 100, 100)
2021-11-26 05:30:05 +00:00
2022-06-22 06:00:49 +00:00
let shapes = path.commandsToShapes(true, 1)
benchmarks.add(Benchmark(
name: "roundedRect opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: opaque,
windingRule: NonZero
)]))
2022-06-21 00:19:32 +00:00
benchmarks.add(Benchmark(
2022-06-22 06:00:49 +00:00
name: "roundedRect not opaque",
2022-06-21 00:19:32 +00:00
fills: @[Fill(
shapes: shapes,
transform: mat3(),
2022-06-22 06:00:49 +00:00
paint: notOpaque,
2022-06-21 00:19:32 +00:00
windingRule: NonZero
)]))
2022-06-25 06:58:04 +00:00
block: # Pentagon
let path = newPath()
path.polygon(vec2(450, 450), 400, 5)
let shapes = path.commandsToShapes(true, 1)
benchmarks.add(Benchmark(
name: "pentagon opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: opaque,
windingRule: NonZero
)]))
benchmarks.add(Benchmark(
name: "pentagon not opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: notOpaque,
windingRule: NonZero
)]))
block: # Circle
let path = newPath()
path.circle(circle(vec2(450, 450), 400))
let shapes = path.commandsToShapes(true, 1)
benchmarks.add(Benchmark(
name: "circle opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: opaque,
windingRule: NonZero
)]))
benchmarks.add(Benchmark(
name: "circle not opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: notOpaque,
windingRule: NonZero
)]))
2022-06-21 00:19:32 +00:00
block: # Heart
2021-11-26 05:30:05 +00:00
let path = parsePath("""
M 100,300
A 200,200 0,0,1 500,300
A 200,200 0,0,1 900,300
Q 900,600 500,900
Q 100,600 100,300 z
""")
2022-06-22 06:00:49 +00:00
let shapes = path.commandsToShapes(true, 1)
2022-06-21 00:19:32 +00:00
benchmarks.add(Benchmark(
2022-06-22 06:00:49 +00:00
name: "heart opaque",
2022-06-21 00:19:32 +00:00
fills: @[Fill(
shapes: shapes,
transform: mat3(),
2022-06-22 06:00:49 +00:00
paint: opaque,
windingRule: NonZero
)]))
benchmarks.add(Benchmark(
name: "heart not opaque",
fills: @[Fill(
shapes: shapes,
transform: mat3(),
paint: notOpaque,
2022-06-21 00:19:32 +00:00
windingRule: NonZero
)]))
block: # Tiger
let
data = readFile("tests/fileformats/svg/Ghostscript_Tiger.svg")
parsed = parseSvg(data)
2021-11-26 05:30:05 +00:00
2022-06-21 00:19:32 +00:00
var fills: seq[Fill]
2021-11-26 05:30:05 +00:00
2022-06-21 00:19:32 +00:00
for (path, props) in parsed.elements:
if props.display and props.opacity > 0:
if props.fill != "none":
let
shapes = path.commandsToShapes(true, 1)
paint = parseSomePaint(props.fill)
fills.add(Fill(
shapes: shapes,
transform: props.transform,
paint: paint,
windingRule: props.fillRule
))
if props.stroke != rgbx(0, 0, 0, 0) and props.strokeWidth > 0:
let strokeShapes = strokeShapes(
parseSomePath(path, false, props.transform.pixelScale),
props.strokeWidth,
props.strokeLineCap,
props.strokeLineJoin,
props.strokeMiterLimit,
props.strokeDashArray,
props.transform.pixelScale
)
2022-07-26 17:47:58 +00:00
let paint = props.stroke.copy()
2022-06-21 00:19:32 +00:00
paint.color.a *= (props.opacity * props.strokeOpacity)
fills.add(Fill(
shapes: strokeShapes,
transform: props.transform,
paint: paint,
windingRule: NonZero
))
2022-06-22 06:00:49 +00:00
benchmarks.add(Benchmark(
name: "tiger",
fills: fills
))
2021-11-29 05:58:54 +00:00
block:
2022-06-21 00:19:32 +00:00
for benchmark in benchmarks:
2021-12-01 06:18:25 +00:00
let
2022-06-21 00:19:32 +00:00
surface = imageSurfaceCreate(FORMAT_ARGB32, 900, 900)
2021-12-01 06:18:25 +00:00
ctx = surface.create()
2021-11-30 22:00:30 +00:00
2022-06-27 03:46:49 +00:00
ctx.setLineWidth(1)
2022-06-21 00:19:32 +00:00
timeIt "[cairo] " & benchmark.name:
for fill in benchmark.fills:
if fill.shapes.len > 0:
ctx.newPath()
for shape in fill.shapes:
ctx.moveTo(shape[0].x, shape[0].y)
for v in shape:
ctx.lineTo(v.x, v.y)
let
color = fill.paint.color
matrix = Matrix(
xx: fill.transform[0, 0],
yx: fill.transform[0, 1],
xy: fill.transform[1, 0],
yy: fill.transform[1, 1],
x0: fill.transform[2, 0],
y0: fill.transform[2, 1],
)
ctx.setSourceRgba(color.r, color.g, color.b, color.a)
ctx.setMatrix(matrix.unsafeAddr)
ctx.setFillRule(
if fill.windingRule == NonZero:
FillRuleWinding
else:
FillRuleEvenOdd
)
ctx.fill()
2022-06-27 03:46:49 +00:00
# ctx.stroke()
2022-06-21 00:19:32 +00:00
# discard surface.writeToPng(("cairo_" & benchmark.name & ".png").cstring)
2021-11-30 22:00:30 +00:00
2022-06-21 00:19:32 +00:00
block:
for benchmark in benchmarks:
let image = newImage(900, 900)
timeIt "[pixie] " & benchmark.name:
for fill in benchmark.fills:
if fill.shapes.len > 0:
let p = newPath()
for shape in fill.shapes:
p.moveTo(shape[0])
for v in shape:
p.lineTo(v)
image.fillPath(
p,
fill.paint,
fill.transform,
fill.windingRule
)
2022-06-27 03:46:49 +00:00
# image.strokePath(
# p,
# fill.paint,
# fill.transform,
# 1
# )
2022-06-21 00:19:32 +00:00
# image.writeFile("pixie_" & benchmark.name & ".png")