protected unsafe virtual void RenderLoop(ISurface surface, Rectangle roi, CancellationToken token, IRenderProgress progress) { var dst = new ColorBgra[surface.Height * surface.Width]; fixed(ColorBgra *dst_ptr = dst) { var dst_wrap = new ColorBgraArrayWrapper(dst_ptr, surface.Width, surface.Height); surface.BeginUpdate(); dst_wrap.BeginUpdate(); OnBeginRender(surface, dst_wrap, roi); var completed_lines = new bool[roi.Height]; var last_completed_index = 0; if (Settings.SingleThreaded || roi.Height <= 1) { for (var y = roi.Y; y <= roi.Bottom; ++y) { if (token.IsCancellationRequested) { return; } RenderLine(surface, dst_wrap, new Rectangle(roi.X, y, roi.Width, 1)); completed_lines[y - roi.Top] = true; if (progress != null) { var last_y = FindLastCompletedLine(completed_lines, last_completed_index); last_completed_index = last_y; progress.CompletedRoi = new Rectangle(roi.X, roi.Y, roi.Width, last_y); progress.PercentComplete = (float)last_y / (float)roi.Height; } } } else { ParallelExtensions.OrderedFor(roi.Y, roi.Bottom + 1, token, (y) => { RenderLine(surface, dst_wrap, new Rectangle(roi.X, y, roi.Width, 1)); completed_lines[y - roi.Top] = true; if (progress != null) { var last_y = FindLastCompletedLine(completed_lines, last_completed_index); last_completed_index = last_y; progress.CompletedRoi = new Rectangle(roi.X, roi.Y, roi.Width, last_y); progress.PercentComplete = (float)last_y / (float)roi.Height; } }); } // Copy the result from our temp destination back into the source var op = new IdentityOp(); op.ApplyAsync(dst_wrap, surface, token).Wait(); surface.EndUpdate(); dst_wrap.EndUpdate(); } }
protected unsafe virtual void RenderLoop (ISurface surface, Rectangle roi, CancellationToken token, IRenderProgress progress) { var dst = new ColorBgra[surface.Height * surface.Width]; fixed (ColorBgra* dst_ptr = dst) { var dst_wrap = new ColorBgraArrayWrapper (dst_ptr, surface.Width, surface.Height); surface.BeginUpdate (); dst_wrap.BeginUpdate (); OnBeginRender (surface, dst_wrap, roi); var completed_lines = new bool[roi.Height]; var last_completed_index = 0; if (Settings.SingleThreaded || roi.Height <= 1) { for (var y = roi.Y; y <= roi.Bottom; ++y) { if (token.IsCancellationRequested) return; RenderLine (surface, dst_wrap, new Rectangle (roi.X, y, roi.Width, 1)); completed_lines[y - roi.Top] = true; if (progress != null) { var last_y = FindLastCompletedLine (completed_lines, last_completed_index); last_completed_index = last_y; progress.CompletedRoi = new Rectangle (roi.X, roi.Y, roi.Width, last_y); progress.PercentComplete = (float)last_y / (float)roi.Height; } } } else { ParallelExtensions.OrderedFor (roi.Y, roi.Bottom + 1, token, (y) => { RenderLine (surface, dst_wrap, new Rectangle (roi.X, y, roi.Width, 1)); completed_lines[y - roi.Top] = true; if (progress != null) { var last_y = FindLastCompletedLine (completed_lines, last_completed_index); last_completed_index = last_y; progress.CompletedRoi = new Rectangle (roi.X, roi.Y, roi.Width, last_y); progress.PercentComplete = (float)last_y / (float)roi.Height; } }); } // Copy the result from our temp destination back into the source var op = new IdentityOp (); op.ApplyAsync (dst_wrap, surface, token).Wait (); surface.EndUpdate (); dst_wrap.EndUpdate (); } }