From 93cac626b3033077bb969696f154d7f07dd6ea7b Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Fri, 10 Jun 2022 14:22:17 -0500 Subject: [PATCH 1/2] only benchmark render --- tests/benchmark_svg.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/benchmark_svg.nim b/tests/benchmark_svg.nim index cde9a8a..b6a7784 100644 --- a/tests/benchmark_svg.nim +++ b/tests/benchmark_svg.nim @@ -1,6 +1,8 @@ import benchy, pixie/fileformats/svg -let data = readFile("tests/fileformats/svg/Ghostscript_Tiger.svg") +let + data = readFile("tests/fileformats/svg/Ghostscript_Tiger.svg") + parsed = parseSvg(data) -timeIt "svg parse + render": - discard newImage(parseSvg(data)) +timeIt "svg render": + discard newImage(parsed) From 7ed8ec507e59405606cc69e568bd3911450bc515 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Fri, 10 Jun 2022 14:46:34 -0500 Subject: [PATCH 2/2] quantize prevents leaks with float32 --- src/pixie/paths.nim | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index 50f6054..6d0eba7 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -50,7 +50,7 @@ type startY, partitionHeight: uint32 const - epsilon: float64 = 0.0001 * PI ## Tiny value used for some computations. Must be float64 to prevent leaks. + epsilon: float32 = 0.0001 * PI ## Tiny value used for some computations. pixelErrorMargin: float32 = 0.2 defaultMiterLimit*: float32 = 4 @@ -1051,6 +1051,12 @@ proc shapesToSegments(shapes: seq[Polygon]): seq[(Segment, int16)] = swap(segment.at, segment.to) winding = -1 + # Quantize the segment to prevent leaks + segment = segment( + vec2(segment.at.x.quantize(1 / 256), segment.at.y.quantize(1 / 256)), + vec2(segment.to.x.quantize(1 / 256), segment.to.y.quantize(1 / 256)) + ) + result.add((segment, winding)) proc transform(shapes: var seq[Polygon], transform: Mat3) = @@ -1250,10 +1256,10 @@ proc computeCoverage( let quality = if aa: 5 else: 1 # Must divide 255 cleanly (1, 3, 5, 15, 17, 51, 85) sampleCoverage = (255 div quality).uint8 - offset = 1 / quality.float64 + offset = 1 / quality.float32 initialOffset = offset / 2 + epsilon - var yLine = y.float64 + initialOffset - offset + var yLine = y.float32 + initialOffset - offset for m in 0 ..< quality: yLine += offset numHits = 0 @@ -1263,7 +1269,7 @@ proc computeCoverage( if entry.m == 0: entry.b else: - (yLine.float32 - entry.b) / entry.m + (yLine - entry.b) / entry.m hits[numHits] = (min(x, width), entry.winding) inc numHits