diff --git a/src/pixie/internal.nim b/src/pixie/internal.nim index 79eda21..bbfaff9 100644 --- a/src/pixie/internal.nim +++ b/src/pixie/internal.nim @@ -202,6 +202,13 @@ proc isOpaque*(data: var seq[ColorRGBX], start, len: int): bool = return false when defined(amd64) and allowSimd: + proc applyOpacity*(color: M128, opacity: float32): ColorRGBX {.inline.} = + let opacityVec = mm_set1_ps(opacity) + var finalColor = mm_cvtps_epi32(mm_mul_ps(color, opacityVec)) + finalColor = mm_packus_epi16(finalColor, mm_setzero_si128()) + finalColor = mm_packus_epi16(finalColor, mm_setzero_si128()) + cast[ColorRGBX](mm_cvtsi128_si32(finalColor)) + proc packAlphaValues(v: M128i): M128i {.inline, raises: [].} = ## Shuffle the alpha values for these 4 colors to the first 4 bytes result = mm_srli_epi32(v, 24) diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index 96eb56b..6dcafac 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1941,6 +1941,14 @@ proc fillShapes( # We have 2 non-intersecting lines that require anti-aliasing # Use trapezoid coverage at the edges and fill in the middle + when allowSimd and defined(amd64): + let vecRgbx = mm_set_ps( + rgbx.a.float32, + rgbx.b.float32, + rgbx.g.float32, + rgbx.r.float32 + ) + proc solveX(entry: PartitionEntry, y: float32): float32 = if entry.m == 0: entry.b @@ -2010,7 +2018,11 @@ proc fillShapes( area = triangleArea + rectArea + rightRectArea dataIndex = image.dataIndex(x, y) backdrop = image.data[dataIndex] - source = rgbx * area + source = + when allowSimd and defined(amd64): + applyOpacity(vecRgbx, area) + else: + rgbx * area image.data[dataIndex] = blender(backdrop, source) block: # Right-side partial coverage @@ -2044,7 +2056,11 @@ proc fillShapes( area = leftRectArea + triangleArea + rectArea dataIndex = image.dataIndex(x, y) backdrop = image.data[dataIndex] - source = rgbx * area + source = + when allowSimd and defined(amd64): + applyOpacity(vecRgbx, area) + else: + rgbx * area image.data[dataIndex] = blender(backdrop, source) let