diff --git a/Services/Compositor/SceneCompositor.cs b/Services/Compositor/SceneCompositor.cs index bf0a7ba..3b0444d 100644 --- a/Services/Compositor/SceneCompositor.cs +++ b/Services/Compositor/SceneCompositor.cs @@ -396,17 +396,17 @@ public sealed class SceneCompositor var x1 = System.Math.Min(cropW, px + dw); var y1 = System.Math.Min(cropH, py + dh); if (x0 >= x1 || y0 >= y1) return; - var d = buffer.AsSpan(); var s = raster.BgraPixels; - for (var y = y0; y < y1; y++) + var parallelOpts = new ParallelOptions { MaxDegreeOfParallelism = 4 }; + Parallel.For(y0, y1, parallelOpts, y => { var si = ((y - py) * dw + (x0 - px)) * 4; var len = x1 - x0; if (op == 256) - BlendRowOpaque(d, (y * cropW + x0) * 4, s.AsSpan(si, len * 4), 0, len); + BlendRowOpaque(buffer, (y * cropW + x0) * 4, s, si, len); else - BlendRowWeighted(d, (y * cropW + x0) * 4, s.AsSpan(si, len * 4), 0, len, op); - } + BlendRowWeighted(buffer, (y * cropW + x0) * 4, s, si, len, op); + }); } /// Copy and blit a global overlay onto the copy @@ -823,12 +823,13 @@ public sealed class SceneCompositor var dy0 = Math.Max(0, sy0 - options.SourceRectY); var dx1 = Math.Min(dstW, sx0 - options.SourceRectX + overlay.Width); var dy1 = Math.Min(dstH, sy0 - options.SourceRectY + overlay.Height); - for (var y = dy0; y < dy1; y++) + var parallelOpts = new ParallelOptions { MaxDegreeOfParallelism = 4 }; + Parallel.For(dy0, dy1, parallelOpts, y => { var si = ((y + options.SourceRectY - sy0) * overlay.Width + dx0 + options.SourceRectX - sx0) * 4; BlendRowOpaque(dst, (y * dstW + dx0) * 4, overlay.BgraPixels, si, dx1 - dx0); - } + }); } /// Straight-alpha source-over blend; the frame's alpha (and the layer opacity) drives coverage.