protected sealed override void OnExecute() { for (int i = 0; i < this.iterations; ++i) { EffectConfigToken localToken; if (this.token == null) { localToken = null; } else { localToken = (EffectConfigToken)this.token.Clone(); } RenderArgs srcArgs = new RenderArgs(image); RenderArgs dstArgs = new RenderArgs(dst); BackgroundEffectRenderer ber = new BackgroundEffectRenderer(effect, localToken, dstArgs, srcArgs, region, 25 * Processor.LogicalCpuCount, Processor.LogicalCpuCount); ber.Start(); ber.Join(); ber.Dispose(); ber = null; } }
private void EffectConfigTokenChangedHandler(object sender, System.EventArgs e) { EffectConfigDialog ecf = (EffectConfigDialog)sender; BackgroundEffectRenderer ber = (BackgroundEffectRenderer)ecf.Tag; if (ber != null) { AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBarAsync(); ber.Start(); } }
protected sealed override void OnExecute() { for (int i = 0; i < this.Iterations; ++i) { EffectConfigToken localToken = Token == null ? null : (EffectConfigToken)Token.Clone(); RenderArgs srcArgs = new RenderArgs(Image); RenderArgs dstArgs = new RenderArgs(Dest); using (BackgroundEffectRenderer ber = new BackgroundEffectRenderer( Effect, localToken, dstArgs, srcArgs, Region, 25 * Processor.LogicalCpuCount, Processor.LogicalCpuCount)) { ber.Start(); ber.Join(); } } }
private bool DoEffect(Effect effect, EffectConfigToken token, PdnRegion selectedRegion, PdnRegion regionToRender, Surface originalSurface) { bool oldDirtyValue = AppWorkspace.ActiveDocumentWorkspace.Document.Dirty; bool resetDirtyValue = false; bool returnVal = false; AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = false; try { using (ProgressDialog aed = new ProgressDialog()) { if (effect.Image != null) { aed.Icon = Utility.ImageToIcon(effect.Image, Utility.TransparentKey); } aed.Opacity = 0.9; aed.Value = 0; aed.Text = effect.Name; aed.Description = string.Format(PdnResources.GetString("Effects.ApplyingDialog.Description"), effect.Name); invalidateTimer.Enabled = true; using (new WaitCursorChanger(AppWorkspace)) { HistoryMemento ha = null; DialogResult result = DialogResult.None; AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar(); AppWorkspace.Widgets.LayerControl.SuspendLayerPreviewUpdates(); try { ManualResetEvent saveEvent = new ManualResetEvent(false); BitmapHistoryMemento bha = null; // perf bug #1445: save this data in a background thread PdnRegion selectedRegionCopy = selectedRegion.Clone(); PaintDotNet.Threading.ThreadPool.Global.QueueUserWorkItem( delegate(object context) { try { ImageResource image; if (effect.Image == null) { image = null; } else { image = ImageResource.FromImage(effect.Image); } bha = new BitmapHistoryMemento(effect.Name, image, this.AppWorkspace.ActiveDocumentWorkspace, this.AppWorkspace.ActiveDocumentWorkspace.ActiveLayerIndex, selectedRegionCopy, originalSurface); } finally { saveEvent.Set(); selectedRegionCopy.Dispose(); selectedRegionCopy = null; } }); BackgroundEffectRenderer ber = new BackgroundEffectRenderer( effect, token, new RenderArgs(((BitmapLayer)AppWorkspace.ActiveDocumentWorkspace.ActiveLayer).Surface), new RenderArgs(originalSurface), regionToRender, tilesPerCpu * renderingThreadCount, renderingThreadCount); aed.Tag = ber; ber.RenderedTile += new RenderedTileEventHandler(aed.RenderedTileHandler); ber.RenderedTile += new RenderedTileEventHandler(RenderedTileHandler); ber.StartingRendering += new EventHandler(StartingRenderingHandler); ber.FinishedRendering += new EventHandler(aed.FinishedRenderingHandler); ber.FinishedRendering += new EventHandler(FinishedRenderingHandler); ber.Start(); result = Utility.ShowDialog(aed, AppWorkspace); if (result == DialogResult.Cancel) { resetDirtyValue = true; using (new WaitCursorChanger(AppWorkspace)) { ber.Abort(); ber.Join(); ((BitmapLayer)AppWorkspace.ActiveDocumentWorkspace.ActiveLayer).Surface.CopySurface(originalSurface); } } invalidateTimer.Enabled = false; ber.Join(); ber.Dispose(); saveEvent.WaitOne(); saveEvent.Close(); saveEvent = null; ha = bha; } catch { using (new WaitCursorChanger(AppWorkspace)) { ((BitmapLayer)AppWorkspace.ActiveDocumentWorkspace.ActiveLayer).Surface.CopySurface(originalSurface); ha = null; } } finally { AppWorkspace.Widgets.LayerControl.ResumeLayerPreviewUpdates(); } using (PdnRegion simplifiedRenderRegion = Utility.SimplifyAndInflateRegion(selectedRegion)) { using (new WaitCursorChanger(AppWorkspace)) { AppWorkspace.ActiveDocumentWorkspace.ActiveLayer.Invalidate(simplifiedRenderRegion); } } using (new WaitCursorChanger(AppWorkspace)) { if (result == DialogResult.OK) { if (ha != null) { AppWorkspace.ActiveDocumentWorkspace.History.PushNewMemento(ha); } AppWorkspace.Update(); returnVal = true; } else { Utility.GCFullCollect(); } } } // using } // using } finally { AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = true; if (resetDirtyValue) { AppWorkspace.ActiveDocumentWorkspace.Document.Dirty = oldDirtyValue; } } AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBarAsync(); return(returnVal); }
public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { ConfigToken token = (ConfigToken)parameters; PdnRegion selection = EnvironmentParameters.GetSelection(srcArgs.Bounds); if (changed) { changed = false; if (dialog != null) { dialog.SetProgressBarMaximum(token.effects.Count, tilesPerCpu * renderingThreadCount); dialog.EnableOKButton(false); } using (Surface scratch = new Surface(srcArgs.Size)) { scratch.CopySurface(srcArgs.Surface); for (int i = 0; i < token.effects.Count; ++i) { ScriptStep step = token.effects[i]; Type type = step.EffectType; if (type == null) { if (dialog != null) { dialog.IncrementProgressBarValue(i, 1); } } else { Effect effect = (Effect)(type.GetConstructor(Type.EmptyTypes).Invoke(new object[0])); effect.Services = Services; effect.EnvironmentParameters = new EffectEnvironmentParameters( step.PrimaryColor, step.SecondaryColor, EnvironmentParameters.BrushWidth, selection, EnvironmentParameters.SourceSurface); BackgroundEffectRenderer ber = new BackgroundEffectRenderer(effect, step.Token, dstArgs, new RenderArgs(scratch), selection, null, tilesPerCpu * renderingThreadCount, renderingThreadCount); ber.RenderedTile += (sender, e) => RenderedTile((BackgroundEffectRenderer)sender, i, e.TileCount); ber.Start(); ber.Join(); scratch.CopySurface(dstArgs.Surface); } if (IsCancelRequested) { return; } } if (dialog != null) { dialog.ClearProgressBars(); dialog.EnableOKButton(true); } } } }
public void RunEffect(Type effectType) { bool oldDirtyValue = AppWorkspace.ActiveDocumentWorkspace.Document.Dirty; bool resetDirtyValue = false; AppWorkspace.Update(); // make sure the window is done 'closing' AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar(); DocumentWorkspace activeDW = AppWorkspace.ActiveDocumentWorkspace; PdnRegion selectedRegion; if (activeDW.Selection.IsEmpty) { selectedRegion = new PdnRegion(activeDW.Document.Bounds); } else { selectedRegion = activeDW.Selection.CreateRegion(); } Exception exception = null; Effect effect = null; BitmapLayer layer = (BitmapLayer)activeDW.ActiveLayer; using (new PushNullToolMode(activeDW)) { try { effect = (Effect)Activator.CreateInstance(effectType); string name = effect.Name; EffectConfigToken newLastToken = null; if (!(effect.CheckForEffectFlags(EffectFlags.Configurable))) { Surface copy = activeDW.BorrowScratchSurface(GetType() + ".RunEffect() using scratch surface for non-configurable rendering"); try { using (new WaitCursorChanger(AppWorkspace)) { copy.CopySurface(layer.Surface); } EffectEnvironmentParameters eep = new EffectEnvironmentParameters( AppWorkspace.AppEnvironment.PrimaryColor, AppWorkspace.AppEnvironment.SecondaryColor, AppWorkspace.AppEnvironment.PenInfo.Width, selectedRegion, copy); effect.EnvironmentParameters = eep; DoEffect(effect, null, selectedRegion, selectedRegion, copy, out exception); } finally { activeDW.ReturnScratchSurface(copy); } } else { PdnRegion previewRegion = (PdnRegion)selectedRegion.Clone(); previewRegion.Intersect(RectangleF.Inflate(activeDW.VisibleDocumentRectangleF, 1, 1)); Surface originalSurface = activeDW.BorrowScratchSurface(GetType() + ".RunEffect() using scratch surface for rendering during configuration"); try { using (new WaitCursorChanger(AppWorkspace)) { originalSurface.CopySurface(layer.Surface); } EffectEnvironmentParameters eep = new EffectEnvironmentParameters( AppWorkspace.AppEnvironment.PrimaryColor, AppWorkspace.AppEnvironment.SecondaryColor, AppWorkspace.AppEnvironment.PenInfo.Width, selectedRegion, originalSurface); effect.EnvironmentParameters = eep; // IDisposable resumeTUFn = AppWorkspace.SuspendThumbnailUpdates(); // using (EffectConfigDialog configDialog = effect.CreateConfigDialog()) { configDialog.Opacity = 0.9; configDialog.Effect = effect; configDialog.EffectSourceSurface = originalSurface; configDialog.Selection = selectedRegion; BackgroundEffectRenderer ber = null; void OnEffectTokenChanged(object sender, EventArgs e) { EffectConfigDialog ecf = (EffectConfigDialog)sender; if (ber != null) { AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBarAsync(); try { ber.Start(); } catch (Exception ex) { exception = ex; ecf.Close(); } } } configDialog.EffectTokenChanged += OnEffectTokenChanged; if (EffectTokens.ContainsKey(effectType)) { EffectConfigToken oldToken = (EffectConfigToken)EffectTokens[effectType].Clone(); configDialog.EffectToken = oldToken; } int pixelCount = layer.Surface.Height; int threadCount = effect.CheckForEffectFlags(EffectFlags.SingleThreaded) ? 1 : RenderingThreadCount; int maxTiles = TilesPerCpu * threadCount; int tileCount = Math.Min(maxTiles, pixelCount); ber = new BackgroundEffectRenderer( effect, configDialog.EffectToken, new RenderArgs(layer.Surface), new RenderArgs(originalSurface), previewRegion, tileCount, threadCount); ber.RenderedTile += new RenderedTileEventHandler(RenderedTileHandler); ber.StartingRendering += new EventHandler(StartingRenderingHandler); ber.FinishedRendering += new EventHandler(FinishedRenderingHandler); InvalidateTimer.Enabled = true; DialogResult dr; try { dr = Utility.ShowDialog(configDialog, AppWorkspace); } catch (Exception ex) { dr = DialogResult.None; exception = ex; } InvalidateTimer.Enabled = false; InvalidateTimer_Tick(InvalidateTimer, EventArgs.Empty); if (dr == DialogResult.OK) { EffectTokens[effectType] = (EffectConfigToken)configDialog.EffectToken.Clone(); } using (new WaitCursorChanger(AppWorkspace)) { try { ber.Abort(); ber.Join(); } catch (Exception ex) { exception = ex; } ber.Dispose(); ber = null; if (dr != DialogResult.OK) { ((BitmapLayer)activeDW.ActiveLayer).Surface.CopySurface(originalSurface); activeDW.ActiveLayer.Invalidate(); } configDialog.EffectTokenChanged -= OnEffectTokenChanged; configDialog.Hide(); AppWorkspace.Update(); previewRegion.Dispose(); } // resumeTUFn.Dispose(); resumeTUFn = null; // if (dr == DialogResult.OK) { PdnRegion remainingToRender = selectedRegion.Clone(); PdnRegion alreadyRendered = PdnRegion.CreateEmpty(); for (int i = 0; i < ProgressRegions.Length; ++i) { if (ProgressRegions[i] == null) { break; } else { remainingToRender.Exclude(ProgressRegions[i]); alreadyRendered.Union(ProgressRegions[i]); } } activeDW.ActiveLayer.Invalidate(alreadyRendered); newLastToken = (EffectConfigToken)configDialog.EffectToken.Clone(); AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar(); DoEffect(effect, newLastToken, selectedRegion, remainingToRender, originalSurface, out exception); } else // if (dr == DialogResult.Cancel) { using (new WaitCursorChanger(AppWorkspace)) { activeDW.ActiveLayer.Invalidate(); Utility.GCFullCollect(); } resetDirtyValue = true; return; } } } catch (Exception ex) { exception = ex; } finally { activeDW.ReturnScratchSurface(originalSurface); } } // if it was from the Effects menu, save it as the "Repeat ...." item if (effect.Category == EffectCategory.Effect) { LastEffect = effect; LastEffectToken = newLastToken == null ? null : (EffectConfigToken)newLastToken.Clone(); PopulateMenu(true); } } catch (Exception ex) { exception = ex; } finally { selectedRegion.Dispose(); AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar(); AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBar(); AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = true; if (ProgressRegions != null) { for (int i = 0; i < ProgressRegions.Length; ++i) { ProgressRegions[i]?.Dispose(); ProgressRegions[i] = null; } } if (resetDirtyValue) { AppWorkspace.ActiveDocumentWorkspace.Document.Dirty = oldDirtyValue; } if (exception != null) { HandleEffectException(AppWorkspace, effect, exception); } } } }