little better

This commit is contained in:
Ryan Oldenburg 2021-11-12 19:42:35 -06:00
parent 695ca9eb05
commit 85a9842369
2 changed files with 70 additions and 65 deletions

View file

@ -23,7 +23,7 @@ block:
a.fill(rgba(255, 255, 255, 255)) a.fill(rgba(255, 255, 255, 255))
timeIt "pixie1": timeIt "pixie1":
var p: pixie.Path let p = newPath()
p.moveTo(0, 0) p.moveTo(0, 0)
p.lineTo(1920, 0) p.lineTo(1920, 0)
p.lineTo(1920, 1080) p.lineTo(1920, 1080)
@ -56,7 +56,7 @@ block:
a.fill(rgba(255, 255, 255, 255)) a.fill(rgba(255, 255, 255, 255))
timeIt "pixie2": timeIt "pixie2":
var p: pixie.Path let p = newPath()
p.moveTo(500, 240) p.moveTo(500, 240)
p.lineTo(1500, 240) p.lineTo(1500, 240)
p.lineTo(1920, 600) p.lineTo(1920, 600)
@ -66,31 +66,31 @@ block:
# a.writeFile("pixie2.png") # a.writeFile("pixie2.png")
block: # block:
let # let
a = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000) # a = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000)
b = imageSurfaceCreate(FORMAT_ARGB32, 500, 500) # b = imageSurfaceCreate(FORMAT_ARGB32, 500, 500)
ac = a.create() # ac = a.create()
bc = b.create() # bc = b.create()
ac.setSourceRgba(1, 0, 0, 1) # ac.setSourceRgba(1, 0, 0, 1)
ac.newPath() # ac.newPath()
ac.rectangle(0, 0, 1000, 1000) # ac.rectangle(0, 0, 1000, 1000)
ac.fill() # ac.fill()
bc.setSourceRgba(0, 1, 0, 1) # bc.setSourceRgba(0, 1, 0, 1)
bc.newPath() # bc.newPath()
bc.rectangle(0, 0, 500, 500) # bc.rectangle(0, 0, 500, 500)
bc.fill() # bc.fill()
let pattern = patternCreateForSurface(b) # let pattern = patternCreateForSurface(b)
timeIt "a": # timeIt "a":
ac.setSource(pattern) # ac.setSource(pattern)
ac.save() # ac.save()
ac.translate(25.2, 25.2) # ac.translate(25.2, 25.2)
ac.rectangle(0, 0, 500, 500) # ac.rectangle(0, 0, 500, 500)
ac.fill() # ac.fill()
ac.restore() # ac.restore()
discard a.writeToPng("a.png") # discard a.writeToPng("a.png")

View file

@ -1201,56 +1201,61 @@ proc computeCoverages(
segment = partitioning.partitions[partitionIndex][i][0] segment = partitioning.partitions[partitionIndex][i][0]
winding = partitioning.partitions[partitionIndex][i][1] winding = partitioning.partitions[partitionIndex][i][1]
if segment.at.y <= yLine and segment.to.y >= yLine: if segment.at.y <= yLine and segment.to.y >= yLine:
let x = let
if segment.at.x - segment.to.x == 0: d = segment.at.x - segment.to.x
segment.at.x x =
else: if d == 0:
let segment.at.x
m = (segment.at.y - segment.to.y) / (segment.at.x - segment.to.x) else:
b = segment.at.y - m * segment.at.x let
(yLine - b) / m m = (segment.at.y - segment.to.y) / d
b = segment.at.y - m * segment.at.x
(yLine - b) / m
if numHits == hits.len: if numHits == hits.len:
hits.setLen(hits.len * 2) hits.setLen(hits.len * 2)
hits[numHits] = (min(x, width), winding) hits[numHits] = (min(x, width), winding)
inc numHits inc numHits
sort(hits, 0, numHits - 1) if numHits > 0:
sort(hits, 0, numHits - 1)
if aa: if not aa:
for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width): continue
var fillStart = prevAt.int
let for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width):
pixelCrossed = at.int - prevAt.int > 0 var fillStart = prevAt.int
leftCover =
if pixelCrossed:
trunc(prevAt) + 1 - prevAt
else:
at - prevAt
if leftCover != 0:
inc fillStart
coverages[prevAt.int - startX] +=
(leftCover * sampleCoverage.float32).uint8
if pixelCrossed: let
let rightCover = at - trunc(at) pixelCrossed = at.int - prevAt.int > 0
if rightCover > 0: leftCover =
coverages[at.int - startX] += if pixelCrossed:
(rightCover * sampleCoverage.float32).uint8 trunc(prevAt) + 1 - prevAt
else:
at - prevAt
if leftCover != 0:
inc fillStart
coverages[prevAt.int - startX] +=
(leftCover * sampleCoverage.float32).uint8
let fillLen = at.int - fillStart if pixelCrossed:
if fillLen > 0: let rightCover = at - trunc(at)
var i = fillStart if rightCover > 0:
when defined(amd64) and not defined(pixieNoSimd): coverages[at.int - startX] +=
let vSampleCoverage = mm_set1_epi8(cast[int8](sampleCoverage)) (rightCover * sampleCoverage.float32).uint8
for j in countup(i, fillStart + fillLen - 16, 16):
var coverage = mm_loadu_si128(coverages[j - startX].addr) let fillLen = at.int - fillStart
coverage = mm_add_epi8(coverage, vSampleCoverage) if fillLen > 0:
mm_storeu_si128(coverages[j - startX].addr, coverage) var i = fillStart
i += 16 when defined(amd64) and not defined(pixieNoSimd):
for j in i ..< fillStart + fillLen: let vSampleCoverage = mm_set1_epi8(cast[int8](sampleCoverage))
coverages[j - startX] += sampleCoverage for j in countup(i, fillStart + fillLen - 16, 16):
var coverage = mm_loadu_si128(coverages[j - startX].addr)
coverage = mm_add_epi8(coverage, vSampleCoverage)
mm_storeu_si128(coverages[j - startX].addr, coverage)
i += 16
for j in i ..< fillStart + fillLen:
coverages[j - startX] += sampleCoverage
proc clearUnsafe(target: Image | Mask, startX, startY, toX, toY: int) = proc clearUnsafe(target: Image | Mask, startX, startY, toX, toY: int) =
## Clears data from [start, to). ## Clears data from [start, to).