Ejemplo n.º 1
0
        protected void ApplyLoop(ISurface src, ISurface dst, Rectangle roi, CancellationToken token, IRenderProgress progress)
        {
            src.BeginUpdate();
            dst.BeginUpdate();

            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.GetPointAddress(roi.X, y);
                    var srcPtr = src.GetPointAddress(roi.X, y);
                    Apply(srcPtr, 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.GetPointAddress(roi.X, y);
                    var srcPtr = src.GetPointAddress(roi.X, y);
                    Apply(srcPtr, 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;
                    }
                });
            }

            src.EndUpdate();
            dst.EndUpdate();
        }
        private unsafe void ApplyAndSwap(ISurface dst, bool swap)
        {
            dst.BeginUpdate();

            var       dest_width = dst.Width;
            var       dst_ptr    = (ColorBgra *)dst.GetRowAddress(0);
            var       mask_index = 0;
            ColorBgra swap_pixel;

            fixed(ColorBgra *fixed_ptr = pixels)
            {
                var pixel_ptr = fixed_ptr;

                dst_ptr += bounds.X + bounds.Y * dest_width;

                for (int y = bounds.Y; y <= bounds.Bottom; y++)
                {
                    for (int x = bounds.X; x <= bounds.Right; x++)
                    {
                        if (bitmask[mask_index++])
                        {
                            if (swap)
                            {
                                swap_pixel = *dst_ptr;
                                *dst_ptr     = *pixel_ptr;
                                *pixel_ptr++ = swap_pixel;
                            }
                            else
                            {
                                *dst_ptr = *pixel_ptr++;
                            }
                        }

                        dst_ptr++;
                    }

                    dst_ptr += dest_width - bounds.Width;
                }
            }

            dst.EndUpdate();
        }
        public unsafe void Render(ISurface surface, params Rectangle[] rois)
        {
            byte startAlpha;
            byte endAlpha;

            if (this.AlphaOnly)
            {
                ComputeAlphaOnlyValuesFromColors(this.startColor, this.endColor, out startAlpha, out endAlpha);
            }
            else
            {
                startAlpha = this.startColor.A;
                endAlpha   = this.endColor.A;
            }

            surface.BeginUpdate();

            for (int ri = 0; ri < rois.Length; ++ri)
            {
                var rect = rois[ri];

                if (this.StartPoint.X == this.EndPoint.X && this.StartPoint.Y == this.EndPoint.Y)
                {
                    // Start and End point are the same ... fill with solid color.
                    for (int y = rect.Top; y <= rect.Bottom; ++y)
                    {
                        var pixelPtr = surface.GetPointAddress(rect.Left, y);

                        for (int x = rect.Left; x <= rect.Right; ++x)
                        {
                            ColorBgra result;

                            if (this.AlphaOnly && this.AlphaBlending)
                            {
                                byte resultAlpha = (byte)Utility.FastDivideShortByByte((ushort)(pixelPtr->A * endAlpha), 255);
                                result   = *pixelPtr;
                                result.A = resultAlpha;
                            }
                            else if (this.AlphaOnly && !this.AlphaBlending)
                            {
                                result   = *pixelPtr;
                                result.A = endAlpha;
                            }
                            else if (!this.AlphaOnly && this.AlphaBlending)
                            {
                                result = this.normalBlendOp.Apply(*pixelPtr, this.endColor);
                                //if (!this.alphaOnly && !this.alphaBlending)
                            }
                            else
                            {
                                result = this.endColor;
                            }

                            *pixelPtr = result;
                            ++pixelPtr;
                        }
                    }
                }
                else
                {
                    var mainrect = rect;
                    Parallel.ForEach(Enumerable.Range(rect.Top, rect.Bottom + 1),
                                     (y) => ProcessGradientLine(startAlpha, endAlpha, y, mainrect, surface));
                }
            }

            surface.EndUpdate();
            AfterRender();
        }
		private unsafe void ApplyAndSwap (ISurface dst, bool swap)
		{
			dst.BeginUpdate ();

			var dest_width = dst.Width;
			var dst_ptr = (ColorBgra*)dst.GetRowAddress (0);
			var mask_index = 0;
			ColorBgra swap_pixel;

			fixed (ColorBgra* fixed_ptr = pixels) {
				var pixel_ptr = fixed_ptr;
				dst_ptr += bounds.X + bounds.Y * dest_width;

				for (int y = bounds.Y; y <= bounds.Bottom; y++) {
					for (int x = bounds.X; x <= bounds.Right; x++) {
						if (bitmask[mask_index++])
							if (swap) {
								swap_pixel = *dst_ptr;
								*dst_ptr = *pixel_ptr;
								*pixel_ptr++ = swap_pixel;
							} else {
								*dst_ptr = *pixel_ptr++;
							}

						dst_ptr++;
					}

					dst_ptr += dest_width - bounds.Width;
				}
			}
			
			dst.EndUpdate ();
		}
		public unsafe void Render (ISurface surface, params Rectangle[] rois)
		{
			byte startAlpha;
			byte endAlpha;
			
			if (this.AlphaOnly) {
				ComputeAlphaOnlyValuesFromColors (this.startColor, this.endColor, out startAlpha, out endAlpha);
			} else {
				startAlpha = this.startColor.A;
				endAlpha = this.endColor.A;
			}
			
			surface.BeginUpdate ();
			
			for (int ri = 0; ri < rois.Length; ++ri) {
				var rect = rois[ri];
				
				if (this.StartPoint.X == this.EndPoint.X && this.StartPoint.Y == this.EndPoint.Y) {
					// Start and End point are the same ... fill with solid color.
					for (int y = rect.Top; y <= rect.Bottom; ++y) {
						var pixelPtr = surface.GetPointAddress(rect.Left, y);
						
						for (int x = rect.Left; x <= rect.Right; ++x) {
							ColorBgra result;
							
							if (this.AlphaOnly && this.AlphaBlending) {
								byte resultAlpha = (byte)Utility.FastDivideShortByByte ((ushort)(pixelPtr->A * endAlpha), 255);
								result = *pixelPtr;
								result.A = resultAlpha;
							} else if (this.AlphaOnly && !this.AlphaBlending) {
								result = *pixelPtr;
								result.A = endAlpha;
							} else if (!this.AlphaOnly && this.AlphaBlending) {
								result = this.normalBlendOp.Apply (*pixelPtr, this.endColor);
							//if (!this.alphaOnly && !this.alphaBlending)
							} else {
								result = this.endColor;
							}
							
							*pixelPtr = result;
							++pixelPtr;
						}
					}
				} else {
					var mainrect = rect;
					Parallel.ForEach(Enumerable.Range (rect.Top, rect.Bottom + 1),
						(y) => ProcessGradientLine(startAlpha, endAlpha, y, mainrect, surface));
				}
			}
			
			surface.EndUpdate ();
			AfterRender ();
		}
		protected void ApplyLoop (ISurface src, ISurface dst, Rectangle roi, CancellationToken token, IRenderProgress progress)
		{
			src.BeginUpdate ();
			dst.BeginUpdate ();

			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 srcPtr = src.GetRowAddress (y);
					Apply (srcPtr, 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 srcPtr = src.GetRowAddress (y);
					Apply (srcPtr, 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;
					}
				});
			}

			src.EndUpdate ();
			dst.EndUpdate ();
		}
Ejemplo n.º 7
0
        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 ();
			}
		}