internal static CalculationOptions[] Split(CalculationOptions options, uint tasks)
        {
            Queue<CalculationOptions> t1 = new Queue<CalculationOptions>();
            Queue<CalculationOptions> t2 = new Queue<CalculationOptions>();

            t1.Enqueue(options);

            tasks = (uint)Math.Pow(4, Math.Ceiling(Math.Log(tasks) / Math.Log(4)));

            while (tasks > 0)
            {
                while (t1.Count > 0)
                {
                    CalculationOptions t = t1.Dequeue();
                    foreach (CalculationOptions spl in SplitInFour(t))
                    {
                        t2.Enqueue(spl);
                    }
                }
                tasks /= 4;
                t1 = t2;
                t2 = new Queue<CalculationOptions>();
            }

            return t1.ToArray();
        }
        internal static CalculationOptions[] SplitInFour(CalculationOptions options)
        {
            CalculationOptions[] opt = new CalculationOptions[4];

            opt[0] = options.Duplicate();
            opt[0].XSkip *= 2;
            opt[0].YSkip *= 2;

            opt[1] = options.Duplicate();
            opt[1].XSkip *= 2;
            opt[1].YSkip *= 2;
            opt[1].XOff += options.XSkip;

            opt[2] = options.Duplicate();
            opt[2].XSkip *= 2;
            opt[2].YSkip *= 2;
            opt[2].YSkip += options.YSkip;

            opt[3] = options.Duplicate();
            opt[3].XSkip *= 2;
            opt[3].YSkip *= 2;
            opt[3].XOff += options.XSkip;
            opt[3].YOff += options.YSkip;

            return opt;
        }
Example #3
0
        public virtual void RenderAsync(CalculationOptions options, RenderCompleteCallback callback)
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                CalculationOptions op = (o as object[])[0] as CalculationOptions;
                RenderCompleteCallback cb = (o as object[])[1] as RenderCompleteCallback;

                OrbitMap calc = Calculate(op);
                cb(calc);
            }, new object[] { options, callback });
        }
Example #4
0
        private void button1_Click(object sender, EventArgs e)
        {
            Colorizer c = colorizers[ci++ % colorizers.Count];

            CalculationOptions opt = new CalculationOptions(pictureBox1.Width, pictureBox1.Height, 100);
            opt.BulbChecking = true;
            opt.OrbitLength = 0;

            RenderOptions rp = new RenderOptions() { CanvasWidth = pictureBox1.Width, CanvasHeight = pictureBox1.Height };

            OrbitMap m = calc.Calculate(opt);
            Bitmap b = c.DrawBitmap(m, rp, opt, null);

            pictureBox1.Image = b;
        }
        public override OrbitMap Calculate(CalculationOptions options)
        {
            // Needs finetuning - a fast internet connection would benefit from smaller tasks (better utilization of computing cores),
            // but a slow one might become too slow from the overhead
            Queue<CalculationOptions> tasks = new Queue<CalculationOptions>(RenderTaskHelper.Split(options, 8 * HostSelector.EffectiveWorkers));

            OrbitMap full = new OrbitMap();
            List<RendererConnection> connections = new List<RendererConnection>();

            while (tasks.Count > 0) // While there are still tasks left
            {
                // Distribute tasks to available renderers
                DistributeTasks(HostSelector, tasks, connections);

                // While we have running render tasks
                while (connections.Count > 0)
                {
                    // Wait for one task to finish
                    WaitHandle[] handles = connections.Select(c => c.WaitHandle).ToArray();
                    int h = WaitHandle.WaitAny(handles);

                    RendererConnection conn = connections[h];
                    connections.RemoveAt(h);

                    HostSelector.ConnectionCompleted(conn);

                    if (conn.Success)
                    {
                        // If it was a success, extend the OrbitMap with these results
                        full.Extend(conn.Result);
                    }
                    else
                    {
                        // TODO error handling, retry?
                        tasks.Enqueue(conn.Task);             // Re-enqueue it until it succeeds (maybe have to do something about that)
                    }

                    // Got an available renderer - fill it with a task
                    DistributeTasks(HostSelector, tasks, connections);
                }
            }
            return full; // Return the combined orbit map
        }
 internal static CalculationOptions[] Split(CalculationOptions options, int tasks)
 {
     if (tasks < 1)
         throw new ArgumentOutOfRangeException();
     return Split(options, (uint)tasks);
 }
Example #7
0
 public abstract OrbitMap Calculate(CalculationOptions options);
 internal void BeginRenderAsync(CalculationOptions opt)
 {
     Task = opt;
     worker = new Thread(Work);
     worker.Start(opt);
 }