Esempio n. 1
0
        /// <summary>
        /// Renders only the portions of the document that have changed (been Invalidated) since
        /// the last call to this function.
        /// </summary>
        /// <param name="args">Contains information used to control where rendering occurs.</param>
        /// <returns>true if any rendering was done (the update list was non-empty), false otherwise</returns>
        public bool Update(RenderArgs dst)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("Document");
            }

            Rectangle[] updateRects;
            int         updateRectsLength;

            updateRegion.GetArrayReadOnly(out updateRects, out updateRectsLength);

            if (updateRectsLength == 0)
            {
                return(false);
            }

            PdnRegion region = Utility.RectanglesToRegion(updateRects, 0, updateRectsLength);

            Rectangle[] rectsOriginal = region.GetRegionScansReadOnlyInt();
            Rectangle[] rectsToUse;

            // Special case where we're drawing 1 big rectangle: split it up!
            // This case happens quite frequently, but we don't want to spend a lot of
            // time analyzing any other case that is more complicated.
            if (rectsOriginal.Length == 1 && rectsOriginal[0].Height > 1)
            {
                Rectangle[] rectsNew = new Rectangle[Processor.LogicalCpuCount];
                Utility.SplitRectangle(rectsOriginal[0], rectsNew);
                rectsToUse = rectsNew;
            }
            else
            {
                rectsToUse = rectsOriginal;
            }

            int cpuCount = Processor.LogicalCpuCount;

            for (int i = 0; i < cpuCount; ++i)
            {
                int start = (i * rectsToUse.Length) / cpuCount;
                int end   = ((i + 1) * rectsToUse.Length) / cpuCount;

                UpdateScansContext usc = new UpdateScansContext(this, dst, rectsToUse, start, end - start);

                if (i == cpuCount - 1)
                {
                    // Reuse this thread for the last job -- no sense creating a new thread.
                    usc.UpdateScans(usc);
                }
                else
                {
                    threadPool.QueueUserWorkItem(new WaitCallback(usc.UpdateScans), usc);
                }
            }

            this.threadPool.Drain();
            Validate();
            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Renders only the portions of the document that have changed (been Invalidated) since 
        /// the last call to this function.
        /// </summary>
        /// <param name="args">Contains information used to control where rendering occurs.</param>
        /// <returns>true if any rendering was done (the update list was non-empty), false otherwise</returns>
        public bool Update(RenderArgs dst)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("Document");
            }

            Rectangle[] updateRects;
            int updateRectsLength;
            updateRegion.GetArrayReadOnly(out updateRects, out updateRectsLength);

            if (updateRectsLength == 0)
            {
                return false;
            }

            PdnRegion region = Utility.RectanglesToRegion(updateRects, 0, updateRectsLength);
            Rectangle[] rectsOriginal = region.GetRegionScansReadOnlyInt();
            Rectangle[] rectsToUse;

            // Special case where we're drawing 1 big rectangle: split it up!
            // This case happens quite frequently, but we don't want to spend a lot of
            // time analyzing any other case that is more complicated.
            if (rectsOriginal.Length == 1 && rectsOriginal[0].Height > 1)
            {
                Rectangle[] rectsNew = new Rectangle[Processor.LogicalCpuCount];
                Utility.SplitRectangle(rectsOriginal[0], rectsNew);
                rectsToUse = rectsNew;
            }
            else
            {
                rectsToUse = rectsOriginal;
            }

            int cpuCount = Processor.LogicalCpuCount;
            for (int i = 0; i < cpuCount; ++i)
            {
                int start = (i * rectsToUse.Length) / cpuCount;
                int end = ((i + 1) * rectsToUse.Length) / cpuCount;

                UpdateScansContext usc = new UpdateScansContext(this, dst, rectsToUse, start, end - start);

                if (i == cpuCount - 1)
                {
                    // Reuse this thread for the last job -- no sense creating a new thread.
                    usc.UpdateScans(usc);
                }
                else
                {
                    threadPool.QueueUserWorkItem(new WaitCallback(usc.UpdateScans), usc);
                }
            }

            this.threadPool.Drain();
            Validate();
            return true;
        }