protected void ApplyLoop (ISurface lhs, ISurface rhs, ISurface dst, Rectangle roi, CancellationToken token, IRenderProgress progress)
{
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;
var dstPtr = dst.GetRowAddress (y);
var lhsPtr = lhs.GetRowAddress (y);
var rhsPtr = rhs.GetRowAddress (y);
Apply (lhsPtr, rhsPtr, dstPtr, roi.Width);
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) => {
var dstPtr = dst.GetRowAddress (y);
var lhsPtr = lhs.GetRowAddress (y);
var rhsPtr = rhs.GetRowAddress (y);
Apply (lhsPtr, rhsPtr, dstPtr, roi.Width);
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;
}
});
}
}