/// <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); }
/// <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; }