From 7e519e75019207d42d0aebe1add4d6675be666e1 Mon Sep 17 00:00:00 2001 From: Dan Manning Date: Mon, 5 Nov 2018 13:27:08 -0600 Subject: [PATCH] ImageSharp-762_Aot-compiling: moved AoT methods to AotCompiler static class --- src/ImageSharp/Advanced/AotCompiler.cs | 103 ++++++++++++++++++ src/ImageSharp/Formats/Gif/ImageExtensions.cs | 42 ------- 2 files changed, 103 insertions(+), 42 deletions(-) create mode 100644 src/ImageSharp/Advanced/AotCompiler.cs diff --git a/src/ImageSharp/Advanced/AotCompiler.cs b/src/ImageSharp/Advanced/AotCompiler.cs new file mode 100644 index 000000000..1c7f12ef7 --- /dev/null +++ b/src/ImageSharp/Advanced/AotCompiler.cs @@ -0,0 +1,103 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Dithering; +using SixLabors.ImageSharp.Processing.Processors.Quantization; + +namespace SixLabors.ImageSharp.Advanced +{ + /// + /// Unlike traditional Mono/.NET, code on the iPhone is statically compiled ahead of time instead of being + /// compiled on demand by a JIT compiler. This means there are a few limitations with respect to generics, + /// these are caused because not every possible generic instantiation can be determined up front at compile time. + /// The Aot Compiler is designed to overcome the limitations of this compiler. + /// + public static class AotCompiler + { + /// + /// Seeds the compiler using the given pixel format. + /// + /// The pixel format. + public static void Seed() + where TPixel : struct, IPixel + { + // This is we actually call all the individual methods you need to seed. + AotCompileOctreeQuantizer(); + AotCompileWuQuantizer(); + AotCompileDithering(); + + // TODO: Do the discovery work to figure out what works and what doesn't. + } + + /// + /// Seeds the compiler using the given pixel formats. + /// + /// The first pixel format. + /// The second pixel format. + public static void Seed() + where TPixel : struct, IPixel + where TPixel2 : struct, IPixel + { + Seed(); + Seed(); + } + + /// + /// Seeds the compiler using the given pixel formats. + /// + /// The first pixel format. + /// The second pixel format. + /// The third pixel format. + public static void Seed() + where TPixel : struct, IPixel + where TPixel2 : struct, IPixel + where TPixel3 : struct, IPixel + { + Seed(); + Seed(); + } + + /// + /// This method doesn't actually do anything but serves an important purpose... + /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion: + /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode." + /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT + /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on + /// iOS so it bombs out. + /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the + /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!! + /// + /// The pixel format. + private static void AotCompileOctreeQuantizer() + where TPixel : struct, IPixel + { + var test = new OctreeFrameQuantizer(new OctreeQuantizer(false)); + test.AotGetPalette(); + } + + /// + /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS. + /// + /// The pixel format. + private static void AotCompileWuQuantizer() + where TPixel : struct, IPixel + { + var test = new WuFrameQuantizer(new WuQuantizer(false)); + test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1)); + test.AotGetPalette(); + } + + /// + /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. + /// + /// The pixel format. + private static void AotCompileDithering() + where TPixel : struct, IPixel + { + var test = new FloydSteinbergDiffuser(); + TPixel pixel = default; + test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs index f1c2ae5fb..3939299e9 100644 --- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs @@ -38,47 +38,5 @@ namespace SixLabors.ImageSharp public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder) where TPixel : struct, IPixel => source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance)); - - /// - /// This method doesn't actually do anything but serves an important purpose... - /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion: - /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode." - /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT - /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on - /// iOS so it bombs out. - /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the - /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!! - /// - /// The pixel format. - public static void AotCompileOctreeQuantizer() - where TPixel : struct, IPixel - { - var test = new OctreeFrameQuantizer(new OctreeQuantizer(false)); - test.AotGetPalette(); - } - - /// - /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS. - /// - /// The pixel format. - public static void AotCompileWuQuantizer() - where TPixel : struct, IPixel - { - var test = new WuFrameQuantizer(new WuQuantizer(false)); - test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1)); - test.AotGetPalette(); - } - - /// - /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS. - /// - /// The pixel format. - public static void AotCompileDithering() - where TPixel : struct, IPixel - { - var test = new FloydSteinbergDiffuser(); - TPixel pixel = default; - test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); - } } }