better cairo benchmark

This commit is contained in:
Ryan Oldenburg 2021-11-25 23:30:05 -06:00
parent 943961677b
commit 0f3b0712b5
2 changed files with 109 additions and 69 deletions

View file

@ -1,96 +1,141 @@
import benchy, cairo, chroma, math, pixie
import benchy, cairo, chroma, math, pixie, pixie/paths {.all.}, strformat
proc doDiff(a, b: Image, name: string) =
let (diffScore, diffImage) = diff(a, b)
echo &"{name} score: {diffScore}"
diffImage.writeFile(&"{name}_diff.png")
block:
let path = newPath()
path.moveTo(0, 0)
path.lineTo(1920, 0)
path.lineTo(1920, 1080)
path.lineTo(0, 1080)
path.closePath()
let shapes = path.commandsToShapes(true, 1)
let
surface = imageSurfaceCreate(FORMAT_ARGB32, 1920, 1080)
ctx = surface.create()
ctx.setSourceRgba(0, 0, 1, 1)
timeIt "cairo1":
ctx.newPath()
ctx.moveTo(0, 0)
ctx.lineTo(1920, 0)
ctx.lineTo(1920, 1080)
ctx.lineTo(0, 1080)
ctx.closePath()
ctx.moveTo(shapes[0][0].x, shapes[0][0].y)
for shape in shapes:
for v in shape:
ctx.lineTo(v.x, v.y)
ctx.fill()
surface.flush()
# discard surface.writeToPng("cairo1.png")
let a = newImage(1920, 1080)
a.fill(rgba(255, 255, 255, 255))
timeIt "pixie1":
let p = newPath()
p.moveTo(0, 0)
p.lineTo(1920, 0)
p.lineTo(1920, 1080)
p.lineTo(0, 1080)
p.closePath()
p.moveTo(shapes[0][0])
for shape in shapes:
for v in shape:
p.lineTo(v)
a.fillPath(p, rgba(0, 0, 255, 255))
# a.writeFile("pixie1.png")
block:
let path = newPath()
path.moveTo(500, 240)
path.lineTo(1500, 240)
path.lineTo(1920, 600)
path.lineTo(0, 600)
path.closePath()
let shapes = path.commandsToShapes(true, 1)
let
surface = imageSurfaceCreate(FORMAT_ARGB32, 1920, 1080)
ctx = surface.create()
ctx.setSourceRgba(0, 0, 1, 1)
timeIt "cairo2":
ctx.setSourceRgba(1, 1, 1, 1)
let operator = ctx.getOperator()
ctx.setOperator(OperatorSource)
ctx.paint()
ctx.setOperator(operator)
ctx.setSourceRgba(0, 0, 1, 1)
ctx.newPath()
ctx.moveTo(500, 240)
ctx.lineTo(1500, 240)
ctx.lineTo(1920, 600)
ctx.lineTo(0, 600)
ctx.closePath()
ctx.moveTo(shapes[0][0].x, shapes[0][0].y)
for shape in shapes:
for v in shape:
ctx.lineTo(v.x, v.y)
ctx.fill()
surface.flush()
surface.flush()
# discard surface.writeToPng("cairo2.png")
let a = newImage(1920, 1080)
a.fill(rgba(255, 255, 255, 255))
timeIt "pixie2":
a.fill(rgba(255, 255, 255, 255))
let p = newPath()
p.moveTo(500, 240)
p.lineTo(1500, 240)
p.lineTo(1920, 600)
p.lineTo(0, 600)
p.closePath()
p.moveTo(shapes[0][0])
for shape in shapes:
for v in shape:
p.lineTo(v)
a.fillPath(p, rgba(0, 0, 255, 255))
# a.writeFile("pixie2.png")
# block:
# let
# a = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
# b = imageSurfaceCreate(FORMAT_ARGB32, 500, 500)
# ac = a.create()
# bc = b.create()
block:
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
""")
# ac.setSourceRgba(1, 0, 0, 1)
# ac.newPath()
# ac.rectangle(0, 0, 1000, 1000)
# ac.fill()
let shapes = path.commandsToShapes(true, 1)
# bc.setSourceRgba(0, 1, 0, 1)
# bc.newPath()
# bc.rectangle(0, 0, 500, 500)
# bc.fill()
let
surface = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
ctx = surface.create()
# let pattern = patternCreateForSurface(b)
timeIt "cairo3":
ctx.setSourceRgba(1, 1, 1, 1)
let operator = ctx.getOperator()
ctx.setOperator(OperatorSource)
ctx.paint()
ctx.setOperator(operator)
# timeIt "a":
# ac.setSource(pattern)
# ac.save()
# ac.translate(25.2, 25.2)
# ac.rectangle(0, 0, 500, 500)
# ac.fill()
# ac.restore()
ctx.setSourceRgba(1, 0, 0, 1)
# discard a.writeToPng("a.png")
ctx.newPath()
ctx.moveTo(shapes[0][0].x, shapes[0][0].y)
for shape in shapes:
for v in shape:
ctx.lineTo(v.x, v.y)
ctx.fill()
surface.flush()
# discard surface.writeToPng("cairo3.png")
let a = newImage(1000, 1000)
timeIt "pixie3":
a.fill(rgba(255, 255, 255, 255))
let p = newPath()
p.moveTo(shapes[0][0])
for shape in shapes:
for v in shape:
p.lineTo(v)
a.fillPath(p, rgba(255, 0, 0, 255))
# a.writeFile("pixie3.png")
# doDiff(readImage("cairo3.png"), a, "cairo3")

View file

@ -1136,23 +1136,18 @@ proc maxEntryCount(partitioning: Partitioning): int =
for i in 0 ..< partitioning.partitions.len:
result = max(result, partitioning.partitions[i].len)
proc insertionSort(
hits: var seq[(float32, int16)], lo, hi: int
) {.inline.} =
for i in lo + 1 .. hi:
var
j = i - 1
k = i
while j >= 0 and hits[j][0] > hits[k][0]:
swap(hits[j + 1], hits[j])
dec j
dec k
proc sort(hits: var seq[(float32, int16)], inl, inr: int) =
proc sortHits(hits: var seq[(float32, int16)], inl, inr: int) =
## Quicksort + insertion sort, in-place and faster than standard lib sort.
let n = inr - inl + 1
if n < 32:
insertionSort(hits, inl, inr)
if n < 32: # Use insertion sort for the rest
for i in inl + 1 .. inr:
var
j = i - 1
k = i
while j >= 0 and hits[j][0] > hits[k][0]:
swap(hits[j + 1], hits[j])
dec j
dec k
return
var
l = inl
@ -1167,8 +1162,8 @@ proc sort(hits: var seq[(float32, int16)], inl, inr: int) =
swap(hits[l], hits[r])
inc l
dec r
sort(hits, inl, r)
sort(hits, l, inr)
sortHits(hits, inl, r)
sortHits(hits, l, inr)
proc shouldFill(
windingRule: WindingRule, count: int
@ -1258,7 +1253,7 @@ proc computeCoverage(
inc numHits
if numHits > 0:
sort(hits, 0, numHits - 1)
sortHits(hits, 0, numHits - 1)
if aa:
for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width):
@ -1991,7 +1986,7 @@ proc overlaps(
if segment.to != at:
hits.add((at.x, winding))
sort(hits, 0, hits.high)
sortHits(hits, 0, hits.high)
var count: int
for (at, winding) in hits: