NinthDesertDude Posted June 16, 2022 Share Posted June 16, 2022 In short, I need to get any effect to at least not crash, because I can't release a feature that crashes PDN. Any effect that can normally run in Paint.net needs to theoretically be able to run in DynamicDraw. ScriptLab is the best for this, but it's inoperable right now and hard to glean info from since it uses chunks of code copied from PDN that depend on now-internal classes. I've also scoured forums a bit and the plugin index; I took what I could from Effect Lab already. Some complicated effects like G'mic work, while some like Radial Blur crash (the only built-in effect that's not behaving). Maybe someone can tell what's null here? Spoiler System.NullReferenceException: Object reference not set to an instance of an object. at PaintDotNet.Effects.Gpu.RadialBlurGpuEffect.OnCreateConfigUI(PropertyCollection props) in D:\src\pdn\src_4_3_x\Effects\Gpu\RadialBlurGpuEffect.cs:line 76 at PaintDotNet.Effects.Gpu.PropertyBasedGpuEffect.PaintDotNet.Effects.IPropertyBasedEffectHost.OnCreateConfigUI(PropertyCollection props) in D:\src\pdn\src_4_3_x\Effects\Gpu\PropertyBasedGpuEffect.cs:line 60 at PaintDotNet.Effects.PropertyBasedEffectHandler`1.RelayCreateConfigUI(PropertyCollection props) in D:\src\pdn\src_4_3_x\Effects\PropertyBasedEffectHandler.cs:line 58 at PaintDotNet.Effects.Gpu.PropertyBasedGpuEffect.CreateConfigUI(PropertyCollection props) in D:\src\pdn\src_4_3_x\Effects\Gpu\PropertyBasedGpuEffect.cs:line 55 at PaintDotNet.Effects.PropertyBasedEffectHandler`1.RelayCreateConfigDialog() in D:\src\pdn\src_4_3_x\Effects\PropertyBasedEffectHandler.cs:line 33 at PaintDotNet.Effects.Gpu.PropertyBasedGpuEffect.CreateConfigDialog() in D:\src\pdn\src_4_3_x\Effects\Gpu\PropertyBasedGpuEffect.cs:line 49 at DynamicDraw.WinDynamicDraw.CmbxChosenEffect_SelectedIndexChanged(Object sender, EventArgs e) at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e) at System.Windows.Forms.ComboBox.WmReflectCommand(Message& m) at System.Windows.Forms.ComboBox.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam) Noteworthy things I'm doing I subscribe to Application.ThreadException already and successfully catch thread errors from some plugins that crash I'm not running any effects in the DoNotDisplay effect category. I run effects using CreateConfigDialog(), then setting the effect, the dialog owner, and token, then ShowDialog().I pass in these environment parameters: effectToDraw.effect.EnvironmentParameters = new EffectEnvironmentParameters( bttnBrushColor.BackColor, Color.Black, sliderBrushSize.Value, Document.DefaultResolution, new PdnRegion(EnvironmentParameters.GetSelectionAsPdnRegion().GetRegionData()), Surface.CopyFromBitmap(bmpCommitted)); On a worker thread, just after the dialog opens or the effect token changes, I render the effect. (ROIs are well-tested and valid, accounting for the full image.) effectToDraw.effect.Render( changedToken ?? effectToDraw.settings ?? new PropertyBasedEffectConfigToken(effectToDraw.propertySettings), stagedBmpSurface, committedBmpSurface, Utils.GetRois(bmpCommitted.Width, bmpCommitted.Height)); All built-in effects work except radial blur, which crashes and isn't caught by the application-level thread exception handler (there are 2 effects that have no dialog and don't give results, but that's probably my fault, and similar ones like Sepia still work). Custom effects work, both property and non-property based, but with varying success. Effects like PasteAlpha will indefinitely hang paint.net and I really, really need a solution to those because I don't want people losing work and I really don't want to maintain a whitelist of working plugins. Has anyone besides ScriptLab, EffectLab and myself tried to run any effect programmatically? Do you see anything wrong with my approach? Any thoughts on what could be failing? All advice welcome! Quote Link to comment Share on other sites More sharing options...
BoltBait Posted June 16, 2022 Share Posted June 16, 2022 The plugin browser runs effects programmatically. https://forums.getpaint.net/topic/110458-the-plugin-browser-v14-oct-2-2021/ 1 Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
toe_head2001 Posted June 16, 2022 Share Posted June 16, 2022 32 minutes ago, NinthDesertDude said: ... PasteAlpha will indefinitely hang paint.net ... Sounds like you're using an old version of Paste Alpha. BoltBait fixed that bug very recently. Quote My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Rick Brewster Posted June 16, 2022 Share Posted June 16, 2022 1 hour ago, NinthDesertDude said: Noteworthy things I'm doing I subscribe to Application.ThreadException Do not do this. It is not acceptable to subscribe to that event -- you will cause massive problems if you do anything wrong, or if you do not unsubscribe from the event. You are attempting a global solution to a local problem. Your job is not to catch and handle exceptions from plugins that you are trying to host. If they crash, you crash. Maintain a list of blocked plugins instead. By "Effect Lab" do you mean pyro's ScriptLab? It was doing a ton of bad things that resulted in it not surviving the migration to .NET 5 / PDN 4.3. Again: Do. Not. Subscribe. To. That. Event. I will block your plugin if you do this. If you're already doing this, I will need to block your current release in the next app update, so you will want to fix that ASAP. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
NinthDesertDude Posted June 16, 2022 Author Share Posted June 16, 2022 (edited) 38 minutes ago, Rick Brewster said: Do. Not. Subscribe. To. That. Event. Easy enough, but how is this worse than crashing paint.net to desktop by any other means? Go ahead and block BrushFilter which does this; the plugin is deprecated and my work here is to replace it, actually. This is the last piece before everything it did is part of DynamicDraw I couldn't find "effect lab", so it's probably the same as ScriptLab. Long ago, I used effect lab to create the BrushFilter plugin. Today all I could find was ScriptLab, which isn't maintained now. All I see is TR's unmerged PR that's now itself out-of-date. Shame to lose such a plugin. I think I have a good way to deal with maintaining a plugin list, if it comes down to it. Though I'm hopeful the plugin browser does everything just right and I can skate by with all plugins working or at least not crashing. For clarity, DynamicDraw is safe and does not do this. Edited June 16, 2022 by NinthDesertDude Quote Link to comment Share on other sites More sharing options...
NinthDesertDude Posted June 16, 2022 Author Share Posted June 16, 2022 2 hours ago, BoltBait said: The plugin browser runs effects programmatically. https://forums.getpaint.net/topic/110458-the-plugin-browser-v14-oct-2-2021/ Is the source code available and/or can it be shared? I want to see if it's doing something differently 2 hours ago, toe_head2001 said: Sounds like you're using an old version of Paste Alpha. BoltBait fixed that bug very recently. Confirmed, it's working correctly and without hanging the entire app. That's great! Thanks for the tip Quote Link to comment Share on other sites More sharing options...
null54 Posted June 16, 2022 Share Posted June 16, 2022 2 hours ago, NinthDesertDude said: Is the source code available and/or can it be shared? As far as I am aware, the source code is not publicly available. You can use ILSpy to examine the decompiled output of the plugin code. Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
Rick Brewster Posted June 16, 2022 Share Posted June 16, 2022 10 hours ago, NinthDesertDude said: Go ahead and block BrushFilter which does this; the plugin is deprecated and my work here is to replace it, actually. This is the last piece before everything it did is part of DynamicDraw BrushFilter was already blocked because the way it was discovering and instantiating plugins just broke with PDN 4.3 / .NET 5. I forget the details. You're using IEffectsService, right? Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
NinthDesertDude Posted June 16, 2022 Author Share Posted June 16, 2022 46 minutes ago, Rick Brewster said: BrushFilter was already blocked because the way it was discovering and instantiating plugins just broke with PDN 4.3 / .NET 5. I forget the details. You're using IEffectsService, right? Wasn't sure if you meant blocked from continuing to future PDN versions, or if you meant effective-immediate removal of any download links and such. Yes I'm using IEffectsService. Thank goodness for it, too. So much easier. Quote Link to comment Share on other sites More sharing options...
null54 Posted June 16, 2022 Share Posted June 16, 2022 19 hours ago, NinthDesertDude said: Maybe someone can tell what's null here? Looking at the code for that method, the only thing I can see that may be null is the EnvironmentParameters property. The Radial Blur effect accesses the EnvironmentParameters.SourceSurface property to set the background image for the offset control. Effects can access the EnvironmentParameters in CreateConfigDialog, OnCreatePropertyCollection and OnCreateConfigUI, so it needs to be initialized before those methods are called. 1 Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
Rick Brewster Posted June 16, 2022 Share Posted June 16, 2022 Pretty sure you're not setting the Services property. I should probably initialize when you call IEffectInfo::CreateInstance(). Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
NinthDesertDude Posted June 18, 2022 Author Share Posted June 18, 2022 On 6/16/2022 at 4:44 PM, null54 said: Effects can access the EnvironmentParameters in CreateConfigDialog, OnCreatePropertyCollection and OnCreateConfigUI, so it needs to be initialized before those methods are called. You've got some really insightful psychic debugging skills there, null54. I was creating the property collection earlier, thinking that was safe to do. Now it works fine. On 6/16/2022 at 4:46 PM, Rick Brewster said: Pretty sure you're not setting the Services property I do have it set actually; I just didn't mention it in the post. Accidental omission. It's set at the same time as environment parameters. Now all I have to do is get an enormous list of all the up-to-date plugins and go through that whole rigamarole again to see what's working...thanks for the help, guys. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted June 18, 2022 Share Posted June 18, 2022 Are you setting Services with your own implementation, or with the Services that Paint.NET gave to you for your Effect class? Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
NinthDesertDude Posted June 18, 2022 Author Share Posted June 18, 2022 3 hours ago, Rick Brewster said: Are you setting Services with your own implementation, or with the Services that Paint.NET gave to you for your Effect class? Right now I do this: effectToDraw.effect.Services = this.Services; let me know if I don't need to set it, and when it gets set would be very good to know in that case, to make sure I won't initialize it too late or something. There's a 2017 thread saying the Services would be set up correctly as long as the effect was set up correctly, but at some point it was either scriptlab or plugin browser which had this line of code that I borrowed, since they render plugins correctly in practice and I was taking implementation over documentation. So yeah, whatever the correct way to do it would be best to know. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted June 18, 2022 Share Posted June 18, 2022 Yeah that's the right way to do it. I may introduce an IEffectsService2, hopefully in 4.4 because I've got a bunch of changes I want to make to the Effect system and class hierarchy. At that point I may change the way things initialize, and make IEffectsService obsolete, but that kind of breaking change will be on an interface boundary and you won't have existing code broken (as in, it won't break plugins that are already installed on end-user's systems). 1 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.