bit of neon in paints

This commit is contained in:
Ryan Oldenburg 2022-07-31 23:15:45 -05:00
parent e4afb30f2d
commit 48d1b17bc4

View file

@ -119,7 +119,7 @@ proc fillGradientLinear(image: Image, paint: Paint) =
if at.y == to.y: # Horizontal gradient if at.y == to.y: # Horizontal gradient
var x: int var x: int
while x < image.width: while x < image.width:
when defined(amd64) and allowSimd: when allowSimd and (defined(amd64) or defined(arm64)):
if x + 4 <= image.width: if x + 4 <= image.width:
var colors: array[4, ColorRGBX] var colors: array[4, ColorRGBX]
for i in 0 ..< 4: for i in 0 ..< 4:
@ -129,9 +129,14 @@ proc fillGradientLinear(image: Image, paint: Paint) =
rgbx = paint.gradientColor(t) rgbx = paint.gradientColor(t)
colors[i] = rgbx colors[i] = rgbx
let colorVec = cast[M128i](colors) when defined(amd64):
for y in 0 ..< image.height: let colorVec = mm_loadu_si128(colors[0].addr)
mm_storeu_si128(image.data[image.dataIndex(x, y)].addr, colorVec) for y in 0 ..< image.height:
mm_storeu_si128(image.data[image.dataIndex(x, y)].addr, colorVec)
else: # arm64
let colorVec = vld1q_u32(colors[0].addr)
for y in 0 ..< image.height:
vst1q_u32(image.data[image.dataIndex(x, y)].addr, colorVec)
x += 4 x += 4
continue continue
@ -150,11 +155,17 @@ proc fillGradientLinear(image: Image, paint: Paint) =
t = toLineSpace(at, to, xy) t = toLineSpace(at, to, xy)
rgbx = paint.gradientColor(t) rgbx = paint.gradientColor(t)
var x: int var x: int
when defined(amd64) and allowSimd: when allowSimd:
let colorVec = mm_set1_epi32(cast[int32](rgbx)) when defined(amd64):
for _ in 0 ..< image.width div 4: let colorVec = mm_set1_epi32(cast[int32](rgbx))
mm_storeu_si128(image.data[image.dataIndex(x, y)].addr, colorVec) for _ in 0 ..< image.width div 4:
x += 4 mm_storeu_si128(image.data[image.dataIndex(x, y)].addr, colorVec)
x += 4
elif defined(arm64):
let colorVec = vmovq_n_u32(cast[uint32](rgbx))
for _ in 0 ..< image.width div 4:
vst1q_u32(image.data[image.dataIndex(x, y)].addr, colorVec)
x += 4
for x in x ..< image.width: for x in x ..< image.width:
image.unsafe[x, y] = rgbx image.unsafe[x, y] = rgbx
@ -227,7 +238,6 @@ proc fillGradientAngular(image: Image, paint: Paint) =
proc fillGradient*(image: Image, paint: Paint) {.raises: [PixieError].} = proc fillGradient*(image: Image, paint: Paint) {.raises: [PixieError].} =
## Fills with the Paint gradient. ## Fills with the Paint gradient.
case paint.kind: case paint.kind:
of LinearGradientPaint: of LinearGradientPaint:
image.fillGradientLinear(paint) image.fillGradientLinear(paint)