bmOverwrite

This commit is contained in:
Ryan Oldenburg 2021-12-12 18:42:01 -06:00
parent 7abe128124
commit 6280af09f0

View file

@ -1335,7 +1335,10 @@ proc fillCoverage(
# If the coverages are not all zero # If the coverages are not all zero
if mm_movemask_epi8(mm_cmpeq_epi32(coverageVec, vec255)) == 0xffff: if mm_movemask_epi8(mm_cmpeq_epi32(coverageVec, vec255)) == 0xffff:
# If the coverages are all 255 # If the coverages are all 255
if blendMode == bmNormal: if blendMode == bmOverwrite:
for i in 0 ..< 4:
mm_storeu_si128(image.data[index + i * 4].addr, colorVec)
elif blendMode == bmNormal:
if rgbx.a == 255: if rgbx.a == 255:
for i in 0 ..< 4: for i in 0 ..< 4:
mm_storeu_si128(image.data[index + i * 4].addr, colorVec) mm_storeu_si128(image.data[index + i * 4].addr, colorVec)
@ -1375,6 +1378,9 @@ proc fillCoverage(
source = mm_or_si128(sourceEven, mm_slli_epi16(sourceOdd, 8)) source = mm_or_si128(sourceEven, mm_slli_epi16(sourceOdd, 8))
if blendMode == bmOverwrite:
mm_storeu_si128(image.data[index + i * 4].addr, source)
else:
let backdrop = mm_loadu_si128(image.data[index + i * 4].addr) let backdrop = mm_loadu_si128(image.data[index + i * 4].addr)
mm_storeu_si128( mm_storeu_si128(
image.data[index + i * 4].addr, image.data[index + i * 4].addr,
@ -1401,13 +1407,18 @@ proc fillCoverage(
if blendMode == bmNormal and coverage == 255 and rgbx.a == 255: if blendMode == bmNormal and coverage == 255 and rgbx.a == 255:
# Skip blending # Skip blending
image.unsafe[x, y] = rgbx image.unsafe[x, y] = rgbx
else: continue
var source = rgbx var source = rgbx
if coverage != 255: if coverage != 255:
source.r = ((source.r.uint32 * coverage) div 255).uint8 source.r = ((source.r.uint32 * coverage) div 255).uint8
source.g = ((source.g.uint32 * coverage) div 255).uint8 source.g = ((source.g.uint32 * coverage) div 255).uint8
source.b = ((source.b.uint32 * coverage) div 255).uint8 source.b = ((source.b.uint32 * coverage) div 255).uint8
source.a = ((source.a.uint32 * coverage) div 255).uint8 source.a = ((source.a.uint32 * coverage) div 255).uint8
if blendMode == bmOverwrite:
image.unsafe[x, y] = source
else:
let backdrop = image.unsafe[x, y] let backdrop = image.unsafe[x, y]
image.unsafe[x, y] = blender(backdrop, source) image.unsafe[x, y] = blender(backdrop, source)
elif blendMode == bmMask: elif blendMode == bmMask:
@ -1428,26 +1439,32 @@ proc fillCoverage(
if blendMode.hasSimdMasker(): if blendMode.hasSimdMasker():
let let
maskerSimd = blendMode.maskerSimd() maskerSimd = blendMode.maskerSimd()
zeroVec = mm_setzero_si128() vecZero = mm_setzero_si128()
for _ in 0 ..< coverages.len div 16: for _ in 0 ..< coverages.len div 16:
let let
index = mask.dataIndex(x, y) index = mask.dataIndex(x, y)
coverage = mm_loadu_si128(coverages[x - startX].unsafeAddr) coverageVec = mm_loadu_si128(coverages[x - startX].unsafeAddr)
if mm_movemask_epi8(mm_cmpeq_epi16(coverage, zeroVec)) != 0xffff: if mm_movemask_epi8(mm_cmpeq_epi16(coverageVec, vecZero)) != 0xffff:
# If the coverages are not all zero # If the coverages are not all zero
if blendMode == bmOverwrite:
mm_storeu_si128(mask.data[index].addr, coverageVec)
else:
let backdrop = mm_loadu_si128(mask.data[index].addr) let backdrop = mm_loadu_si128(mask.data[index].addr)
mm_storeu_si128( mm_storeu_si128(
mask.data[index].addr, mask.data[index].addr,
maskerSimd(backdrop, coverage) maskerSimd(backdrop, coverageVec)
) )
elif blendMode == bmMask: elif blendMode == bmMask:
mm_storeu_si128(mask.data[index].addr, zeroVec) mm_storeu_si128(mask.data[index].addr, vecZero)
x += 16 x += 16
let masker = blendMode.masker() let masker = blendMode.masker()
for x in x ..< startX + coverages.len: for x in x ..< startX + coverages.len:
let coverage = coverages[x - startX] let coverage = coverages[x - startX]
if coverage != 0 or blendMode == bmExcludeMask: if coverage != 0 or blendMode == bmExcludeMask:
if blendMode == bmOverwrite:
mask.unsafe[x, y] = coverage
else:
let backdrop = mask.unsafe[x, y] let backdrop = mask.unsafe[x, y]
mask.unsafe[x, y] = masker(backdrop, coverage) mask.unsafe[x, y] = masker(backdrop, coverage)
elif blendMode == bmMask: elif blendMode == bmMask:
@ -1479,7 +1496,7 @@ proc fillHits(
filledTo = fillStart + fillLen filledTo = fillStart + fillLen
if blendMode == bmNormal and rgbx.a == 255: if blendMode == bmOverwrite or (blendMode == bmNormal and rgbx.a == 255):
fillUnsafe(image.data, rgbx, image.dataIndex(fillStart, y), fillLen) fillUnsafe(image.data, rgbx, image.dataIndex(fillStart, y), fillLen)
continue continue
@ -1541,7 +1558,7 @@ proc fillHits(
filledTo = fillStart + fillLen filledTo = fillStart + fillLen
if blendMode == bmNormal or blendMode == bmOverwrite: if blendMode in {bmNormal, bmOverwrite}:
fillUnsafe(mask.data, 255, mask.dataIndex(fillStart, y), fillLen) fillUnsafe(mask.data, 255, mask.dataIndex(fillStart, y), fillLen)
continue continue