internal void Begin([NotNull] AttractorModel attractor) { if (attractor == null) { throw new ArgumentNullException(nameof(attractor)); } Statistics.Reset(attractor); PerformanceCounter.Reset(); _stopwatch.Reset(); lock (_randomLock) { _random = new Random((int)DateTime.Now.Ticks); } if (!Equals(attractor, _attractor)) { _attractor = attractor; _transforms = attractor.Transforms.ToArray(); _colors = attractor.ColorMap.Render(1024); _selector = new TransformSelector(_transforms); } _onBeginning?.Invoke(); PerformanceCounter.Start(); _stopwatch.Start(); }
internal void Reset([NotNull] AttractorModel attractor) { if (!IsEnabled) { return; } lock (_stLock) { _hitCounters = new int[attractor.Transforms.Count]; _min = new Vertex(double.NaN, double.NaN); _max = new Vertex(double.NaN, double.NaN); } }
public void Iterate([NotNull] AttractorModel attractor, double density, CancellationToken cancellationToken = default) { if (attractor == null) { throw new ArgumentNullException(nameof(attractor)); } if (density <= 0 || cancellationToken.IsCancellationRequested) { return; } var batchSize = mBatchSize; var totalSize = (long)Math.Ceiling(_context.BackBuffer.BufferSize * density); _configuration?.Invoke(_context); var batchCount = (int)Math.Ceiling((double)totalSize / batchSize); var threads = Enumerable.Range(0, batchCount).Select(x => new IterationThread(_context)).ToArray(); using (new Scope(() => _context.Begin(attractor), () => _context.End(threads.Length, density)).Enter()) { var parallelOptions = new ParallelOptions(); if (!AllowMultithreading) { parallelOptions.MaxDegreeOfParallelism = 1; batchSize = (long)Math.Ceiling(_context.BackBuffer.BufferSize * density); } if (cancellationToken.IsCancellationRequested) { return; } Parallel.ForEach(threads, parallelOptions, thread => ProcessBatch(thread, batchSize, cancellationToken)); } if (cancellationToken.IsCancellationRequested) { return; } using (_context.PerformanceCounter.EnterMeasureScope("Bitmap processing")) { _context.BackBuffer.ProcessImage(this, _context, cancellationToken); } }
public void Iterate([NotNull] AttractorModel attractor, CancellationToken cancellationToken = default) => Iterate(attractor, 1, cancellationToken);
protected override IResult Execute(CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(FormulaFile)) { WriteHelp(); return(Result.Success); } Log.Write("Preparing..."); var formulaFileName = Path.GetFileName(FormulaFile); var directory = new FileSystemStore(Path.GetDirectoryName(FormulaFile) ?? throw new FileNotFoundException("Unable to access formula file", FormulaFile)); var size = Resolution <= 0 ? 512 : Resolution; using (var backBuffer = new BackBuffer(size, size)) { using var bitmap = new Bitmap(backBuffer.Width, backBuffer.Height, PixelFormat.Format32bppArgb); using var diagnostics = new DiagnosticsWindow(); using var preview = new PreviewControl(backBuffer, bitmap); var formula = AttractorModel.FromJson(directory.Open(formulaFileName).AsText()); var iterator = new Iterator(backBuffer).Configure(config => config .Statistics(s => s.SetEnabled(Trace)) .PerformanceCounter(s => s.SetEnabled(Trace)) .OnFinalize(WriteHeader) .Log(Log)); iterator.AllowMultithreading = !ForceSingleThreading; var n = 0; using (var bitmapG = Graphics.FromImage(bitmap)) { bitmapG.FillRectangle(Brushes.Black, 0, 0, bitmap.Width, bitmap.Height); } preview.SampleCallback = (sample, stats) => { diagnostics.Invoke(new Action( () => { diagnostics.brightness.Series[0].Points.AddXY(iterator.GetCurrentDensity(), stats.AverageBrightness); diagnostics.peakPoint.Series[0].Points.AddXY(iterator.GetCurrentDensity(), stats.HighAccumulator); diagnostics.peakPoint.Series[1].Points.AddXY(iterator.GetCurrentDensity(), stats.LowAccumulator); })); }; preview.RenderCallback = () => { var cd = iterator.GetCurrentDensity(); var increment = cd < 10 ? 1 : GetDensity(++n) / 10.0; // ReSharper disable once MethodSupportsCancellation iterator.Iterate(formula, increment); _totalDensity = iterator.GetCurrentDensity(); }; preview.Dock = DockStyle.Fill; diagnostics.histogramPanel.Controls.Add(preview); var thread = new Thread(() => preview.RenderLoop(() => !preview.Visible)) { IsBackground = true }; diagnostics.Shown += (o, e) => thread.Start(); diagnostics.ShowDialog(); } return(Result.Success); }