From de13c129e43aa3f905cae8a1da9b6e79ec8dd959 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sun, 12 Dec 2021 21:48:02 -0600 Subject: [PATCH] isOpaque --- experiments/benchmark_cairo_draw.nim | 10 ++++++--- src/pixie/images.nim | 32 ++++++++++++++++++++++++---- tests/benchmark_images.nim | 4 ++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/experiments/benchmark_cairo_draw.nim b/experiments/benchmark_cairo_draw.nim index 0538d0c..3444978 100644 --- a/experiments/benchmark_cairo_draw.nim +++ b/experiments/benchmark_cairo_draw.nim @@ -8,6 +8,12 @@ block: ctx = tmp.create() timeIt "cairo draw basic": + # ctx.setSourceRgba(0.5, 0.5, 0.5, 1) + # let operator = ctx.getOperator() + # ctx.setOperator(OperatorSource) + # ctx.paint() + # ctx.setOperator(operator) + ctx.setSource(backdrop, 0, 0) ctx.paint() ctx.setSource(source, 0, 0) @@ -22,10 +28,8 @@ block: source = readImage("tests/fileformats/svg/masters/Ghostscript_Tiger.png") tmp = newImage(1568, 940) - timeIt "isOneColor": - doAssert not backdrop.isOneColor() - timeIt "pixie draw basic": + # tmp.fill(rgbx(127, 127, 127, 255)) tmp.draw(backdrop) tmp.draw(source) diff --git a/src/pixie/images.nim b/src/pixie/images.nim index a863331..3062b7c 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -148,7 +148,7 @@ proc isOneColor*(image: Image): bool {.raises: [].} = values1 = mm_loadu_si128(image.data[i + 4].addr) mask0 = mm_movemask_epi8(mm_cmpeq_epi8(values0, colorVec)) mask1 = mm_movemask_epi8(mm_cmpeq_epi8(values1, colorVec)) - if mask0 != uint16.high.int or mask1 != uint16.high.int: + if mask0 != 0xffff or mask1 != 0xffff: return false i += 8 @@ -162,7 +162,7 @@ proc isTransparent*(image: Image): bool {.raises: [].} = var i: int when defined(amd64) and not defined(pixieNoSimd): - let zeroVec = mm_setzero_si128() + let vecZero = mm_setzero_si128() for _ in 0 ..< image.data.len div 16: let values0 = mm_loadu_si128(image.data[i + 0].addr) @@ -172,8 +172,7 @@ proc isTransparent*(image: Image): bool {.raises: [].} = values01 = mm_or_si128(values0, values1) values23 = mm_or_si128(values2, values3) values = mm_or_si128(values01, values23) - mask = mm_movemask_epi8(mm_cmpeq_epi8(values, zeroVec)) - if mask != uint16.high.int: + if mm_movemask_epi8(mm_cmpeq_epi8(values, vecZero)) != 0xffff: return false i += 16 @@ -181,6 +180,31 @@ proc isTransparent*(image: Image): bool {.raises: [].} = if image.data[j].a != 0: return false +proc isOpaque*(image: Image): bool {.raises: [].} = + result = true + + var i: int + when defined(amd64) and not defined(pixieNoSimd): + let + vec255 = mm_set1_epi32(cast[int32](uint32.high)) + colorMask = mm_set1_epi32(cast[int32]([255.uint8, 255, 255, 0])) + for _ in 0 ..< image.data.len div 16: + let + values0 = mm_loadu_si128(image.data[i + 0].addr) + values1 = mm_loadu_si128(image.data[i + 4].addr) + values2 = mm_loadu_si128(image.data[i + 8].addr) + values3 = mm_loadu_si128(image.data[i + 12].addr) + values01 = mm_and_si128(values0, values1) + values23 = mm_and_si128(values2, values3) + values = mm_or_si128(mm_and_si128(values01, values23), colorMask) + if mm_movemask_epi8(mm_cmpeq_epi8(values, vec255)) != 0xffff: + return false + i += 16 + + for j in i ..< image.data.len: + if image.data[j].a != 255: + return false + proc flipHorizontal*(image: Image) {.raises: [].} = ## Flips the image around the Y axis. let w = image.width div 2 diff --git a/tests/benchmark_images.nim b/tests/benchmark_images.nim index 728397b..7be2761 100644 --- a/tests/benchmark_images.nim +++ b/tests/benchmark_images.nim @@ -25,6 +25,10 @@ image.fill(rgba(0, 0, 0, 0)) timeIt "isTransparent": doAssert image.isTransparent() +image.fill(rgba(255, 255, 255, 255)) +timeIt "isOpaque": + doAssert image.isOpaque() + reset() timeIt "subImage":