Browse Source

exploring an alternative way of generating methods

af/merge-core
Vicente Penades 8 years ago
parent
commit
ac9002e302
  1. 3077
      src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs
  2. 177
      src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt
  3. 157
      src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.cs

3077
src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs

File diff suppressed because it is too large

177
src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt

@ -21,6 +21,8 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
internal static partial class PorterDuffFunctions
{
<# void GenerateVectorCompositor(string name, string sourceVar, string destVar, string blendVar)
{
int a_s = sourceVar == "Vector4.Zero" ? 0 : 1;
@ -45,55 +47,152 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
return xform;
}
<# } #>
<# void GeneratePixelBlender(string blender, string compositor) { #>
<# void GeneratePixelBlenders(string blender) { #>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_<#=compositor#>(Vector4 backdrop, Vector4 source, float opacity)
public static Vector4 <#=blender#>_Src(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return <#=compositor#>(backdrop,source, <#=blender#>(backdrop, source));
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return Src(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPixel <#=blender#>_<#=compositor#><TPixel>(TPixel backdrop, TPixel source, float opacity)
where TPixel : struct, IPixel<TPixel>
public static Vector4 <#=blender#>_SrcAtop(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return SrcAtop(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_SrcOver(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return SrcOver(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_SrcIn(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return SrcIn(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_SrcOut(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return SrcOut(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_Dest(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return Dest(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_DestAtop(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return DestAtop(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_DestOver(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
Vector4 backdropV = backdrop.ToVector4();
Vector4 sourceV = source.ToVector4();
sourceV.W *= opacity;
return DestOver(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_DestIn(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return DestIn(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_DestOut(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return DestOut(backdrop, source, <#=blender#>(backdrop, source));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_Clear(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return Clear(backdrop, source, source);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 <#=blender#>_Xor(Vector4 backdrop, Vector4 source, float opacity)
{
opacity = opacity.Clamp(0, 1);
source.W *= opacity;
return Xor(backdrop, source, source);
}
<# } #>
<# void GenerateGenericPixelBlender(string blender, string composer) { #>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPixel <#=blender#>_<#=composer#><TPixel>(TPixel backdrop, TPixel source, float opacity)
where TPixel : struct, IPixel<TPixel>
{
TPixel dest = default;
dest.PackFromVector4(<#=compositor#>(backdropV,sourceV, <#=blender#>(backdropV, sourceV)));
dest.PackFromVector4(<#=blender#>_<#=composer#>(backdrop.ToVector4(),source.ToVector4(),opacity));
return dest;
}
}
<# } #>
#region Compositors
#region Blenders
<#
GenerateVectorCompositor("Src", "source", "Vector4.Zero", "xform");
GenerateVectorCompositor("SrcAtop", "Vector4.Zero", "backdrop", "xform");
GenerateVectorCompositor("SrcOver", "source", "backdrop", "xform");
GenerateVectorCompositor("SrcIn", "Vector4.Zero", "Vector4.Zero", "xform");
GenerateVectorCompositor("SrcOut", "source", "Vector4.Zero", "Vector4.Zero");
GenerateVectorCompositor("Dest", "Vector4.Zero", "backdrop", "backdrop");
GenerateVectorCompositor("DestAtop", "source", "Vector4.Zero", "backdrop");
GenerateVectorCompositor("DestOver", "source", "backdrop", "backdrop");
GenerateVectorCompositor("DestIn", "Vector4.Zero", "Vector4.Zero", "backdrop");
GenerateVectorCompositor("DestOut", "Vector4.Zero", "backdrop", "Vector4.Zero");
GenerateVectorCompositor("Clear", "Vector4.Zero", "Vector4.Zero", "Vector4.Zero");
GenerateVectorCompositor("Xor", "source", "backdrop", "Vector4.Zero");
#>
#endregion
// GenerateVectorCompositor("Src", "source", "Vector4.Zero", "xform");
GenerateVectorCompositor("SrcAtop", "Vector4.Zero", "backdrop", "xform");
GenerateVectorCompositor("SrcOver", "source", "backdrop", "xform");
// GenerateVectorCompositor("SrcIn", "Vector4.Zero", "Vector4.Zero", "xform");
// GenerateVectorCompositor("SrcOut", "source", "Vector4.Zero", "Vector4.Zero");
GenerateVectorCompositor("Dest", "Vector4.Zero", "backdrop", "backdrop");
// GenerateVectorCompositor("DestAtop", "source", "Vector4.Zero", "backdrop");
// GenerateVectorCompositor("DestOver", "source", "backdrop", "backdrop");
// GenerateVectorCompositor("DestIn", "Vector4.Zero", "Vector4.Zero", "backdrop");
GenerateVectorCompositor("DestOut", "Vector4.Zero", "backdrop", "Vector4.Zero");
// GenerateVectorCompositor("Clear", "Vector4.Zero", "Vector4.Zero", "Vector4.Zero");
GenerateVectorCompositor("Xor", "source", "backdrop", "Vector4.Zero");
#region Blenders
<#
string[] composers = new []{
"Src" ,
"SrcAtop" ,
@ -121,14 +220,16 @@ string[] blenders = new []{
"HardLight"
};
foreach(var composer in composers)
{
foreach(var blender in blenders)
{
GeneratePixelBlender(blender,composer);
{
GeneratePixelBlenders(blender);
foreach(var composer in composers)
{
GenerateGenericPixelBlender(blender,composer);
}
}
}
#>
#endregion

157
src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.cs

@ -20,11 +20,13 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </remarks>
internal static partial class PorterDuffFunctions
{
#region color blenders
/// <summary>
/// Source over backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Normal(Vector4 backdrop, Vector4 source)
@ -36,7 +38,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Source multiplied by backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Multiply(Vector4 backdrop, Vector4 source)
@ -48,7 +50,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Source added to backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Add(Vector4 backdrop, Vector4 source)
@ -60,7 +62,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Source subtracted from backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Subtract(Vector4 backdrop, Vector4 source)
@ -72,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Complement of source multiplied by the complement of backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Screen(Vector4 backdrop, Vector4 source)
@ -84,7 +86,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Per element, chooses the smallest value of source and backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Darken(Vector4 backdrop, Vector4 source)
@ -96,7 +98,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Per element, chooses the largest value of source and backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Lighten(Vector4 backdrop, Vector4 source)
@ -108,7 +110,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Overlays source over backdrop
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Overlay(Vector4 backdrop, Vector4 source)
@ -124,7 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// Hard light effect
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 HardLight(Vector4 backdrop, Vector4 source)
@ -148,6 +150,10 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
return backdrop <= 0.5f ? (2 * backdrop * source) : 1 - ((2 * (1 - source)) * (1 - backdrop));
}
#endregion
#region alpha composers
/// <summary>
/// General composition function for all modes, with a general solution for alpha channel
/// </summary>
@ -155,11 +161,8 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// <param name="source">Original source color</param>
/// <param name="xform">Desired transformed color, without taking Alpha channel in account</param>
/// <returns>The final color</returns>
/// <remarks>
/// This is the default compositor for "normal" alpha blending, which matches the generated SrcOver compositor.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 Compose(Vector4 backdrop, Vector4 source, Vector4 xform)
private static Vector4 SrcOver_Reference(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
@ -175,5 +178,133 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
return xform;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Src(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
float bw = backdrop.W - xw;
float sw = source.W - xw;
// calculate final alpha
float fw = (sw * 1) + (bw * 0) + (xw * 1);
// calculate final value
xform = ((xform * xw) + (Vector4.Zero * bw) + (source * sw)) / MathF.Max(fw, Constants.Epsilon);
xform.W = fw;
return Vector4.Lerp(backdrop, xform, source.W);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 SrcIn(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
// calculate final value
xform.W = xw;
return Vector4.Lerp(backdrop, xform, source.W);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 SrcOut(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
float bw = backdrop.W - xw;
float sw = source.W - xw;
// calculate final alpha
float fw = sw;
// calculate final value
xform = source;
xform.W = fw;
return Vector4.Lerp(backdrop, xform, source.W);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 DestAtop(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
float bw = backdrop.W - xw;
float sw = source.W - xw;
// calculate final alpha
float fw = (sw * 1) + (bw * 0) + (xw * 1);
// calculate final value
xform = ((backdrop * xw) + (Vector4.Zero * bw) + (source * sw)) / MathF.Max(fw, Constants.Epsilon);
xform.W = fw;
return Vector4.Lerp(backdrop, xform, source.W);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 DestOver(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
float bw = backdrop.W - xw;
float sw = source.W - xw;
// calculate final alpha
float fw = (sw * 1) + (bw * 1) + (xw * 1);
// calculate final value
xform = ((backdrop * xw) + (backdrop * bw) + (source * sw)) / MathF.Max(fw, Constants.Epsilon);
xform.W = fw;
return Vector4.Lerp(backdrop, xform, source.W);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 DestIn(Vector4 backdrop, Vector4 source, Vector4 xform)
{
// calculate weights
float xw = backdrop.W * source.W;
float bw = backdrop.W - xw;
float sw = source.W - xw;
// calculate final alpha
float fw = (sw * 0) + (bw * 0) + (xw * 1);
// calculate final value
xform = ((backdrop * xw) + (Vector4.Zero * bw) + (Vector4.Zero * sw)) / MathF.Max(fw, Constants.Epsilon);
xform.W = fw;
return Vector4.Lerp(backdrop, xform, source.W);
}
/// <summary>
/// General composition function for all modes, with a general solution for alpha channel
/// </summary>
/// <param name="backdrop">Original Backdrop color</param>
/// <param name="source">Original source color</param>
/// <param name="xform">Desired transformed color, without taking Alpha channel in account</param>
/// <returns>The final color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 Clear(Vector4 backdrop, Vector4 source, Vector4 xform)
{
return Vector4.Lerp(backdrop, Vector4.Zero, xform.W);
}
#endregion
}
}
Loading…
Cancel
Save