From 3a40f7680c6cc110f2411edb4b8cf5b48b054c12 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 30 Jan 2021 16:24:35 -0600 Subject: [PATCH 1/5] Revert "triple blend when needed" This reverts commit 014413b6276d194e0255313874beccfc86614afd. --- src/pixie/blends.nim | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index e99aead..3037594 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -57,22 +57,6 @@ proc hardLightPremultiplied(backdrop, source: uint32): uint8 {.inline.} = proc blendAlpha(backdrop, source: uint8): uint8 {.inline.} = source + ((backdrop.uint32 * (255 - source)) div 255).uint8 -proc tripleBlend(result: var ColorRGBA, backdrop, source: ColorRGBA) = - result.a = blendAlpha(backdrop.a, source.a) - if result.a == 0: - result = rgba(0, 0, 0, 0) - else: - let - t0 = (255 - backdrop.a.uint32) * source.a.uint32 - t1 = (255 - source.a.uint32) * backdrop.a.uint32 - t2 = 255.uint32 * 255 - r = t0 * source.r + t1 * backdrop.r + t2 * result.r - g = t0 * source.g + t1 * backdrop.g + t2 * result.g - b = t0 * source.b + t1 * backdrop.b + t2 * result.b - result.r = (r div 255 div result.a).uint8 - result.g = (g div 255 div result.a).uint8 - result.b = (b div 255 div result.a).uint8 - proc blendNormalPremultiplied*(backdrop, source: ColorRGBA): ColorRGBA {.inline.} = if backdrop.a == 0: return source @@ -91,13 +75,13 @@ proc blendDarkenPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = result.r = min(backdrop.r, source.r) result.g = min(backdrop.g, source.g) result.b = min(backdrop.b, source.b) - result.tripleBlend(backdrop, source) + result.a = blendAlpha(backdrop.a, source.a) proc blendMultiplyPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = result.r = ((backdrop.r.uint32 * source.r) div 255).uint8 result.g = ((backdrop.g.uint32 * source.g) div 255).uint8 result.b = ((backdrop.b.uint32 * source.b) div 255).uint8 - result.tripleBlend(backdrop, source) + result.a = blendAlpha(backdrop.a, source.a) proc blendLinearBurnPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = result.r = min(0, backdrop.r.uint32 + source.r.uint32 - 255).uint8 @@ -122,7 +106,7 @@ proc blendColorBurnPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = result.r = blend(backdrop.r, source.r) result.g = blend(backdrop.g, source.g) result.b = blend(backdrop.b, source.b) - result.tripleBlend(backdrop, source) + result.a = blendAlpha(backdrop.a, source.a) proc blendScreenPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = result.r = screenPremultiplied(backdrop.r, source.r) From f05354dc790a8fe1e3f9d80611ba1067f119bd3b Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 30 Jan 2021 16:25:02 -0600 Subject: [PATCH 2/5] Revert "working int impl" This reverts commit 74fcf2a9f25694c2b546ee090000f75f5de0bdef. --- src/pixie/blends.nim | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 3037594..9ba66f0 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -554,6 +554,13 @@ proc blendHardLight(backdrop, source: ColorRGBA): ColorRGBA = result = result.toStraightAlpha() proc blendSoftLight(backdrop, source: ColorRGBA): ColorRGBA = + # proc softLight(backdrop, source: int32): uint8 {.inline.} = + # ## Pegtop + # ( + # ((255 - 2 * source) * backdrop ^ 2) div 255 ^ 2 + + # (2 * source * backdrop) div 255 + # ).uint8 + when defined(amd64) and not defined(pixieNoSimd): let vb = mm_setr_ps(backdrop.r.float32, backdrop.g.float32, backdrop.b.float32, 0) @@ -570,16 +577,6 @@ proc blendSoftLight(backdrop, source: ColorRGBA): ColorRGBA = result = alphaFix(backdrop, source, vb, vs, vm) else: blendSoftLightFloats(backdrop.color, source.color).rgba - # proc softLight(backdrop, source: int32): uint8 {.inline.} = - # ## Pegtop - # ( - # ((255 - 2 * source) * (backdrop ^ 2)) div (255 ^ 2) + - # (2 * source * backdrop) div 255 - # ).uint8 - # result.r = softLight(backdrop.r.int32, source.r.int32) - # result.g = softLight(backdrop.g.int32, source.g.int32) - # result.b = softLight(backdrop.b.int32, source.b.int32) - # result = alphaFix(backdrop, source, result) proc blendDifference(backdrop, source: ColorRGBA): ColorRGBA = let From fd59b20e7d367419e5b2f9962a6dbb8e0ffb1266 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 30 Jan 2021 16:25:21 -0600 Subject: [PATCH 3/5] Revert "for non simd for now" This reverts commit a16315a9cf0efcf1b6c98af08569ef442a70d47f. --- src/pixie/blends.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 9ba66f0..61a6a4f 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -239,9 +239,9 @@ proc `-`*(c: Color, v: float32): Color {.inline.} = # else: # screen(backdrop, 2 * source - 1) -proc softLight(backdrop, source: float32): float32 {.inline.} = - ## Pegtop - (1 - 2 * source) * backdrop ^ 2 + 2 * source * backdrop +# proc softLight(backdrop, source: float32): float32 {.inline.} = +# ## Pegtop +# (1 - 2 * source) * backdrop ^ 2 + 2 * source * backdrop proc Lum(C: Color): float32 {.inline.} = 0.3 * C.r + 0.59 * C.g + 0.11 * C.b @@ -367,11 +367,11 @@ proc alphaFix(backdrop, source, mixed: Color): Color = # result.b = hardLight(backdrop.b, source.b) # result = alphaFix(backdrop, source, result) -proc blendSoftLightFloats*(backdrop, source: Color): Color {.inline.} = - result.r = softLight(backdrop.r, source.r) - result.g = softLight(backdrop.g, source.g) - result.b = softLight(backdrop.b, source.b) - result = alphaFix(backdrop, source, result) +# proc blendSoftLightFloats*(backdrop, source: Color): Color {.inline.} = +# result.r = softLight(backdrop.r, source.r) +# result.g = softLight(backdrop.g, source.g) +# result.b = softLight(backdrop.b, source.b) +# result = alphaFix(backdrop, source, result) # proc blendDifferenceFloats*(backdrop, source: Color): Color {.inline.} = # result.r = abs(backdrop.r - source.r) From a801e9d3598c679cf422f0619c6d428d90dc1811 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 30 Jan 2021 16:25:38 -0600 Subject: [PATCH 4/5] Revert "premultiplied blends for most" This reverts commit 052e114db1f2878c213bb6eba5b65b82fc445f81. --- src/pixie/blends.nim | 246 ++++++++++++++----------------------------- 1 file changed, 78 insertions(+), 168 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 61a6a4f..255db39 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -39,24 +39,6 @@ type when defined(release): {.push checks: off.} -proc min(a, b: uint32): uint32 {.inline.} = - if a < b: a else: b - -proc max(a, b: uint32): uint32 {.inline.} = - if a > b: a else: b - -proc screenPremultiplied(backdrop, source: uint32): uint8 {.inline.} = - (255 - ((255 - backdrop) * (255 - source)) div 255).uint8 - -proc hardLightPremultiplied(backdrop, source: uint32): uint8 {.inline.} = - if source <= 127: - ((backdrop * 2 * source) div 255).uint8 - else: - screenPremultiplied(backdrop, 2 * source - 255) - -proc blendAlpha(backdrop, source: uint8): uint8 {.inline.} = - source + ((backdrop.uint32 * (255 - source)) div 255).uint8 - proc blendNormalPremultiplied*(backdrop, source: ColorRGBA): ColorRGBA {.inline.} = if backdrop.a == 0: return source @@ -69,95 +51,7 @@ proc blendNormalPremultiplied*(backdrop, source: ColorRGBA): ColorRGBA {.inline. result.r = source.r + ((backdrop.r.uint32 * k) div 255).uint8 result.g = source.g + ((backdrop.g.uint32 * k) div 255).uint8 result.b = source.b + ((backdrop.b.uint32 * k) div 255).uint8 - result.a = blendAlpha(backdrop.a, source.a) - -proc blendDarkenPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = min(backdrop.r, source.r) - result.g = min(backdrop.g, source.g) - result.b = min(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendMultiplyPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = ((backdrop.r.uint32 * source.r) div 255).uint8 - result.g = ((backdrop.g.uint32 * source.g) div 255).uint8 - result.b = ((backdrop.b.uint32 * source.b) div 255).uint8 - result.a = blendAlpha(backdrop.a, source.a) - -proc blendLinearBurnPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = min(0, backdrop.r.uint32 + source.r.uint32 - 255).uint8 - result.g = min(0, backdrop.g.uint32 + source.g.uint32 - 255).uint8 - result.b = min(0, backdrop.b.uint32 + source.b.uint32 - 255).uint8 - result.a = blendAlpha(backdrop.a, source.a) - -proc blendLightenPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = max(backdrop.r, source.r) - result.g = max(backdrop.g, source.g) - result.b = max(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendColorBurnPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - proc blend(backdrop, source: uint32): uint8 {.inline.} = - if backdrop == 255: - 255.uint8 - elif source == 0: - 0 - else: - 255 - min(255, (255 * (255 - backdrop)) div source).uint8 - result.r = blend(backdrop.r, source.r) - result.g = blend(backdrop.g, source.g) - result.b = blend(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendScreenPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = screenPremultiplied(backdrop.r, source.r) - result.g = screenPremultiplied(backdrop.g, source.g) - result.b = screenPremultiplied(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendLinearDodgePremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = min(backdrop.r.uint32 + source.r, 255).uint8 - result.g = min(backdrop.g.uint32 + source.g, 255).uint8 - result.b = min(backdrop.b.uint32 + source.b, 255).uint8 - result.a = blendAlpha(backdrop.a, source.a) - -proc blendColorDodgePremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - proc blend(backdrop, source: uint32): uint8 {.inline.} = - if backdrop == 0: - 0.uint8 - elif source == 255: - 255 - else: - min(255, (255 * backdrop) div (255 - source)).uint8 - result.r = blend(backdrop.r, source.r) - result.g = blend(backdrop.g, source.g) - result.b = blend(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendOverlayPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = hardLightPremultiplied(source.r, backdrop.r) - result.g = hardLightPremultiplied(source.g, backdrop.g) - result.b = hardLightPremultiplied(source.b, backdrop.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendHardLightyPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = hardLightPremultiplied(backdrop.r, source.r) - result.g = hardLightPremultiplied(backdrop.g, source.g) - result.b = hardLightPremultiplied(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendDifferencePremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - result.r = max(backdrop.r, source.r) - min(backdrop.r, source.r) - result.g = max(backdrop.g, source.g) - min(backdrop.g, source.g) - result.b = max(backdrop.b, source.b) - min(backdrop.b, source.b) - result.a = blendAlpha(backdrop.a, source.a) - -proc blendExclusionPremultiplied(backdrop, source: ColorRGBA): ColorRGBA = - proc blend(backdrop, source: uint32): uint8 {.inline.} = - max(0, backdrop + source - (2 * backdrop * source) div 255).uint8 - result.r = blend(backdrop.r.uint32, source.r.uint32) - result.g = blend(backdrop.g.uint32, source.g.uint32) - result.b = blend(backdrop.b.uint32, source.b.uint32) - result.a = blendAlpha(backdrop.a, source.a) + result.a = source.a + ((backdrop.a.uint32 * k) div 255).uint8 when defined(amd64) and not defined(pixieNoSimd): proc blendNormalPremultiplied*(backdrop, source: M128i): M128i {.inline.} = @@ -477,6 +371,18 @@ else: result.b = (b div a div 255).uint8 result.a = a.uint8 +proc min(a, b: uint32): uint32 {.inline.} = + if a < b: a else: b + +proc screen(backdrop, source: uint32): uint8 {.inline.} = + (255 - ((255 - backdrop) * (255 - source)) div 255).uint8 + +proc hardLight(backdrop, source: uint32): uint8 {.inline.} = + if source <= 127: + ((backdrop * 2 * source) div 255).uint8 + else: + screen(backdrop, 2 * source - 255) + proc blendNormal(backdrop, source: ColorRGBA): ColorRGBA = blendNormalPremultiplied( backdrop.toPremultipliedAlpha(), @@ -484,74 +390,78 @@ proc blendNormal(backdrop, source: ColorRGBA): ColorRGBA = ).toStraightAlpha() proc blendDarken(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendDarkenPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = min(backdrop.r, source.r) + result.g = min(backdrop.g, source.g) + result.b = min(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendMultiply(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendMultiplyPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = ((backdrop.r.uint32 * source.r) div 255).uint8 + result.g = ((backdrop.g.uint32 * source.g) div 255).uint8 + result.b = ((backdrop.b.uint32 * source.b) div 255).uint8 + result = alphaFix(backdrop, source, result) proc blendLinearBurn(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendLinearBurnPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = min(0, backdrop.r.int16 + source.r.int16 - 255).uint8 + result.g = min(0, backdrop.g.int16 + source.g.int16 - 255).uint8 + result.b = min(0, backdrop.b.int16 + source.b.int16 - 255).uint8 + result = alphaFix(backdrop, source, result) proc blendColorBurn(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendColorBurnPremultiplied(backdrop, source) - result = result.toStraightAlpha() + proc blend(backdrop, source: uint32): uint8 {.inline.} = + if backdrop == 255: + 255.uint8 + elif source == 0: + 0 + else: + 255 - min(255, (255 * (255 - backdrop)) div source).uint8 + result.r = blend(backdrop.r, source.r) + result.g = blend(backdrop.g, source.g) + result.b = blend(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendLighten(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendLightenPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = max(backdrop.r, source.r) + result.g = max(backdrop.g, source.g) + result.b = max(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendScreen(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendScreenPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = screen(backdrop.r, source.r) + result.g = screen(backdrop.g, source.g) + result.b = screen(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendLinearDodge(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendLinearDodgePremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = min(backdrop.r.uint32 + source.r, 255).uint8 + result.g = min(backdrop.g.uint32 + source.g, 255).uint8 + result.b = min(backdrop.b.uint32 + source.b, 255).uint8 + result = alphaFix(backdrop, source, result) proc blendColorDodge(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendColorDodgePremultiplied(backdrop, source) - result = result.toStraightAlpha() + proc blend(backdrop, source: uint32): uint8 {.inline.} = + if backdrop == 0: + 0.uint8 + elif source == 255: + 255 + else: + min(255, (255 * backdrop) div (255 - source)).uint8 + result.r = blend(backdrop.r, source.r) + result.g = blend(backdrop.g, source.g) + result.b = blend(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendOverlay(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendOverlayPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = hardLight(source.r, backdrop.r) + result.g = hardLight(source.g, backdrop.g) + result.b = hardLight(source.b, backdrop.b) + result = alphaFix(backdrop, source, result) proc blendHardLight(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendHardLightyPremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = hardLight(backdrop.r, source.r) + result.g = hardLight(backdrop.g, source.g) + result.b = hardLight(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendSoftLight(backdrop, source: ColorRGBA): ColorRGBA = # proc softLight(backdrop, source: int32): uint8 {.inline.} = @@ -579,18 +489,18 @@ proc blendSoftLight(backdrop, source: ColorRGBA): ColorRGBA = blendSoftLightFloats(backdrop.color, source.color).rgba proc blendDifference(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendDifferencePremultiplied(backdrop, source) - result = result.toStraightAlpha() + result.r = max(backdrop.r, source.r) - min(backdrop.r, source.r) + result.g = max(backdrop.g, source.g) - min(backdrop.g, source.g) + result.b = max(backdrop.b, source.b) - min(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendExclusion(backdrop, source: ColorRGBA): ColorRGBA = - let - backdrop = backdrop.toPremultipliedAlpha() - source = source.toPremultipliedAlpha() - result = blendExclusionPremultiplied(backdrop, source) - result = result.toStraightAlpha() + proc blend(backdrop, source: int32): uint8 {.inline.} = + max(0, backdrop + source - (2 * backdrop * source) div 255).uint8 + result.r = blend(backdrop.r.int32, source.r.int32) + result.g = blend(backdrop.g.int32, source.g.int32) + result.b = blend(backdrop.b.int32, source.b.int32) + result = alphaFix(backdrop, source, result) proc blendColor(backdrop, source: ColorRGBA): ColorRGBA = blendColorFloats(backdrop.color, source.color).rgba @@ -610,7 +520,7 @@ proc blendMask(backdrop, source: ColorRGBA): ColorRGBA = proc blendSubtractMask(backdrop, source: ColorRGBA): ColorRGBA = result = backdrop - result.a = max(0, (backdrop.a.uint32 * (255 - source.a.uint32)) div 255).uint8 + result.a = max(0, (backdrop.a.int32 * (255 - source.a.int32)) div 255).uint8 proc blendIntersectMask(backdrop, source: ColorRGBA): ColorRGBA = result = backdrop From 90a88e4393edbaf5bf4d117bc6c075f720ed962b Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 30 Jan 2021 16:25:57 -0600 Subject: [PATCH 5/5] Revert "unused" This reverts commit 8aab92712708e509962528256e8a3b0cf25f9406. --- src/pixie/blends.nim | 216 +++++++++++++++--------------- tests/benchmark_blends.nim | 264 ++++++++++++++++++------------------- 2 files changed, 240 insertions(+), 240 deletions(-) diff --git a/src/pixie/blends.nim b/src/pixie/blends.nim index 255db39..4b4553e 100644 --- a/src/pixie/blends.nim +++ b/src/pixie/blends.nim @@ -124,18 +124,18 @@ proc `-`*(c: Color, v: float32): Color {.inline.} = result.b = c.b - v result.a = c.a - v -# proc screen(backdrop, source: float32): float32 {.inline.} = -# 1 - (1 - backdrop) * (1 - source) +proc screen(backdrop, source: float32): float32 {.inline.} = + 1 - (1 - backdrop) * (1 - source) -# proc hardLight(backdrop, source: float32): float32 {.inline.} = -# if source <= 0.5: -# backdrop * 2 * source -# else: -# screen(backdrop, 2 * source - 1) +proc hardLight(backdrop, source: float32): float32 {.inline.} = + if source <= 0.5: + backdrop * 2 * source + else: + screen(backdrop, 2 * source - 1) -# proc softLight(backdrop, source: float32): float32 {.inline.} = -# ## Pegtop -# (1 - 2 * source) * backdrop ^ 2 + 2 * source * backdrop +proc softLight(backdrop, source: float32): float32 {.inline.} = + ## Pegtop + (1 - 2 * source) * backdrop ^ 2 + 2 * source * backdrop proc Lum(C: Color): float32 {.inline.} = 0.3 * C.r + 0.59 * C.g + 0.11 * C.b @@ -183,103 +183,103 @@ proc alphaFix(backdrop, source, mixed: Color): Color = result.g /= result.a result.b /= result.a -# proc blendNormalFloats*(backdrop, source: Color): Color {.inline.} = -# result = source -# result = alphaFix(backdrop, source, result) +proc blendNormalFloats*(backdrop, source: Color): Color {.inline.} = + result = source + result = alphaFix(backdrop, source, result) -# proc blendDarkenFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = min(backdrop.r, source.r) -# result.g = min(backdrop.g, source.g) -# result.b = min(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendDarkenFloats*(backdrop, source: Color): Color {.inline.} = + result.r = min(backdrop.r, source.r) + result.g = min(backdrop.g, source.g) + result.b = min(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendMultiplyFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = backdrop.r * source.r -# result.g = backdrop.g * source.g -# result.b = backdrop.b * source.b -# result = alphaFix(backdrop, source, result) +proc blendMultiplyFloats*(backdrop, source: Color): Color {.inline.} = + result.r = backdrop.r * source.r + result.g = backdrop.g * source.g + result.b = backdrop.b * source.b + result = alphaFix(backdrop, source, result) -# proc blendLinearBurnFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = backdrop.r + source.r - 1 -# result.g = backdrop.g + source.g - 1 -# result.b = backdrop.b + source.b - 1 -# result = alphaFix(backdrop, source, result) +proc blendLinearBurnFloats*(backdrop, source: Color): Color {.inline.} = + result.r = backdrop.r + source.r - 1 + result.g = backdrop.g + source.g - 1 + result.b = backdrop.b + source.b - 1 + result = alphaFix(backdrop, source, result) -# proc blendColorBurnFloats*(backdrop, source: Color): Color {.inline.} = -# proc blend(backdrop, source: float32): float32 {.inline.} = -# if backdrop == 1: -# 1.0 -# elif source == 0: -# 0.0 -# else: -# 1.0 - min(1, (1 - backdrop) / source) -# result.r = blend(backdrop.r, source.r) -# result.g = blend(backdrop.g, source.g) -# result.b = blend(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendColorBurnFloats*(backdrop, source: Color): Color {.inline.} = + proc blend(backdrop, source: float32): float32 {.inline.} = + if backdrop == 1: + 1.0 + elif source == 0: + 0.0 + else: + 1.0 - min(1, (1 - backdrop) / source) + result.r = blend(backdrop.r, source.r) + result.g = blend(backdrop.g, source.g) + result.b = blend(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendLightenFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = max(backdrop.r, source.r) -# result.g = max(backdrop.g, source.g) -# result.b = max(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendLightenFloats*(backdrop, source: Color): Color {.inline.} = + result.r = max(backdrop.r, source.r) + result.g = max(backdrop.g, source.g) + result.b = max(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendScreenFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = screen(backdrop.r, source.r) -# result.g = screen(backdrop.g, source.g) -# result.b = screen(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendScreenFloats*(backdrop, source: Color): Color {.inline.} = + result.r = screen(backdrop.r, source.r) + result.g = screen(backdrop.g, source.g) + result.b = screen(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendLinearDodgeFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = backdrop.r + source.r -# result.g = backdrop.g + source.g -# result.b = backdrop.b + source.b -# result = alphaFix(backdrop, source, result) +proc blendLinearDodgeFloats*(backdrop, source: Color): Color {.inline.} = + result.r = backdrop.r + source.r + result.g = backdrop.g + source.g + result.b = backdrop.b + source.b + result = alphaFix(backdrop, source, result) -# proc blendColorDodgeFloats*(backdrop, source: Color): Color {.inline.} = -# proc blend(backdrop, source: float32): float32 {.inline.} = -# if backdrop == 0: -# 0.0 -# elif source == 1: -# 1.0 -# else: -# min(1, backdrop / (1 - source)) -# result.r = blend(backdrop.r, source.r) -# result.g = blend(backdrop.g, source.g) -# result.b = blend(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendColorDodgeFloats*(backdrop, source: Color): Color {.inline.} = + proc blend(backdrop, source: float32): float32 {.inline.} = + if backdrop == 0: + 0.0 + elif source == 1: + 1.0 + else: + min(1, backdrop / (1 - source)) + result.r = blend(backdrop.r, source.r) + result.g = blend(backdrop.g, source.g) + result.b = blend(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendOverlayFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = hardLight(source.r, backdrop.r) -# result.g = hardLight(source.g, backdrop.g) -# result.b = hardLight(source.b, backdrop.b) -# result = alphaFix(backdrop, source, result) +proc blendOverlayFloats*(backdrop, source: Color): Color {.inline.} = + result.r = hardLight(source.r, backdrop.r) + result.g = hardLight(source.g, backdrop.g) + result.b = hardLight(source.b, backdrop.b) + result = alphaFix(backdrop, source, result) -# proc blendHardLightFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = hardLight(backdrop.r, source.r) -# result.g = hardLight(backdrop.g, source.g) -# result.b = hardLight(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendHardLightFloats*(backdrop, source: Color): Color {.inline.} = + result.r = hardLight(backdrop.r, source.r) + result.g = hardLight(backdrop.g, source.g) + result.b = hardLight(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendSoftLightFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = softLight(backdrop.r, source.r) -# result.g = softLight(backdrop.g, source.g) -# result.b = softLight(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendSoftLightFloats*(backdrop, source: Color): Color {.inline.} = + result.r = softLight(backdrop.r, source.r) + result.g = softLight(backdrop.g, source.g) + result.b = softLight(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) -# proc blendDifferenceFloats*(backdrop, source: Color): Color {.inline.} = -# result.r = abs(backdrop.r - source.r) -# result.g = abs(backdrop.g - source.g) -# result.b = abs(backdrop.b - source.b) -# result = alphaFix(backdrop, source, result) +proc blendDifferenceFloats*(backdrop, source: Color): Color {.inline.} = + result.r = abs(backdrop.r - source.r) + result.g = abs(backdrop.g - source.g) + result.b = abs(backdrop.b - source.b) + result = alphaFix(backdrop, source, result) -# proc blendExclusionFloats*(backdrop, source: Color): Color {.inline.} = -# proc blend(backdrop, source: float32): float32 {.inline.} = -# backdrop + source - 2 * backdrop * source -# result.r = blend(backdrop.r, source.r) -# result.g = blend(backdrop.g, source.g) -# result.b = blend(backdrop.b, source.b) -# result = alphaFix(backdrop, source, result) +proc blendExclusionFloats*(backdrop, source: Color): Color {.inline.} = + proc blend(backdrop, source: float32): float32 {.inline.} = + backdrop + source - 2 * backdrop * source + result.r = blend(backdrop.r, source.r) + result.g = blend(backdrop.g, source.g) + result.b = blend(backdrop.b, source.b) + result = alphaFix(backdrop, source, result) proc blendColorFloats*(backdrop, source: Color): Color {.inline.} = result = SetLum(source, Lum(backdrop)) @@ -297,24 +297,24 @@ proc blendSaturationFloats*(backdrop, source: Color): Color {.inline.} = result = SetLum(SetSat(backdrop, Sat(source)), Lum(backdrop)) result = alphaFix(backdrop, source, result) -# proc blendMaskFloats*(backdrop, source: Color): Color {.inline.} = -# result = backdrop -# result.a = min(backdrop.a, source.a) +proc blendMaskFloats*(backdrop, source: Color): Color {.inline.} = + result = backdrop + result.a = min(backdrop.a, source.a) -# proc blendSubtractMaskFloats*(backdrop, source: Color): Color {.inline.} = -# result = backdrop -# result.a = backdrop.a * (1 - source.a) +proc blendSubtractMaskFloats*(backdrop, source: Color): Color {.inline.} = + result = backdrop + result.a = backdrop.a * (1 - source.a) -# proc blendIntersectMaskFloats*(backdrop, source: Color): Color {.inline.} = -# result = backdrop -# result.a = backdrop.a * source.a +proc blendIntersectMaskFloats*(backdrop, source: Color): Color {.inline.} = + result = backdrop + result.a = backdrop.a * source.a -# proc blendExcludeMaskFloats*(backdrop, source: Color): Color {.inline.} = -# result = backdrop -# result.a = abs(backdrop.a - source.a) +proc blendExcludeMaskFloats*(backdrop, source: Color): Color {.inline.} = + result = backdrop + result.a = abs(backdrop.a - source.a) -# proc blendOverwriteFloats*(backdrop, source: Color): Color {.inline.} = -# source +proc blendOverwriteFloats*(backdrop, source: Color): Color {.inline.} = + source when defined(amd64) and not defined(pixieNoSimd): proc alphaFix(backdrop, source: ColorRGBA, vb, vs, vm: M128): ColorRGBA = diff --git a/tests/benchmark_blends.nim b/tests/benchmark_blends.nim index b424468..98a0b07 100644 --- a/tests/benchmark_blends.nim +++ b/tests/benchmark_blends.nim @@ -1,4 +1,4 @@ -import benchy, chroma, pixie/images +import benchy, chroma, vmath, pixie/images include pixie/blends @@ -18,13 +18,13 @@ timeIt "blendNormal": reset() -# timeIt "blendNormalFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendNormalFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendNormalFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendNormalFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendDarken": for i in 0 ..< backdrop.data.len: @@ -32,13 +32,13 @@ timeIt "blendDarken": reset() -# timeIt "blendDarkenFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendDarkenFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendDarkenFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendDarkenFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendMultiply": for i in 0 ..< backdrop.data.len: @@ -46,13 +46,13 @@ timeIt "blendMultiply": reset() -# timeIt "blendMultiplyFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendMultiplyFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendMultiplyFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendMultiplyFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendLinearBurn": for i in 0 ..< backdrop.data.len: @@ -60,13 +60,13 @@ timeIt "blendLinearBurn": reset() -# timeIt "blendLinearBurnFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendLinearBurnFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendLinearBurnFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendLinearBurnFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendColorBurn": for i in 0 ..< backdrop.data.len: @@ -74,13 +74,13 @@ timeIt "blendColorBurn": reset() -# timeIt "blendColorBurnFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendColorBurnFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendColorBurnFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendColorBurnFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendLighten": for i in 0 ..< backdrop.data.len: @@ -88,13 +88,13 @@ timeIt "blendLighten": reset() -# timeIt "blendLightenFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendLightenFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendLightenFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendLightenFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendScreen": for i in 0 ..< backdrop.data.len: @@ -102,13 +102,13 @@ timeIt "blendScreen": reset() -# timeIt "blendScreenFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendScreenFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendScreenFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendScreenFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendLinearDodge": for i in 0 ..< backdrop.data.len: @@ -116,13 +116,13 @@ timeIt "blendLinearDodge": reset() -# timeIt "blendLinearDodgeFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendLinearDodgeFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendLinearDodgeFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendLinearDodgeFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendColorDodge": for i in 0 ..< backdrop.data.len: @@ -130,13 +130,13 @@ timeIt "blendColorDodge": reset() -# timeIt "blendColorDodgeFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendColorDodgeFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendColorDodgeFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendColorDodgeFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendOverlay": for i in 0 ..< backdrop.data.len: @@ -144,13 +144,13 @@ timeIt "blendOverlay": reset() -# timeIt "blendOverlayFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendOverlayFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendOverlayFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendOverlayFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendSoftLight": for i in 0 ..< backdrop.data.len: @@ -158,13 +158,13 @@ timeIt "blendSoftLight": reset() -# timeIt "blendSoftLightFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendSoftLightFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendSoftLightFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendSoftLightFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendHardLight": for i in 0 ..< backdrop.data.len: @@ -172,13 +172,13 @@ timeIt "blendHardLight": reset() -# timeIt "blendHardLightFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendHardLightFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendHardLightFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendHardLightFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendDifference": for i in 0 ..< backdrop.data.len: @@ -186,13 +186,13 @@ timeIt "blendDifference": reset() -# timeIt "blendDifferenceFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendDifferenceFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendDifferenceFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendDifferenceFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendExclusion": for i in 0 ..< backdrop.data.len: @@ -200,13 +200,13 @@ timeIt "blendExclusion": reset() -# timeIt "blendExclusionFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendExclusionFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendExclusionFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendExclusionFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendHue": for i in 0 ..< backdrop.data.len: @@ -214,13 +214,13 @@ timeIt "blendHue": reset() -# timeIt "blendHueFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendHueFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendHueFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendHueFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendSaturation": for i in 0 ..< backdrop.data.len: @@ -228,11 +228,11 @@ timeIt "blendSaturation": reset() -# timeIt "blendSaturationFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendSaturationFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendSaturationFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendSaturationFloats( + backdrop.data[i].color, source.data[i].color + ).rgba reset() @@ -242,13 +242,13 @@ timeIt "blendColor": reset() -# timeIt "blendColorFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendColorFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendColorFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendColorFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendLuminosity": for i in 0 ..< backdrop.data.len: @@ -256,13 +256,13 @@ timeIt "blendLuminosity": reset() -# timeIt "blendLuminosityFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendLuminosityFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendLuminosityFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendLuminosityFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendMask": for i in 0 ..< backdrop.data.len: @@ -270,13 +270,13 @@ timeIt "blendMask": reset() -# timeIt "blendMaskFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendMaskFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendMaskFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendMaskFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendSubtractMask": for i in 0 ..< backdrop.data.len: @@ -284,13 +284,13 @@ timeIt "blendSubtractMask": reset() -# timeIt "blendSubtractMaskFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendSubtractMaskFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendSubtractMaskFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendSubtractMaskFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendIntersectMask": for i in 0 ..< backdrop.data.len: @@ -298,13 +298,13 @@ timeIt "blendIntersectMask": reset() -# timeIt "blendIntersectMaskFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendIntersectMaskFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendIntersectMaskFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendIntersectMaskFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendExcludeMask": for i in 0 ..< backdrop.data.len: @@ -312,13 +312,13 @@ timeIt "blendExcludeMask": reset() -# timeIt "blendExcludeMaskFloats": -# for i in 0 ..< backdrop.data.len: -# backdrop.data[i] = blendExcludeMaskFloats( -# backdrop.data[i].color, source.data[i].color -# ).rgba +timeIt "blendExcludeMaskFloats": + for i in 0 ..< backdrop.data.len: + backdrop.data[i] = blendExcludeMaskFloats( + backdrop.data[i].color, source.data[i].color + ).rgba -# reset() +reset() timeIt "blendNormalPremultiplied": for i in 0 ..< backdrop.data.len: