diff --git a/experiments/benchmark_cairo.nim b/experiments/benchmark_cairo.nim index 1bb3bc0..754f661 100644 --- a/experiments/benchmark_cairo.nim +++ b/experiments/benchmark_cairo.nim @@ -23,7 +23,7 @@ block: a.fill(rgba(255, 255, 255, 255)) timeIt "pixie1": - var p: pixie.Path + let p = newPath() p.moveTo(0, 0) p.lineTo(1920, 0) p.lineTo(1920, 1080) @@ -56,7 +56,7 @@ block: a.fill(rgba(255, 255, 255, 255)) timeIt "pixie2": - var p: pixie.Path + let p = newPath() p.moveTo(500, 240) p.lineTo(1500, 240) p.lineTo(1920, 600) @@ -66,31 +66,31 @@ block: # 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 +# a = imageSurfaceCreate(FORMAT_ARGB32, 1000, 1000) +# b = imageSurfaceCreate(FORMAT_ARGB32, 500, 500) +# ac = a.create() +# bc = b.create() - ac.setSourceRgba(1, 0, 0, 1) - ac.newPath() - ac.rectangle(0, 0, 1000, 1000) - ac.fill() +# ac.setSourceRgba(1, 0, 0, 1) +# ac.newPath() +# ac.rectangle(0, 0, 1000, 1000) +# ac.fill() - bc.setSourceRgba(0, 1, 0, 1) - bc.newPath() - bc.rectangle(0, 0, 500, 500) - bc.fill() +# bc.setSourceRgba(0, 1, 0, 1) +# bc.newPath() +# bc.rectangle(0, 0, 500, 500) +# bc.fill() - let pattern = patternCreateForSurface(b) +# let pattern = patternCreateForSurface(b) - timeIt "a": - ac.setSource(pattern) - ac.save() - ac.translate(25.2, 25.2) - ac.rectangle(0, 0, 500, 500) - ac.fill() - ac.restore() +# timeIt "a": +# ac.setSource(pattern) +# ac.save() +# ac.translate(25.2, 25.2) +# ac.rectangle(0, 0, 500, 500) +# ac.fill() +# ac.restore() - discard a.writeToPng("a.png") +# discard a.writeToPng("a.png") diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index 638c147..496c045 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1201,56 +1201,61 @@ proc computeCoverages( segment = partitioning.partitions[partitionIndex][i][0] winding = partitioning.partitions[partitionIndex][i][1] if segment.at.y <= yLine and segment.to.y >= yLine: - let x = - if segment.at.x - segment.to.x == 0: - segment.at.x - else: - let - m = (segment.at.y - segment.to.y) / (segment.at.x - segment.to.x) - b = segment.at.y - m * segment.at.x - (yLine - b) / m + let + d = segment.at.x - segment.to.x + x = + if d == 0: + segment.at.x + else: + let + m = (segment.at.y - segment.to.y) / d + b = segment.at.y - m * segment.at.x + (yLine - b) / m if numHits == hits.len: hits.setLen(hits.len * 2) hits[numHits] = (min(x, width), winding) inc numHits - sort(hits, 0, numHits - 1) + if numHits > 0: + sort(hits, 0, numHits - 1) - if aa: - for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width): - var fillStart = prevAt.int + if not aa: + continue - let - pixelCrossed = at.int - prevAt.int > 0 - leftCover = - if pixelCrossed: - trunc(prevAt) + 1 - prevAt - else: - at - prevAt - if leftCover != 0: - inc fillStart - coverages[prevAt.int - startX] += - (leftCover * sampleCoverage.float32).uint8 + for (prevAt, at, count) in hits.walk(numHits, windingRule, y, width): + var fillStart = prevAt.int - if pixelCrossed: - let rightCover = at - trunc(at) - if rightCover > 0: - coverages[at.int - startX] += - (rightCover * sampleCoverage.float32).uint8 + let + pixelCrossed = at.int - prevAt.int > 0 + leftCover = + if pixelCrossed: + 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 fillLen > 0: - var i = fillStart - when defined(amd64) and not defined(pixieNoSimd): - let vSampleCoverage = mm_set1_epi8(cast[int8](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 + if pixelCrossed: + let rightCover = at - trunc(at) + if rightCover > 0: + coverages[at.int - startX] += + (rightCover * sampleCoverage.float32).uint8 + + let fillLen = at.int - fillStart + if fillLen > 0: + var i = fillStart + when defined(amd64) and not defined(pixieNoSimd): + let vSampleCoverage = mm_set1_epi8(cast[int8](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) = ## Clears data from [start, to).