// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Jobs; using SixLabors.ImageSharp.Formats.Heif.Av1.Pipeline.SuperResolution; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Heif; /// /// Measures normative AV1 super-resolution filtering across a full-HD luma plane. /// [Config(typeof(Configuration))] [MemoryDiagnoser(displayGenColumns: false)] [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] [CategoriesColumn] public class Av1SuperResolutionBenchmarks { /// /// The displayed luma width after normative upscaling. /// private const int UpscaledWidth = 1920; /// /// The coded luma width produced by a fixed super-resolution denominator of twelve. /// private const int CodedWidth = 1280; /// /// The number of visible rows in the measured luma plane. /// private const int Height = 1080; /// /// The fixed-point source-position increment for the measured scale ratio. /// private readonly int step = Av1SuperResolutionFilter.GetConvolveStep(CodedWidth, UpscaledWidth); /// /// The initial fixed-point source position for the measured scale ratio. /// private readonly int initialSubpixel; /// /// The replicated-edge eight-bit source row. /// private readonly byte[] source8 = new byte[CodedWidth + (Av1SuperResolutionFilter.SourceBorder * 2)]; /// /// The filtered eight-bit output row. /// private readonly byte[] destination8 = new byte[UpscaledWidth]; /// /// The replicated-edge twelve-bit source row. /// private readonly ushort[] source12 = new ushort[CodedWidth + (Av1SuperResolutionFilter.SourceBorder * 2)]; /// /// The filtered twelve-bit output row. /// private readonly ushort[] destination12 = new ushort[UpscaledWidth]; /// /// Initializes a new instance of the class. /// public Av1SuperResolutionBenchmarks() { this.initialSubpixel = Av1SuperResolutionFilter.GetInitialSubpixel(CodedWidth, UpscaledWidth, this.step); } /// /// Populates deterministic source samples and their replicated frame edges outside the measured traversal. /// [GlobalSetup] public void Setup() { Span reconstructed8 = this.source8.AsSpan(Av1SuperResolutionFilter.SourceBorder, CodedWidth); Span reconstructed12 = this.source12.AsSpan(Av1SuperResolutionFilter.SourceBorder, CodedWidth); for (int column = 0; column < CodedWidth; column++) { int sample = ((column * 4051) + 127) & byte.MaxValue; reconstructed8[column] = (byte)sample; reconstructed12[column] = (ushort)(sample << 4); } this.source8.AsSpan(0, Av1SuperResolutionFilter.SourceBorder).Fill(reconstructed8[0]); this.source8.AsSpan(Av1SuperResolutionFilter.SourceBorder + CodedWidth).Fill(reconstructed8[^1]); this.source12.AsSpan(0, Av1SuperResolutionFilter.SourceBorder).Fill(reconstructed12[0]); this.source12.AsSpan(Av1SuperResolutionFilter.SourceBorder + CodedWidth).Fill(reconstructed12[^1]); } /// /// Measures normative eight-bit filtering for a full-HD luma plane. /// /// The final filtered sample, keeping the output observable. [Benchmark] [BenchmarkCategory("8Bit")] public byte Filter8BitPlane() { for (int row = 0; row < Height; row++) { Av1SuperResolutionFilter.UpscaleRow(this.source8, this.destination8, this.step, this.initialSubpixel); } return this.destination8[^1]; } /// /// Measures normative twelve-bit filtering for a full-HD luma plane. /// /// The final filtered sample, keeping the output observable. [Benchmark] [BenchmarkCategory("12Bit")] public ushort Filter12BitPlane() { for (int row = 0; row < Height; row++) { Av1SuperResolutionFilter.UpscaleRow(this.source12, this.destination12, this.step, this.initialSubpixel, 12); } return this.destination12[^1]; } /// /// Configures production-process measurements for hardware and scalar filtering. /// public sealed class Configuration : ManualConfig { /// /// Initializes a new instance of the class. /// public Configuration() { this.AddJob(Job.ShortRun.WithId("Hardware").AsBaseline()); this.AddJob( Job.ShortRun .WithId("Scalar") .WithEnvironmentVariable("DOTNET_EnableHWIntrinsic", "0")); } } }