From be598a108b38d94cf62fc4595bf1a8e7859bb343 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Mon, 13 Dec 2021 00:29:51 -0600 Subject: [PATCH] bmMask nonsimd draw faster --- experiments/benchmark_cairo_draw.nim | 32 ++++++++++++++++++++++++++++ src/pixie/blends.nim | 2 +- src/pixie/images.nim | 24 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/experiments/benchmark_cairo_draw.nim b/experiments/benchmark_cairo_draw.nim index 3444978..d6db25b 100644 --- a/experiments/benchmark_cairo_draw.nim +++ b/experiments/benchmark_cairo_draw.nim @@ -35,6 +35,38 @@ block: # tmp.writeFile("tmp2.png") +block: + let + backdrop = imageSurfaceCreateFromPng("tests/fileformats/svg/masters/dragon2.png") + source = imageSurfaceCreateFromPng("tests/fileformats/svg/masters/Ghostscript_Tiger.png") + tmp = imageSurfaceCreate(FORMAT_ARGB32, 1568, 940) + ctx = tmp.create() + + timeIt "cairo draw mask": + ctx.setSourceRgba(1, 1, 1, 1) + let operator = ctx.getOperator() + ctx.setOperator(OperatorSource) + ctx.paint() + ctx.setOperator(operator) + + ctx.setSource(backdrop, 0, 0) + ctx.mask(source, 0, 0) + tmp.flush() + + echo tmp.writeToPng("tmp_masked.png") + +block: + let + backdrop = readImage("tests/fileformats/svg/masters/dragon2.png") + source = readImage("tests/fileformats/svg/masters/Ghostscript_Tiger.png") + tmp = newImage(1568, 940) + + timeIt "pixie draw mask": + tmp.draw(backdrop) + tmp.draw(source, blendMode = bmMask) + + tmp.writeFile("tmp_masked2.png") + block: let backdrop = imageSurfaceCreateFromPng("tests/fileformats/svg/masters/dragon2.png") diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 0eb83c8..316b289 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -419,7 +419,7 @@ proc blendSaturation(backdrop, source: ColorRGBX): ColorRGBX = blended = SetLum(SetSat(backdrop, Sat(source)), Lum(backdrop)) result = alphaFix(backdrop, source, blended).rgba.rgbx() -proc blendMask(backdrop, source: ColorRGBX): ColorRGBX = +proc blendMask*(backdrop, source: ColorRGBX): ColorRGBX = let k = source.a.uint32 result.r = ((backdrop.r * k) div 255).uint8 result.g = ((backdrop.g * k) div 255).uint8 diff --git a/src/pixie/images.nim b/src/pixie/images.nim index c73eb85..20eb4e5 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -955,6 +955,30 @@ proc drawUber( let backdrop = a.unsafe[x, y] a.unsafe[x, y] = blendAlpha(backdrop, source) srcPos += dx + elif blendMode == bmMask: + for x in x ..< xMax: + let samplePos = ivec2((srcPos.x - h).int32, (srcPos.y - h).int32) + when type(a) is Image: + when type(b) is Image: + let source = b.unsafe[samplePos.x, samplePos.y] + else: # b is a Mask + let source = rgbx(0, 0, 0, b.unsafe[samplePos.x, samplePos.y]) + if source.a == 0: + a.unsafe[x, y] = rgbx(0, 0, 0, 0) + elif source.a != 255: + let backdrop = a.unsafe[x, y] + a.unsafe[x, y] = blendMask(backdrop, source) + else: # a is a Mask + when type(b) is Image: + let source = b.unsafe[samplePos.x, samplePos.y].a + else: # b is a Mask + let source = b.unsafe[samplePos.x, samplePos.y] + if source == 0: + a.unsafe[x, y] = 0 + elif source != 255: + let backdrop = a.unsafe[x, y] + a.unsafe[x, y] = blendAlpha(backdrop, source) + srcPos += dx else: for x in x ..< xMax: let samplePos = ivec2((srcPos.x - h).int32, (srcPos.y - h).int32)